summaryrefslogtreecommitdiff
path: root/public/assets/admin_bundle-e15d8265faa7d827f0b57416f9aeec7a730d7f47ede994b76014444669fb2081.js
diff options
context:
space:
mode:
Diffstat (limited to 'public/assets/admin_bundle-e15d8265faa7d827f0b57416f9aeec7a730d7f47ede994b76014444669fb2081.js')
-rw-r--r--public/assets/admin_bundle-e15d8265faa7d827f0b57416f9aeec7a730d7f47ede994b76014444669fb2081.js31775
1 files changed, 31775 insertions, 0 deletions
diff --git a/public/assets/admin_bundle-e15d8265faa7d827f0b57416f9aeec7a730d7f47ede994b76014444669fb2081.js b/public/assets/admin_bundle-e15d8265faa7d827f0b57416f9aeec7a730d7f47ede994b76014444669fb2081.js
new file mode 100644
index 0000000..68bb979
--- /dev/null
+++ b/public/assets/admin_bundle-e15d8265faa7d827f0b57416f9aeec7a730d7f47ede994b76014444669fb2081.js
@@ -0,0 +1,31775 @@
1/*!
2 * jQuery JavaScript Library v1.12.4
3 * http://jquery.com/
4 *
5 * Includes Sizzle.js
6 * http://sizzlejs.com/
7 *
8 * Copyright jQuery Foundation and other contributors
9 * Released under the MIT license
10 * http://jquery.org/license
11 *
12 * Date: 2016-05-20T17:17Z
13 */
14
15(function( global, factory ) {
16
17 if ( typeof module === "object" && typeof module.exports === "object" ) {
18 // For CommonJS and CommonJS-like environments where a proper `window`
19 // is present, execute the factory and get jQuery.
20 // For environments that do not have a `window` with a `document`
21 // (such as Node.js), expose a factory as module.exports.
22 // This accentuates the need for the creation of a real `window`.
23 // e.g. var jQuery = require("jquery")(window);
24 // See ticket #14549 for more info.
25 module.exports = global.document ?
26 factory( global, true ) :
27 function( w ) {
28 if ( !w.document ) {
29 throw new Error( "jQuery requires a window with a document" );
30 }
31 return factory( w );
32 };
33 } else {
34 factory( global );
35 }
36
37// Pass this if window is not defined yet
38}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
39
40// Support: Firefox 18+
41// Can't be in strict mode, several libs including ASP.NET trace
42// the stack via arguments.caller.callee and Firefox dies if
43// you try to trace through "use strict" call chains. (#13335)
44//"use strict";
45var deletedIds = [];
46
47var document = window.document;
48
49var slice = deletedIds.slice;
50
51var concat = deletedIds.concat;
52
53var push = deletedIds.push;
54
55var indexOf = deletedIds.indexOf;
56
57var class2type = {};
58
59var toString = class2type.toString;
60
61var hasOwn = class2type.hasOwnProperty;
62
63var support = {};
64
65
66
67var
68 version = "1.12.4",
69
70 // Define a local copy of jQuery
71 jQuery = function( selector, context ) {
72
73 // The jQuery object is actually just the init constructor 'enhanced'
74 // Need init if jQuery is called (just allow error to be thrown if not included)
75 return new jQuery.fn.init( selector, context );
76 },
77
78 // Support: Android<4.1, IE<9
79 // Make sure we trim BOM and NBSP
80 rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
81
82 // Matches dashed string for camelizing
83 rmsPrefix = /^-ms-/,
84 rdashAlpha = /-([\da-z])/gi,
85
86 // Used by jQuery.camelCase as callback to replace()
87 fcamelCase = function( all, letter ) {
88 return letter.toUpperCase();
89 };
90
91jQuery.fn = jQuery.prototype = {
92
93 // The current version of jQuery being used
94 jquery: version,
95
96 constructor: jQuery,
97
98 // Start with an empty selector
99 selector: "",
100
101 // The default length of a jQuery object is 0
102 length: 0,
103
104 toArray: function() {
105 return slice.call( this );
106 },
107
108 // Get the Nth element in the matched element set OR
109 // Get the whole matched element set as a clean array
110 get: function( num ) {
111 return num != null ?
112
113 // Return just the one element from the set
114 ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
115
116 // Return all the elements in a clean array
117 slice.call( this );
118 },
119
120 // Take an array of elements and push it onto the stack
121 // (returning the new matched element set)
122 pushStack: function( elems ) {
123
124 // Build a new jQuery matched element set
125 var ret = jQuery.merge( this.constructor(), elems );
126
127 // Add the old object onto the stack (as a reference)
128 ret.prevObject = this;
129 ret.context = this.context;
130
131 // Return the newly-formed element set
132 return ret;
133 },
134
135 // Execute a callback for every element in the matched set.
136 each: function( callback ) {
137 return jQuery.each( this, callback );
138 },
139
140 map: function( callback ) {
141 return this.pushStack( jQuery.map( this, function( elem, i ) {
142 return callback.call( elem, i, elem );
143 } ) );
144 },
145
146 slice: function() {
147 return this.pushStack( slice.apply( this, arguments ) );
148 },
149
150 first: function() {
151 return this.eq( 0 );
152 },
153
154 last: function() {
155 return this.eq( -1 );
156 },
157
158 eq: function( i ) {
159 var len = this.length,
160 j = +i + ( i < 0 ? len : 0 );
161 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
162 },
163
164 end: function() {
165 return this.prevObject || this.constructor();
166 },
167
168 // For internal use only.
169 // Behaves like an Array's method, not like a jQuery method.
170 push: push,
171 sort: deletedIds.sort,
172 splice: deletedIds.splice
173};
174
175jQuery.extend = jQuery.fn.extend = function() {
176 var src, copyIsArray, copy, name, options, clone,
177 target = arguments[ 0 ] || {},
178 i = 1,
179 length = arguments.length,
180 deep = false;
181
182 // Handle a deep copy situation
183 if ( typeof target === "boolean" ) {
184 deep = target;
185
186 // skip the boolean and the target
187 target = arguments[ i ] || {};
188 i++;
189 }
190
191 // Handle case when target is a string or something (possible in deep copy)
192 if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
193 target = {};
194 }
195
196 // extend jQuery itself if only one argument is passed
197 if ( i === length ) {
198 target = this;
199 i--;
200 }
201
202 for ( ; i < length; i++ ) {
203
204 // Only deal with non-null/undefined values
205 if ( ( options = arguments[ i ] ) != null ) {
206
207 // Extend the base object
208 for ( name in options ) {
209 src = target[ name ];
210 copy = options[ name ];
211
212 // Prevent never-ending loop
213 if ( target === copy ) {
214 continue;
215 }
216
217 // Recurse if we're merging plain objects or arrays
218 if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
219 ( copyIsArray = jQuery.isArray( copy ) ) ) ) {
220
221 if ( copyIsArray ) {
222 copyIsArray = false;
223 clone = src && jQuery.isArray( src ) ? src : [];
224
225 } else {
226 clone = src && jQuery.isPlainObject( src ) ? src : {};
227 }
228
229 // Never move original objects, clone them
230 target[ name ] = jQuery.extend( deep, clone, copy );
231
232 // Don't bring in undefined values
233 } else if ( copy !== undefined ) {
234 target[ name ] = copy;
235 }
236 }
237 }
238 }
239
240 // Return the modified object
241 return target;
242};
243
244jQuery.extend( {
245
246 // Unique for each copy of jQuery on the page
247 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
248
249 // Assume jQuery is ready without the ready module
250 isReady: true,
251
252 error: function( msg ) {
253 throw new Error( msg );
254 },
255
256 noop: function() {},
257
258 // See test/unit/core.js for details concerning isFunction.
259 // Since version 1.3, DOM methods and functions like alert
260 // aren't supported. They return false on IE (#2968).
261 isFunction: function( obj ) {
262 return jQuery.type( obj ) === "function";
263 },
264
265 isArray: Array.isArray || function( obj ) {
266 return jQuery.type( obj ) === "array";
267 },
268
269 isWindow: function( obj ) {
270 /* jshint eqeqeq: false */
271 return obj != null && obj == obj.window;
272 },
273
274 isNumeric: function( obj ) {
275
276 // parseFloat NaNs numeric-cast false positives (null|true|false|"")
277 // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
278 // subtraction forces infinities to NaN
279 // adding 1 corrects loss of precision from parseFloat (#15100)
280 var realStringObj = obj && obj.toString();
281 return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
282 },
283
284 isEmptyObject: function( obj ) {
285 var name;
286 for ( name in obj ) {
287 return false;
288 }
289 return true;
290 },
291
292 isPlainObject: function( obj ) {
293 var key;
294
295 // Must be an Object.
296 // Because of IE, we also have to check the presence of the constructor property.
297 // Make sure that DOM nodes and window objects don't pass through, as well
298 if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
299 return false;
300 }
301
302 try {
303
304 // Not own constructor property must be Object
305 if ( obj.constructor &&
306 !hasOwn.call( obj, "constructor" ) &&
307 !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
308 return false;
309 }
310 } catch ( e ) {
311
312 // IE8,9 Will throw exceptions on certain host objects #9897
313 return false;
314 }
315
316 // Support: IE<9
317 // Handle iteration over inherited properties before own properties.
318 if ( !support.ownFirst ) {
319 for ( key in obj ) {
320 return hasOwn.call( obj, key );
321 }
322 }
323
324 // Own properties are enumerated firstly, so to speed up,
325 // if last one is own, then all properties are own.
326 for ( key in obj ) {}
327
328 return key === undefined || hasOwn.call( obj, key );
329 },
330
331 type: function( obj ) {
332 if ( obj == null ) {
333 return obj + "";
334 }
335 return typeof obj === "object" || typeof obj === "function" ?
336 class2type[ toString.call( obj ) ] || "object" :
337 typeof obj;
338 },
339
340 // Workarounds based on findings by Jim Driscoll
341 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
342 globalEval: function( data ) {
343 if ( data && jQuery.trim( data ) ) {
344
345 // We use execScript on Internet Explorer
346 // We use an anonymous function so that context is window
347 // rather than jQuery in Firefox
348 ( window.execScript || function( data ) {
349 window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation
350 } )( data );
351 }
352 },
353
354 // Convert dashed to camelCase; used by the css and data modules
355 // Microsoft forgot to hump their vendor prefix (#9572)
356 camelCase: function( string ) {
357 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
358 },
359
360 nodeName: function( elem, name ) {
361 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
362 },
363
364 each: function( obj, callback ) {
365 var length, i = 0;
366
367 if ( isArrayLike( obj ) ) {
368 length = obj.length;
369 for ( ; i < length; i++ ) {
370 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
371 break;
372 }
373 }
374 } else {
375 for ( i in obj ) {
376 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
377 break;
378 }
379 }
380 }
381
382 return obj;
383 },
384
385 // Support: Android<4.1, IE<9
386 trim: function( text ) {
387 return text == null ?
388 "" :
389 ( text + "" ).replace( rtrim, "" );
390 },
391
392 // results is for internal usage only
393 makeArray: function( arr, results ) {
394 var ret = results || [];
395
396 if ( arr != null ) {
397 if ( isArrayLike( Object( arr ) ) ) {
398 jQuery.merge( ret,
399 typeof arr === "string" ?
400 [ arr ] : arr
401 );
402 } else {
403 push.call( ret, arr );
404 }
405 }
406
407 return ret;
408 },
409
410 inArray: function( elem, arr, i ) {
411 var len;
412
413 if ( arr ) {
414 if ( indexOf ) {
415 return indexOf.call( arr, elem, i );
416 }
417
418 len = arr.length;
419 i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
420
421 for ( ; i < len; i++ ) {
422
423 // Skip accessing in sparse arrays
424 if ( i in arr && arr[ i ] === elem ) {
425 return i;
426 }
427 }
428 }
429
430 return -1;
431 },
432
433 merge: function( first, second ) {
434 var len = +second.length,
435 j = 0,
436 i = first.length;
437
438 while ( j < len ) {
439 first[ i++ ] = second[ j++ ];
440 }
441
442 // Support: IE<9
443 // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
444 if ( len !== len ) {
445 while ( second[ j ] !== undefined ) {
446 first[ i++ ] = second[ j++ ];
447 }
448 }
449
450 first.length = i;
451
452 return first;
453 },
454
455 grep: function( elems, callback, invert ) {
456 var callbackInverse,
457 matches = [],
458 i = 0,
459 length = elems.length,
460 callbackExpect = !invert;
461
462 // Go through the array, only saving the items
463 // that pass the validator function
464 for ( ; i < length; i++ ) {
465 callbackInverse = !callback( elems[ i ], i );
466 if ( callbackInverse !== callbackExpect ) {
467 matches.push( elems[ i ] );
468 }
469 }
470
471 return matches;
472 },
473
474 // arg is for internal usage only
475 map: function( elems, callback, arg ) {
476 var length, value,
477 i = 0,
478 ret = [];
479
480 // Go through the array, translating each of the items to their new values
481 if ( isArrayLike( elems ) ) {
482 length = elems.length;
483 for ( ; i < length; i++ ) {
484 value = callback( elems[ i ], i, arg );
485
486 if ( value != null ) {
487 ret.push( value );
488 }
489 }
490
491 // Go through every key on the object,
492 } else {
493 for ( i in elems ) {
494 value = callback( elems[ i ], i, arg );
495
496 if ( value != null ) {
497 ret.push( value );
498 }
499 }
500 }
501
502 // Flatten any nested arrays
503 return concat.apply( [], ret );
504 },
505
506 // A global GUID counter for objects
507 guid: 1,
508
509 // Bind a function to a context, optionally partially applying any
510 // arguments.
511 proxy: function( fn, context ) {
512 var args, proxy, tmp;
513
514 if ( typeof context === "string" ) {
515 tmp = fn[ context ];
516 context = fn;
517 fn = tmp;
518 }
519
520 // Quick check to determine if target is callable, in the spec
521 // this throws a TypeError, but we will just return undefined.
522 if ( !jQuery.isFunction( fn ) ) {
523 return undefined;
524 }
525
526 // Simulated bind
527 args = slice.call( arguments, 2 );
528 proxy = function() {
529 return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
530 };
531
532 // Set the guid of unique handler to the same of original handler, so it can be removed
533 proxy.guid = fn.guid = fn.guid || jQuery.guid++;
534
535 return proxy;
536 },
537
538 now: function() {
539 return +( new Date() );
540 },
541
542 // jQuery.support is not used in Core but other projects attach their
543 // properties to it so it needs to exist.
544 support: support
545} );
546
547// JSHint would error on this code due to the Symbol not being defined in ES5.
548// Defining this global in .jshintrc would create a danger of using the global
549// unguarded in another place, it seems safer to just disable JSHint for these
550// three lines.
551/* jshint ignore: start */
552if ( typeof Symbol === "function" ) {
553 jQuery.fn[ Symbol.iterator ] = deletedIds[ Symbol.iterator ];
554}
555/* jshint ignore: end */
556
557// Populate the class2type map
558jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
559function( i, name ) {
560 class2type[ "[object " + name + "]" ] = name.toLowerCase();
561} );
562
563function isArrayLike( obj ) {
564
565 // Support: iOS 8.2 (not reproducible in simulator)
566 // `in` check used to prevent JIT error (gh-2145)
567 // hasOwn isn't used here due to false negatives
568 // regarding Nodelist length in IE
569 var length = !!obj && "length" in obj && obj.length,
570 type = jQuery.type( obj );
571
572 if ( type === "function" || jQuery.isWindow( obj ) ) {
573 return false;
574 }
575
576 return type === "array" || length === 0 ||
577 typeof length === "number" && length > 0 && ( length - 1 ) in obj;
578}
579var Sizzle =
580/*!
581 * Sizzle CSS Selector Engine v2.2.1
582 * http://sizzlejs.com/
583 *
584 * Copyright jQuery Foundation and other contributors
585 * Released under the MIT license
586 * http://jquery.org/license
587 *
588 * Date: 2015-10-17
589 */
590(function( window ) {
591
592var i,
593 support,
594 Expr,
595 getText,
596 isXML,
597 tokenize,
598 compile,
599 select,
600 outermostContext,
601 sortInput,
602 hasDuplicate,
603
604 // Local document vars
605 setDocument,
606 document,
607 docElem,
608 documentIsHTML,
609 rbuggyQSA,
610 rbuggyMatches,
611 matches,
612 contains,
613
614 // Instance-specific data
615 expando = "sizzle" + 1 * new Date(),
616 preferredDoc = window.document,
617 dirruns = 0,
618 done = 0,
619 classCache = createCache(),
620 tokenCache = createCache(),
621 compilerCache = createCache(),
622 sortOrder = function( a, b ) {
623 if ( a === b ) {
624 hasDuplicate = true;
625 }
626 return 0;
627 },
628
629 // General-purpose constants
630 MAX_NEGATIVE = 1 << 31,
631
632 // Instance methods
633 hasOwn = ({}).hasOwnProperty,
634 arr = [],
635 pop = arr.pop,
636 push_native = arr.push,
637 push = arr.push,
638 slice = arr.slice,
639 // Use a stripped-down indexOf as it's faster than native
640 // http://jsperf.com/thor-indexof-vs-for/5
641 indexOf = function( list, elem ) {
642 var i = 0,
643 len = list.length;
644 for ( ; i < len; i++ ) {
645 if ( list[i] === elem ) {
646 return i;
647 }
648 }
649 return -1;
650 },
651
652 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
653
654 // Regular expressions
655
656 // http://www.w3.org/TR/css3-selectors/#whitespace
657 whitespace = "[\\x20\\t\\r\\n\\f]",
658
659 // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
660 identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
661
662 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
663 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
664 // Operator (capture 2)
665 "*([*^$|!~]?=)" + whitespace +
666 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
667 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
668 "*\\]",
669
670 pseudos = ":(" + identifier + ")(?:\\((" +
671 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
672 // 1. quoted (capture 3; capture 4 or capture 5)
673 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
674 // 2. simple (capture 6)
675 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
676 // 3. anything else (capture 2)
677 ".*" +
678 ")\\)|)",
679
680 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
681 rwhitespace = new RegExp( whitespace + "+", "g" ),
682 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
683
684 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
685 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
686
687 rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
688
689 rpseudo = new RegExp( pseudos ),
690 ridentifier = new RegExp( "^" + identifier + "$" ),
691
692 matchExpr = {
693 "ID": new RegExp( "^#(" + identifier + ")" ),
694 "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
695 "TAG": new RegExp( "^(" + identifier + "|[*])" ),
696 "ATTR": new RegExp( "^" + attributes ),
697 "PSEUDO": new RegExp( "^" + pseudos ),
698 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
699 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
700 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
701 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
702 // For use in libraries implementing .is()
703 // We use this for POS matching in `select`
704 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
705 whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
706 },
707
708 rinputs = /^(?:input|select|textarea|button)$/i,
709 rheader = /^h\d$/i,
710
711 rnative = /^[^{]+\{\s*\[native \w/,
712
713 // Easily-parseable/retrievable ID or TAG or CLASS selectors
714 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
715
716 rsibling = /[+~]/,
717 rescape = /'|\\/g,
718
719 // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
720 runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
721 funescape = function( _, escaped, escapedWhitespace ) {
722 var high = "0x" + escaped - 0x10000;
723 // NaN means non-codepoint
724 // Support: Firefox<24
725 // Workaround erroneous numeric interpretation of +"0x"
726 return high !== high || escapedWhitespace ?
727 escaped :
728 high < 0 ?
729 // BMP codepoint
730 String.fromCharCode( high + 0x10000 ) :
731 // Supplemental Plane codepoint (surrogate pair)
732 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
733 },
734
735 // Used for iframes
736 // See setDocument()
737 // Removing the function wrapper causes a "Permission Denied"
738 // error in IE
739 unloadHandler = function() {
740 setDocument();
741 };
742
743// Optimize for push.apply( _, NodeList )
744try {
745 push.apply(
746 (arr = slice.call( preferredDoc.childNodes )),
747 preferredDoc.childNodes
748 );
749 // Support: Android<4.0
750 // Detect silently failing push.apply
751 arr[ preferredDoc.childNodes.length ].nodeType;
752} catch ( e ) {
753 push = { apply: arr.length ?
754
755 // Leverage slice if possible
756 function( target, els ) {
757 push_native.apply( target, slice.call(els) );
758 } :
759
760 // Support: IE<9
761 // Otherwise append directly
762 function( target, els ) {
763 var j = target.length,
764 i = 0;
765 // Can't trust NodeList.length
766 while ( (target[j++] = els[i++]) ) {}
767 target.length = j - 1;
768 }
769 };
770}
771
772function Sizzle( selector, context, results, seed ) {
773 var m, i, elem, nid, nidselect, match, groups, newSelector,
774 newContext = context && context.ownerDocument,
775
776 // nodeType defaults to 9, since context defaults to document
777 nodeType = context ? context.nodeType : 9;
778
779 results = results || [];
780
781 // Return early from calls with invalid selector or context
782 if ( typeof selector !== "string" || !selector ||
783 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
784
785 return results;
786 }
787
788 // Try to shortcut find operations (as opposed to filters) in HTML documents
789 if ( !seed ) {
790
791 if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
792 setDocument( context );
793 }
794 context = context || document;
795
796 if ( documentIsHTML ) {
797
798 // If the selector is sufficiently simple, try using a "get*By*" DOM method
799 // (excepting DocumentFragment context, where the methods don't exist)
800 if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
801
802 // ID selector
803 if ( (m = match[1]) ) {
804
805 // Document context
806 if ( nodeType === 9 ) {
807 if ( (elem = context.getElementById( m )) ) {
808
809 // Support: IE, Opera, Webkit
810 // TODO: identify versions
811 // getElementById can match elements by name instead of ID
812 if ( elem.id === m ) {
813 results.push( elem );
814 return results;
815 }
816 } else {
817 return results;
818 }
819
820 // Element context
821 } else {
822
823 // Support: IE, Opera, Webkit
824 // TODO: identify versions
825 // getElementById can match elements by name instead of ID
826 if ( newContext && (elem = newContext.getElementById( m )) &&
827 contains( context, elem ) &&
828 elem.id === m ) {
829
830 results.push( elem );
831 return results;
832 }
833 }
834
835 // Type selector
836 } else if ( match[2] ) {
837 push.apply( results, context.getElementsByTagName( selector ) );
838 return results;
839
840 // Class selector
841 } else if ( (m = match[3]) && support.getElementsByClassName &&
842 context.getElementsByClassName ) {
843
844 push.apply( results, context.getElementsByClassName( m ) );
845 return results;
846 }
847 }
848
849 // Take advantage of querySelectorAll
850 if ( support.qsa &&
851 !compilerCache[ selector + " " ] &&
852 (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
853
854 if ( nodeType !== 1 ) {
855 newContext = context;
856 newSelector = selector;
857
858 // qSA looks outside Element context, which is not what we want
859 // Thanks to Andrew Dupont for this workaround technique
860 // Support: IE <=8
861 // Exclude object elements
862 } else if ( context.nodeName.toLowerCase() !== "object" ) {
863
864 // Capture the context ID, setting it first if necessary
865 if ( (nid = context.getAttribute( "id" )) ) {
866 nid = nid.replace( rescape, "\\$&" );
867 } else {
868 context.setAttribute( "id", (nid = expando) );
869 }
870
871 // Prefix every selector in the list
872 groups = tokenize( selector );
873 i = groups.length;
874 nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
875 while ( i-- ) {
876 groups[i] = nidselect + " " + toSelector( groups[i] );
877 }
878 newSelector = groups.join( "," );
879
880 // Expand context for sibling selectors
881 newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
882 context;
883 }
884
885 if ( newSelector ) {
886 try {
887 push.apply( results,
888 newContext.querySelectorAll( newSelector )
889 );
890 return results;
891 } catch ( qsaError ) {
892 } finally {
893 if ( nid === expando ) {
894 context.removeAttribute( "id" );
895 }
896 }
897 }
898 }
899 }
900 }
901
902 // All others
903 return select( selector.replace( rtrim, "$1" ), context, results, seed );
904}
905
906/**
907 * Create key-value caches of limited size
908 * @returns {function(string, object)} Returns the Object data after storing it on itself with
909 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
910 * deleting the oldest entry
911 */
912function createCache() {
913 var keys = [];
914
915 function cache( key, value ) {
916 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
917 if ( keys.push( key + " " ) > Expr.cacheLength ) {
918 // Only keep the most recent entries
919 delete cache[ keys.shift() ];
920 }
921 return (cache[ key + " " ] = value);
922 }
923 return cache;
924}
925
926/**
927 * Mark a function for special use by Sizzle
928 * @param {Function} fn The function to mark
929 */
930function markFunction( fn ) {
931 fn[ expando ] = true;
932 return fn;
933}
934
935/**
936 * Support testing using an element
937 * @param {Function} fn Passed the created div and expects a boolean result
938 */
939function assert( fn ) {
940 var div = document.createElement("div");
941
942 try {
943 return !!fn( div );
944 } catch (e) {
945 return false;
946 } finally {
947 // Remove from its parent by default
948 if ( div.parentNode ) {
949 div.parentNode.removeChild( div );
950 }
951 // release memory in IE
952 div = null;
953 }
954}
955
956/**
957 * Adds the same handler for all of the specified attrs
958 * @param {String} attrs Pipe-separated list of attributes
959 * @param {Function} handler The method that will be applied
960 */
961function addHandle( attrs, handler ) {
962 var arr = attrs.split("|"),
963 i = arr.length;
964
965 while ( i-- ) {
966 Expr.attrHandle[ arr[i] ] = handler;
967 }
968}
969
970/**
971 * Checks document order of two siblings
972 * @param {Element} a
973 * @param {Element} b
974 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
975 */
976function siblingCheck( a, b ) {
977 var cur = b && a,
978 diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
979 ( ~b.sourceIndex || MAX_NEGATIVE ) -
980 ( ~a.sourceIndex || MAX_NEGATIVE );
981
982 // Use IE sourceIndex if available on both nodes
983 if ( diff ) {
984 return diff;
985 }
986
987 // Check if b follows a
988 if ( cur ) {
989 while ( (cur = cur.nextSibling) ) {
990 if ( cur === b ) {
991 return -1;
992 }
993 }
994 }
995
996 return a ? 1 : -1;
997}
998
999/**
1000 * Returns a function to use in pseudos for input types
1001 * @param {String} type
1002 */
1003function createInputPseudo( type ) {
1004 return function( elem ) {
1005 var name = elem.nodeName.toLowerCase();
1006 return name === "input" && elem.type === type;
1007 };
1008}
1009
1010/**
1011 * Returns a function to use in pseudos for buttons
1012 * @param {String} type
1013 */
1014function createButtonPseudo( type ) {
1015 return function( elem ) {
1016 var name = elem.nodeName.toLowerCase();
1017 return (name === "input" || name === "button") && elem.type === type;
1018 };
1019}
1020
1021/**
1022 * Returns a function to use in pseudos for positionals
1023 * @param {Function} fn
1024 */
1025function createPositionalPseudo( fn ) {
1026 return markFunction(function( argument ) {
1027 argument = +argument;
1028 return markFunction(function( seed, matches ) {
1029 var j,
1030 matchIndexes = fn( [], seed.length, argument ),
1031 i = matchIndexes.length;
1032
1033 // Match elements found at the specified indexes
1034 while ( i-- ) {
1035 if ( seed[ (j = matchIndexes[i]) ] ) {
1036 seed[j] = !(matches[j] = seed[j]);
1037 }
1038 }
1039 });
1040 });
1041}
1042
1043/**
1044 * Checks a node for validity as a Sizzle context
1045 * @param {Element|Object=} context
1046 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1047 */
1048function testContext( context ) {
1049 return context && typeof context.getElementsByTagName !== "undefined" && context;
1050}
1051
1052// Expose support vars for convenience
1053support = Sizzle.support = {};
1054
1055/**
1056 * Detects XML nodes
1057 * @param {Element|Object} elem An element or a document
1058 * @returns {Boolean} True iff elem is a non-HTML XML node
1059 */
1060isXML = Sizzle.isXML = function( elem ) {
1061 // documentElement is verified for cases where it doesn't yet exist
1062 // (such as loading iframes in IE - #4833)
1063 var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1064 return documentElement ? documentElement.nodeName !== "HTML" : false;
1065};
1066
1067/**
1068 * Sets document-related variables once based on the current document
1069 * @param {Element|Object} [doc] An element or document object to use to set the document
1070 * @returns {Object} Returns the current document
1071 */
1072setDocument = Sizzle.setDocument = function( node ) {
1073 var hasCompare, parent,
1074 doc = node ? node.ownerDocument || node : preferredDoc;
1075
1076 // Return early if doc is invalid or already selected
1077 if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1078 return document;
1079 }
1080
1081 // Update global variables
1082 document = doc;
1083 docElem = document.documentElement;
1084 documentIsHTML = !isXML( document );
1085
1086 // Support: IE 9-11, Edge
1087 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1088 if ( (parent = document.defaultView) && parent.top !== parent ) {
1089 // Support: IE 11
1090 if ( parent.addEventListener ) {
1091 parent.addEventListener( "unload", unloadHandler, false );
1092
1093 // Support: IE 9 - 10 only
1094 } else if ( parent.attachEvent ) {
1095 parent.attachEvent( "onunload", unloadHandler );
1096 }
1097 }
1098
1099 /* Attributes
1100 ---------------------------------------------------------------------- */
1101
1102 // Support: IE<8
1103 // Verify that getAttribute really returns attributes and not properties
1104 // (excepting IE8 booleans)
1105 support.attributes = assert(function( div ) {
1106 div.className = "i";
1107 return !div.getAttribute("className");
1108 });
1109
1110 /* getElement(s)By*
1111 ---------------------------------------------------------------------- */
1112
1113 // Check if getElementsByTagName("*") returns only elements
1114 support.getElementsByTagName = assert(function( div ) {
1115 div.appendChild( document.createComment("") );
1116 return !div.getElementsByTagName("*").length;
1117 });
1118
1119 // Support: IE<9
1120 support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1121
1122 // Support: IE<10
1123 // Check if getElementById returns elements by name
1124 // The broken getElementById methods don't pick up programatically-set names,
1125 // so use a roundabout getElementsByName test
1126 support.getById = assert(function( div ) {
1127 docElem.appendChild( div ).id = expando;
1128 return !document.getElementsByName || !document.getElementsByName( expando ).length;
1129 });
1130
1131 // ID find and filter
1132 if ( support.getById ) {
1133 Expr.find["ID"] = function( id, context ) {
1134 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1135 var m = context.getElementById( id );
1136 return m ? [ m ] : [];
1137 }
1138 };
1139 Expr.filter["ID"] = function( id ) {
1140 var attrId = id.replace( runescape, funescape );
1141 return function( elem ) {
1142 return elem.getAttribute("id") === attrId;
1143 };
1144 };
1145 } else {
1146 // Support: IE6/7
1147 // getElementById is not reliable as a find shortcut
1148 delete Expr.find["ID"];
1149
1150 Expr.filter["ID"] = function( id ) {
1151 var attrId = id.replace( runescape, funescape );
1152 return function( elem ) {
1153 var node = typeof elem.getAttributeNode !== "undefined" &&
1154 elem.getAttributeNode("id");
1155 return node && node.value === attrId;
1156 };
1157 };
1158 }
1159
1160 // Tag
1161 Expr.find["TAG"] = support.getElementsByTagName ?
1162 function( tag, context ) {
1163 if ( typeof context.getElementsByTagName !== "undefined" ) {
1164 return context.getElementsByTagName( tag );
1165
1166 // DocumentFragment nodes don't have gEBTN
1167 } else if ( support.qsa ) {
1168 return context.querySelectorAll( tag );
1169 }
1170 } :
1171
1172 function( tag, context ) {
1173 var elem,
1174 tmp = [],
1175 i = 0,
1176 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1177 results = context.getElementsByTagName( tag );
1178
1179 // Filter out possible comments
1180 if ( tag === "*" ) {
1181 while ( (elem = results[i++]) ) {
1182 if ( elem.nodeType === 1 ) {
1183 tmp.push( elem );
1184 }
1185 }
1186
1187 return tmp;
1188 }
1189 return results;
1190 };
1191
1192 // Class
1193 Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1194 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1195 return context.getElementsByClassName( className );
1196 }
1197 };
1198
1199 /* QSA/matchesSelector
1200 ---------------------------------------------------------------------- */
1201
1202 // QSA and matchesSelector support
1203
1204 // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1205 rbuggyMatches = [];
1206
1207 // qSa(:focus) reports false when true (Chrome 21)
1208 // We allow this because of a bug in IE8/9 that throws an error
1209 // whenever `document.activeElement` is accessed on an iframe
1210 // So, we allow :focus to pass through QSA all the time to avoid the IE error
1211 // See http://bugs.jquery.com/ticket/13378
1212 rbuggyQSA = [];
1213
1214 if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
1215 // Build QSA regex
1216 // Regex strategy adopted from Diego Perini
1217 assert(function( div ) {
1218 // Select is set to empty string on purpose
1219 // This is to test IE's treatment of not explicitly
1220 // setting a boolean content attribute,
1221 // since its presence should be enough
1222 // http://bugs.jquery.com/ticket/12359
1223 docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
1224 "<select id='" + expando + "-\r\\' msallowcapture=''>" +
1225 "<option selected=''></option></select>";
1226
1227 // Support: IE8, Opera 11-12.16
1228 // Nothing should be selected when empty strings follow ^= or $= or *=
1229 // The test attribute must be unknown in Opera but "safe" for WinRT
1230 // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1231 if ( div.querySelectorAll("[msallowcapture^='']").length ) {
1232 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1233 }
1234
1235 // Support: IE8
1236 // Boolean attributes and "value" are not treated correctly
1237 if ( !div.querySelectorAll("[selected]").length ) {
1238 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1239 }
1240
1241 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1242 if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1243 rbuggyQSA.push("~=");
1244 }
1245
1246 // Webkit/Opera - :checked should return selected option elements
1247 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1248 // IE8 throws error here and will not see later tests
1249 if ( !div.querySelectorAll(":checked").length ) {
1250 rbuggyQSA.push(":checked");
1251 }
1252
1253 // Support: Safari 8+, iOS 8+
1254 // https://bugs.webkit.org/show_bug.cgi?id=136851
1255 // In-page `selector#id sibing-combinator selector` fails
1256 if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
1257 rbuggyQSA.push(".#.+[+~]");
1258 }
1259 });
1260
1261 assert(function( div ) {
1262 // Support: Windows 8 Native Apps
1263 // The type and name attributes are restricted during .innerHTML assignment
1264 var input = document.createElement("input");
1265 input.setAttribute( "type", "hidden" );
1266 div.appendChild( input ).setAttribute( "name", "D" );
1267
1268 // Support: IE8
1269 // Enforce case-sensitivity of name attribute
1270 if ( div.querySelectorAll("[name=d]").length ) {
1271 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1272 }
1273
1274 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1275 // IE8 throws error here and will not see later tests
1276 if ( !div.querySelectorAll(":enabled").length ) {
1277 rbuggyQSA.push( ":enabled", ":disabled" );
1278 }
1279
1280 // Opera 10-11 does not throw on post-comma invalid pseudos
1281 div.querySelectorAll("*,:x");
1282 rbuggyQSA.push(",.*:");
1283 });
1284 }
1285
1286 if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1287 docElem.webkitMatchesSelector ||
1288 docElem.mozMatchesSelector ||
1289 docElem.oMatchesSelector ||
1290 docElem.msMatchesSelector) )) ) {
1291
1292 assert(function( div ) {
1293 // Check to see if it's possible to do matchesSelector
1294 // on a disconnected node (IE 9)
1295 support.disconnectedMatch = matches.call( div, "div" );
1296
1297 // This should fail with an exception
1298 // Gecko does not error, returns false instead
1299 matches.call( div, "[s!='']:x" );
1300 rbuggyMatches.push( "!=", pseudos );
1301 });
1302 }
1303
1304 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1305 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1306
1307 /* Contains
1308 ---------------------------------------------------------------------- */
1309 hasCompare = rnative.test( docElem.compareDocumentPosition );
1310
1311 // Element contains another
1312 // Purposefully self-exclusive
1313 // As in, an element does not contain itself
1314 contains = hasCompare || rnative.test( docElem.contains ) ?
1315 function( a, b ) {
1316 var adown = a.nodeType === 9 ? a.documentElement : a,
1317 bup = b && b.parentNode;
1318 return a === bup || !!( bup && bup.nodeType === 1 && (
1319 adown.contains ?
1320 adown.contains( bup ) :
1321 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1322 ));
1323 } :
1324 function( a, b ) {
1325 if ( b ) {
1326 while ( (b = b.parentNode) ) {
1327 if ( b === a ) {
1328 return true;
1329 }
1330 }
1331 }
1332 return false;
1333 };
1334
1335 /* Sorting
1336 ---------------------------------------------------------------------- */
1337
1338 // Document order sorting
1339 sortOrder = hasCompare ?
1340 function( a, b ) {
1341
1342 // Flag for duplicate removal
1343 if ( a === b ) {
1344 hasDuplicate = true;
1345 return 0;
1346 }
1347
1348 // Sort on method existence if only one input has compareDocumentPosition
1349 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1350 if ( compare ) {
1351 return compare;
1352 }
1353
1354 // Calculate position if both inputs belong to the same document
1355 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1356 a.compareDocumentPosition( b ) :
1357
1358 // Otherwise we know they are disconnected
1359 1;
1360
1361 // Disconnected nodes
1362 if ( compare & 1 ||
1363 (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1364
1365 // Choose the first element that is related to our preferred document
1366 if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1367 return -1;
1368 }
1369 if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1370 return 1;
1371 }
1372
1373 // Maintain original order
1374 return sortInput ?
1375 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1376 0;
1377 }
1378
1379 return compare & 4 ? -1 : 1;
1380 } :
1381 function( a, b ) {
1382 // Exit early if the nodes are identical
1383 if ( a === b ) {
1384 hasDuplicate = true;
1385 return 0;
1386 }
1387
1388 var cur,
1389 i = 0,
1390 aup = a.parentNode,
1391 bup = b.parentNode,
1392 ap = [ a ],
1393 bp = [ b ];
1394
1395 // Parentless nodes are either documents or disconnected
1396 if ( !aup || !bup ) {
1397 return a === document ? -1 :
1398 b === document ? 1 :
1399 aup ? -1 :
1400 bup ? 1 :
1401 sortInput ?
1402 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1403 0;
1404
1405 // If the nodes are siblings, we can do a quick check
1406 } else if ( aup === bup ) {
1407 return siblingCheck( a, b );
1408 }
1409
1410 // Otherwise we need full lists of their ancestors for comparison
1411 cur = a;
1412 while ( (cur = cur.parentNode) ) {
1413 ap.unshift( cur );
1414 }
1415 cur = b;
1416 while ( (cur = cur.parentNode) ) {
1417 bp.unshift( cur );
1418 }
1419
1420 // Walk down the tree looking for a discrepancy
1421 while ( ap[i] === bp[i] ) {
1422 i++;
1423 }
1424
1425 return i ?
1426 // Do a sibling check if the nodes have a common ancestor
1427 siblingCheck( ap[i], bp[i] ) :
1428
1429 // Otherwise nodes in our document sort first
1430 ap[i] === preferredDoc ? -1 :
1431 bp[i] === preferredDoc ? 1 :
1432 0;
1433 };
1434
1435 return document;
1436};
1437
1438Sizzle.matches = function( expr, elements ) {
1439 return Sizzle( expr, null, null, elements );
1440};
1441
1442Sizzle.matchesSelector = function( elem, expr ) {
1443 // Set document vars if needed
1444 if ( ( elem.ownerDocument || elem ) !== document ) {
1445 setDocument( elem );
1446 }
1447
1448 // Make sure that attribute selectors are quoted
1449 expr = expr.replace( rattributeQuotes, "='$1']" );
1450
1451 if ( support.matchesSelector && documentIsHTML &&
1452 !compilerCache[ expr + " " ] &&
1453 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1454 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
1455
1456 try {
1457 var ret = matches.call( elem, expr );
1458
1459 // IE 9's matchesSelector returns false on disconnected nodes
1460 if ( ret || support.disconnectedMatch ||
1461 // As well, disconnected nodes are said to be in a document
1462 // fragment in IE 9
1463 elem.document && elem.document.nodeType !== 11 ) {
1464 return ret;
1465 }
1466 } catch (e) {}
1467 }
1468
1469 return Sizzle( expr, document, null, [ elem ] ).length > 0;
1470};
1471
1472Sizzle.contains = function( context, elem ) {
1473 // Set document vars if needed
1474 if ( ( context.ownerDocument || context ) !== document ) {
1475 setDocument( context );
1476 }
1477 return contains( context, elem );
1478};
1479
1480Sizzle.attr = function( elem, name ) {
1481 // Set document vars if needed
1482 if ( ( elem.ownerDocument || elem ) !== document ) {
1483 setDocument( elem );
1484 }
1485
1486 var fn = Expr.attrHandle[ name.toLowerCase() ],
1487 // Don't get fooled by Object.prototype properties (jQuery #13807)
1488 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1489 fn( elem, name, !documentIsHTML ) :
1490 undefined;
1491
1492 return val !== undefined ?
1493 val :
1494 support.attributes || !documentIsHTML ?
1495 elem.getAttribute( name ) :
1496 (val = elem.getAttributeNode(name)) && val.specified ?
1497 val.value :
1498 null;
1499};
1500
1501Sizzle.error = function( msg ) {
1502 throw new Error( "Syntax error, unrecognized expression: " + msg );
1503};
1504
1505/**
1506 * Document sorting and removing duplicates
1507 * @param {ArrayLike} results
1508 */
1509Sizzle.uniqueSort = function( results ) {
1510 var elem,
1511 duplicates = [],
1512 j = 0,
1513 i = 0;
1514
1515 // Unless we *know* we can detect duplicates, assume their presence
1516 hasDuplicate = !support.detectDuplicates;
1517 sortInput = !support.sortStable && results.slice( 0 );
1518 results.sort( sortOrder );
1519
1520 if ( hasDuplicate ) {
1521 while ( (elem = results[i++]) ) {
1522 if ( elem === results[ i ] ) {
1523 j = duplicates.push( i );
1524 }
1525 }
1526 while ( j-- ) {
1527 results.splice( duplicates[ j ], 1 );
1528 }
1529 }
1530
1531 // Clear input after sorting to release objects
1532 // See https://github.com/jquery/sizzle/pull/225
1533 sortInput = null;
1534
1535 return results;
1536};
1537
1538/**
1539 * Utility function for retrieving the text value of an array of DOM nodes
1540 * @param {Array|Element} elem
1541 */
1542getText = Sizzle.getText = function( elem ) {
1543 var node,
1544 ret = "",
1545 i = 0,
1546 nodeType = elem.nodeType;
1547
1548 if ( !nodeType ) {
1549 // If no nodeType, this is expected to be an array
1550 while ( (node = elem[i++]) ) {
1551 // Do not traverse comment nodes
1552 ret += getText( node );
1553 }
1554 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1555 // Use textContent for elements
1556 // innerText usage removed for consistency of new lines (jQuery #11153)
1557 if ( typeof elem.textContent === "string" ) {
1558 return elem.textContent;
1559 } else {
1560 // Traverse its children
1561 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1562 ret += getText( elem );
1563 }
1564 }
1565 } else if ( nodeType === 3 || nodeType === 4 ) {
1566 return elem.nodeValue;
1567 }
1568 // Do not include comment or processing instruction nodes
1569
1570 return ret;
1571};
1572
1573Expr = Sizzle.selectors = {
1574
1575 // Can be adjusted by the user
1576 cacheLength: 50,
1577
1578 createPseudo: markFunction,
1579
1580 match: matchExpr,
1581
1582 attrHandle: {},
1583
1584 find: {},
1585
1586 relative: {
1587 ">": { dir: "parentNode", first: true },
1588 " ": { dir: "parentNode" },
1589 "+": { dir: "previousSibling", first: true },
1590 "~": { dir: "previousSibling" }
1591 },
1592
1593 preFilter: {
1594 "ATTR": function( match ) {
1595 match[1] = match[1].replace( runescape, funescape );
1596
1597 // Move the given value to match[3] whether quoted or unquoted
1598 match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1599
1600 if ( match[2] === "~=" ) {
1601 match[3] = " " + match[3] + " ";
1602 }
1603
1604 return match.slice( 0, 4 );
1605 },
1606
1607 "CHILD": function( match ) {
1608 /* matches from matchExpr["CHILD"]
1609 1 type (only|nth|...)
1610 2 what (child|of-type)
1611 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1612 4 xn-component of xn+y argument ([+-]?\d*n|)
1613 5 sign of xn-component
1614 6 x of xn-component
1615 7 sign of y-component
1616 8 y of y-component
1617 */
1618 match[1] = match[1].toLowerCase();
1619
1620 if ( match[1].slice( 0, 3 ) === "nth" ) {
1621 // nth-* requires argument
1622 if ( !match[3] ) {
1623 Sizzle.error( match[0] );
1624 }
1625
1626 // numeric x and y parameters for Expr.filter.CHILD
1627 // remember that false/true cast respectively to 0/1
1628 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1629 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1630
1631 // other types prohibit arguments
1632 } else if ( match[3] ) {
1633 Sizzle.error( match[0] );
1634 }
1635
1636 return match;
1637 },
1638
1639 "PSEUDO": function( match ) {
1640 var excess,
1641 unquoted = !match[6] && match[2];
1642
1643 if ( matchExpr["CHILD"].test( match[0] ) ) {
1644 return null;
1645 }
1646
1647 // Accept quoted arguments as-is
1648 if ( match[3] ) {
1649 match[2] = match[4] || match[5] || "";
1650
1651 // Strip excess characters from unquoted arguments
1652 } else if ( unquoted && rpseudo.test( unquoted ) &&
1653 // Get excess from tokenize (recursively)
1654 (excess = tokenize( unquoted, true )) &&
1655 // advance to the next closing parenthesis
1656 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1657
1658 // excess is a negative index
1659 match[0] = match[0].slice( 0, excess );
1660 match[2] = unquoted.slice( 0, excess );
1661 }
1662
1663 // Return only captures needed by the pseudo filter method (type and argument)
1664 return match.slice( 0, 3 );
1665 }
1666 },
1667
1668 filter: {
1669
1670 "TAG": function( nodeNameSelector ) {
1671 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1672 return nodeNameSelector === "*" ?
1673 function() { return true; } :
1674 function( elem ) {
1675 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1676 };
1677 },
1678
1679 "CLASS": function( className ) {
1680 var pattern = classCache[ className + " " ];
1681
1682 return pattern ||
1683 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1684 classCache( className, function( elem ) {
1685 return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1686 });
1687 },
1688
1689 "ATTR": function( name, operator, check ) {
1690 return function( elem ) {
1691 var result = Sizzle.attr( elem, name );
1692
1693 if ( result == null ) {
1694 return operator === "!=";
1695 }
1696 if ( !operator ) {
1697 return true;
1698 }
1699
1700 result += "";
1701
1702 return operator === "=" ? result === check :
1703 operator === "!=" ? result !== check :
1704 operator === "^=" ? check && result.indexOf( check ) === 0 :
1705 operator === "*=" ? check && result.indexOf( check ) > -1 :
1706 operator === "$=" ? check && result.slice( -check.length ) === check :
1707 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1708 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1709 false;
1710 };
1711 },
1712
1713 "CHILD": function( type, what, argument, first, last ) {
1714 var simple = type.slice( 0, 3 ) !== "nth",
1715 forward = type.slice( -4 ) !== "last",
1716 ofType = what === "of-type";
1717
1718 return first === 1 && last === 0 ?
1719
1720 // Shortcut for :nth-*(n)
1721 function( elem ) {
1722 return !!elem.parentNode;
1723 } :
1724
1725 function( elem, context, xml ) {
1726 var cache, uniqueCache, outerCache, node, nodeIndex, start,
1727 dir = simple !== forward ? "nextSibling" : "previousSibling",
1728 parent = elem.parentNode,
1729 name = ofType && elem.nodeName.toLowerCase(),
1730 useCache = !xml && !ofType,
1731 diff = false;
1732
1733 if ( parent ) {
1734
1735 // :(first|last|only)-(child|of-type)
1736 if ( simple ) {
1737 while ( dir ) {
1738 node = elem;
1739 while ( (node = node[ dir ]) ) {
1740 if ( ofType ?
1741 node.nodeName.toLowerCase() === name :
1742 node.nodeType === 1 ) {
1743
1744 return false;
1745 }
1746 }
1747 // Reverse direction for :only-* (if we haven't yet done so)
1748 start = dir = type === "only" && !start && "nextSibling";
1749 }
1750 return true;
1751 }
1752
1753 start = [ forward ? parent.firstChild : parent.lastChild ];
1754
1755 // non-xml :nth-child(...) stores cache data on `parent`
1756 if ( forward && useCache ) {
1757
1758 // Seek `elem` from a previously-cached index
1759
1760 // ...in a gzip-friendly way
1761 node = parent;
1762 outerCache = node[ expando ] || (node[ expando ] = {});
1763
1764 // Support: IE <9 only
1765 // Defend against cloned attroperties (jQuery gh-1709)
1766 uniqueCache = outerCache[ node.uniqueID ] ||
1767 (outerCache[ node.uniqueID ] = {});
1768
1769 cache = uniqueCache[ type ] || [];
1770 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1771 diff = nodeIndex && cache[ 2 ];
1772 node = nodeIndex && parent.childNodes[ nodeIndex ];
1773
1774 while ( (node = ++nodeIndex && node && node[ dir ] ||
1775
1776 // Fallback to seeking `elem` from the start
1777 (diff = nodeIndex = 0) || start.pop()) ) {
1778
1779 // When found, cache indexes on `parent` and break
1780 if ( node.nodeType === 1 && ++diff && node === elem ) {
1781 uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
1782 break;
1783 }
1784 }
1785
1786 } else {
1787 // Use previously-cached element index if available
1788 if ( useCache ) {
1789 // ...in a gzip-friendly way
1790 node = elem;
1791 outerCache = node[ expando ] || (node[ expando ] = {});
1792
1793 // Support: IE <9 only
1794 // Defend against cloned attroperties (jQuery gh-1709)
1795 uniqueCache = outerCache[ node.uniqueID ] ||
1796 (outerCache[ node.uniqueID ] = {});
1797
1798 cache = uniqueCache[ type ] || [];
1799 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1800 diff = nodeIndex;
1801 }
1802
1803 // xml :nth-child(...)
1804 // or :nth-last-child(...) or :nth(-last)?-of-type(...)
1805 if ( diff === false ) {
1806 // Use the same loop as above to seek `elem` from the start
1807 while ( (node = ++nodeIndex && node && node[ dir ] ||
1808 (diff = nodeIndex = 0) || start.pop()) ) {
1809
1810 if ( ( ofType ?
1811 node.nodeName.toLowerCase() === name :
1812 node.nodeType === 1 ) &&
1813 ++diff ) {
1814
1815 // Cache the index of each encountered element
1816 if ( useCache ) {
1817 outerCache = node[ expando ] || (node[ expando ] = {});
1818
1819 // Support: IE <9 only
1820 // Defend against cloned attroperties (jQuery gh-1709)
1821 uniqueCache = outerCache[ node.uniqueID ] ||
1822 (outerCache[ node.uniqueID ] = {});
1823
1824 uniqueCache[ type ] = [ dirruns, diff ];
1825 }
1826
1827 if ( node === elem ) {
1828 break;
1829 }
1830 }
1831 }
1832 }
1833 }
1834
1835 // Incorporate the offset, then check against cycle size
1836 diff -= last;
1837 return diff === first || ( diff % first === 0 && diff / first >= 0 );
1838 }
1839 };
1840 },
1841
1842 "PSEUDO": function( pseudo, argument ) {
1843 // pseudo-class names are case-insensitive
1844 // http://www.w3.org/TR/selectors/#pseudo-classes
1845 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1846 // Remember that setFilters inherits from pseudos
1847 var args,
1848 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1849 Sizzle.error( "unsupported pseudo: " + pseudo );
1850
1851 // The user may use createPseudo to indicate that
1852 // arguments are needed to create the filter function
1853 // just as Sizzle does
1854 if ( fn[ expando ] ) {
1855 return fn( argument );
1856 }
1857
1858 // But maintain support for old signatures
1859 if ( fn.length > 1 ) {
1860 args = [ pseudo, pseudo, "", argument ];
1861 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1862 markFunction(function( seed, matches ) {
1863 var idx,
1864 matched = fn( seed, argument ),
1865 i = matched.length;
1866 while ( i-- ) {
1867 idx = indexOf( seed, matched[i] );
1868 seed[ idx ] = !( matches[ idx ] = matched[i] );
1869 }
1870 }) :
1871 function( elem ) {
1872 return fn( elem, 0, args );
1873 };
1874 }
1875
1876 return fn;
1877 }
1878 },
1879
1880 pseudos: {
1881 // Potentially complex pseudos
1882 "not": markFunction(function( selector ) {
1883 // Trim the selector passed to compile
1884 // to avoid treating leading and trailing
1885 // spaces as combinators
1886 var input = [],
1887 results = [],
1888 matcher = compile( selector.replace( rtrim, "$1" ) );
1889
1890 return matcher[ expando ] ?
1891 markFunction(function( seed, matches, context, xml ) {
1892 var elem,
1893 unmatched = matcher( seed, null, xml, [] ),
1894 i = seed.length;
1895
1896 // Match elements unmatched by `matcher`
1897 while ( i-- ) {
1898 if ( (elem = unmatched[i]) ) {
1899 seed[i] = !(matches[i] = elem);
1900 }
1901 }
1902 }) :
1903 function( elem, context, xml ) {
1904 input[0] = elem;
1905 matcher( input, null, xml, results );
1906 // Don't keep the element (issue #299)
1907 input[0] = null;
1908 return !results.pop();
1909 };
1910 }),
1911
1912 "has": markFunction(function( selector ) {
1913 return function( elem ) {
1914 return Sizzle( selector, elem ).length > 0;
1915 };
1916 }),
1917
1918 "contains": markFunction(function( text ) {
1919 text = text.replace( runescape, funescape );
1920 return function( elem ) {
1921 return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1922 };
1923 }),
1924
1925 // "Whether an element is represented by a :lang() selector
1926 // is based solely on the element's language value
1927 // being equal to the identifier C,
1928 // or beginning with the identifier C immediately followed by "-".
1929 // The matching of C against the element's language value is performed case-insensitively.
1930 // The identifier C does not have to be a valid language name."
1931 // http://www.w3.org/TR/selectors/#lang-pseudo
1932 "lang": markFunction( function( lang ) {
1933 // lang value must be a valid identifier
1934 if ( !ridentifier.test(lang || "") ) {
1935 Sizzle.error( "unsupported lang: " + lang );
1936 }
1937 lang = lang.replace( runescape, funescape ).toLowerCase();
1938 return function( elem ) {
1939 var elemLang;
1940 do {
1941 if ( (elemLang = documentIsHTML ?
1942 elem.lang :
1943 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1944
1945 elemLang = elemLang.toLowerCase();
1946 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1947 }
1948 } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1949 return false;
1950 };
1951 }),
1952
1953 // Miscellaneous
1954 "target": function( elem ) {
1955 var hash = window.location && window.location.hash;
1956 return hash && hash.slice( 1 ) === elem.id;
1957 },
1958
1959 "root": function( elem ) {
1960 return elem === docElem;
1961 },
1962
1963 "focus": function( elem ) {
1964 return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1965 },
1966
1967 // Boolean properties
1968 "enabled": function( elem ) {
1969 return elem.disabled === false;
1970 },
1971
1972 "disabled": function( elem ) {
1973 return elem.disabled === true;
1974 },
1975
1976 "checked": function( elem ) {
1977 // In CSS3, :checked should return both checked and selected elements
1978 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1979 var nodeName = elem.nodeName.toLowerCase();
1980 return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1981 },
1982
1983 "selected": function( elem ) {
1984 // Accessing this property makes selected-by-default
1985 // options in Safari work properly
1986 if ( elem.parentNode ) {
1987 elem.parentNode.selectedIndex;
1988 }
1989
1990 return elem.selected === true;
1991 },
1992
1993 // Contents
1994 "empty": function( elem ) {
1995 // http://www.w3.org/TR/selectors/#empty-pseudo
1996 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1997 // but not by others (comment: 8; processing instruction: 7; etc.)
1998 // nodeType < 6 works because attributes (2) do not appear as children
1999 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2000 if ( elem.nodeType < 6 ) {
2001 return false;
2002 }
2003 }
2004 return true;
2005 },
2006
2007 "parent": function( elem ) {
2008 return !Expr.pseudos["empty"]( elem );
2009 },
2010
2011 // Element/input types
2012 "header": function( elem ) {
2013 return rheader.test( elem.nodeName );
2014 },
2015
2016 "input": function( elem ) {
2017 return rinputs.test( elem.nodeName );
2018 },
2019
2020 "button": function( elem ) {
2021 var name = elem.nodeName.toLowerCase();
2022 return name === "input" && elem.type === "button" || name === "button";
2023 },
2024
2025 "text": function( elem ) {
2026 var attr;
2027 return elem.nodeName.toLowerCase() === "input" &&
2028 elem.type === "text" &&
2029
2030 // Support: IE<8
2031 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2032 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
2033 },
2034
2035 // Position-in-collection
2036 "first": createPositionalPseudo(function() {
2037 return [ 0 ];
2038 }),
2039
2040 "last": createPositionalPseudo(function( matchIndexes, length ) {
2041 return [ length - 1 ];
2042 }),
2043
2044 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
2045 return [ argument < 0 ? argument + length : argument ];
2046 }),
2047
2048 "even": createPositionalPseudo(function( matchIndexes, length ) {
2049 var i = 0;
2050 for ( ; i < length; i += 2 ) {
2051 matchIndexes.push( i );
2052 }
2053 return matchIndexes;
2054 }),
2055
2056 "odd": createPositionalPseudo(function( matchIndexes, length ) {
2057 var i = 1;
2058 for ( ; i < length; i += 2 ) {
2059 matchIndexes.push( i );
2060 }
2061 return matchIndexes;
2062 }),
2063
2064 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2065 var i = argument < 0 ? argument + length : argument;
2066 for ( ; --i >= 0; ) {
2067 matchIndexes.push( i );
2068 }
2069 return matchIndexes;
2070 }),
2071
2072 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2073 var i = argument < 0 ? argument + length : argument;
2074 for ( ; ++i < length; ) {
2075 matchIndexes.push( i );
2076 }
2077 return matchIndexes;
2078 })
2079 }
2080};
2081
2082Expr.pseudos["nth"] = Expr.pseudos["eq"];
2083
2084// Add button/input type pseudos
2085for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2086 Expr.pseudos[ i ] = createInputPseudo( i );
2087}
2088for ( i in { submit: true, reset: true } ) {
2089 Expr.pseudos[ i ] = createButtonPseudo( i );
2090}
2091
2092// Easy API for creating new setFilters
2093function setFilters() {}
2094setFilters.prototype = Expr.filters = Expr.pseudos;
2095Expr.setFilters = new setFilters();
2096
2097tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2098 var matched, match, tokens, type,
2099 soFar, groups, preFilters,
2100 cached = tokenCache[ selector + " " ];
2101
2102 if ( cached ) {
2103 return parseOnly ? 0 : cached.slice( 0 );
2104 }
2105
2106 soFar = selector;
2107 groups = [];
2108 preFilters = Expr.preFilter;
2109
2110 while ( soFar ) {
2111
2112 // Comma and first run
2113 if ( !matched || (match = rcomma.exec( soFar )) ) {
2114 if ( match ) {
2115 // Don't consume trailing commas as valid
2116 soFar = soFar.slice( match[0].length ) || soFar;
2117 }
2118 groups.push( (tokens = []) );
2119 }
2120
2121 matched = false;
2122
2123 // Combinators
2124 if ( (match = rcombinators.exec( soFar )) ) {
2125 matched = match.shift();
2126 tokens.push({
2127 value: matched,
2128 // Cast descendant combinators to space
2129 type: match[0].replace( rtrim, " " )
2130 });
2131 soFar = soFar.slice( matched.length );
2132 }
2133
2134 // Filters
2135 for ( type in Expr.filter ) {
2136 if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2137 (match = preFilters[ type ]( match ))) ) {
2138 matched = match.shift();
2139 tokens.push({
2140 value: matched,
2141 type: type,
2142 matches: match
2143 });
2144 soFar = soFar.slice( matched.length );
2145 }
2146 }
2147
2148 if ( !matched ) {
2149 break;
2150 }
2151 }
2152
2153 // Return the length of the invalid excess
2154 // if we're just parsing
2155 // Otherwise, throw an error or return tokens
2156 return parseOnly ?
2157 soFar.length :
2158 soFar ?
2159 Sizzle.error( selector ) :
2160 // Cache the tokens
2161 tokenCache( selector, groups ).slice( 0 );
2162};
2163
2164function toSelector( tokens ) {
2165 var i = 0,
2166 len = tokens.length,
2167 selector = "";
2168 for ( ; i < len; i++ ) {
2169 selector += tokens[i].value;
2170 }
2171 return selector;
2172}
2173
2174function addCombinator( matcher, combinator, base ) {
2175 var dir = combinator.dir,
2176 checkNonElements = base && dir === "parentNode",
2177 doneName = done++;
2178
2179 return combinator.first ?
2180 // Check against closest ancestor/preceding element
2181 function( elem, context, xml ) {
2182 while ( (elem = elem[ dir ]) ) {
2183 if ( elem.nodeType === 1 || checkNonElements ) {
2184 return matcher( elem, context, xml );
2185 }
2186 }
2187 } :
2188
2189 // Check against all ancestor/preceding elements
2190 function( elem, context, xml ) {
2191 var oldCache, uniqueCache, outerCache,
2192 newCache = [ dirruns, doneName ];
2193
2194 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2195 if ( xml ) {
2196 while ( (elem = elem[ dir ]) ) {
2197 if ( elem.nodeType === 1 || checkNonElements ) {
2198 if ( matcher( elem, context, xml ) ) {
2199 return true;
2200 }
2201 }
2202 }
2203 } else {
2204 while ( (elem = elem[ dir ]) ) {
2205 if ( elem.nodeType === 1 || checkNonElements ) {
2206 outerCache = elem[ expando ] || (elem[ expando ] = {});
2207
2208 // Support: IE <9 only
2209 // Defend against cloned attroperties (jQuery gh-1709)
2210 uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
2211
2212 if ( (oldCache = uniqueCache[ dir ]) &&
2213 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2214
2215 // Assign to newCache so results back-propagate to previous elements
2216 return (newCache[ 2 ] = oldCache[ 2 ]);
2217 } else {
2218 // Reuse newcache so results back-propagate to previous elements
2219 uniqueCache[ dir ] = newCache;
2220
2221 // A match means we're done; a fail means we have to keep checking
2222 if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2223 return true;
2224 }
2225 }
2226 }
2227 }
2228 }
2229 };
2230}
2231
2232function elementMatcher( matchers ) {
2233 return matchers.length > 1 ?
2234 function( elem, context, xml ) {
2235 var i = matchers.length;
2236 while ( i-- ) {
2237 if ( !matchers[i]( elem, context, xml ) ) {
2238 return false;
2239 }
2240 }
2241 return true;
2242 } :
2243 matchers[0];
2244}
2245
2246function multipleContexts( selector, contexts, results ) {
2247 var i = 0,
2248 len = contexts.length;
2249 for ( ; i < len; i++ ) {
2250 Sizzle( selector, contexts[i], results );
2251 }
2252 return results;
2253}
2254
2255function condense( unmatched, map, filter, context, xml ) {
2256 var elem,
2257 newUnmatched = [],
2258 i = 0,
2259 len = unmatched.length,
2260 mapped = map != null;
2261
2262 for ( ; i < len; i++ ) {
2263 if ( (elem = unmatched[i]) ) {
2264 if ( !filter || filter( elem, context, xml ) ) {
2265 newUnmatched.push( elem );
2266 if ( mapped ) {
2267 map.push( i );
2268 }
2269 }
2270 }
2271 }
2272
2273 return newUnmatched;
2274}
2275
2276function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2277 if ( postFilter && !postFilter[ expando ] ) {
2278 postFilter = setMatcher( postFilter );
2279 }
2280 if ( postFinder && !postFinder[ expando ] ) {
2281 postFinder = setMatcher( postFinder, postSelector );
2282 }
2283 return markFunction(function( seed, results, context, xml ) {
2284 var temp, i, elem,
2285 preMap = [],
2286 postMap = [],
2287 preexisting = results.length,
2288
2289 // Get initial elements from seed or context
2290 elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2291
2292 // Prefilter to get matcher input, preserving a map for seed-results synchronization
2293 matcherIn = preFilter && ( seed || !selector ) ?
2294 condense( elems, preMap, preFilter, context, xml ) :
2295 elems,
2296
2297 matcherOut = matcher ?
2298 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2299 postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2300
2301 // ...intermediate processing is necessary
2302 [] :
2303
2304 // ...otherwise use results directly
2305 results :
2306 matcherIn;
2307
2308 // Find primary matches
2309 if ( matcher ) {
2310 matcher( matcherIn, matcherOut, context, xml );
2311 }
2312
2313 // Apply postFilter
2314 if ( postFilter ) {
2315 temp = condense( matcherOut, postMap );
2316 postFilter( temp, [], context, xml );
2317
2318 // Un-match failing elements by moving them back to matcherIn
2319 i = temp.length;
2320 while ( i-- ) {
2321 if ( (elem = temp[i]) ) {
2322 matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2323 }
2324 }
2325 }
2326
2327 if ( seed ) {
2328 if ( postFinder || preFilter ) {
2329 if ( postFinder ) {
2330 // Get the final matcherOut by condensing this intermediate into postFinder contexts
2331 temp = [];
2332 i = matcherOut.length;
2333 while ( i-- ) {
2334 if ( (elem = matcherOut[i]) ) {
2335 // Restore matcherIn since elem is not yet a final match
2336 temp.push( (matcherIn[i] = elem) );
2337 }
2338 }
2339 postFinder( null, (matcherOut = []), temp, xml );
2340 }
2341
2342 // Move matched elements from seed to results to keep them synchronized
2343 i = matcherOut.length;
2344 while ( i-- ) {
2345 if ( (elem = matcherOut[i]) &&
2346 (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2347
2348 seed[temp] = !(results[temp] = elem);
2349 }
2350 }
2351 }
2352
2353 // Add elements to results, through postFinder if defined
2354 } else {
2355 matcherOut = condense(
2356 matcherOut === results ?
2357 matcherOut.splice( preexisting, matcherOut.length ) :
2358 matcherOut
2359 );
2360 if ( postFinder ) {
2361 postFinder( null, results, matcherOut, xml );
2362 } else {
2363 push.apply( results, matcherOut );
2364 }
2365 }
2366 });
2367}
2368
2369function matcherFromTokens( tokens ) {
2370 var checkContext, matcher, j,
2371 len = tokens.length,
2372 leadingRelative = Expr.relative[ tokens[0].type ],
2373 implicitRelative = leadingRelative || Expr.relative[" "],
2374 i = leadingRelative ? 1 : 0,
2375
2376 // The foundational matcher ensures that elements are reachable from top-level context(s)
2377 matchContext = addCombinator( function( elem ) {
2378 return elem === checkContext;
2379 }, implicitRelative, true ),
2380 matchAnyContext = addCombinator( function( elem ) {
2381 return indexOf( checkContext, elem ) > -1;
2382 }, implicitRelative, true ),
2383 matchers = [ function( elem, context, xml ) {
2384 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2385 (checkContext = context).nodeType ?
2386 matchContext( elem, context, xml ) :
2387 matchAnyContext( elem, context, xml ) );
2388 // Avoid hanging onto element (issue #299)
2389 checkContext = null;
2390 return ret;
2391 } ];
2392
2393 for ( ; i < len; i++ ) {
2394 if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2395 matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2396 } else {
2397 matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2398
2399 // Return special upon seeing a positional matcher
2400 if ( matcher[ expando ] ) {
2401 // Find the next relative operator (if any) for proper handling
2402 j = ++i;
2403 for ( ; j < len; j++ ) {
2404 if ( Expr.relative[ tokens[j].type ] ) {
2405 break;
2406 }
2407 }
2408 return setMatcher(
2409 i > 1 && elementMatcher( matchers ),
2410 i > 1 && toSelector(
2411 // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2412 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2413 ).replace( rtrim, "$1" ),
2414 matcher,
2415 i < j && matcherFromTokens( tokens.slice( i, j ) ),
2416 j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2417 j < len && toSelector( tokens )
2418 );
2419 }
2420 matchers.push( matcher );
2421 }
2422 }
2423
2424 return elementMatcher( matchers );
2425}
2426
2427function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2428 var bySet = setMatchers.length > 0,
2429 byElement = elementMatchers.length > 0,
2430 superMatcher = function( seed, context, xml, results, outermost ) {
2431 var elem, j, matcher,
2432 matchedCount = 0,
2433 i = "0",
2434 unmatched = seed && [],
2435 setMatched = [],
2436 contextBackup = outermostContext,
2437 // We must always have either seed elements or outermost context
2438 elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2439 // Use integer dirruns iff this is the outermost matcher
2440 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2441 len = elems.length;
2442
2443 if ( outermost ) {
2444 outermostContext = context === document || context || outermost;
2445 }
2446
2447 // Add elements passing elementMatchers directly to results
2448 // Support: IE<9, Safari
2449 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2450 for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2451 if ( byElement && elem ) {
2452 j = 0;
2453 if ( !context && elem.ownerDocument !== document ) {
2454 setDocument( elem );
2455 xml = !documentIsHTML;
2456 }
2457 while ( (matcher = elementMatchers[j++]) ) {
2458 if ( matcher( elem, context || document, xml) ) {
2459 results.push( elem );
2460 break;
2461 }
2462 }
2463 if ( outermost ) {
2464 dirruns = dirrunsUnique;
2465 }
2466 }
2467
2468 // Track unmatched elements for set filters
2469 if ( bySet ) {
2470 // They will have gone through all possible matchers
2471 if ( (elem = !matcher && elem) ) {
2472 matchedCount--;
2473 }
2474
2475 // Lengthen the array for every element, matched or not
2476 if ( seed ) {
2477 unmatched.push( elem );
2478 }
2479 }
2480 }
2481
2482 // `i` is now the count of elements visited above, and adding it to `matchedCount`
2483 // makes the latter nonnegative.
2484 matchedCount += i;
2485
2486 // Apply set filters to unmatched elements
2487 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2488 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2489 // no element matchers and no seed.
2490 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2491 // case, which will result in a "00" `matchedCount` that differs from `i` but is also
2492 // numerically zero.
2493 if ( bySet && i !== matchedCount ) {
2494 j = 0;
2495 while ( (matcher = setMatchers[j++]) ) {
2496 matcher( unmatched, setMatched, context, xml );
2497 }
2498
2499 if ( seed ) {
2500 // Reintegrate element matches to eliminate the need for sorting
2501 if ( matchedCount > 0 ) {
2502 while ( i-- ) {
2503 if ( !(unmatched[i] || setMatched[i]) ) {
2504 setMatched[i] = pop.call( results );
2505 }
2506 }
2507 }
2508
2509 // Discard index placeholder values to get only actual matches
2510 setMatched = condense( setMatched );
2511 }
2512
2513 // Add matches to results
2514 push.apply( results, setMatched );
2515
2516 // Seedless set matches succeeding multiple successful matchers stipulate sorting
2517 if ( outermost && !seed && setMatched.length > 0 &&
2518 ( matchedCount + setMatchers.length ) > 1 ) {
2519
2520 Sizzle.uniqueSort( results );
2521 }
2522 }
2523
2524 // Override manipulation of globals by nested matchers
2525 if ( outermost ) {
2526 dirruns = dirrunsUnique;
2527 outermostContext = contextBackup;
2528 }
2529
2530 return unmatched;
2531 };
2532
2533 return bySet ?
2534 markFunction( superMatcher ) :
2535 superMatcher;
2536}
2537
2538compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2539 var i,
2540 setMatchers = [],
2541 elementMatchers = [],
2542 cached = compilerCache[ selector + " " ];
2543
2544 if ( !cached ) {
2545 // Generate a function of recursive functions that can be used to check each element
2546 if ( !match ) {
2547 match = tokenize( selector );
2548 }
2549 i = match.length;
2550 while ( i-- ) {
2551 cached = matcherFromTokens( match[i] );
2552 if ( cached[ expando ] ) {
2553 setMatchers.push( cached );
2554 } else {
2555 elementMatchers.push( cached );
2556 }
2557 }
2558
2559 // Cache the compiled function
2560 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2561
2562 // Save selector and tokenization
2563 cached.selector = selector;
2564 }
2565 return cached;
2566};
2567
2568/**
2569 * A low-level selection function that works with Sizzle's compiled
2570 * selector functions
2571 * @param {String|Function} selector A selector or a pre-compiled
2572 * selector function built with Sizzle.compile
2573 * @param {Element} context
2574 * @param {Array} [results]
2575 * @param {Array} [seed] A set of elements to match against
2576 */
2577select = Sizzle.select = function( selector, context, results, seed ) {
2578 var i, tokens, token, type, find,
2579 compiled = typeof selector === "function" && selector,
2580 match = !seed && tokenize( (selector = compiled.selector || selector) );
2581
2582 results = results || [];
2583
2584 // Try to minimize operations if there is only one selector in the list and no seed
2585 // (the latter of which guarantees us context)
2586 if ( match.length === 1 ) {
2587
2588 // Reduce context if the leading compound selector is an ID
2589 tokens = match[0] = match[0].slice( 0 );
2590 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2591 support.getById && context.nodeType === 9 && documentIsHTML &&
2592 Expr.relative[ tokens[1].type ] ) {
2593
2594 context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2595 if ( !context ) {
2596 return results;
2597
2598 // Precompiled matchers will still verify ancestry, so step up a level
2599 } else if ( compiled ) {
2600 context = context.parentNode;
2601 }
2602
2603 selector = selector.slice( tokens.shift().value.length );
2604 }
2605
2606 // Fetch a seed set for right-to-left matching
2607 i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2608 while ( i-- ) {
2609 token = tokens[i];
2610
2611 // Abort if we hit a combinator
2612 if ( Expr.relative[ (type = token.type) ] ) {
2613 break;
2614 }
2615 if ( (find = Expr.find[ type ]) ) {
2616 // Search, expanding context for leading sibling combinators
2617 if ( (seed = find(
2618 token.matches[0].replace( runescape, funescape ),
2619 rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2620 )) ) {
2621
2622 // If seed is empty or no tokens remain, we can return early
2623 tokens.splice( i, 1 );
2624 selector = seed.length && toSelector( tokens );
2625 if ( !selector ) {
2626 push.apply( results, seed );
2627 return results;
2628 }
2629
2630 break;
2631 }
2632 }
2633 }
2634 }
2635
2636 // Compile and execute a filtering function if one is not provided
2637 // Provide `match` to avoid retokenization if we modified the selector above
2638 ( compiled || compile( selector, match ) )(
2639 seed,
2640 context,
2641 !documentIsHTML,
2642 results,
2643 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2644 );
2645 return results;
2646};
2647
2648// One-time assignments
2649
2650// Sort stability
2651support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2652
2653// Support: Chrome 14-35+
2654// Always assume duplicates if they aren't passed to the comparison function
2655support.detectDuplicates = !!hasDuplicate;
2656
2657// Initialize against the default document
2658setDocument();
2659
2660// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2661// Detached nodes confoundingly follow *each other*
2662support.sortDetached = assert(function( div1 ) {
2663 // Should return 1, but returns 4 (following)
2664 return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2665});
2666
2667// Support: IE<8
2668// Prevent attribute/property "interpolation"
2669// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2670if ( !assert(function( div ) {
2671 div.innerHTML = "<a href='#'></a>";
2672 return div.firstChild.getAttribute("href") === "#" ;
2673}) ) {
2674 addHandle( "type|href|height|width", function( elem, name, isXML ) {
2675 if ( !isXML ) {
2676 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2677 }
2678 });
2679}
2680
2681// Support: IE<9
2682// Use defaultValue in place of getAttribute("value")
2683if ( !support.attributes || !assert(function( div ) {
2684 div.innerHTML = "<input/>";
2685 div.firstChild.setAttribute( "value", "" );
2686 return div.firstChild.getAttribute( "value" ) === "";
2687}) ) {
2688 addHandle( "value", function( elem, name, isXML ) {
2689 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2690 return elem.defaultValue;
2691 }
2692 });
2693}
2694
2695// Support: IE<9
2696// Use getAttributeNode to fetch booleans when getAttribute lies
2697if ( !assert(function( div ) {
2698 return div.getAttribute("disabled") == null;
2699}) ) {
2700 addHandle( booleans, function( elem, name, isXML ) {
2701 var val;
2702 if ( !isXML ) {
2703 return elem[ name ] === true ? name.toLowerCase() :
2704 (val = elem.getAttributeNode( name )) && val.specified ?
2705 val.value :
2706 null;
2707 }
2708 });
2709}
2710
2711return Sizzle;
2712
2713})( window );
2714
2715
2716
2717jQuery.find = Sizzle;
2718jQuery.expr = Sizzle.selectors;
2719jQuery.expr[ ":" ] = jQuery.expr.pseudos;
2720jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2721jQuery.text = Sizzle.getText;
2722jQuery.isXMLDoc = Sizzle.isXML;
2723jQuery.contains = Sizzle.contains;
2724
2725
2726
2727var dir = function( elem, dir, until ) {
2728 var matched = [],
2729 truncate = until !== undefined;
2730
2731 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
2732 if ( elem.nodeType === 1 ) {
2733 if ( truncate && jQuery( elem ).is( until ) ) {
2734 break;
2735 }
2736 matched.push( elem );
2737 }
2738 }
2739 return matched;
2740};
2741
2742
2743var siblings = function( n, elem ) {
2744 var matched = [];
2745
2746 for ( ; n; n = n.nextSibling ) {
2747 if ( n.nodeType === 1 && n !== elem ) {
2748 matched.push( n );
2749 }
2750 }
2751
2752 return matched;
2753};
2754
2755
2756var rneedsContext = jQuery.expr.match.needsContext;
2757
2758var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
2759
2760
2761
2762var risSimple = /^.[^:#\[\.,]*$/;
2763
2764// Implement the identical functionality for filter and not
2765function winnow( elements, qualifier, not ) {
2766 if ( jQuery.isFunction( qualifier ) ) {
2767 return jQuery.grep( elements, function( elem, i ) {
2768 /* jshint -W018 */
2769 return !!qualifier.call( elem, i, elem ) !== not;
2770 } );
2771
2772 }
2773
2774 if ( qualifier.nodeType ) {
2775 return jQuery.grep( elements, function( elem ) {
2776 return ( elem === qualifier ) !== not;
2777 } );
2778
2779 }
2780
2781 if ( typeof qualifier === "string" ) {
2782 if ( risSimple.test( qualifier ) ) {
2783 return jQuery.filter( qualifier, elements, not );
2784 }
2785
2786 qualifier = jQuery.filter( qualifier, elements );
2787 }
2788
2789 return jQuery.grep( elements, function( elem ) {
2790 return ( jQuery.inArray( elem, qualifier ) > -1 ) !== not;
2791 } );
2792}
2793
2794jQuery.filter = function( expr, elems, not ) {
2795 var elem = elems[ 0 ];
2796
2797 if ( not ) {
2798 expr = ":not(" + expr + ")";
2799 }
2800
2801 return elems.length === 1 && elem.nodeType === 1 ?
2802 jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
2803 jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2804 return elem.nodeType === 1;
2805 } ) );
2806};
2807
2808jQuery.fn.extend( {
2809 find: function( selector ) {
2810 var i,
2811 ret = [],
2812 self = this,
2813 len = self.length;
2814
2815 if ( typeof selector !== "string" ) {
2816 return this.pushStack( jQuery( selector ).filter( function() {
2817 for ( i = 0; i < len; i++ ) {
2818 if ( jQuery.contains( self[ i ], this ) ) {
2819 return true;
2820 }
2821 }
2822 } ) );
2823 }
2824
2825 for ( i = 0; i < len; i++ ) {
2826 jQuery.find( selector, self[ i ], ret );
2827 }
2828
2829 // Needed because $( selector, context ) becomes $( context ).find( selector )
2830 ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
2831 ret.selector = this.selector ? this.selector + " " + selector : selector;
2832 return ret;
2833 },
2834 filter: function( selector ) {
2835 return this.pushStack( winnow( this, selector || [], false ) );
2836 },
2837 not: function( selector ) {
2838 return this.pushStack( winnow( this, selector || [], true ) );
2839 },
2840 is: function( selector ) {
2841 return !!winnow(
2842 this,
2843
2844 // If this is a positional/relative selector, check membership in the returned set
2845 // so $("p:first").is("p:last") won't return true for a doc with two "p".
2846 typeof selector === "string" && rneedsContext.test( selector ) ?
2847 jQuery( selector ) :
2848 selector || [],
2849 false
2850 ).length;
2851 }
2852} );
2853
2854
2855// Initialize a jQuery object
2856
2857
2858// A central reference to the root jQuery(document)
2859var rootjQuery,
2860
2861 // A simple way to check for HTML strings
2862 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2863 // Strict HTML recognition (#11290: must start with <)
2864 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2865
2866 init = jQuery.fn.init = function( selector, context, root ) {
2867 var match, elem;
2868
2869 // HANDLE: $(""), $(null), $(undefined), $(false)
2870 if ( !selector ) {
2871 return this;
2872 }
2873
2874 // init accepts an alternate rootjQuery
2875 // so migrate can support jQuery.sub (gh-2101)
2876 root = root || rootjQuery;
2877
2878 // Handle HTML strings
2879 if ( typeof selector === "string" ) {
2880 if ( selector.charAt( 0 ) === "<" &&
2881 selector.charAt( selector.length - 1 ) === ">" &&
2882 selector.length >= 3 ) {
2883
2884 // Assume that strings that start and end with <> are HTML and skip the regex check
2885 match = [ null, selector, null ];
2886
2887 } else {
2888 match = rquickExpr.exec( selector );
2889 }
2890
2891 // Match html or make sure no context is specified for #id
2892 if ( match && ( match[ 1 ] || !context ) ) {
2893
2894 // HANDLE: $(html) -> $(array)
2895 if ( match[ 1 ] ) {
2896 context = context instanceof jQuery ? context[ 0 ] : context;
2897
2898 // scripts is true for back-compat
2899 // Intentionally let the error be thrown if parseHTML is not present
2900 jQuery.merge( this, jQuery.parseHTML(
2901 match[ 1 ],
2902 context && context.nodeType ? context.ownerDocument || context : document,
2903 true
2904 ) );
2905
2906 // HANDLE: $(html, props)
2907 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
2908 for ( match in context ) {
2909
2910 // Properties of context are called as methods if possible
2911 if ( jQuery.isFunction( this[ match ] ) ) {
2912 this[ match ]( context[ match ] );
2913
2914 // ...and otherwise set as attributes
2915 } else {
2916 this.attr( match, context[ match ] );
2917 }
2918 }
2919 }
2920
2921 return this;
2922
2923 // HANDLE: $(#id)
2924 } else {
2925 elem = document.getElementById( match[ 2 ] );
2926
2927 // Check parentNode to catch when Blackberry 4.6 returns
2928 // nodes that are no longer in the document #6963
2929 if ( elem && elem.parentNode ) {
2930
2931 // Handle the case where IE and Opera return items
2932 // by name instead of ID
2933 if ( elem.id !== match[ 2 ] ) {
2934 return rootjQuery.find( selector );
2935 }
2936
2937 // Otherwise, we inject the element directly into the jQuery object
2938 this.length = 1;
2939 this[ 0 ] = elem;
2940 }
2941
2942 this.context = document;
2943 this.selector = selector;
2944 return this;
2945 }
2946
2947 // HANDLE: $(expr, $(...))
2948 } else if ( !context || context.jquery ) {
2949 return ( context || root ).find( selector );
2950
2951 // HANDLE: $(expr, context)
2952 // (which is just equivalent to: $(context).find(expr)
2953 } else {
2954 return this.constructor( context ).find( selector );
2955 }
2956
2957 // HANDLE: $(DOMElement)
2958 } else if ( selector.nodeType ) {
2959 this.context = this[ 0 ] = selector;
2960 this.length = 1;
2961 return this;
2962
2963 // HANDLE: $(function)
2964 // Shortcut for document ready
2965 } else if ( jQuery.isFunction( selector ) ) {
2966 return typeof root.ready !== "undefined" ?
2967 root.ready( selector ) :
2968
2969 // Execute immediately if ready is not present
2970 selector( jQuery );
2971 }
2972
2973 if ( selector.selector !== undefined ) {
2974 this.selector = selector.selector;
2975 this.context = selector.context;
2976 }
2977
2978 return jQuery.makeArray( selector, this );
2979 };
2980
2981// Give the init function the jQuery prototype for later instantiation
2982init.prototype = jQuery.fn;
2983
2984// Initialize central reference
2985rootjQuery = jQuery( document );
2986
2987
2988var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2989
2990 // methods guaranteed to produce a unique set when starting from a unique set
2991 guaranteedUnique = {
2992 children: true,
2993 contents: true,
2994 next: true,
2995 prev: true
2996 };
2997
2998jQuery.fn.extend( {
2999 has: function( target ) {
3000 var i,
3001 targets = jQuery( target, this ),
3002 len = targets.length;
3003
3004 return this.filter( function() {
3005 for ( i = 0; i < len; i++ ) {
3006 if ( jQuery.contains( this, targets[ i ] ) ) {
3007 return true;
3008 }
3009 }
3010 } );
3011 },
3012
3013 closest: function( selectors, context ) {
3014 var cur,
3015 i = 0,
3016 l = this.length,
3017 matched = [],
3018 pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
3019 jQuery( selectors, context || this.context ) :
3020 0;
3021
3022 for ( ; i < l; i++ ) {
3023 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
3024
3025 // Always skip document fragments
3026 if ( cur.nodeType < 11 && ( pos ?
3027 pos.index( cur ) > -1 :
3028
3029 // Don't pass non-elements to Sizzle
3030 cur.nodeType === 1 &&
3031 jQuery.find.matchesSelector( cur, selectors ) ) ) {
3032
3033 matched.push( cur );
3034 break;
3035 }
3036 }
3037 }
3038
3039 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3040 },
3041
3042 // Determine the position of an element within
3043 // the matched set of elements
3044 index: function( elem ) {
3045
3046 // No argument, return index in parent
3047 if ( !elem ) {
3048 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3049 }
3050
3051 // index in selector
3052 if ( typeof elem === "string" ) {
3053 return jQuery.inArray( this[ 0 ], jQuery( elem ) );
3054 }
3055
3056 // Locate the position of the desired element
3057 return jQuery.inArray(
3058
3059 // If it receives a jQuery object, the first element is used
3060 elem.jquery ? elem[ 0 ] : elem, this );
3061 },
3062
3063 add: function( selector, context ) {
3064 return this.pushStack(
3065 jQuery.uniqueSort(
3066 jQuery.merge( this.get(), jQuery( selector, context ) )
3067 )
3068 );
3069 },
3070
3071 addBack: function( selector ) {
3072 return this.add( selector == null ?
3073 this.prevObject : this.prevObject.filter( selector )
3074 );
3075 }
3076} );
3077
3078function sibling( cur, dir ) {
3079 do {
3080 cur = cur[ dir ];
3081 } while ( cur && cur.nodeType !== 1 );
3082
3083 return cur;
3084}
3085
3086jQuery.each( {
3087 parent: function( elem ) {
3088 var parent = elem.parentNode;
3089 return parent && parent.nodeType !== 11 ? parent : null;
3090 },
3091 parents: function( elem ) {
3092 return dir( elem, "parentNode" );
3093 },
3094 parentsUntil: function( elem, i, until ) {
3095 return dir( elem, "parentNode", until );
3096 },
3097 next: function( elem ) {
3098 return sibling( elem, "nextSibling" );
3099 },
3100 prev: function( elem ) {
3101 return sibling( elem, "previousSibling" );
3102 },
3103 nextAll: function( elem ) {
3104 return dir( elem, "nextSibling" );
3105 },
3106 prevAll: function( elem ) {
3107 return dir( elem, "previousSibling" );
3108 },
3109 nextUntil: function( elem, i, until ) {
3110 return dir( elem, "nextSibling", until );
3111 },
3112 prevUntil: function( elem, i, until ) {
3113 return dir( elem, "previousSibling", until );
3114 },
3115 siblings: function( elem ) {
3116 return siblings( ( elem.parentNode || {} ).firstChild, elem );
3117 },
3118 children: function( elem ) {
3119 return siblings( elem.firstChild );
3120 },
3121 contents: function( elem ) {
3122 return jQuery.nodeName( elem, "iframe" ) ?
3123 elem.contentDocument || elem.contentWindow.document :
3124 jQuery.merge( [], elem.childNodes );
3125 }
3126}, function( name, fn ) {
3127 jQuery.fn[ name ] = function( until, selector ) {
3128 var ret = jQuery.map( this, fn, until );
3129
3130 if ( name.slice( -5 ) !== "Until" ) {
3131 selector = until;
3132 }
3133
3134 if ( selector && typeof selector === "string" ) {
3135 ret = jQuery.filter( selector, ret );
3136 }
3137
3138 if ( this.length > 1 ) {
3139
3140 // Remove duplicates
3141 if ( !guaranteedUnique[ name ] ) {
3142 ret = jQuery.uniqueSort( ret );
3143 }
3144
3145 // Reverse order for parents* and prev-derivatives
3146 if ( rparentsprev.test( name ) ) {
3147 ret = ret.reverse();
3148 }
3149 }
3150
3151 return this.pushStack( ret );
3152 };
3153} );
3154var rnotwhite = ( /\S+/g );
3155
3156
3157
3158// Convert String-formatted options into Object-formatted ones
3159function createOptions( options ) {
3160 var object = {};
3161 jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3162 object[ flag ] = true;
3163 } );
3164 return object;
3165}
3166
3167/*
3168 * Create a callback list using the following parameters:
3169 *
3170 * options: an optional list of space-separated options that will change how
3171 * the callback list behaves or a more traditional option object
3172 *
3173 * By default a callback list will act like an event callback list and can be
3174 * "fired" multiple times.
3175 *
3176 * Possible options:
3177 *
3178 * once: will ensure the callback list can only be fired once (like a Deferred)
3179 *
3180 * memory: will keep track of previous values and will call any callback added
3181 * after the list has been fired right away with the latest "memorized"
3182 * values (like a Deferred)
3183 *
3184 * unique: will ensure a callback can only be added once (no duplicate in the list)
3185 *
3186 * stopOnFalse: interrupt callings when a callback returns false
3187 *
3188 */
3189jQuery.Callbacks = function( options ) {
3190
3191 // Convert options from String-formatted to Object-formatted if needed
3192 // (we check in cache first)
3193 options = typeof options === "string" ?
3194 createOptions( options ) :
3195 jQuery.extend( {}, options );
3196
3197 var // Flag to know if list is currently firing
3198 firing,
3199
3200 // Last fire value for non-forgettable lists
3201 memory,
3202
3203 // Flag to know if list was already fired
3204 fired,
3205
3206 // Flag to prevent firing
3207 locked,
3208
3209 // Actual callback list
3210 list = [],
3211
3212 // Queue of execution data for repeatable lists
3213 queue = [],
3214
3215 // Index of currently firing callback (modified by add/remove as needed)
3216 firingIndex = -1,
3217
3218 // Fire callbacks
3219 fire = function() {
3220
3221 // Enforce single-firing
3222 locked = options.once;
3223
3224 // Execute callbacks for all pending executions,
3225 // respecting firingIndex overrides and runtime changes
3226 fired = firing = true;
3227 for ( ; queue.length; firingIndex = -1 ) {
3228 memory = queue.shift();
3229 while ( ++firingIndex < list.length ) {
3230
3231 // Run callback and check for early termination
3232 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3233 options.stopOnFalse ) {
3234
3235 // Jump to end and forget the data so .add doesn't re-fire
3236 firingIndex = list.length;
3237 memory = false;
3238 }
3239 }
3240 }
3241
3242 // Forget the data if we're done with it
3243 if ( !options.memory ) {
3244 memory = false;
3245 }
3246
3247 firing = false;
3248
3249 // Clean up if we're done firing for good
3250 if ( locked ) {
3251
3252 // Keep an empty list if we have data for future add calls
3253 if ( memory ) {
3254 list = [];
3255
3256 // Otherwise, this object is spent
3257 } else {
3258 list = "";
3259 }
3260 }
3261 },
3262
3263 // Actual Callbacks object
3264 self = {
3265
3266 // Add a callback or a collection of callbacks to the list
3267 add: function() {
3268 if ( list ) {
3269
3270 // If we have memory from a past run, we should fire after adding
3271 if ( memory && !firing ) {
3272 firingIndex = list.length - 1;
3273 queue.push( memory );
3274 }
3275
3276 ( function add( args ) {
3277 jQuery.each( args, function( _, arg ) {
3278 if ( jQuery.isFunction( arg ) ) {
3279 if ( !options.unique || !self.has( arg ) ) {
3280 list.push( arg );
3281 }
3282 } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
3283
3284 // Inspect recursively
3285 add( arg );
3286 }
3287 } );
3288 } )( arguments );
3289
3290 if ( memory && !firing ) {
3291 fire();
3292 }
3293 }
3294 return this;
3295 },
3296
3297 // Remove a callback from the list
3298 remove: function() {
3299 jQuery.each( arguments, function( _, arg ) {
3300 var index;
3301 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3302 list.splice( index, 1 );
3303
3304 // Handle firing indexes
3305 if ( index <= firingIndex ) {
3306 firingIndex--;
3307 }
3308 }
3309 } );
3310 return this;
3311 },
3312
3313 // Check if a given callback is in the list.
3314 // If no argument is given, return whether or not list has callbacks attached.
3315 has: function( fn ) {
3316 return fn ?
3317 jQuery.inArray( fn, list ) > -1 :
3318 list.length > 0;
3319 },
3320
3321 // Remove all callbacks from the list
3322 empty: function() {
3323 if ( list ) {
3324 list = [];
3325 }
3326 return this;
3327 },
3328
3329 // Disable .fire and .add
3330 // Abort any current/pending executions
3331 // Clear all callbacks and values
3332 disable: function() {
3333 locked = queue = [];
3334 list = memory = "";
3335 return this;
3336 },
3337 disabled: function() {
3338 return !list;
3339 },
3340
3341 // Disable .fire
3342 // Also disable .add unless we have memory (since it would have no effect)
3343 // Abort any pending executions
3344 lock: function() {
3345 locked = true;
3346 if ( !memory ) {
3347 self.disable();
3348 }
3349 return this;
3350 },
3351 locked: function() {
3352 return !!locked;
3353 },
3354
3355 // Call all callbacks with the given context and arguments
3356 fireWith: function( context, args ) {
3357 if ( !locked ) {
3358 args = args || [];
3359 args = [ context, args.slice ? args.slice() : args ];
3360 queue.push( args );
3361 if ( !firing ) {
3362 fire();
3363 }
3364 }
3365 return this;
3366 },
3367
3368 // Call all the callbacks with the given arguments
3369 fire: function() {
3370 self.fireWith( this, arguments );
3371 return this;
3372 },
3373
3374 // To know if the callbacks have already been called at least once
3375 fired: function() {
3376 return !!fired;
3377 }
3378 };
3379
3380 return self;
3381};
3382
3383
3384jQuery.extend( {
3385
3386 Deferred: function( func ) {
3387 var tuples = [
3388
3389 // action, add listener, listener list, final state
3390 [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
3391 [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
3392 [ "notify", "progress", jQuery.Callbacks( "memory" ) ]
3393 ],
3394 state = "pending",
3395 promise = {
3396 state: function() {
3397 return state;
3398 },
3399 always: function() {
3400 deferred.done( arguments ).fail( arguments );
3401 return this;
3402 },
3403 then: function( /* fnDone, fnFail, fnProgress */ ) {
3404 var fns = arguments;
3405 return jQuery.Deferred( function( newDefer ) {
3406 jQuery.each( tuples, function( i, tuple ) {
3407 var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3408
3409 // deferred[ done | fail | progress ] for forwarding actions to newDefer
3410 deferred[ tuple[ 1 ] ]( function() {
3411 var returned = fn && fn.apply( this, arguments );
3412 if ( returned && jQuery.isFunction( returned.promise ) ) {
3413 returned.promise()
3414 .progress( newDefer.notify )
3415 .done( newDefer.resolve )
3416 .fail( newDefer.reject );
3417 } else {
3418 newDefer[ tuple[ 0 ] + "With" ](
3419 this === promise ? newDefer.promise() : this,
3420 fn ? [ returned ] : arguments
3421 );
3422 }
3423 } );
3424 } );
3425 fns = null;
3426 } ).promise();
3427 },
3428
3429 // Get a promise for this deferred
3430 // If obj is provided, the promise aspect is added to the object
3431 promise: function( obj ) {
3432 return obj != null ? jQuery.extend( obj, promise ) : promise;
3433 }
3434 },
3435 deferred = {};
3436
3437 // Keep pipe for back-compat
3438 promise.pipe = promise.then;
3439
3440 // Add list-specific methods
3441 jQuery.each( tuples, function( i, tuple ) {
3442 var list = tuple[ 2 ],
3443 stateString = tuple[ 3 ];
3444
3445 // promise[ done | fail | progress ] = list.add
3446 promise[ tuple[ 1 ] ] = list.add;
3447
3448 // Handle state
3449 if ( stateString ) {
3450 list.add( function() {
3451
3452 // state = [ resolved | rejected ]
3453 state = stateString;
3454
3455 // [ reject_list | resolve_list ].disable; progress_list.lock
3456 }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3457 }
3458
3459 // deferred[ resolve | reject | notify ]
3460 deferred[ tuple[ 0 ] ] = function() {
3461 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
3462 return this;
3463 };
3464 deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
3465 } );
3466
3467 // Make the deferred a promise
3468 promise.promise( deferred );
3469
3470 // Call given func if any
3471 if ( func ) {
3472 func.call( deferred, deferred );
3473 }
3474
3475 // All done!
3476 return deferred;
3477 },
3478
3479 // Deferred helper
3480 when: function( subordinate /* , ..., subordinateN */ ) {
3481 var i = 0,
3482 resolveValues = slice.call( arguments ),
3483 length = resolveValues.length,
3484
3485 // the count of uncompleted subordinates
3486 remaining = length !== 1 ||
3487 ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3488
3489 // the master Deferred.
3490 // If resolveValues consist of only a single Deferred, just use that.
3491 deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3492
3493 // Update function for both resolve and progress values
3494 updateFunc = function( i, contexts, values ) {
3495 return function( value ) {
3496 contexts[ i ] = this;
3497 values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3498 if ( values === progressValues ) {
3499 deferred.notifyWith( contexts, values );
3500
3501 } else if ( !( --remaining ) ) {
3502 deferred.resolveWith( contexts, values );
3503 }
3504 };
3505 },
3506
3507 progressValues, progressContexts, resolveContexts;
3508
3509 // add listeners to Deferred subordinates; treat others as resolved
3510 if ( length > 1 ) {
3511 progressValues = new Array( length );
3512 progressContexts = new Array( length );
3513 resolveContexts = new Array( length );
3514 for ( ; i < length; i++ ) {
3515 if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3516 resolveValues[ i ].promise()
3517 .progress( updateFunc( i, progressContexts, progressValues ) )
3518 .done( updateFunc( i, resolveContexts, resolveValues ) )
3519 .fail( deferred.reject );
3520 } else {
3521 --remaining;
3522 }
3523 }
3524 }
3525
3526 // if we're not waiting on anything, resolve the master
3527 if ( !remaining ) {
3528 deferred.resolveWith( resolveContexts, resolveValues );
3529 }
3530
3531 return deferred.promise();
3532 }
3533} );
3534
3535
3536// The deferred used on DOM ready
3537var readyList;
3538
3539jQuery.fn.ready = function( fn ) {
3540
3541 // Add the callback
3542 jQuery.ready.promise().done( fn );
3543
3544 return this;
3545};
3546
3547jQuery.extend( {
3548
3549 // Is the DOM ready to be used? Set to true once it occurs.
3550 isReady: false,
3551
3552 // A counter to track how many items to wait for before
3553 // the ready event fires. See #6781
3554 readyWait: 1,
3555
3556 // Hold (or release) the ready event
3557 holdReady: function( hold ) {
3558 if ( hold ) {
3559 jQuery.readyWait++;
3560 } else {
3561 jQuery.ready( true );
3562 }
3563 },
3564
3565 // Handle when the DOM is ready
3566 ready: function( wait ) {
3567
3568 // Abort if there are pending holds or we're already ready
3569 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3570 return;
3571 }
3572
3573 // Remember that the DOM is ready
3574 jQuery.isReady = true;
3575
3576 // If a normal DOM Ready event fired, decrement, and wait if need be
3577 if ( wait !== true && --jQuery.readyWait > 0 ) {
3578 return;
3579 }
3580
3581 // If there are functions bound, to execute
3582 readyList.resolveWith( document, [ jQuery ] );
3583
3584 // Trigger any bound ready events
3585 if ( jQuery.fn.triggerHandler ) {
3586 jQuery( document ).triggerHandler( "ready" );
3587 jQuery( document ).off( "ready" );
3588 }
3589 }
3590} );
3591
3592/**
3593 * Clean-up method for dom ready events
3594 */
3595function detach() {
3596 if ( document.addEventListener ) {
3597 document.removeEventListener( "DOMContentLoaded", completed );
3598 window.removeEventListener( "load", completed );
3599
3600 } else {
3601 document.detachEvent( "onreadystatechange", completed );
3602 window.detachEvent( "onload", completed );
3603 }
3604}
3605
3606/**
3607 * The ready event handler and self cleanup method
3608 */
3609function completed() {
3610
3611 // readyState === "complete" is good enough for us to call the dom ready in oldIE
3612 if ( document.addEventListener ||
3613 window.event.type === "load" ||
3614 document.readyState === "complete" ) {
3615
3616 detach();
3617 jQuery.ready();
3618 }
3619}
3620
3621jQuery.ready.promise = function( obj ) {
3622 if ( !readyList ) {
3623
3624 readyList = jQuery.Deferred();
3625
3626 // Catch cases where $(document).ready() is called
3627 // after the browser event has already occurred.
3628 // Support: IE6-10
3629 // Older IE sometimes signals "interactive" too soon
3630 if ( document.readyState === "complete" ||
3631 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
3632
3633 // Handle it asynchronously to allow scripts the opportunity to delay ready
3634 window.setTimeout( jQuery.ready );
3635
3636 // Standards-based browsers support DOMContentLoaded
3637 } else if ( document.addEventListener ) {
3638
3639 // Use the handy event callback
3640 document.addEventListener( "DOMContentLoaded", completed );
3641
3642 // A fallback to window.onload, that will always work
3643 window.addEventListener( "load", completed );
3644
3645 // If IE event model is used
3646 } else {
3647
3648 // Ensure firing before onload, maybe late but safe also for iframes
3649 document.attachEvent( "onreadystatechange", completed );
3650
3651 // A fallback to window.onload, that will always work
3652 window.attachEvent( "onload", completed );
3653
3654 // If IE and not a frame
3655 // continually check to see if the document is ready
3656 var top = false;
3657
3658 try {
3659 top = window.frameElement == null && document.documentElement;
3660 } catch ( e ) {}
3661
3662 if ( top && top.doScroll ) {
3663 ( function doScrollCheck() {
3664 if ( !jQuery.isReady ) {
3665
3666 try {
3667
3668 // Use the trick by Diego Perini
3669 // http://javascript.nwbox.com/IEContentLoaded/
3670 top.doScroll( "left" );
3671 } catch ( e ) {
3672 return window.setTimeout( doScrollCheck, 50 );
3673 }
3674
3675 // detach all dom ready events
3676 detach();
3677
3678 // and execute any waiting functions
3679 jQuery.ready();
3680 }
3681 } )();
3682 }
3683 }
3684 }
3685 return readyList.promise( obj );
3686};
3687
3688// Kick off the DOM ready check even if the user does not
3689jQuery.ready.promise();
3690
3691
3692
3693
3694// Support: IE<9
3695// Iteration over object's inherited properties before its own
3696var i;
3697for ( i in jQuery( support ) ) {
3698 break;
3699}
3700support.ownFirst = i === "0";
3701
3702// Note: most support tests are defined in their respective modules.
3703// false until the test is run
3704support.inlineBlockNeedsLayout = false;
3705
3706// Execute ASAP in case we need to set body.style.zoom
3707jQuery( function() {
3708
3709 // Minified: var a,b,c,d
3710 var val, div, body, container;
3711
3712 body = document.getElementsByTagName( "body" )[ 0 ];
3713 if ( !body || !body.style ) {
3714
3715 // Return for frameset docs that don't have a body
3716 return;
3717 }
3718
3719 // Setup
3720 div = document.createElement( "div" );
3721 container = document.createElement( "div" );
3722 container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
3723 body.appendChild( container ).appendChild( div );
3724
3725 if ( typeof div.style.zoom !== "undefined" ) {
3726
3727 // Support: IE<8
3728 // Check if natively block-level elements act like inline-block
3729 // elements when setting their display to 'inline' and giving
3730 // them layout
3731 div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
3732
3733 support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
3734 if ( val ) {
3735
3736 // Prevent IE 6 from affecting layout for positioned elements #11048
3737 // Prevent IE from shrinking the body in IE 7 mode #12869
3738 // Support: IE<8
3739 body.style.zoom = 1;
3740 }
3741 }
3742
3743 body.removeChild( container );
3744} );
3745
3746
3747( function() {
3748 var div = document.createElement( "div" );
3749
3750 // Support: IE<9
3751 support.deleteExpando = true;
3752 try {
3753 delete div.test;
3754 } catch ( e ) {
3755 support.deleteExpando = false;
3756 }
3757
3758 // Null elements to avoid leaks in IE.
3759 div = null;
3760} )();
3761var acceptData = function( elem ) {
3762 var noData = jQuery.noData[ ( elem.nodeName + " " ).toLowerCase() ],
3763 nodeType = +elem.nodeType || 1;
3764
3765 // Do not set data on non-element DOM nodes because it will not be cleared (#8335).
3766 return nodeType !== 1 && nodeType !== 9 ?
3767 false :
3768
3769 // Nodes accept data unless otherwise specified; rejection can be conditional
3770 !noData || noData !== true && elem.getAttribute( "classid" ) === noData;
3771};
3772
3773
3774
3775
3776var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3777 rmultiDash = /([A-Z])/g;
3778
3779function dataAttr( elem, key, data ) {
3780
3781 // If nothing was found internally, try to fetch any
3782 // data from the HTML5 data-* attribute
3783 if ( data === undefined && elem.nodeType === 1 ) {
3784
3785 var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
3786
3787 data = elem.getAttribute( name );
3788
3789 if ( typeof data === "string" ) {
3790 try {
3791 data = data === "true" ? true :
3792 data === "false" ? false :
3793 data === "null" ? null :
3794
3795 // Only convert to a number if it doesn't change the string
3796 +data + "" === data ? +data :
3797 rbrace.test( data ) ? jQuery.parseJSON( data ) :
3798 data;
3799 } catch ( e ) {}
3800
3801 // Make sure we set the data so it isn't changed later
3802 jQuery.data( elem, key, data );
3803
3804 } else {
3805 data = undefined;
3806 }
3807 }
3808
3809 return data;
3810}
3811
3812// checks a cache object for emptiness
3813function isEmptyDataObject( obj ) {
3814 var name;
3815 for ( name in obj ) {
3816
3817 // if the public data object is empty, the private is still empty
3818 if ( name === "data" && jQuery.isEmptyObject( obj[ name ] ) ) {
3819 continue;
3820 }
3821 if ( name !== "toJSON" ) {
3822 return false;
3823 }
3824 }
3825
3826 return true;
3827}
3828
3829function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
3830 if ( !acceptData( elem ) ) {
3831 return;
3832 }
3833
3834 var ret, thisCache,
3835 internalKey = jQuery.expando,
3836
3837 // We have to handle DOM nodes and JS objects differently because IE6-7
3838 // can't GC object references properly across the DOM-JS boundary
3839 isNode = elem.nodeType,
3840
3841 // Only DOM nodes need the global jQuery cache; JS object data is
3842 // attached directly to the object so GC can occur automatically
3843 cache = isNode ? jQuery.cache : elem,
3844
3845 // Only defining an ID for JS objects if its cache already exists allows
3846 // the code to shortcut on the same path as a DOM node with no cache
3847 id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
3848
3849 // Avoid doing any more work than we need to when trying to get data on an
3850 // object that has no data at all
3851 if ( ( !id || !cache[ id ] || ( !pvt && !cache[ id ].data ) ) &&
3852 data === undefined && typeof name === "string" ) {
3853 return;
3854 }
3855
3856 if ( !id ) {
3857
3858 // Only DOM nodes need a new unique ID for each element since their data
3859 // ends up in the global cache
3860 if ( isNode ) {
3861 id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
3862 } else {
3863 id = internalKey;
3864 }
3865 }
3866
3867 if ( !cache[ id ] ) {
3868
3869 // Avoid exposing jQuery metadata on plain JS objects when the object
3870 // is serialized using JSON.stringify
3871 cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
3872 }
3873
3874 // An object can be passed to jQuery.data instead of a key/value pair; this gets
3875 // shallow copied over onto the existing cache
3876 if ( typeof name === "object" || typeof name === "function" ) {
3877 if ( pvt ) {
3878 cache[ id ] = jQuery.extend( cache[ id ], name );
3879 } else {
3880 cache[ id ].data = jQuery.extend( cache[ id ].data, name );
3881 }
3882 }
3883
3884 thisCache = cache[ id ];
3885
3886 // jQuery data() is stored in a separate object inside the object's internal data
3887 // cache in order to avoid key collisions between internal data and user-defined
3888 // data.
3889 if ( !pvt ) {
3890 if ( !thisCache.data ) {
3891 thisCache.data = {};
3892 }
3893
3894 thisCache = thisCache.data;
3895 }
3896
3897 if ( data !== undefined ) {
3898 thisCache[ jQuery.camelCase( name ) ] = data;
3899 }
3900
3901 // Check for both converted-to-camel and non-converted data property names
3902 // If a data property was specified
3903 if ( typeof name === "string" ) {
3904
3905 // First Try to find as-is property data
3906 ret = thisCache[ name ];
3907
3908 // Test for null|undefined property data
3909 if ( ret == null ) {
3910
3911 // Try to find the camelCased property
3912 ret = thisCache[ jQuery.camelCase( name ) ];
3913 }
3914 } else {
3915 ret = thisCache;
3916 }
3917
3918 return ret;
3919}
3920
3921function internalRemoveData( elem, name, pvt ) {
3922 if ( !acceptData( elem ) ) {
3923 return;
3924 }
3925
3926 var thisCache, i,
3927 isNode = elem.nodeType,
3928
3929 // See jQuery.data for more information
3930 cache = isNode ? jQuery.cache : elem,
3931 id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
3932
3933 // If there is already no cache entry for this object, there is no
3934 // purpose in continuing
3935 if ( !cache[ id ] ) {
3936 return;
3937 }
3938
3939 if ( name ) {
3940
3941 thisCache = pvt ? cache[ id ] : cache[ id ].data;
3942
3943 if ( thisCache ) {
3944
3945 // Support array or space separated string names for data keys
3946 if ( !jQuery.isArray( name ) ) {
3947
3948 // try the string as a key before any manipulation
3949 if ( name in thisCache ) {
3950 name = [ name ];
3951 } else {
3952
3953 // split the camel cased version by spaces unless a key with the spaces exists
3954 name = jQuery.camelCase( name );
3955 if ( name in thisCache ) {
3956 name = [ name ];
3957 } else {
3958 name = name.split( " " );
3959 }
3960 }
3961 } else {
3962
3963 // If "name" is an array of keys...
3964 // When data is initially created, via ("key", "val") signature,
3965 // keys will be converted to camelCase.
3966 // Since there is no way to tell _how_ a key was added, remove
3967 // both plain key and camelCase key. #12786
3968 // This will only penalize the array argument path.
3969 name = name.concat( jQuery.map( name, jQuery.camelCase ) );
3970 }
3971
3972 i = name.length;
3973 while ( i-- ) {
3974 delete thisCache[ name[ i ] ];
3975 }
3976
3977 // If there is no data left in the cache, we want to continue
3978 // and let the cache object itself get destroyed
3979 if ( pvt ? !isEmptyDataObject( thisCache ) : !jQuery.isEmptyObject( thisCache ) ) {
3980 return;
3981 }
3982 }
3983 }
3984
3985 // See jQuery.data for more information
3986 if ( !pvt ) {
3987 delete cache[ id ].data;
3988
3989 // Don't destroy the parent cache unless the internal data object
3990 // had been the only thing left in it
3991 if ( !isEmptyDataObject( cache[ id ] ) ) {
3992 return;
3993 }
3994 }
3995
3996 // Destroy the cache
3997 if ( isNode ) {
3998 jQuery.cleanData( [ elem ], true );
3999
4000 // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
4001 /* jshint eqeqeq: false */
4002 } else if ( support.deleteExpando || cache != cache.window ) {
4003 /* jshint eqeqeq: true */
4004 delete cache[ id ];
4005
4006 // When all else fails, undefined
4007 } else {
4008 cache[ id ] = undefined;
4009 }
4010}
4011
4012jQuery.extend( {
4013 cache: {},
4014
4015 // The following elements (space-suffixed to avoid Object.prototype collisions)
4016 // throw uncatchable exceptions if you attempt to set expando properties
4017 noData: {
4018 "applet ": true,
4019 "embed ": true,
4020
4021 // ...but Flash objects (which have this classid) *can* handle expandos
4022 "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
4023 },
4024
4025 hasData: function( elem ) {
4026 elem = elem.nodeType ? jQuery.cache[ elem[ jQuery.expando ] ] : elem[ jQuery.expando ];
4027 return !!elem && !isEmptyDataObject( elem );
4028 },
4029
4030 data: function( elem, name, data ) {
4031 return internalData( elem, name, data );
4032 },
4033
4034 removeData: function( elem, name ) {
4035 return internalRemoveData( elem, name );
4036 },
4037
4038 // For internal use only.
4039 _data: function( elem, name, data ) {
4040 return internalData( elem, name, data, true );
4041 },
4042
4043 _removeData: function( elem, name ) {
4044 return internalRemoveData( elem, name, true );
4045 }
4046} );
4047
4048jQuery.fn.extend( {
4049 data: function( key, value ) {
4050 var i, name, data,
4051 elem = this[ 0 ],
4052 attrs = elem && elem.attributes;
4053
4054 // Special expections of .data basically thwart jQuery.access,
4055 // so implement the relevant behavior ourselves
4056
4057 // Gets all values
4058 if ( key === undefined ) {
4059 if ( this.length ) {
4060 data = jQuery.data( elem );
4061
4062 if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
4063 i = attrs.length;
4064 while ( i-- ) {
4065
4066 // Support: IE11+
4067 // The attrs elements can be null (#14894)
4068 if ( attrs[ i ] ) {
4069 name = attrs[ i ].name;
4070 if ( name.indexOf( "data-" ) === 0 ) {
4071 name = jQuery.camelCase( name.slice( 5 ) );
4072 dataAttr( elem, name, data[ name ] );
4073 }
4074 }
4075 }
4076 jQuery._data( elem, "parsedAttrs", true );
4077 }
4078 }
4079
4080 return data;
4081 }
4082
4083 // Sets multiple values
4084 if ( typeof key === "object" ) {
4085 return this.each( function() {
4086 jQuery.data( this, key );
4087 } );
4088 }
4089
4090 return arguments.length > 1 ?
4091
4092 // Sets one value
4093 this.each( function() {
4094 jQuery.data( this, key, value );
4095 } ) :
4096
4097 // Gets one value
4098 // Try to fetch any internally stored data first
4099 elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
4100 },
4101
4102 removeData: function( key ) {
4103 return this.each( function() {
4104 jQuery.removeData( this, key );
4105 } );
4106 }
4107} );
4108
4109
4110jQuery.extend( {
4111 queue: function( elem, type, data ) {
4112 var queue;
4113
4114 if ( elem ) {
4115 type = ( type || "fx" ) + "queue";
4116 queue = jQuery._data( elem, type );
4117
4118 // Speed up dequeue by getting out quickly if this is just a lookup
4119 if ( data ) {
4120 if ( !queue || jQuery.isArray( data ) ) {
4121 queue = jQuery._data( elem, type, jQuery.makeArray( data ) );
4122 } else {
4123 queue.push( data );
4124 }
4125 }
4126 return queue || [];
4127 }
4128 },
4129
4130 dequeue: function( elem, type ) {
4131 type = type || "fx";
4132
4133 var queue = jQuery.queue( elem, type ),
4134 startLength = queue.length,
4135 fn = queue.shift(),
4136 hooks = jQuery._queueHooks( elem, type ),
4137 next = function() {
4138 jQuery.dequeue( elem, type );
4139 };
4140
4141 // If the fx queue is dequeued, always remove the progress sentinel
4142 if ( fn === "inprogress" ) {
4143 fn = queue.shift();
4144 startLength--;
4145 }
4146
4147 if ( fn ) {
4148
4149 // Add a progress sentinel to prevent the fx queue from being
4150 // automatically dequeued
4151 if ( type === "fx" ) {
4152 queue.unshift( "inprogress" );
4153 }
4154
4155 // clear up the last queue stop function
4156 delete hooks.stop;
4157 fn.call( elem, next, hooks );
4158 }
4159
4160 if ( !startLength && hooks ) {
4161 hooks.empty.fire();
4162 }
4163 },
4164
4165 // not intended for public consumption - generates a queueHooks object,
4166 // or returns the current one
4167 _queueHooks: function( elem, type ) {
4168 var key = type + "queueHooks";
4169 return jQuery._data( elem, key ) || jQuery._data( elem, key, {
4170 empty: jQuery.Callbacks( "once memory" ).add( function() {
4171 jQuery._removeData( elem, type + "queue" );
4172 jQuery._removeData( elem, key );
4173 } )
4174 } );
4175 }
4176} );
4177
4178jQuery.fn.extend( {
4179 queue: function( type, data ) {
4180 var setter = 2;
4181
4182 if ( typeof type !== "string" ) {
4183 data = type;
4184 type = "fx";
4185 setter--;
4186 }
4187
4188 if ( arguments.length < setter ) {
4189 return jQuery.queue( this[ 0 ], type );
4190 }
4191
4192 return data === undefined ?
4193 this :
4194 this.each( function() {
4195 var queue = jQuery.queue( this, type, data );
4196
4197 // ensure a hooks for this queue
4198 jQuery._queueHooks( this, type );
4199
4200 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
4201 jQuery.dequeue( this, type );
4202 }
4203 } );
4204 },
4205 dequeue: function( type ) {
4206 return this.each( function() {
4207 jQuery.dequeue( this, type );
4208 } );
4209 },
4210 clearQueue: function( type ) {
4211 return this.queue( type || "fx", [] );
4212 },
4213
4214 // Get a promise resolved when queues of a certain type
4215 // are emptied (fx is the type by default)
4216 promise: function( type, obj ) {
4217 var tmp,
4218 count = 1,
4219 defer = jQuery.Deferred(),
4220 elements = this,
4221 i = this.length,
4222 resolve = function() {
4223 if ( !( --count ) ) {
4224 defer.resolveWith( elements, [ elements ] );
4225 }
4226 };
4227
4228 if ( typeof type !== "string" ) {
4229 obj = type;
4230 type = undefined;
4231 }
4232 type = type || "fx";
4233
4234 while ( i-- ) {
4235 tmp = jQuery._data( elements[ i ], type + "queueHooks" );
4236 if ( tmp && tmp.empty ) {
4237 count++;
4238 tmp.empty.add( resolve );
4239 }
4240 }
4241 resolve();
4242 return defer.promise( obj );
4243 }
4244} );
4245
4246
4247( function() {
4248 var shrinkWrapBlocksVal;
4249
4250 support.shrinkWrapBlocks = function() {
4251 if ( shrinkWrapBlocksVal != null ) {
4252 return shrinkWrapBlocksVal;
4253 }
4254
4255 // Will be changed later if needed.
4256 shrinkWrapBlocksVal = false;
4257
4258 // Minified: var b,c,d
4259 var div, body, container;
4260
4261 body = document.getElementsByTagName( "body" )[ 0 ];
4262 if ( !body || !body.style ) {
4263
4264 // Test fired too early or in an unsupported environment, exit.
4265 return;
4266 }
4267
4268 // Setup
4269 div = document.createElement( "div" );
4270 container = document.createElement( "div" );
4271 container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
4272 body.appendChild( container ).appendChild( div );
4273
4274 // Support: IE6
4275 // Check if elements with layout shrink-wrap their children
4276 if ( typeof div.style.zoom !== "undefined" ) {
4277
4278 // Reset CSS: box-sizing; display; margin; border
4279 div.style.cssText =
4280
4281 // Support: Firefox<29, Android 2.3
4282 // Vendor-prefix box-sizing
4283 "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
4284 "box-sizing:content-box;display:block;margin:0;border:0;" +
4285 "padding:1px;width:1px;zoom:1";
4286 div.appendChild( document.createElement( "div" ) ).style.width = "5px";
4287 shrinkWrapBlocksVal = div.offsetWidth !== 3;
4288 }
4289
4290 body.removeChild( container );
4291
4292 return shrinkWrapBlocksVal;
4293 };
4294
4295} )();
4296var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
4297
4298var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
4299
4300
4301var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4302
4303var isHidden = function( elem, el ) {
4304
4305 // isHidden might be called from jQuery#filter function;
4306 // in that case, element will be second argument
4307 elem = el || elem;
4308 return jQuery.css( elem, "display" ) === "none" ||
4309 !jQuery.contains( elem.ownerDocument, elem );
4310 };
4311
4312
4313
4314function adjustCSS( elem, prop, valueParts, tween ) {
4315 var adjusted,
4316 scale = 1,
4317 maxIterations = 20,
4318 currentValue = tween ?
4319 function() { return tween.cur(); } :
4320 function() { return jQuery.css( elem, prop, "" ); },
4321 initial = currentValue(),
4322 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
4323
4324 // Starting value computation is required for potential unit mismatches
4325 initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
4326 rcssNum.exec( jQuery.css( elem, prop ) );
4327
4328 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
4329
4330 // Trust units reported by jQuery.css
4331 unit = unit || initialInUnit[ 3 ];
4332
4333 // Make sure we update the tween properties later on
4334 valueParts = valueParts || [];
4335
4336 // Iteratively approximate from a nonzero starting point
4337 initialInUnit = +initial || 1;
4338
4339 do {
4340
4341 // If previous iteration zeroed out, double until we get *something*.
4342 // Use string for doubling so we don't accidentally see scale as unchanged below
4343 scale = scale || ".5";
4344
4345 // Adjust and apply
4346 initialInUnit = initialInUnit / scale;
4347 jQuery.style( elem, prop, initialInUnit + unit );
4348
4349 // Update scale, tolerating zero or NaN from tween.cur()
4350 // Break the loop if scale is unchanged or perfect, or if we've just had enough.
4351 } while (
4352 scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
4353 );
4354 }
4355
4356 if ( valueParts ) {
4357 initialInUnit = +initialInUnit || +initial || 0;
4358
4359 // Apply relative offset (+=/-=) if specified
4360 adjusted = valueParts[ 1 ] ?
4361 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
4362 +valueParts[ 2 ];
4363 if ( tween ) {
4364 tween.unit = unit;
4365 tween.start = initialInUnit;
4366 tween.end = adjusted;
4367 }
4368 }
4369 return adjusted;
4370}
4371
4372
4373// Multifunctional method to get and set values of a collection
4374// The value/s can optionally be executed if it's a function
4375var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
4376 var i = 0,
4377 length = elems.length,
4378 bulk = key == null;
4379
4380 // Sets many values
4381 if ( jQuery.type( key ) === "object" ) {
4382 chainable = true;
4383 for ( i in key ) {
4384 access( elems, fn, i, key[ i ], true, emptyGet, raw );
4385 }
4386
4387 // Sets one value
4388 } else if ( value !== undefined ) {
4389 chainable = true;
4390
4391 if ( !jQuery.isFunction( value ) ) {
4392 raw = true;
4393 }
4394
4395 if ( bulk ) {
4396
4397 // Bulk operations run against the entire set
4398 if ( raw ) {
4399 fn.call( elems, value );
4400 fn = null;
4401
4402 // ...except when executing function values
4403 } else {
4404 bulk = fn;
4405 fn = function( elem, key, value ) {
4406 return bulk.call( jQuery( elem ), value );
4407 };
4408 }
4409 }
4410
4411 if ( fn ) {
4412 for ( ; i < length; i++ ) {
4413 fn(
4414 elems[ i ],
4415 key,
4416 raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) )
4417 );
4418 }
4419 }
4420 }
4421
4422 return chainable ?
4423 elems :
4424
4425 // Gets
4426 bulk ?
4427 fn.call( elems ) :
4428 length ? fn( elems[ 0 ], key ) : emptyGet;
4429};
4430var rcheckableType = ( /^(?:checkbox|radio)$/i );
4431
4432var rtagName = ( /<([\w:-]+)/ );
4433
4434var rscriptType = ( /^$|\/(?:java|ecma)script/i );
4435
4436var rleadingWhitespace = ( /^\s+/ );
4437
4438var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|" +
4439 "details|dialog|figcaption|figure|footer|header|hgroup|main|" +
4440 "mark|meter|nav|output|picture|progress|section|summary|template|time|video";
4441
4442
4443
4444function createSafeFragment( document ) {
4445 var list = nodeNames.split( "|" ),
4446 safeFrag = document.createDocumentFragment();
4447
4448 if ( safeFrag.createElement ) {
4449 while ( list.length ) {
4450 safeFrag.createElement(
4451 list.pop()
4452 );
4453 }
4454 }
4455 return safeFrag;
4456}
4457
4458
4459( function() {
4460 var div = document.createElement( "div" ),
4461 fragment = document.createDocumentFragment(),
4462 input = document.createElement( "input" );
4463
4464 // Setup
4465 div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
4466
4467 // IE strips leading whitespace when .innerHTML is used
4468 support.leadingWhitespace = div.firstChild.nodeType === 3;
4469
4470 // Make sure that tbody elements aren't automatically inserted
4471 // IE will insert them into empty tables
4472 support.tbody = !div.getElementsByTagName( "tbody" ).length;
4473
4474 // Make sure that link elements get serialized correctly by innerHTML
4475 // This requires a wrapper element in IE
4476 support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
4477
4478 // Makes sure cloning an html5 element does not cause problems
4479 // Where outerHTML is undefined, this still works
4480 support.html5Clone =
4481 document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>";
4482
4483 // Check if a disconnected checkbox will retain its checked
4484 // value of true after appended to the DOM (IE6/7)
4485 input.type = "checkbox";
4486 input.checked = true;
4487 fragment.appendChild( input );
4488 support.appendChecked = input.checked;
4489
4490 // Make sure textarea (and checkbox) defaultValue is properly cloned
4491 // Support: IE6-IE11+
4492 div.innerHTML = "<textarea>x</textarea>";
4493 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4494
4495 // #11217 - WebKit loses check when the name is after the checked attribute
4496 fragment.appendChild( div );
4497
4498 // Support: Windows Web Apps (WWA)
4499 // `name` and `type` must use .setAttribute for WWA (#14901)
4500 input = document.createElement( "input" );
4501 input.setAttribute( "type", "radio" );
4502 input.setAttribute( "checked", "checked" );
4503 input.setAttribute( "name", "t" );
4504
4505 div.appendChild( input );
4506
4507 // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
4508 // old WebKit doesn't clone checked state correctly in fragments
4509 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4510
4511 // Support: IE<9
4512 // Cloned elements keep attachEvent handlers, we use addEventListener on IE9+
4513 support.noCloneEvent = !!div.addEventListener;
4514
4515 // Support: IE<9
4516 // Since attributes and properties are the same in IE,
4517 // cleanData must set properties to undefined rather than use removeAttribute
4518 div[ jQuery.expando ] = 1;
4519 support.attributes = !div.getAttribute( jQuery.expando );
4520} )();
4521
4522
4523// We have to close these tags to support XHTML (#13200)
4524var wrapMap = {
4525 option: [ 1, "<select multiple='multiple'>", "</select>" ],
4526 legend: [ 1, "<fieldset>", "</fieldset>" ],
4527 area: [ 1, "<map>", "</map>" ],
4528
4529 // Support: IE8
4530 param: [ 1, "<object>", "</object>" ],
4531 thead: [ 1, "<table>", "</table>" ],
4532 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4533 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
4534 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4535
4536 // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
4537 // unless wrapped in a div with non-breaking characters in front of it.
4538 _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
4539};
4540
4541// Support: IE8-IE9
4542wrapMap.optgroup = wrapMap.option;
4543
4544wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4545wrapMap.th = wrapMap.td;
4546
4547
4548function getAll( context, tag ) {
4549 var elems, elem,
4550 i = 0,
4551 found = typeof context.getElementsByTagName !== "undefined" ?
4552 context.getElementsByTagName( tag || "*" ) :
4553 typeof context.querySelectorAll !== "undefined" ?
4554 context.querySelectorAll( tag || "*" ) :
4555 undefined;
4556
4557 if ( !found ) {
4558 for ( found = [], elems = context.childNodes || context;
4559 ( elem = elems[ i ] ) != null;
4560 i++
4561 ) {
4562 if ( !tag || jQuery.nodeName( elem, tag ) ) {
4563 found.push( elem );
4564 } else {
4565 jQuery.merge( found, getAll( elem, tag ) );
4566 }
4567 }
4568 }
4569
4570 return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
4571 jQuery.merge( [ context ], found ) :
4572 found;
4573}
4574
4575
4576// Mark scripts as having already been evaluated
4577function setGlobalEval( elems, refElements ) {
4578 var elem,
4579 i = 0;
4580 for ( ; ( elem = elems[ i ] ) != null; i++ ) {
4581 jQuery._data(
4582 elem,
4583 "globalEval",
4584 !refElements || jQuery._data( refElements[ i ], "globalEval" )
4585 );
4586 }
4587}
4588
4589
4590var rhtml = /<|&#?\w+;/,
4591 rtbody = /<tbody/i;
4592
4593function fixDefaultChecked( elem ) {
4594 if ( rcheckableType.test( elem.type ) ) {
4595 elem.defaultChecked = elem.checked;
4596 }
4597}
4598
4599function buildFragment( elems, context, scripts, selection, ignored ) {
4600 var j, elem, contains,
4601 tmp, tag, tbody, wrap,
4602 l = elems.length,
4603
4604 // Ensure a safe fragment
4605 safe = createSafeFragment( context ),
4606
4607 nodes = [],
4608 i = 0;
4609
4610 for ( ; i < l; i++ ) {
4611 elem = elems[ i ];
4612
4613 if ( elem || elem === 0 ) {
4614
4615 // Add nodes directly
4616 if ( jQuery.type( elem ) === "object" ) {
4617 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
4618
4619 // Convert non-html into a text node
4620 } else if ( !rhtml.test( elem ) ) {
4621 nodes.push( context.createTextNode( elem ) );
4622
4623 // Convert html into DOM nodes
4624 } else {
4625 tmp = tmp || safe.appendChild( context.createElement( "div" ) );
4626
4627 // Deserialize a standard representation
4628 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
4629 wrap = wrapMap[ tag ] || wrapMap._default;
4630
4631 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
4632
4633 // Descend through wrappers to the right content
4634 j = wrap[ 0 ];
4635 while ( j-- ) {
4636 tmp = tmp.lastChild;
4637 }
4638
4639 // Manually add leading whitespace removed by IE
4640 if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
4641 nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[ 0 ] ) );
4642 }
4643
4644 // Remove IE's autoinserted <tbody> from table fragments
4645 if ( !support.tbody ) {
4646
4647 // String was a <table>, *may* have spurious <tbody>
4648 elem = tag === "table" && !rtbody.test( elem ) ?
4649 tmp.firstChild :
4650
4651 // String was a bare <thead> or <tfoot>
4652 wrap[ 1 ] === "<table>" && !rtbody.test( elem ) ?
4653 tmp :
4654 0;
4655
4656 j = elem && elem.childNodes.length;
4657 while ( j-- ) {
4658 if ( jQuery.nodeName( ( tbody = elem.childNodes[ j ] ), "tbody" ) &&
4659 !tbody.childNodes.length ) {
4660
4661 elem.removeChild( tbody );
4662 }
4663 }
4664 }
4665
4666 jQuery.merge( nodes, tmp.childNodes );
4667
4668 // Fix #12392 for WebKit and IE > 9
4669 tmp.textContent = "";
4670
4671 // Fix #12392 for oldIE
4672 while ( tmp.firstChild ) {
4673 tmp.removeChild( tmp.firstChild );
4674 }
4675
4676 // Remember the top-level container for proper cleanup
4677 tmp = safe.lastChild;
4678 }
4679 }
4680 }
4681
4682 // Fix #11356: Clear elements from fragment
4683 if ( tmp ) {
4684 safe.removeChild( tmp );
4685 }
4686
4687 // Reset defaultChecked for any radios and checkboxes
4688 // about to be appended to the DOM in IE 6/7 (#8060)
4689 if ( !support.appendChecked ) {
4690 jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
4691 }
4692
4693 i = 0;
4694 while ( ( elem = nodes[ i++ ] ) ) {
4695
4696 // Skip elements already in the context collection (trac-4087)
4697 if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
4698 if ( ignored ) {
4699 ignored.push( elem );
4700 }
4701
4702 continue;
4703 }
4704
4705 contains = jQuery.contains( elem.ownerDocument, elem );
4706
4707 // Append to fragment
4708 tmp = getAll( safe.appendChild( elem ), "script" );
4709
4710 // Preserve script evaluation history
4711 if ( contains ) {
4712 setGlobalEval( tmp );
4713 }
4714
4715 // Capture executables
4716 if ( scripts ) {
4717 j = 0;
4718 while ( ( elem = tmp[ j++ ] ) ) {
4719 if ( rscriptType.test( elem.type || "" ) ) {
4720 scripts.push( elem );
4721 }
4722 }
4723 }
4724 }
4725
4726 tmp = null;
4727
4728 return safe;
4729}
4730
4731
4732( function() {
4733 var i, eventName,
4734 div = document.createElement( "div" );
4735
4736 // Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events)
4737 for ( i in { submit: true, change: true, focusin: true } ) {
4738 eventName = "on" + i;
4739
4740 if ( !( support[ i ] = eventName in window ) ) {
4741
4742 // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
4743 div.setAttribute( eventName, "t" );
4744 support[ i ] = div.attributes[ eventName ].expando === false;
4745 }
4746 }
4747
4748 // Null elements to avoid leaks in IE.
4749 div = null;
4750} )();
4751
4752
4753var rformElems = /^(?:input|select|textarea)$/i,
4754 rkeyEvent = /^key/,
4755 rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
4756 rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
4757 rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4758
4759function returnTrue() {
4760 return true;
4761}
4762
4763function returnFalse() {
4764 return false;
4765}
4766
4767// Support: IE9
4768// See #13393 for more info
4769function safeActiveElement() {
4770 try {
4771 return document.activeElement;
4772 } catch ( err ) { }
4773}
4774
4775function on( elem, types, selector, data, fn, one ) {
4776 var origFn, type;
4777
4778 // Types can be a map of types/handlers
4779 if ( typeof types === "object" ) {
4780
4781 // ( types-Object, selector, data )
4782 if ( typeof selector !== "string" ) {
4783
4784 // ( types-Object, data )
4785 data = data || selector;
4786 selector = undefined;
4787 }
4788 for ( type in types ) {
4789 on( elem, type, selector, data, types[ type ], one );
4790 }
4791 return elem;
4792 }
4793
4794 if ( data == null && fn == null ) {
4795
4796 // ( types, fn )
4797 fn = selector;
4798 data = selector = undefined;
4799 } else if ( fn == null ) {
4800 if ( typeof selector === "string" ) {
4801
4802 // ( types, selector, fn )
4803 fn = data;
4804 data = undefined;
4805 } else {
4806
4807 // ( types, data, fn )
4808 fn = data;
4809 data = selector;
4810 selector = undefined;
4811 }
4812 }
4813 if ( fn === false ) {
4814 fn = returnFalse;
4815 } else if ( !fn ) {
4816 return elem;
4817 }
4818
4819 if ( one === 1 ) {
4820 origFn = fn;
4821 fn = function( event ) {
4822
4823 // Can use an empty set, since event contains the info
4824 jQuery().off( event );
4825 return origFn.apply( this, arguments );
4826 };
4827
4828 // Use same guid so caller can remove using origFn
4829 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
4830 }
4831 return elem.each( function() {
4832 jQuery.event.add( this, types, fn, data, selector );
4833 } );
4834}
4835
4836/*
4837 * Helper functions for managing events -- not part of the public interface.
4838 * Props to Dean Edwards' addEvent library for many of the ideas.
4839 */
4840jQuery.event = {
4841
4842 global: {},
4843
4844 add: function( elem, types, handler, data, selector ) {
4845 var tmp, events, t, handleObjIn,
4846 special, eventHandle, handleObj,
4847 handlers, type, namespaces, origType,
4848 elemData = jQuery._data( elem );
4849
4850 // Don't attach events to noData or text/comment nodes (but allow plain objects)
4851 if ( !elemData ) {
4852 return;
4853 }
4854
4855 // Caller can pass in an object of custom data in lieu of the handler
4856 if ( handler.handler ) {
4857 handleObjIn = handler;
4858 handler = handleObjIn.handler;
4859 selector = handleObjIn.selector;
4860 }
4861
4862 // Make sure that the handler has a unique ID, used to find/remove it later
4863 if ( !handler.guid ) {
4864 handler.guid = jQuery.guid++;
4865 }
4866
4867 // Init the element's event structure and main handler, if this is the first
4868 if ( !( events = elemData.events ) ) {
4869 events = elemData.events = {};
4870 }
4871 if ( !( eventHandle = elemData.handle ) ) {
4872 eventHandle = elemData.handle = function( e ) {
4873
4874 // Discard the second event of a jQuery.event.trigger() and
4875 // when an event is called after a page has unloaded
4876 return typeof jQuery !== "undefined" &&
4877 ( !e || jQuery.event.triggered !== e.type ) ?
4878 jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
4879 undefined;
4880 };
4881
4882 // Add elem as a property of the handle fn to prevent a memory leak
4883 // with IE non-native events
4884 eventHandle.elem = elem;
4885 }
4886
4887 // Handle multiple events separated by a space
4888 types = ( types || "" ).match( rnotwhite ) || [ "" ];
4889 t = types.length;
4890 while ( t-- ) {
4891 tmp = rtypenamespace.exec( types[ t ] ) || [];
4892 type = origType = tmp[ 1 ];
4893 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4894
4895 // There *must* be a type, no attaching namespace-only handlers
4896 if ( !type ) {
4897 continue;
4898 }
4899
4900 // If event changes its type, use the special event handlers for the changed type
4901 special = jQuery.event.special[ type ] || {};
4902
4903 // If selector defined, determine special event api type, otherwise given type
4904 type = ( selector ? special.delegateType : special.bindType ) || type;
4905
4906 // Update special based on newly reset type
4907 special = jQuery.event.special[ type ] || {};
4908
4909 // handleObj is passed to all event handlers
4910 handleObj = jQuery.extend( {
4911 type: type,
4912 origType: origType,
4913 data: data,
4914 handler: handler,
4915 guid: handler.guid,
4916 selector: selector,
4917 needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4918 namespace: namespaces.join( "." )
4919 }, handleObjIn );
4920
4921 // Init the event handler queue if we're the first
4922 if ( !( handlers = events[ type ] ) ) {
4923 handlers = events[ type ] = [];
4924 handlers.delegateCount = 0;
4925
4926 // Only use addEventListener/attachEvent if the special events handler returns false
4927 if ( !special.setup ||
4928 special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4929
4930 // Bind the global event handler to the element
4931 if ( elem.addEventListener ) {
4932 elem.addEventListener( type, eventHandle, false );
4933
4934 } else if ( elem.attachEvent ) {
4935 elem.attachEvent( "on" + type, eventHandle );
4936 }
4937 }
4938 }
4939
4940 if ( special.add ) {
4941 special.add.call( elem, handleObj );
4942
4943 if ( !handleObj.handler.guid ) {
4944 handleObj.handler.guid = handler.guid;
4945 }
4946 }
4947
4948 // Add to the element's handler list, delegates in front
4949 if ( selector ) {
4950 handlers.splice( handlers.delegateCount++, 0, handleObj );
4951 } else {
4952 handlers.push( handleObj );
4953 }
4954
4955 // Keep track of which events have ever been used, for event optimization
4956 jQuery.event.global[ type ] = true;
4957 }
4958
4959 // Nullify elem to prevent memory leaks in IE
4960 elem = null;
4961 },
4962
4963 // Detach an event or set of events from an element
4964 remove: function( elem, types, handler, selector, mappedTypes ) {
4965 var j, handleObj, tmp,
4966 origCount, t, events,
4967 special, handlers, type,
4968 namespaces, origType,
4969 elemData = jQuery.hasData( elem ) && jQuery._data( elem );
4970
4971 if ( !elemData || !( events = elemData.events ) ) {
4972 return;
4973 }
4974
4975 // Once for each type.namespace in types; type may be omitted
4976 types = ( types || "" ).match( rnotwhite ) || [ "" ];
4977 t = types.length;
4978 while ( t-- ) {
4979 tmp = rtypenamespace.exec( types[ t ] ) || [];
4980 type = origType = tmp[ 1 ];
4981 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4982
4983 // Unbind all events (on this namespace, if provided) for the element
4984 if ( !type ) {
4985 for ( type in events ) {
4986 jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4987 }
4988 continue;
4989 }
4990
4991 special = jQuery.event.special[ type ] || {};
4992 type = ( selector ? special.delegateType : special.bindType ) || type;
4993 handlers = events[ type ] || [];
4994 tmp = tmp[ 2 ] &&
4995 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
4996
4997 // Remove matching events
4998 origCount = j = handlers.length;
4999 while ( j-- ) {
5000 handleObj = handlers[ j ];
5001
5002 if ( ( mappedTypes || origType === handleObj.origType ) &&
5003 ( !handler || handler.guid === handleObj.guid ) &&
5004 ( !tmp || tmp.test( handleObj.namespace ) ) &&
5005 ( !selector || selector === handleObj.selector ||
5006 selector === "**" && handleObj.selector ) ) {
5007 handlers.splice( j, 1 );
5008
5009 if ( handleObj.selector ) {
5010 handlers.delegateCount--;
5011 }
5012 if ( special.remove ) {
5013 special.remove.call( elem, handleObj );
5014 }
5015 }
5016 }
5017
5018 // Remove generic event handler if we removed something and no more handlers exist
5019 // (avoids potential for endless recursion during removal of special event handlers)
5020 if ( origCount && !handlers.length ) {
5021 if ( !special.teardown ||
5022 special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
5023
5024 jQuery.removeEvent( elem, type, elemData.handle );
5025 }
5026
5027 delete events[ type ];
5028 }
5029 }
5030
5031 // Remove the expando if it's no longer used
5032 if ( jQuery.isEmptyObject( events ) ) {
5033 delete elemData.handle;
5034
5035 // removeData also checks for emptiness and clears the expando if empty
5036 // so use it instead of delete
5037 jQuery._removeData( elem, "events" );
5038 }
5039 },
5040
5041 trigger: function( event, data, elem, onlyHandlers ) {
5042 var handle, ontype, cur,
5043 bubbleType, special, tmp, i,
5044 eventPath = [ elem || document ],
5045 type = hasOwn.call( event, "type" ) ? event.type : event,
5046 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
5047
5048 cur = tmp = elem = elem || document;
5049
5050 // Don't do events on text and comment nodes
5051 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
5052 return;
5053 }
5054
5055 // focus/blur morphs to focusin/out; ensure we're not firing them right now
5056 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
5057 return;
5058 }
5059
5060 if ( type.indexOf( "." ) > -1 ) {
5061
5062 // Namespaced trigger; create a regexp to match event type in handle()
5063 namespaces = type.split( "." );
5064 type = namespaces.shift();
5065 namespaces.sort();
5066 }
5067 ontype = type.indexOf( ":" ) < 0 && "on" + type;
5068
5069 // Caller can pass in a jQuery.Event object, Object, or just an event type string
5070 event = event[ jQuery.expando ] ?
5071 event :
5072 new jQuery.Event( type, typeof event === "object" && event );
5073
5074 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
5075 event.isTrigger = onlyHandlers ? 2 : 3;
5076 event.namespace = namespaces.join( "." );
5077 event.rnamespace = event.namespace ?
5078 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
5079 null;
5080
5081 // Clean up the event in case it is being reused
5082 event.result = undefined;
5083 if ( !event.target ) {
5084 event.target = elem;
5085 }
5086
5087 // Clone any incoming data and prepend the event, creating the handler arg list
5088 data = data == null ?
5089 [ event ] :
5090 jQuery.makeArray( data, [ event ] );
5091
5092 // Allow special events to draw outside the lines
5093 special = jQuery.event.special[ type ] || {};
5094 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
5095 return;
5096 }
5097
5098 // Determine event propagation path in advance, per W3C events spec (#9951)
5099 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
5100 if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
5101
5102 bubbleType = special.delegateType || type;
5103 if ( !rfocusMorph.test( bubbleType + type ) ) {
5104 cur = cur.parentNode;
5105 }
5106 for ( ; cur; cur = cur.parentNode ) {
5107 eventPath.push( cur );
5108 tmp = cur;
5109 }
5110
5111 // Only add window if we got to document (e.g., not plain obj or detached DOM)
5112 if ( tmp === ( elem.ownerDocument || document ) ) {
5113 eventPath.push( tmp.defaultView || tmp.parentWindow || window );
5114 }
5115 }
5116
5117 // Fire handlers on the event path
5118 i = 0;
5119 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
5120
5121 event.type = i > 1 ?
5122 bubbleType :
5123 special.bindType || type;
5124
5125 // jQuery handler
5126 handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] &&
5127 jQuery._data( cur, "handle" );
5128
5129 if ( handle ) {
5130 handle.apply( cur, data );
5131 }
5132
5133 // Native handler
5134 handle = ontype && cur[ ontype ];
5135 if ( handle && handle.apply && acceptData( cur ) ) {
5136 event.result = handle.apply( cur, data );
5137 if ( event.result === false ) {
5138 event.preventDefault();
5139 }
5140 }
5141 }
5142 event.type = type;
5143
5144 // If nobody prevented the default action, do it now
5145 if ( !onlyHandlers && !event.isDefaultPrevented() ) {
5146
5147 if (
5148 ( !special._default ||
5149 special._default.apply( eventPath.pop(), data ) === false
5150 ) && acceptData( elem )
5151 ) {
5152
5153 // Call a native DOM method on the target with the same name name as the event.
5154 // Can't use an .isFunction() check here because IE6/7 fails that test.
5155 // Don't do default actions on window, that's where global variables be (#6170)
5156 if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
5157
5158 // Don't re-trigger an onFOO event when we call its FOO() method
5159 tmp = elem[ ontype ];
5160
5161 if ( tmp ) {
5162 elem[ ontype ] = null;
5163 }
5164
5165 // Prevent re-triggering of the same event, since we already bubbled it above
5166 jQuery.event.triggered = type;
5167 try {
5168 elem[ type ]();
5169 } catch ( e ) {
5170
5171 // IE<9 dies on focus/blur to hidden element (#1486,#12518)
5172 // only reproducible on winXP IE8 native, not IE9 in IE8 mode
5173 }
5174 jQuery.event.triggered = undefined;
5175
5176 if ( tmp ) {
5177 elem[ ontype ] = tmp;
5178 }
5179 }
5180 }
5181 }
5182
5183 return event.result;
5184 },
5185
5186 dispatch: function( event ) {
5187
5188 // Make a writable jQuery.Event from the native event object
5189 event = jQuery.event.fix( event );
5190
5191 var i, j, ret, matched, handleObj,
5192 handlerQueue = [],
5193 args = slice.call( arguments ),
5194 handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
5195 special = jQuery.event.special[ event.type ] || {};
5196
5197 // Use the fix-ed jQuery.Event rather than the (read-only) native event
5198 args[ 0 ] = event;
5199 event.delegateTarget = this;
5200
5201 // Call the preDispatch hook for the mapped type, and let it bail if desired
5202 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
5203 return;
5204 }
5205
5206 // Determine handlers
5207 handlerQueue = jQuery.event.handlers.call( this, event, handlers );
5208
5209 // Run delegates first; they may want to stop propagation beneath us
5210 i = 0;
5211 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
5212 event.currentTarget = matched.elem;
5213
5214 j = 0;
5215 while ( ( handleObj = matched.handlers[ j++ ] ) &&
5216 !event.isImmediatePropagationStopped() ) {
5217
5218 // Triggered event must either 1) have no namespace, or 2) have namespace(s)
5219 // a subset or equal to those in the bound event (both can have no namespace).
5220 if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
5221
5222 event.handleObj = handleObj;
5223 event.data = handleObj.data;
5224
5225 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
5226 handleObj.handler ).apply( matched.elem, args );
5227
5228 if ( ret !== undefined ) {
5229 if ( ( event.result = ret ) === false ) {
5230 event.preventDefault();
5231 event.stopPropagation();
5232 }
5233 }
5234 }
5235 }
5236 }
5237
5238 // Call the postDispatch hook for the mapped type
5239 if ( special.postDispatch ) {
5240 special.postDispatch.call( this, event );
5241 }
5242
5243 return event.result;
5244 },
5245
5246 handlers: function( event, handlers ) {
5247 var i, matches, sel, handleObj,
5248 handlerQueue = [],
5249 delegateCount = handlers.delegateCount,
5250 cur = event.target;
5251
5252 // Support (at least): Chrome, IE9
5253 // Find delegate handlers
5254 // Black-hole SVG <use> instance trees (#13180)
5255 //
5256 // Support: Firefox<=42+
5257 // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
5258 if ( delegateCount && cur.nodeType &&
5259 ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
5260
5261 /* jshint eqeqeq: false */
5262 for ( ; cur != this; cur = cur.parentNode || this ) {
5263 /* jshint eqeqeq: true */
5264
5265 // Don't check non-elements (#13208)
5266 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
5267 if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
5268 matches = [];
5269 for ( i = 0; i < delegateCount; i++ ) {
5270 handleObj = handlers[ i ];
5271
5272 // Don't conflict with Object.prototype properties (#13203)
5273 sel = handleObj.selector + " ";
5274
5275 if ( matches[ sel ] === undefined ) {
5276 matches[ sel ] = handleObj.needsContext ?
5277 jQuery( sel, this ).index( cur ) > -1 :
5278 jQuery.find( sel, this, null, [ cur ] ).length;
5279 }
5280 if ( matches[ sel ] ) {
5281 matches.push( handleObj );
5282 }
5283 }
5284 if ( matches.length ) {
5285 handlerQueue.push( { elem: cur, handlers: matches } );
5286 }
5287 }
5288 }
5289 }
5290
5291 // Add the remaining (directly-bound) handlers
5292 if ( delegateCount < handlers.length ) {
5293 handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
5294 }
5295
5296 return handlerQueue;
5297 },
5298
5299 fix: function( event ) {
5300 if ( event[ jQuery.expando ] ) {
5301 return event;
5302 }
5303
5304 // Create a writable copy of the event object and normalize some properties
5305 var i, prop, copy,
5306 type = event.type,
5307 originalEvent = event,
5308 fixHook = this.fixHooks[ type ];
5309
5310 if ( !fixHook ) {
5311 this.fixHooks[ type ] = fixHook =
5312 rmouseEvent.test( type ) ? this.mouseHooks :
5313 rkeyEvent.test( type ) ? this.keyHooks :
5314 {};
5315 }
5316 copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
5317
5318 event = new jQuery.Event( originalEvent );
5319
5320 i = copy.length;
5321 while ( i-- ) {
5322 prop = copy[ i ];
5323 event[ prop ] = originalEvent[ prop ];
5324 }
5325
5326 // Support: IE<9
5327 // Fix target property (#1925)
5328 if ( !event.target ) {
5329 event.target = originalEvent.srcElement || document;
5330 }
5331
5332 // Support: Safari 6-8+
5333 // Target should not be a text node (#504, #13143)
5334 if ( event.target.nodeType === 3 ) {
5335 event.target = event.target.parentNode;
5336 }
5337
5338 // Support: IE<9
5339 // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
5340 event.metaKey = !!event.metaKey;
5341
5342 return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
5343 },
5344
5345 // Includes some event props shared by KeyEvent and MouseEvent
5346 props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
5347 "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
5348
5349 fixHooks: {},
5350
5351 keyHooks: {
5352 props: "char charCode key keyCode".split( " " ),
5353 filter: function( event, original ) {
5354
5355 // Add which for key events
5356 if ( event.which == null ) {
5357 event.which = original.charCode != null ? original.charCode : original.keyCode;
5358 }
5359
5360 return event;
5361 }
5362 },
5363
5364 mouseHooks: {
5365 props: ( "button buttons clientX clientY fromElement offsetX offsetY " +
5366 "pageX pageY screenX screenY toElement" ).split( " " ),
5367 filter: function( event, original ) {
5368 var body, eventDoc, doc,
5369 button = original.button,
5370 fromElement = original.fromElement;
5371
5372 // Calculate pageX/Y if missing and clientX/Y available
5373 if ( event.pageX == null && original.clientX != null ) {
5374 eventDoc = event.target.ownerDocument || document;
5375 doc = eventDoc.documentElement;
5376 body = eventDoc.body;
5377
5378 event.pageX = original.clientX +
5379 ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
5380 ( doc && doc.clientLeft || body && body.clientLeft || 0 );
5381 event.pageY = original.clientY +
5382 ( doc && doc.scrollTop || body && body.scrollTop || 0 ) -
5383 ( doc && doc.clientTop || body && body.clientTop || 0 );
5384 }
5385
5386 // Add relatedTarget, if necessary
5387 if ( !event.relatedTarget && fromElement ) {
5388 event.relatedTarget = fromElement === event.target ?
5389 original.toElement :
5390 fromElement;
5391 }
5392
5393 // Add which for click: 1 === left; 2 === middle; 3 === right
5394 // Note: button is not normalized, so don't use it
5395 if ( !event.which && button !== undefined ) {
5396 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
5397 }
5398
5399 return event;
5400 }
5401 },
5402
5403 special: {
5404 load: {
5405
5406 // Prevent triggered image.load events from bubbling to window.load
5407 noBubble: true
5408 },
5409 focus: {
5410
5411 // Fire native event if possible so blur/focus sequence is correct
5412 trigger: function() {
5413 if ( this !== safeActiveElement() && this.focus ) {
5414 try {
5415 this.focus();
5416 return false;
5417 } catch ( e ) {
5418
5419 // Support: IE<9
5420 // If we error on focus to hidden element (#1486, #12518),
5421 // let .trigger() run the handlers
5422 }
5423 }
5424 },
5425 delegateType: "focusin"
5426 },
5427 blur: {
5428 trigger: function() {
5429 if ( this === safeActiveElement() && this.blur ) {
5430 this.blur();
5431 return false;
5432 }
5433 },
5434 delegateType: "focusout"
5435 },
5436 click: {
5437
5438 // For checkbox, fire native event so checked state will be right
5439 trigger: function() {
5440 if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
5441 this.click();
5442 return false;
5443 }
5444 },
5445
5446 // For cross-browser consistency, don't fire native .click() on links
5447 _default: function( event ) {
5448 return jQuery.nodeName( event.target, "a" );
5449 }
5450 },
5451
5452 beforeunload: {
5453 postDispatch: function( event ) {
5454
5455 // Support: Firefox 20+
5456 // Firefox doesn't alert if the returnValue field is not set.
5457 if ( event.result !== undefined && event.originalEvent ) {
5458 event.originalEvent.returnValue = event.result;
5459 }
5460 }
5461 }
5462 },
5463
5464 // Piggyback on a donor event to simulate a different one
5465 simulate: function( type, elem, event ) {
5466 var e = jQuery.extend(
5467 new jQuery.Event(),
5468 event,
5469 {
5470 type: type,
5471 isSimulated: true
5472
5473 // Previously, `originalEvent: {}` was set here, so stopPropagation call
5474 // would not be triggered on donor event, since in our own
5475 // jQuery.event.stopPropagation function we had a check for existence of
5476 // originalEvent.stopPropagation method, so, consequently it would be a noop.
5477 //
5478 // Guard for simulated events was moved to jQuery.event.stopPropagation function
5479 // since `originalEvent` should point to the original event for the
5480 // constancy with other events and for more focused logic
5481 }
5482 );
5483
5484 jQuery.event.trigger( e, null, elem );
5485
5486 if ( e.isDefaultPrevented() ) {
5487 event.preventDefault();
5488 }
5489 }
5490};
5491
5492jQuery.removeEvent = document.removeEventListener ?
5493 function( elem, type, handle ) {
5494
5495 // This "if" is needed for plain objects
5496 if ( elem.removeEventListener ) {
5497 elem.removeEventListener( type, handle );
5498 }
5499 } :
5500 function( elem, type, handle ) {
5501 var name = "on" + type;
5502
5503 if ( elem.detachEvent ) {
5504
5505 // #8545, #7054, preventing memory leaks for custom events in IE6-8
5506 // detachEvent needed property on element, by name of that event,
5507 // to properly expose it to GC
5508 if ( typeof elem[ name ] === "undefined" ) {
5509 elem[ name ] = null;
5510 }
5511
5512 elem.detachEvent( name, handle );
5513 }
5514 };
5515
5516jQuery.Event = function( src, props ) {
5517
5518 // Allow instantiation without the 'new' keyword
5519 if ( !( this instanceof jQuery.Event ) ) {
5520 return new jQuery.Event( src, props );
5521 }
5522
5523 // Event object
5524 if ( src && src.type ) {
5525 this.originalEvent = src;
5526 this.type = src.type;
5527
5528 // Events bubbling up the document may have been marked as prevented
5529 // by a handler lower down the tree; reflect the correct value.
5530 this.isDefaultPrevented = src.defaultPrevented ||
5531 src.defaultPrevented === undefined &&
5532
5533 // Support: IE < 9, Android < 4.0
5534 src.returnValue === false ?
5535 returnTrue :
5536 returnFalse;
5537
5538 // Event type
5539 } else {
5540 this.type = src;
5541 }
5542
5543 // Put explicitly provided properties onto the event object
5544 if ( props ) {
5545 jQuery.extend( this, props );
5546 }
5547
5548 // Create a timestamp if incoming event doesn't have one
5549 this.timeStamp = src && src.timeStamp || jQuery.now();
5550
5551 // Mark it as fixed
5552 this[ jQuery.expando ] = true;
5553};
5554
5555// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5556// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5557jQuery.Event.prototype = {
5558 constructor: jQuery.Event,
5559 isDefaultPrevented: returnFalse,
5560 isPropagationStopped: returnFalse,
5561 isImmediatePropagationStopped: returnFalse,
5562
5563 preventDefault: function() {
5564 var e = this.originalEvent;
5565
5566 this.isDefaultPrevented = returnTrue;
5567 if ( !e ) {
5568 return;
5569 }
5570
5571 // If preventDefault exists, run it on the original event
5572 if ( e.preventDefault ) {
5573 e.preventDefault();
5574
5575 // Support: IE
5576 // Otherwise set the returnValue property of the original event to false
5577 } else {
5578 e.returnValue = false;
5579 }
5580 },
5581 stopPropagation: function() {
5582 var e = this.originalEvent;
5583
5584 this.isPropagationStopped = returnTrue;
5585
5586 if ( !e || this.isSimulated ) {
5587 return;
5588 }
5589
5590 // If stopPropagation exists, run it on the original event
5591 if ( e.stopPropagation ) {
5592 e.stopPropagation();
5593 }
5594
5595 // Support: IE
5596 // Set the cancelBubble property of the original event to true
5597 e.cancelBubble = true;
5598 },
5599 stopImmediatePropagation: function() {
5600 var e = this.originalEvent;
5601
5602 this.isImmediatePropagationStopped = returnTrue;
5603
5604 if ( e && e.stopImmediatePropagation ) {
5605 e.stopImmediatePropagation();
5606 }
5607
5608 this.stopPropagation();
5609 }
5610};
5611
5612// Create mouseenter/leave events using mouseover/out and event-time checks
5613// so that event delegation works in jQuery.
5614// Do the same for pointerenter/pointerleave and pointerover/pointerout
5615//
5616// Support: Safari 7 only
5617// Safari sends mouseenter too often; see:
5618// https://code.google.com/p/chromium/issues/detail?id=470258
5619// for the description of the bug (it existed in older Chrome versions as well).
5620jQuery.each( {
5621 mouseenter: "mouseover",
5622 mouseleave: "mouseout",
5623 pointerenter: "pointerover",
5624 pointerleave: "pointerout"
5625}, function( orig, fix ) {
5626 jQuery.event.special[ orig ] = {
5627 delegateType: fix,
5628 bindType: fix,
5629
5630 handle: function( event ) {
5631 var ret,
5632 target = this,
5633 related = event.relatedTarget,
5634 handleObj = event.handleObj;
5635
5636 // For mouseenter/leave call the handler if related is outside the target.
5637 // NB: No relatedTarget if the mouse left/entered the browser window
5638 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
5639 event.type = handleObj.origType;
5640 ret = handleObj.handler.apply( this, arguments );
5641 event.type = fix;
5642 }
5643 return ret;
5644 }
5645 };
5646} );
5647
5648// IE submit delegation
5649if ( !support.submit ) {
5650
5651 jQuery.event.special.submit = {
5652 setup: function() {
5653
5654 // Only need this for delegated form submit events
5655 if ( jQuery.nodeName( this, "form" ) ) {
5656 return false;
5657 }
5658
5659 // Lazy-add a submit handler when a descendant form may potentially be submitted
5660 jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
5661
5662 // Node name check avoids a VML-related crash in IE (#9807)
5663 var elem = e.target,
5664 form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ?
5665
5666 // Support: IE <=8
5667 // We use jQuery.prop instead of elem.form
5668 // to allow fixing the IE8 delegated submit issue (gh-2332)
5669 // by 3rd party polyfills/workarounds.
5670 jQuery.prop( elem, "form" ) :
5671 undefined;
5672
5673 if ( form && !jQuery._data( form, "submit" ) ) {
5674 jQuery.event.add( form, "submit._submit", function( event ) {
5675 event._submitBubble = true;
5676 } );
5677 jQuery._data( form, "submit", true );
5678 }
5679 } );
5680
5681 // return undefined since we don't need an event listener
5682 },
5683
5684 postDispatch: function( event ) {
5685
5686 // If form was submitted by the user, bubble the event up the tree
5687 if ( event._submitBubble ) {
5688 delete event._submitBubble;
5689 if ( this.parentNode && !event.isTrigger ) {
5690 jQuery.event.simulate( "submit", this.parentNode, event );
5691 }
5692 }
5693 },
5694
5695 teardown: function() {
5696
5697 // Only need this for delegated form submit events
5698 if ( jQuery.nodeName( this, "form" ) ) {
5699 return false;
5700 }
5701
5702 // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
5703 jQuery.event.remove( this, "._submit" );
5704 }
5705 };
5706}
5707
5708// IE change delegation and checkbox/radio fix
5709if ( !support.change ) {
5710
5711 jQuery.event.special.change = {
5712
5713 setup: function() {
5714
5715 if ( rformElems.test( this.nodeName ) ) {
5716
5717 // IE doesn't fire change on a check/radio until blur; trigger it on click
5718 // after a propertychange. Eat the blur-change in special.change.handle.
5719 // This still fires onchange a second time for check/radio after blur.
5720 if ( this.type === "checkbox" || this.type === "radio" ) {
5721 jQuery.event.add( this, "propertychange._change", function( event ) {
5722 if ( event.originalEvent.propertyName === "checked" ) {
5723 this._justChanged = true;
5724 }
5725 } );
5726 jQuery.event.add( this, "click._change", function( event ) {
5727 if ( this._justChanged && !event.isTrigger ) {
5728 this._justChanged = false;
5729 }
5730
5731 // Allow triggered, simulated change events (#11500)
5732 jQuery.event.simulate( "change", this, event );
5733 } );
5734 }
5735 return false;
5736 }
5737
5738 // Delegated event; lazy-add a change handler on descendant inputs
5739 jQuery.event.add( this, "beforeactivate._change", function( e ) {
5740 var elem = e.target;
5741
5742 if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "change" ) ) {
5743 jQuery.event.add( elem, "change._change", function( event ) {
5744 if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
5745 jQuery.event.simulate( "change", this.parentNode, event );
5746 }
5747 } );
5748 jQuery._data( elem, "change", true );
5749 }
5750 } );
5751 },
5752
5753 handle: function( event ) {
5754 var elem = event.target;
5755
5756 // Swallow native change events from checkbox/radio, we already triggered them above
5757 if ( this !== elem || event.isSimulated || event.isTrigger ||
5758 ( elem.type !== "radio" && elem.type !== "checkbox" ) ) {
5759
5760 return event.handleObj.handler.apply( this, arguments );
5761 }
5762 },
5763
5764 teardown: function() {
5765 jQuery.event.remove( this, "._change" );
5766
5767 return !rformElems.test( this.nodeName );
5768 }
5769 };
5770}
5771
5772// Support: Firefox
5773// Firefox doesn't have focus(in | out) events
5774// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
5775//
5776// Support: Chrome, Safari
5777// focus(in | out) events fire after focus & blur events,
5778// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
5779// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
5780if ( !support.focusin ) {
5781 jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
5782
5783 // Attach a single capturing handler on the document while someone wants focusin/focusout
5784 var handler = function( event ) {
5785 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
5786 };
5787
5788 jQuery.event.special[ fix ] = {
5789 setup: function() {
5790 var doc = this.ownerDocument || this,
5791 attaches = jQuery._data( doc, fix );
5792
5793 if ( !attaches ) {
5794 doc.addEventListener( orig, handler, true );
5795 }
5796 jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
5797 },
5798 teardown: function() {
5799 var doc = this.ownerDocument || this,
5800 attaches = jQuery._data( doc, fix ) - 1;
5801
5802 if ( !attaches ) {
5803 doc.removeEventListener( orig, handler, true );
5804 jQuery._removeData( doc, fix );
5805 } else {
5806 jQuery._data( doc, fix, attaches );
5807 }
5808 }
5809 };
5810 } );
5811}
5812
5813jQuery.fn.extend( {
5814
5815 on: function( types, selector, data, fn ) {
5816 return on( this, types, selector, data, fn );
5817 },
5818 one: function( types, selector, data, fn ) {
5819 return on( this, types, selector, data, fn, 1 );
5820 },
5821 off: function( types, selector, fn ) {
5822 var handleObj, type;
5823 if ( types && types.preventDefault && types.handleObj ) {
5824
5825 // ( event ) dispatched jQuery.Event
5826 handleObj = types.handleObj;
5827 jQuery( types.delegateTarget ).off(
5828 handleObj.namespace ?
5829 handleObj.origType + "." + handleObj.namespace :
5830 handleObj.origType,
5831 handleObj.selector,
5832 handleObj.handler
5833 );
5834 return this;
5835 }
5836 if ( typeof types === "object" ) {
5837
5838 // ( types-object [, selector] )
5839 for ( type in types ) {
5840 this.off( type, selector, types[ type ] );
5841 }
5842 return this;
5843 }
5844 if ( selector === false || typeof selector === "function" ) {
5845
5846 // ( types [, fn] )
5847 fn = selector;
5848 selector = undefined;
5849 }
5850 if ( fn === false ) {
5851 fn = returnFalse;
5852 }
5853 return this.each( function() {
5854 jQuery.event.remove( this, types, fn, selector );
5855 } );
5856 },
5857
5858 trigger: function( type, data ) {
5859 return this.each( function() {
5860 jQuery.event.trigger( type, data, this );
5861 } );
5862 },
5863 triggerHandler: function( type, data ) {
5864 var elem = this[ 0 ];
5865 if ( elem ) {
5866 return jQuery.event.trigger( type, data, elem, true );
5867 }
5868 }
5869} );
5870
5871
5872var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
5873 rnoshimcache = new RegExp( "<(?:" + nodeNames + ")[\\s/>]", "i" ),
5874 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
5875
5876 // Support: IE 10-11, Edge 10240+
5877 // In IE/Edge using regex groups here causes severe slowdowns.
5878 // See https://connect.microsoft.com/IE/feedback/details/1736512/
5879 rnoInnerhtml = /<script|<style|<link/i,
5880
5881 // checked="checked" or checked
5882 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5883 rscriptTypeMasked = /^true\/(.*)/,
5884 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
5885 safeFragment = createSafeFragment( document ),
5886 fragmentDiv = safeFragment.appendChild( document.createElement( "div" ) );
5887
5888// Support: IE<8
5889// Manipulating tables requires a tbody
5890function manipulationTarget( elem, content ) {
5891 return jQuery.nodeName( elem, "table" ) &&
5892 jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
5893
5894 elem.getElementsByTagName( "tbody" )[ 0 ] ||
5895 elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) :
5896 elem;
5897}
5898
5899// Replace/restore the type attribute of script elements for safe DOM manipulation
5900function disableScript( elem ) {
5901 elem.type = ( jQuery.find.attr( elem, "type" ) !== null ) + "/" + elem.type;
5902 return elem;
5903}
5904function restoreScript( elem ) {
5905 var match = rscriptTypeMasked.exec( elem.type );
5906 if ( match ) {
5907 elem.type = match[ 1 ];
5908 } else {
5909 elem.removeAttribute( "type" );
5910 }
5911 return elem;
5912}
5913
5914function cloneCopyEvent( src, dest ) {
5915 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5916 return;
5917 }
5918
5919 var type, i, l,
5920 oldData = jQuery._data( src ),
5921 curData = jQuery._data( dest, oldData ),
5922 events = oldData.events;
5923
5924 if ( events ) {
5925 delete curData.handle;
5926 curData.events = {};
5927
5928 for ( type in events ) {
5929 for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5930 jQuery.event.add( dest, type, events[ type ][ i ] );
5931 }
5932 }
5933 }
5934
5935 // make the cloned public data object a copy from the original
5936 if ( curData.data ) {
5937 curData.data = jQuery.extend( {}, curData.data );
5938 }
5939}
5940
5941function fixCloneNodeIssues( src, dest ) {
5942 var nodeName, e, data;
5943
5944 // We do not need to do anything for non-Elements
5945 if ( dest.nodeType !== 1 ) {
5946 return;
5947 }
5948
5949 nodeName = dest.nodeName.toLowerCase();
5950
5951 // IE6-8 copies events bound via attachEvent when using cloneNode.
5952 if ( !support.noCloneEvent && dest[ jQuery.expando ] ) {
5953 data = jQuery._data( dest );
5954
5955 for ( e in data.events ) {
5956 jQuery.removeEvent( dest, e, data.handle );
5957 }
5958
5959 // Event data gets referenced instead of copied if the expando gets copied too
5960 dest.removeAttribute( jQuery.expando );
5961 }
5962
5963 // IE blanks contents when cloning scripts, and tries to evaluate newly-set text
5964 if ( nodeName === "script" && dest.text !== src.text ) {
5965 disableScript( dest ).text = src.text;
5966 restoreScript( dest );
5967
5968 // IE6-10 improperly clones children of object elements using classid.
5969 // IE10 throws NoModificationAllowedError if parent is null, #12132.
5970 } else if ( nodeName === "object" ) {
5971 if ( dest.parentNode ) {
5972 dest.outerHTML = src.outerHTML;
5973 }
5974
5975 // This path appears unavoidable for IE9. When cloning an object
5976 // element in IE9, the outerHTML strategy above is not sufficient.
5977 // If the src has innerHTML and the destination does not,
5978 // copy the src.innerHTML into the dest.innerHTML. #10324
5979 if ( support.html5Clone && ( src.innerHTML && !jQuery.trim( dest.innerHTML ) ) ) {
5980 dest.innerHTML = src.innerHTML;
5981 }
5982
5983 } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5984
5985 // IE6-8 fails to persist the checked state of a cloned checkbox
5986 // or radio button. Worse, IE6-7 fail to give the cloned element
5987 // a checked appearance if the defaultChecked value isn't also set
5988
5989 dest.defaultChecked = dest.checked = src.checked;
5990
5991 // IE6-7 get confused and end up setting the value of a cloned
5992 // checkbox/radio button to an empty string instead of "on"
5993 if ( dest.value !== src.value ) {
5994 dest.value = src.value;
5995 }
5996
5997 // IE6-8 fails to return the selected option to the default selected
5998 // state when cloning options
5999 } else if ( nodeName === "option" ) {
6000 dest.defaultSelected = dest.selected = src.defaultSelected;
6001
6002 // IE6-8 fails to set the defaultValue to the correct value when
6003 // cloning other types of input fields
6004 } else if ( nodeName === "input" || nodeName === "textarea" ) {
6005 dest.defaultValue = src.defaultValue;
6006 }
6007}
6008
6009function domManip( collection, args, callback, ignored ) {
6010
6011 // Flatten any nested arrays
6012 args = concat.apply( [], args );
6013
6014 var first, node, hasScripts,
6015 scripts, doc, fragment,
6016 i = 0,
6017 l = collection.length,
6018 iNoClone = l - 1,
6019 value = args[ 0 ],
6020 isFunction = jQuery.isFunction( value );
6021
6022 // We can't cloneNode fragments that contain checked, in WebKit
6023 if ( isFunction ||
6024 ( l > 1 && typeof value === "string" &&
6025 !support.checkClone && rchecked.test( value ) ) ) {
6026 return collection.each( function( index ) {
6027 var self = collection.eq( index );
6028 if ( isFunction ) {
6029 args[ 0 ] = value.call( this, index, self.html() );
6030 }
6031 domManip( self, args, callback, ignored );
6032 } );
6033 }
6034
6035 if ( l ) {
6036 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
6037 first = fragment.firstChild;
6038
6039 if ( fragment.childNodes.length === 1 ) {
6040 fragment = first;
6041 }
6042
6043 // Require either new content or an interest in ignored elements to invoke the callback
6044 if ( first || ignored ) {
6045 scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
6046 hasScripts = scripts.length;
6047
6048 // Use the original fragment for the last item
6049 // instead of the first because it can end up
6050 // being emptied incorrectly in certain situations (#8070).
6051 for ( ; i < l; i++ ) {
6052 node = fragment;
6053
6054 if ( i !== iNoClone ) {
6055 node = jQuery.clone( node, true, true );
6056
6057 // Keep references to cloned scripts for later restoration
6058 if ( hasScripts ) {
6059
6060 // Support: Android<4.1, PhantomJS<2
6061 // push.apply(_, arraylike) throws on ancient WebKit
6062 jQuery.merge( scripts, getAll( node, "script" ) );
6063 }
6064 }
6065
6066 callback.call( collection[ i ], node, i );
6067 }
6068
6069 if ( hasScripts ) {
6070 doc = scripts[ scripts.length - 1 ].ownerDocument;
6071
6072 // Reenable scripts
6073 jQuery.map( scripts, restoreScript );
6074
6075 // Evaluate executable scripts on first document insertion
6076 for ( i = 0; i < hasScripts; i++ ) {
6077 node = scripts[ i ];
6078 if ( rscriptType.test( node.type || "" ) &&
6079 !jQuery._data( node, "globalEval" ) &&
6080 jQuery.contains( doc, node ) ) {
6081
6082 if ( node.src ) {
6083
6084 // Optional AJAX dependency, but won't run scripts if not present
6085 if ( jQuery._evalUrl ) {
6086 jQuery._evalUrl( node.src );
6087 }
6088 } else {
6089 jQuery.globalEval(
6090 ( node.text || node.textContent || node.innerHTML || "" )
6091 .replace( rcleanScript, "" )
6092 );
6093 }
6094 }
6095 }
6096 }
6097
6098 // Fix #11809: Avoid leaking memory
6099 fragment = first = null;
6100 }
6101 }
6102
6103 return collection;
6104}
6105
6106function remove( elem, selector, keepData ) {
6107 var node,
6108 elems = selector ? jQuery.filter( selector, elem ) : elem,
6109 i = 0;
6110
6111 for ( ; ( node = elems[ i ] ) != null; i++ ) {
6112
6113 if ( !keepData && node.nodeType === 1 ) {
6114 jQuery.cleanData( getAll( node ) );
6115 }
6116
6117 if ( node.parentNode ) {
6118 if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
6119 setGlobalEval( getAll( node, "script" ) );
6120 }
6121 node.parentNode.removeChild( node );
6122 }
6123 }
6124
6125 return elem;
6126}
6127
6128jQuery.extend( {
6129 htmlPrefilter: function( html ) {
6130 return html.replace( rxhtmlTag, "<$1></$2>" );
6131 },
6132
6133 clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6134 var destElements, node, clone, i, srcElements,
6135 inPage = jQuery.contains( elem.ownerDocument, elem );
6136
6137 if ( support.html5Clone || jQuery.isXMLDoc( elem ) ||
6138 !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
6139
6140 clone = elem.cloneNode( true );
6141
6142 // IE<=8 does not properly clone detached, unknown element nodes
6143 } else {
6144 fragmentDiv.innerHTML = elem.outerHTML;
6145 fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
6146 }
6147
6148 if ( ( !support.noCloneEvent || !support.noCloneChecked ) &&
6149 ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) {
6150
6151 // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
6152 destElements = getAll( clone );
6153 srcElements = getAll( elem );
6154
6155 // Fix all IE cloning issues
6156 for ( i = 0; ( node = srcElements[ i ] ) != null; ++i ) {
6157
6158 // Ensure that the destination node is not null; Fixes #9587
6159 if ( destElements[ i ] ) {
6160 fixCloneNodeIssues( node, destElements[ i ] );
6161 }
6162 }
6163 }
6164
6165 // Copy the events from the original to the clone
6166 if ( dataAndEvents ) {
6167 if ( deepDataAndEvents ) {
6168 srcElements = srcElements || getAll( elem );
6169 destElements = destElements || getAll( clone );
6170
6171 for ( i = 0; ( node = srcElements[ i ] ) != null; i++ ) {
6172 cloneCopyEvent( node, destElements[ i ] );
6173 }
6174 } else {
6175 cloneCopyEvent( elem, clone );
6176 }
6177 }
6178
6179 // Preserve script evaluation history
6180 destElements = getAll( clone, "script" );
6181 if ( destElements.length > 0 ) {
6182 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
6183 }
6184
6185 destElements = srcElements = node = null;
6186
6187 // Return the cloned set
6188 return clone;
6189 },
6190
6191 cleanData: function( elems, /* internal */ forceAcceptData ) {
6192 var elem, type, id, data,
6193 i = 0,
6194 internalKey = jQuery.expando,
6195 cache = jQuery.cache,
6196 attributes = support.attributes,
6197 special = jQuery.event.special;
6198
6199 for ( ; ( elem = elems[ i ] ) != null; i++ ) {
6200 if ( forceAcceptData || acceptData( elem ) ) {
6201
6202 id = elem[ internalKey ];
6203 data = id && cache[ id ];
6204
6205 if ( data ) {
6206 if ( data.events ) {
6207 for ( type in data.events ) {
6208 if ( special[ type ] ) {
6209 jQuery.event.remove( elem, type );
6210
6211 // This is a shortcut to avoid jQuery.event.remove's overhead
6212 } else {
6213 jQuery.removeEvent( elem, type, data.handle );
6214 }
6215 }
6216 }
6217
6218 // Remove cache only if it was not already removed by jQuery.event.remove
6219 if ( cache[ id ] ) {
6220
6221 delete cache[ id ];
6222
6223 // Support: IE<9
6224 // IE does not allow us to delete expando properties from nodes
6225 // IE creates expando attributes along with the property
6226 // IE does not have a removeAttribute function on Document nodes
6227 if ( !attributes && typeof elem.removeAttribute !== "undefined" ) {
6228 elem.removeAttribute( internalKey );
6229
6230 // Webkit & Blink performance suffers when deleting properties
6231 // from DOM nodes, so set to undefined instead
6232 // https://code.google.com/p/chromium/issues/detail?id=378607
6233 } else {
6234 elem[ internalKey ] = undefined;
6235 }
6236
6237 deletedIds.push( id );
6238 }
6239 }
6240 }
6241 }
6242 }
6243} );
6244
6245jQuery.fn.extend( {
6246
6247 // Keep domManip exposed until 3.0 (gh-2225)
6248 domManip: domManip,
6249
6250 detach: function( selector ) {
6251 return remove( this, selector, true );
6252 },
6253
6254 remove: function( selector ) {
6255 return remove( this, selector );
6256 },
6257
6258 text: function( value ) {
6259 return access( this, function( value ) {
6260 return value === undefined ?
6261 jQuery.text( this ) :
6262 this.empty().append(
6263 ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value )
6264 );
6265 }, null, value, arguments.length );
6266 },
6267
6268 append: function() {
6269 return domManip( this, arguments, function( elem ) {
6270 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6271 var target = manipulationTarget( this, elem );
6272 target.appendChild( elem );
6273 }
6274 } );
6275 },
6276
6277 prepend: function() {
6278 return domManip( this, arguments, function( elem ) {
6279 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6280 var target = manipulationTarget( this, elem );
6281 target.insertBefore( elem, target.firstChild );
6282 }
6283 } );
6284 },
6285
6286 before: function() {
6287 return domManip( this, arguments, function( elem ) {
6288 if ( this.parentNode ) {
6289 this.parentNode.insertBefore( elem, this );
6290 }
6291 } );
6292 },
6293
6294 after: function() {
6295 return domManip( this, arguments, function( elem ) {
6296 if ( this.parentNode ) {
6297 this.parentNode.insertBefore( elem, this.nextSibling );
6298 }
6299 } );
6300 },
6301
6302 empty: function() {
6303 var elem,
6304 i = 0;
6305
6306 for ( ; ( elem = this[ i ] ) != null; i++ ) {
6307
6308 // Remove element nodes and prevent memory leaks
6309 if ( elem.nodeType === 1 ) {
6310 jQuery.cleanData( getAll( elem, false ) );
6311 }
6312
6313 // Remove any remaining nodes
6314 while ( elem.firstChild ) {
6315 elem.removeChild( elem.firstChild );
6316 }
6317
6318 // If this is a select, ensure that it displays empty (#12336)
6319 // Support: IE<9
6320 if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
6321 elem.options.length = 0;
6322 }
6323 }
6324
6325 return this;
6326 },
6327
6328 clone: function( dataAndEvents, deepDataAndEvents ) {
6329 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
6330 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
6331
6332 return this.map( function() {
6333 return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
6334 } );
6335 },
6336
6337 html: function( value ) {
6338 return access( this, function( value ) {
6339 var elem = this[ 0 ] || {},
6340 i = 0,
6341 l = this.length;
6342
6343 if ( value === undefined ) {
6344 return elem.nodeType === 1 ?
6345 elem.innerHTML.replace( rinlinejQuery, "" ) :
6346 undefined;
6347 }
6348
6349 // See if we can take a shortcut and just use innerHTML
6350 if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
6351 ( support.htmlSerialize || !rnoshimcache.test( value ) ) &&
6352 ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
6353 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
6354
6355 value = jQuery.htmlPrefilter( value );
6356
6357 try {
6358 for ( ; i < l; i++ ) {
6359
6360 // Remove element nodes and prevent memory leaks
6361 elem = this[ i ] || {};
6362 if ( elem.nodeType === 1 ) {
6363 jQuery.cleanData( getAll( elem, false ) );
6364 elem.innerHTML = value;
6365 }
6366 }
6367
6368 elem = 0;
6369
6370 // If using innerHTML throws an exception, use the fallback method
6371 } catch ( e ) {}
6372 }
6373
6374 if ( elem ) {
6375 this.empty().append( value );
6376 }
6377 }, null, value, arguments.length );
6378 },
6379
6380 replaceWith: function() {
6381 var ignored = [];
6382
6383 // Make the changes, replacing each non-ignored context element with the new content
6384 return domManip( this, arguments, function( elem ) {
6385 var parent = this.parentNode;
6386
6387 if ( jQuery.inArray( this, ignored ) < 0 ) {
6388 jQuery.cleanData( getAll( this ) );
6389 if ( parent ) {
6390 parent.replaceChild( elem, this );
6391 }
6392 }
6393
6394 // Force callback invocation
6395 }, ignored );
6396 }
6397} );
6398
6399jQuery.each( {
6400 appendTo: "append",
6401 prependTo: "prepend",
6402 insertBefore: "before",
6403 insertAfter: "after",
6404 replaceAll: "replaceWith"
6405}, function( name, original ) {
6406 jQuery.fn[ name ] = function( selector ) {
6407 var elems,
6408 i = 0,
6409 ret = [],
6410 insert = jQuery( selector ),
6411 last = insert.length - 1;
6412
6413 for ( ; i <= last; i++ ) {
6414 elems = i === last ? this : this.clone( true );
6415 jQuery( insert[ i ] )[ original ]( elems );
6416
6417 // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
6418 push.apply( ret, elems.get() );
6419 }
6420
6421 return this.pushStack( ret );
6422 };
6423} );
6424
6425
6426var iframe,
6427 elemdisplay = {
6428
6429 // Support: Firefox
6430 // We have to pre-define these values for FF (#10227)
6431 HTML: "block",
6432 BODY: "block"
6433 };
6434
6435/**
6436 * Retrieve the actual display of a element
6437 * @param {String} name nodeName of the element
6438 * @param {Object} doc Document object
6439 */
6440
6441// Called only from within defaultDisplay
6442function actualDisplay( name, doc ) {
6443 var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
6444
6445 display = jQuery.css( elem[ 0 ], "display" );
6446
6447 // We don't have any data stored on the element,
6448 // so use "detach" method as fast way to get rid of the element
6449 elem.detach();
6450
6451 return display;
6452}
6453
6454/**
6455 * Try to determine the default display value of an element
6456 * @param {String} nodeName
6457 */
6458function defaultDisplay( nodeName ) {
6459 var doc = document,
6460 display = elemdisplay[ nodeName ];
6461
6462 if ( !display ) {
6463 display = actualDisplay( nodeName, doc );
6464
6465 // If the simple way fails, read from inside an iframe
6466 if ( display === "none" || !display ) {
6467
6468 // Use the already-created iframe if possible
6469 iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
6470 .appendTo( doc.documentElement );
6471
6472 // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
6473 doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;
6474
6475 // Support: IE
6476 doc.write();
6477 doc.close();
6478
6479 display = actualDisplay( nodeName, doc );
6480 iframe.detach();
6481 }
6482
6483 // Store the correct default display
6484 elemdisplay[ nodeName ] = display;
6485 }
6486
6487 return display;
6488}
6489var rmargin = ( /^margin/ );
6490
6491var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
6492
6493var swap = function( elem, options, callback, args ) {
6494 var ret, name,
6495 old = {};
6496
6497 // Remember the old values, and insert the new ones
6498 for ( name in options ) {
6499 old[ name ] = elem.style[ name ];
6500 elem.style[ name ] = options[ name ];
6501 }
6502
6503 ret = callback.apply( elem, args || [] );
6504
6505 // Revert the old values
6506 for ( name in options ) {
6507 elem.style[ name ] = old[ name ];
6508 }
6509
6510 return ret;
6511};
6512
6513
6514var documentElement = document.documentElement;
6515
6516
6517
6518( function() {
6519 var pixelPositionVal, pixelMarginRightVal, boxSizingReliableVal,
6520 reliableHiddenOffsetsVal, reliableMarginRightVal, reliableMarginLeftVal,
6521 container = document.createElement( "div" ),
6522 div = document.createElement( "div" );
6523
6524 // Finish early in limited (non-browser) environments
6525 if ( !div.style ) {
6526 return;
6527 }
6528
6529 div.style.cssText = "float:left;opacity:.5";
6530
6531 // Support: IE<9
6532 // Make sure that element opacity exists (as opposed to filter)
6533 support.opacity = div.style.opacity === "0.5";
6534
6535 // Verify style float existence
6536 // (IE uses styleFloat instead of cssFloat)
6537 support.cssFloat = !!div.style.cssFloat;
6538
6539 div.style.backgroundClip = "content-box";
6540 div.cloneNode( true ).style.backgroundClip = "";
6541 support.clearCloneStyle = div.style.backgroundClip === "content-box";
6542
6543 container = document.createElement( "div" );
6544 container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
6545 "padding:0;margin-top:1px;position:absolute";
6546 div.innerHTML = "";
6547 container.appendChild( div );
6548
6549 // Support: Firefox<29, Android 2.3
6550 // Vendor-prefix box-sizing
6551 support.boxSizing = div.style.boxSizing === "" || div.style.MozBoxSizing === "" ||
6552 div.style.WebkitBoxSizing === "";
6553
6554 jQuery.extend( support, {
6555 reliableHiddenOffsets: function() {
6556 if ( pixelPositionVal == null ) {
6557 computeStyleTests();
6558 }
6559 return reliableHiddenOffsetsVal;
6560 },
6561
6562 boxSizingReliable: function() {
6563
6564 // We're checking for pixelPositionVal here instead of boxSizingReliableVal
6565 // since that compresses better and they're computed together anyway.
6566 if ( pixelPositionVal == null ) {
6567 computeStyleTests();
6568 }
6569 return boxSizingReliableVal;
6570 },
6571
6572 pixelMarginRight: function() {
6573
6574 // Support: Android 4.0-4.3
6575 if ( pixelPositionVal == null ) {
6576 computeStyleTests();
6577 }
6578 return pixelMarginRightVal;
6579 },
6580
6581 pixelPosition: function() {
6582 if ( pixelPositionVal == null ) {
6583 computeStyleTests();
6584 }
6585 return pixelPositionVal;
6586 },
6587
6588 reliableMarginRight: function() {
6589
6590 // Support: Android 2.3
6591 if ( pixelPositionVal == null ) {
6592 computeStyleTests();
6593 }
6594 return reliableMarginRightVal;
6595 },
6596
6597 reliableMarginLeft: function() {
6598
6599 // Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
6600 if ( pixelPositionVal == null ) {
6601 computeStyleTests();
6602 }
6603 return reliableMarginLeftVal;
6604 }
6605 } );
6606
6607 function computeStyleTests() {
6608 var contents, divStyle,
6609 documentElement = document.documentElement;
6610
6611 // Setup
6612 documentElement.appendChild( container );
6613
6614 div.style.cssText =
6615
6616 // Support: Android 2.3
6617 // Vendor-prefix box-sizing
6618 "-webkit-box-sizing:border-box;box-sizing:border-box;" +
6619 "position:relative;display:block;" +
6620 "margin:auto;border:1px;padding:1px;" +
6621 "top:1%;width:50%";
6622
6623 // Support: IE<9
6624 // Assume reasonable values in the absence of getComputedStyle
6625 pixelPositionVal = boxSizingReliableVal = reliableMarginLeftVal = false;
6626 pixelMarginRightVal = reliableMarginRightVal = true;
6627
6628 // Check for getComputedStyle so that this code is not run in IE<9.
6629 if ( window.getComputedStyle ) {
6630 divStyle = window.getComputedStyle( div );
6631 pixelPositionVal = ( divStyle || {} ).top !== "1%";
6632 reliableMarginLeftVal = ( divStyle || {} ).marginLeft === "2px";
6633 boxSizingReliableVal = ( divStyle || { width: "4px" } ).width === "4px";
6634
6635 // Support: Android 4.0 - 4.3 only
6636 // Some styles come back with percentage values, even though they shouldn't
6637 div.style.marginRight = "50%";
6638 pixelMarginRightVal = ( divStyle || { marginRight: "4px" } ).marginRight === "4px";
6639
6640 // Support: Android 2.3 only
6641 // Div with explicit width and no margin-right incorrectly
6642 // gets computed margin-right based on width of container (#3333)
6643 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6644 contents = div.appendChild( document.createElement( "div" ) );
6645
6646 // Reset CSS: box-sizing; display; margin; border; padding
6647 contents.style.cssText = div.style.cssText =
6648
6649 // Support: Android 2.3
6650 // Vendor-prefix box-sizing
6651 "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
6652 "box-sizing:content-box;display:block;margin:0;border:0;padding:0";
6653 contents.style.marginRight = contents.style.width = "0";
6654 div.style.width = "1px";
6655
6656 reliableMarginRightVal =
6657 !parseFloat( ( window.getComputedStyle( contents ) || {} ).marginRight );
6658
6659 div.removeChild( contents );
6660 }
6661
6662 // Support: IE6-8
6663 // First check that getClientRects works as expected
6664 // Check if table cells still have offsetWidth/Height when they are set
6665 // to display:none and there are still other visible table cells in a
6666 // table row; if so, offsetWidth/Height are not reliable for use when
6667 // determining if an element has been hidden directly using
6668 // display:none (it is still safe to use offsets if a parent element is
6669 // hidden; don safety goggles and see bug #4512 for more information).
6670 div.style.display = "none";
6671 reliableHiddenOffsetsVal = div.getClientRects().length === 0;
6672 if ( reliableHiddenOffsetsVal ) {
6673 div.style.display = "";
6674 div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
6675 div.childNodes[ 0 ].style.borderCollapse = "separate";
6676 contents = div.getElementsByTagName( "td" );
6677 contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none";
6678 reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
6679 if ( reliableHiddenOffsetsVal ) {
6680 contents[ 0 ].style.display = "";
6681 contents[ 1 ].style.display = "none";
6682 reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
6683 }
6684 }
6685
6686 // Teardown
6687 documentElement.removeChild( container );
6688 }
6689
6690} )();
6691
6692
6693var getStyles, curCSS,
6694 rposition = /^(top|right|bottom|left)$/;
6695
6696if ( window.getComputedStyle ) {
6697 getStyles = function( elem ) {
6698
6699 // Support: IE<=11+, Firefox<=30+ (#15098, #14150)
6700 // IE throws on elements created in popups
6701 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6702 var view = elem.ownerDocument.defaultView;
6703
6704 if ( !view || !view.opener ) {
6705 view = window;
6706 }
6707
6708 return view.getComputedStyle( elem );
6709 };
6710
6711 curCSS = function( elem, name, computed ) {
6712 var width, minWidth, maxWidth, ret,
6713 style = elem.style;
6714
6715 computed = computed || getStyles( elem );
6716
6717 // getPropertyValue is only needed for .css('filter') in IE9, see #12537
6718 ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
6719
6720 // Support: Opera 12.1x only
6721 // Fall back to style even without computed
6722 // computed is undefined for elems on document fragments
6723 if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {
6724 ret = jQuery.style( elem, name );
6725 }
6726
6727 if ( computed ) {
6728
6729 // A tribute to the "awesome hack by Dean Edwards"
6730 // Chrome < 17 and Safari 5.0 uses "computed value"
6731 // instead of "used value" for margin-right
6732 // Safari 5.1.7 (at least) returns percentage for a larger set of values,
6733 // but width seems to be reliably pixels
6734 // this is against the CSSOM draft spec:
6735 // http://dev.w3.org/csswg/cssom/#resolved-values
6736 if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
6737
6738 // Remember the original values
6739 width = style.width;
6740 minWidth = style.minWidth;
6741 maxWidth = style.maxWidth;
6742
6743 // Put in the new values to get a computed value out
6744 style.minWidth = style.maxWidth = style.width = ret;
6745 ret = computed.width;
6746
6747 // Revert the changed values
6748 style.width = width;
6749 style.minWidth = minWidth;
6750 style.maxWidth = maxWidth;
6751 }
6752 }
6753
6754 // Support: IE
6755 // IE returns zIndex value as an integer.
6756 return ret === undefined ?
6757 ret :
6758 ret + "";
6759 };
6760} else if ( documentElement.currentStyle ) {
6761 getStyles = function( elem ) {
6762 return elem.currentStyle;
6763 };
6764
6765 curCSS = function( elem, name, computed ) {
6766 var left, rs, rsLeft, ret,
6767 style = elem.style;
6768
6769 computed = computed || getStyles( elem );
6770 ret = computed ? computed[ name ] : undefined;
6771
6772 // Avoid setting ret to empty string here
6773 // so we don't default to auto
6774 if ( ret == null && style && style[ name ] ) {
6775 ret = style[ name ];
6776 }
6777
6778 // From the awesome hack by Dean Edwards
6779 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6780
6781 // If we're not dealing with a regular pixel number
6782 // but a number that has a weird ending, we need to convert it to pixels
6783 // but not position css attributes, as those are
6784 // proportional to the parent element instead
6785 // and we can't measure the parent instead because it
6786 // might trigger a "stacking dolls" problem
6787 if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
6788
6789 // Remember the original values
6790 left = style.left;
6791 rs = elem.runtimeStyle;
6792 rsLeft = rs && rs.left;
6793
6794 // Put in the new values to get a computed value out
6795 if ( rsLeft ) {
6796 rs.left = elem.currentStyle.left;
6797 }
6798 style.left = name === "fontSize" ? "1em" : ret;
6799 ret = style.pixelLeft + "px";
6800
6801 // Revert the changed values
6802 style.left = left;
6803 if ( rsLeft ) {
6804 rs.left = rsLeft;
6805 }
6806 }
6807
6808 // Support: IE
6809 // IE returns zIndex value as an integer.
6810 return ret === undefined ?
6811 ret :
6812 ret + "" || "auto";
6813 };
6814}
6815
6816
6817
6818
6819function addGetHookIf( conditionFn, hookFn ) {
6820
6821 // Define the hook, we'll check on the first run if it's really needed.
6822 return {
6823 get: function() {
6824 if ( conditionFn() ) {
6825
6826 // Hook not needed (or it's not possible to use it due
6827 // to missing dependency), remove it.
6828 delete this.get;
6829 return;
6830 }
6831
6832 // Hook needed; redefine it so that the support test is not executed again.
6833 return ( this.get = hookFn ).apply( this, arguments );
6834 }
6835 };
6836}
6837
6838
6839var
6840
6841 ralpha = /alpha\([^)]*\)/i,
6842 ropacity = /opacity\s*=\s*([^)]*)/i,
6843
6844 // swappable if display is none or starts with table except
6845 // "table", "table-cell", or "table-caption"
6846 // see here for display values:
6847 // https://developer.mozilla.org/en-US/docs/CSS/display
6848 rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6849 rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
6850
6851 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6852 cssNormalTransform = {
6853 letterSpacing: "0",
6854 fontWeight: "400"
6855 },
6856
6857 cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
6858 emptyStyle = document.createElement( "div" ).style;
6859
6860
6861// return a css property mapped to a potentially vendor prefixed property
6862function vendorPropName( name ) {
6863
6864 // shortcut for names that are not vendor prefixed
6865 if ( name in emptyStyle ) {
6866 return name;
6867 }
6868
6869 // check for vendor prefixed names
6870 var capName = name.charAt( 0 ).toUpperCase() + name.slice( 1 ),
6871 i = cssPrefixes.length;
6872
6873 while ( i-- ) {
6874 name = cssPrefixes[ i ] + capName;
6875 if ( name in emptyStyle ) {
6876 return name;
6877 }
6878 }
6879}
6880
6881function showHide( elements, show ) {
6882 var display, elem, hidden,
6883 values = [],
6884 index = 0,
6885 length = elements.length;
6886
6887 for ( ; index < length; index++ ) {
6888 elem = elements[ index ];
6889 if ( !elem.style ) {
6890 continue;
6891 }
6892
6893 values[ index ] = jQuery._data( elem, "olddisplay" );
6894 display = elem.style.display;
6895 if ( show ) {
6896
6897 // Reset the inline display of this element to learn if it is
6898 // being hidden by cascaded rules or not
6899 if ( !values[ index ] && display === "none" ) {
6900 elem.style.display = "";
6901 }
6902
6903 // Set elements which have been overridden with display: none
6904 // in a stylesheet to whatever the default browser style is
6905 // for such an element
6906 if ( elem.style.display === "" && isHidden( elem ) ) {
6907 values[ index ] =
6908 jQuery._data( elem, "olddisplay", defaultDisplay( elem.nodeName ) );
6909 }
6910 } else {
6911 hidden = isHidden( elem );
6912
6913 if ( display && display !== "none" || !hidden ) {
6914 jQuery._data(
6915 elem,
6916 "olddisplay",
6917 hidden ? display : jQuery.css( elem, "display" )
6918 );
6919 }
6920 }
6921 }
6922
6923 // Set the display of most of the elements in a second loop
6924 // to avoid the constant reflow
6925 for ( index = 0; index < length; index++ ) {
6926 elem = elements[ index ];
6927 if ( !elem.style ) {
6928 continue;
6929 }
6930 if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6931 elem.style.display = show ? values[ index ] || "" : "none";
6932 }
6933 }
6934
6935 return elements;
6936}
6937
6938function setPositiveNumber( elem, value, subtract ) {
6939 var matches = rnumsplit.exec( value );
6940 return matches ?
6941
6942 // Guard against undefined "subtract", e.g., when used as in cssHooks
6943 Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
6944 value;
6945}
6946
6947function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
6948 var i = extra === ( isBorderBox ? "border" : "content" ) ?
6949
6950 // If we already have the right measurement, avoid augmentation
6951 4 :
6952
6953 // Otherwise initialize for horizontal or vertical properties
6954 name === "width" ? 1 : 0,
6955
6956 val = 0;
6957
6958 for ( ; i < 4; i += 2 ) {
6959
6960 // both box models exclude margin, so add it if we want it
6961 if ( extra === "margin" ) {
6962 val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
6963 }
6964
6965 if ( isBorderBox ) {
6966
6967 // border-box includes padding, so remove it if we want content
6968 if ( extra === "content" ) {
6969 val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6970 }
6971
6972 // at this point, extra isn't border nor margin, so remove border
6973 if ( extra !== "margin" ) {
6974 val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6975 }
6976 } else {
6977
6978 // at this point, extra isn't content, so add padding
6979 val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6980
6981 // at this point, extra isn't content nor padding, so add border
6982 if ( extra !== "padding" ) {
6983 val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6984 }
6985 }
6986 }
6987
6988 return val;
6989}
6990
6991function getWidthOrHeight( elem, name, extra ) {
6992
6993 // Start with offset property, which is equivalent to the border-box value
6994 var valueIsBorderBox = true,
6995 val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6996 styles = getStyles( elem ),
6997 isBorderBox = support.boxSizing &&
6998 jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
6999
7000 // some non-html elements return undefined for offsetWidth, so check for null/undefined
7001 // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
7002 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
7003 if ( val <= 0 || val == null ) {
7004
7005 // Fall back to computed then uncomputed css if necessary
7006 val = curCSS( elem, name, styles );
7007 if ( val < 0 || val == null ) {
7008 val = elem.style[ name ];
7009 }
7010
7011 // Computed unit is not pixels. Stop here and return.
7012 if ( rnumnonpx.test( val ) ) {
7013 return val;
7014 }
7015
7016 // we need the check for style in case a browser which returns unreliable values
7017 // for getComputedStyle silently falls back to the reliable elem.style
7018 valueIsBorderBox = isBorderBox &&
7019 ( support.boxSizingReliable() || val === elem.style[ name ] );
7020
7021 // Normalize "", auto, and prepare for extra
7022 val = parseFloat( val ) || 0;
7023 }
7024
7025 // use the active box-sizing model to add/subtract irrelevant styles
7026 return ( val +
7027 augmentWidthOrHeight(
7028 elem,
7029 name,
7030 extra || ( isBorderBox ? "border" : "content" ),
7031 valueIsBorderBox,
7032 styles
7033 )
7034 ) + "px";
7035}
7036
7037jQuery.extend( {
7038
7039 // Add in style property hooks for overriding the default
7040 // behavior of getting and setting a style property
7041 cssHooks: {
7042 opacity: {
7043 get: function( elem, computed ) {
7044 if ( computed ) {
7045
7046 // We should always get a number back from opacity
7047 var ret = curCSS( elem, "opacity" );
7048 return ret === "" ? "1" : ret;
7049 }
7050 }
7051 }
7052 },
7053
7054 // Don't automatically add "px" to these possibly-unitless properties
7055 cssNumber: {
7056 "animationIterationCount": true,
7057 "columnCount": true,
7058 "fillOpacity": true,
7059 "flexGrow": true,
7060 "flexShrink": true,
7061 "fontWeight": true,
7062 "lineHeight": true,
7063 "opacity": true,
7064 "order": true,
7065 "orphans": true,
7066 "widows": true,
7067 "zIndex": true,
7068 "zoom": true
7069 },
7070
7071 // Add in properties whose names you wish to fix before
7072 // setting or getting the value
7073 cssProps: {
7074
7075 // normalize float css property
7076 "float": support.cssFloat ? "cssFloat" : "styleFloat"
7077 },
7078
7079 // Get and set the style property on a DOM Node
7080 style: function( elem, name, value, extra ) {
7081
7082 // Don't set styles on text and comment nodes
7083 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
7084 return;
7085 }
7086
7087 // Make sure that we're working with the right name
7088 var ret, type, hooks,
7089 origName = jQuery.camelCase( name ),
7090 style = elem.style;
7091
7092 name = jQuery.cssProps[ origName ] ||
7093 ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
7094
7095 // gets hook for the prefixed version
7096 // followed by the unprefixed version
7097 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
7098
7099 // Check if we're setting a value
7100 if ( value !== undefined ) {
7101 type = typeof value;
7102
7103 // Convert "+=" or "-=" to relative numbers (#7345)
7104 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
7105 value = adjustCSS( elem, name, ret );
7106
7107 // Fixes bug #9237
7108 type = "number";
7109 }
7110
7111 // Make sure that null and NaN values aren't set. See: #7116
7112 if ( value == null || value !== value ) {
7113 return;
7114 }
7115
7116 // If a number was passed in, add the unit (except for certain CSS properties)
7117 if ( type === "number" ) {
7118 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
7119 }
7120
7121 // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
7122 // but it would mean to define eight
7123 // (for every problematic property) identical functions
7124 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
7125 style[ name ] = "inherit";
7126 }
7127
7128 // If a hook was provided, use that value, otherwise just set the specified value
7129 if ( !hooks || !( "set" in hooks ) ||
7130 ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
7131
7132 // Support: IE
7133 // Swallow errors from 'invalid' CSS values (#5509)
7134 try {
7135 style[ name ] = value;
7136 } catch ( e ) {}
7137 }
7138
7139 } else {
7140
7141 // If a hook was provided get the non-computed value from there
7142 if ( hooks && "get" in hooks &&
7143 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
7144
7145 return ret;
7146 }
7147
7148 // Otherwise just get the value from the style object
7149 return style[ name ];
7150 }
7151 },
7152
7153 css: function( elem, name, extra, styles ) {
7154 var num, val, hooks,
7155 origName = jQuery.camelCase( name );
7156
7157 // Make sure that we're working with the right name
7158 name = jQuery.cssProps[ origName ] ||
7159 ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
7160
7161 // gets hook for the prefixed version
7162 // followed by the unprefixed version
7163 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
7164
7165 // If a hook was provided get the computed value from there
7166 if ( hooks && "get" in hooks ) {
7167 val = hooks.get( elem, true, extra );
7168 }
7169
7170 // Otherwise, if a way to get the computed value exists, use that
7171 if ( val === undefined ) {
7172 val = curCSS( elem, name, styles );
7173 }
7174
7175 //convert "normal" to computed value
7176 if ( val === "normal" && name in cssNormalTransform ) {
7177 val = cssNormalTransform[ name ];
7178 }
7179
7180 // Return, converting to number if forced or a qualifier was provided and val looks numeric
7181 if ( extra === "" || extra ) {
7182 num = parseFloat( val );
7183 return extra === true || isFinite( num ) ? num || 0 : val;
7184 }
7185 return val;
7186 }
7187} );
7188
7189jQuery.each( [ "height", "width" ], function( i, name ) {
7190 jQuery.cssHooks[ name ] = {
7191 get: function( elem, computed, extra ) {
7192 if ( computed ) {
7193
7194 // certain elements can have dimension info if we invisibly show them
7195 // however, it must have a current display style that would benefit from this
7196 return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
7197 elem.offsetWidth === 0 ?
7198 swap( elem, cssShow, function() {
7199 return getWidthOrHeight( elem, name, extra );
7200 } ) :
7201 getWidthOrHeight( elem, name, extra );
7202 }
7203 },
7204
7205 set: function( elem, value, extra ) {
7206 var styles = extra && getStyles( elem );
7207 return setPositiveNumber( elem, value, extra ?
7208 augmentWidthOrHeight(
7209 elem,
7210 name,
7211 extra,
7212 support.boxSizing &&
7213 jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
7214 styles
7215 ) : 0
7216 );
7217 }
7218 };
7219} );
7220
7221if ( !support.opacity ) {
7222 jQuery.cssHooks.opacity = {
7223 get: function( elem, computed ) {
7224
7225 // IE uses filters for opacity
7226 return ropacity.test( ( computed && elem.currentStyle ?
7227 elem.currentStyle.filter :
7228 elem.style.filter ) || "" ) ?
7229 ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
7230 computed ? "1" : "";
7231 },
7232
7233 set: function( elem, value ) {
7234 var style = elem.style,
7235 currentStyle = elem.currentStyle,
7236 opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
7237 filter = currentStyle && currentStyle.filter || style.filter || "";
7238
7239 // IE has trouble with opacity if it does not have layout
7240 // Force it by setting the zoom level
7241 style.zoom = 1;
7242
7243 // if setting opacity to 1, and no other filters exist -
7244 // attempt to remove filter attribute #6652
7245 // if value === "", then remove inline opacity #12685
7246 if ( ( value >= 1 || value === "" ) &&
7247 jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
7248 style.removeAttribute ) {
7249
7250 // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
7251 // if "filter:" is present at all, clearType is disabled, we want to avoid this
7252 // style.removeAttribute is IE Only, but so apparently is this code path...
7253 style.removeAttribute( "filter" );
7254
7255 // if there is no filter style applied in a css rule
7256 // or unset inline opacity, we are done
7257 if ( value === "" || currentStyle && !currentStyle.filter ) {
7258 return;
7259 }
7260 }
7261
7262 // otherwise, set new filter values
7263 style.filter = ralpha.test( filter ) ?
7264 filter.replace( ralpha, opacity ) :
7265 filter + " " + opacity;
7266 }
7267 };
7268}
7269
7270jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
7271 function( elem, computed ) {
7272 if ( computed ) {
7273 return swap( elem, { "display": "inline-block" },
7274 curCSS, [ elem, "marginRight" ] );
7275 }
7276 }
7277);
7278
7279jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
7280 function( elem, computed ) {
7281 if ( computed ) {
7282 return (
7283 parseFloat( curCSS( elem, "marginLeft" ) ) ||
7284
7285 // Support: IE<=11+
7286 // Running getBoundingClientRect on a disconnected node in IE throws an error
7287 // Support: IE8 only
7288 // getClientRects() errors on disconnected elems
7289 ( jQuery.contains( elem.ownerDocument, elem ) ?
7290 elem.getBoundingClientRect().left -
7291 swap( elem, { marginLeft: 0 }, function() {
7292 return elem.getBoundingClientRect().left;
7293 } ) :
7294 0
7295 )
7296 ) + "px";
7297 }
7298 }
7299);
7300
7301// These hooks are used by animate to expand properties
7302jQuery.each( {
7303 margin: "",
7304 padding: "",
7305 border: "Width"
7306}, function( prefix, suffix ) {
7307 jQuery.cssHooks[ prefix + suffix ] = {
7308 expand: function( value ) {
7309 var i = 0,
7310 expanded = {},
7311
7312 // assumes a single number if not a string
7313 parts = typeof value === "string" ? value.split( " " ) : [ value ];
7314
7315 for ( ; i < 4; i++ ) {
7316 expanded[ prefix + cssExpand[ i ] + suffix ] =
7317 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
7318 }
7319
7320 return expanded;
7321 }
7322 };
7323
7324 if ( !rmargin.test( prefix ) ) {
7325 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
7326 }
7327} );
7328
7329jQuery.fn.extend( {
7330 css: function( name, value ) {
7331 return access( this, function( elem, name, value ) {
7332 var styles, len,
7333 map = {},
7334 i = 0;
7335
7336 if ( jQuery.isArray( name ) ) {
7337 styles = getStyles( elem );
7338 len = name.length;
7339
7340 for ( ; i < len; i++ ) {
7341 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
7342 }
7343
7344 return map;
7345 }
7346
7347 return value !== undefined ?
7348 jQuery.style( elem, name, value ) :
7349 jQuery.css( elem, name );
7350 }, name, value, arguments.length > 1 );
7351 },
7352 show: function() {
7353 return showHide( this, true );
7354 },
7355 hide: function() {
7356 return showHide( this );
7357 },
7358 toggle: function( state ) {
7359 if ( typeof state === "boolean" ) {
7360 return state ? this.show() : this.hide();
7361 }
7362
7363 return this.each( function() {
7364 if ( isHidden( this ) ) {
7365 jQuery( this ).show();
7366 } else {
7367 jQuery( this ).hide();
7368 }
7369 } );
7370 }
7371} );
7372
7373
7374function Tween( elem, options, prop, end, easing ) {
7375 return new Tween.prototype.init( elem, options, prop, end, easing );
7376}
7377jQuery.Tween = Tween;
7378
7379Tween.prototype = {
7380 constructor: Tween,
7381 init: function( elem, options, prop, end, easing, unit ) {
7382 this.elem = elem;
7383 this.prop = prop;
7384 this.easing = easing || jQuery.easing._default;
7385 this.options = options;
7386 this.start = this.now = this.cur();
7387 this.end = end;
7388 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
7389 },
7390 cur: function() {
7391 var hooks = Tween.propHooks[ this.prop ];
7392
7393 return hooks && hooks.get ?
7394 hooks.get( this ) :
7395 Tween.propHooks._default.get( this );
7396 },
7397 run: function( percent ) {
7398 var eased,
7399 hooks = Tween.propHooks[ this.prop ];
7400
7401 if ( this.options.duration ) {
7402 this.pos = eased = jQuery.easing[ this.easing ](
7403 percent, this.options.duration * percent, 0, 1, this.options.duration
7404 );
7405 } else {
7406 this.pos = eased = percent;
7407 }
7408 this.now = ( this.end - this.start ) * eased + this.start;
7409
7410 if ( this.options.step ) {
7411 this.options.step.call( this.elem, this.now, this );
7412 }
7413
7414 if ( hooks && hooks.set ) {
7415 hooks.set( this );
7416 } else {
7417 Tween.propHooks._default.set( this );
7418 }
7419 return this;
7420 }
7421};
7422
7423Tween.prototype.init.prototype = Tween.prototype;
7424
7425Tween.propHooks = {
7426 _default: {
7427 get: function( tween ) {
7428 var result;
7429
7430 // Use a property on the element directly when it is not a DOM element,
7431 // or when there is no matching style property that exists.
7432 if ( tween.elem.nodeType !== 1 ||
7433 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
7434 return tween.elem[ tween.prop ];
7435 }
7436
7437 // passing an empty string as a 3rd parameter to .css will automatically
7438 // attempt a parseFloat and fallback to a string if the parse fails
7439 // so, simple values such as "10px" are parsed to Float.
7440 // complex values such as "rotate(1rad)" are returned as is.
7441 result = jQuery.css( tween.elem, tween.prop, "" );
7442
7443 // Empty strings, null, undefined and "auto" are converted to 0.
7444 return !result || result === "auto" ? 0 : result;
7445 },
7446 set: function( tween ) {
7447
7448 // use step hook for back compat - use cssHook if its there - use .style if its
7449 // available and use plain properties where available
7450 if ( jQuery.fx.step[ tween.prop ] ) {
7451 jQuery.fx.step[ tween.prop ]( tween );
7452 } else if ( tween.elem.nodeType === 1 &&
7453 ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
7454 jQuery.cssHooks[ tween.prop ] ) ) {
7455 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
7456 } else {
7457 tween.elem[ tween.prop ] = tween.now;
7458 }
7459 }
7460 }
7461};
7462
7463// Support: IE <=9
7464// Panic based approach to setting things on disconnected nodes
7465
7466Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
7467 set: function( tween ) {
7468 if ( tween.elem.nodeType && tween.elem.parentNode ) {
7469 tween.elem[ tween.prop ] = tween.now;
7470 }
7471 }
7472};
7473
7474jQuery.easing = {
7475 linear: function( p ) {
7476 return p;
7477 },
7478 swing: function( p ) {
7479 return 0.5 - Math.cos( p * Math.PI ) / 2;
7480 },
7481 _default: "swing"
7482};
7483
7484jQuery.fx = Tween.prototype.init;
7485
7486// Back Compat <1.8 extension point
7487jQuery.fx.step = {};
7488
7489
7490
7491
7492var
7493 fxNow, timerId,
7494 rfxtypes = /^(?:toggle|show|hide)$/,
7495 rrun = /queueHooks$/;
7496
7497// Animations created synchronously will run synchronously
7498function createFxNow() {
7499 window.setTimeout( function() {
7500 fxNow = undefined;
7501 } );
7502 return ( fxNow = jQuery.now() );
7503}
7504
7505// Generate parameters to create a standard animation
7506function genFx( type, includeWidth ) {
7507 var which,
7508 attrs = { height: type },
7509 i = 0;
7510
7511 // if we include width, step value is 1 to do all cssExpand values,
7512 // if we don't include width, step value is 2 to skip over Left and Right
7513 includeWidth = includeWidth ? 1 : 0;
7514 for ( ; i < 4 ; i += 2 - includeWidth ) {
7515 which = cssExpand[ i ];
7516 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
7517 }
7518
7519 if ( includeWidth ) {
7520 attrs.opacity = attrs.width = type;
7521 }
7522
7523 return attrs;
7524}
7525
7526function createTween( value, prop, animation ) {
7527 var tween,
7528 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
7529 index = 0,
7530 length = collection.length;
7531 for ( ; index < length; index++ ) {
7532 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
7533
7534 // we're done with this property
7535 return tween;
7536 }
7537 }
7538}
7539
7540function defaultPrefilter( elem, props, opts ) {
7541 /* jshint validthis: true */
7542 var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
7543 anim = this,
7544 orig = {},
7545 style = elem.style,
7546 hidden = elem.nodeType && isHidden( elem ),
7547 dataShow = jQuery._data( elem, "fxshow" );
7548
7549 // handle queue: false promises
7550 if ( !opts.queue ) {
7551 hooks = jQuery._queueHooks( elem, "fx" );
7552 if ( hooks.unqueued == null ) {
7553 hooks.unqueued = 0;
7554 oldfire = hooks.empty.fire;
7555 hooks.empty.fire = function() {
7556 if ( !hooks.unqueued ) {
7557 oldfire();
7558 }
7559 };
7560 }
7561 hooks.unqueued++;
7562
7563 anim.always( function() {
7564
7565 // doing this makes sure that the complete handler will be called
7566 // before this completes
7567 anim.always( function() {
7568 hooks.unqueued--;
7569 if ( !jQuery.queue( elem, "fx" ).length ) {
7570 hooks.empty.fire();
7571 }
7572 } );
7573 } );
7574 }
7575
7576 // height/width overflow pass
7577 if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
7578
7579 // Make sure that nothing sneaks out
7580 // Record all 3 overflow attributes because IE does not
7581 // change the overflow attribute when overflowX and
7582 // overflowY are set to the same value
7583 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
7584
7585 // Set display property to inline-block for height/width
7586 // animations on inline elements that are having width/height animated
7587 display = jQuery.css( elem, "display" );
7588
7589 // Test default display if display is currently "none"
7590 checkDisplay = display === "none" ?
7591 jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
7592
7593 if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
7594
7595 // inline-level elements accept inline-block;
7596 // block-level elements need to be inline with layout
7597 if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) {
7598 style.display = "inline-block";
7599 } else {
7600 style.zoom = 1;
7601 }
7602 }
7603 }
7604
7605 if ( opts.overflow ) {
7606 style.overflow = "hidden";
7607 if ( !support.shrinkWrapBlocks() ) {
7608 anim.always( function() {
7609 style.overflow = opts.overflow[ 0 ];
7610 style.overflowX = opts.overflow[ 1 ];
7611 style.overflowY = opts.overflow[ 2 ];
7612 } );
7613 }
7614 }
7615
7616 // show/hide pass
7617 for ( prop in props ) {
7618 value = props[ prop ];
7619 if ( rfxtypes.exec( value ) ) {
7620 delete props[ prop ];
7621 toggle = toggle || value === "toggle";
7622 if ( value === ( hidden ? "hide" : "show" ) ) {
7623
7624 // If there is dataShow left over from a stopped hide or show
7625 // and we are going to proceed with show, we should pretend to be hidden
7626 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
7627 hidden = true;
7628 } else {
7629 continue;
7630 }
7631 }
7632 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
7633
7634 // Any non-fx value stops us from restoring the original display value
7635 } else {
7636 display = undefined;
7637 }
7638 }
7639
7640 if ( !jQuery.isEmptyObject( orig ) ) {
7641 if ( dataShow ) {
7642 if ( "hidden" in dataShow ) {
7643 hidden = dataShow.hidden;
7644 }
7645 } else {
7646 dataShow = jQuery._data( elem, "fxshow", {} );
7647 }
7648
7649 // store state if its toggle - enables .stop().toggle() to "reverse"
7650 if ( toggle ) {
7651 dataShow.hidden = !hidden;
7652 }
7653 if ( hidden ) {
7654 jQuery( elem ).show();
7655 } else {
7656 anim.done( function() {
7657 jQuery( elem ).hide();
7658 } );
7659 }
7660 anim.done( function() {
7661 var prop;
7662 jQuery._removeData( elem, "fxshow" );
7663 for ( prop in orig ) {
7664 jQuery.style( elem, prop, orig[ prop ] );
7665 }
7666 } );
7667 for ( prop in orig ) {
7668 tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
7669
7670 if ( !( prop in dataShow ) ) {
7671 dataShow[ prop ] = tween.start;
7672 if ( hidden ) {
7673 tween.end = tween.start;
7674 tween.start = prop === "width" || prop === "height" ? 1 : 0;
7675 }
7676 }
7677 }
7678
7679 // If this is a noop like .hide().hide(), restore an overwritten display value
7680 } else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) {
7681 style.display = display;
7682 }
7683}
7684
7685function propFilter( props, specialEasing ) {
7686 var index, name, easing, value, hooks;
7687
7688 // camelCase, specialEasing and expand cssHook pass
7689 for ( index in props ) {
7690 name = jQuery.camelCase( index );
7691 easing = specialEasing[ name ];
7692 value = props[ index ];
7693 if ( jQuery.isArray( value ) ) {
7694 easing = value[ 1 ];
7695 value = props[ index ] = value[ 0 ];
7696 }
7697
7698 if ( index !== name ) {
7699 props[ name ] = value;
7700 delete props[ index ];
7701 }
7702
7703 hooks = jQuery.cssHooks[ name ];
7704 if ( hooks && "expand" in hooks ) {
7705 value = hooks.expand( value );
7706 delete props[ name ];
7707
7708 // not quite $.extend, this wont overwrite keys already present.
7709 // also - reusing 'index' from above because we have the correct "name"
7710 for ( index in value ) {
7711 if ( !( index in props ) ) {
7712 props[ index ] = value[ index ];
7713 specialEasing[ index ] = easing;
7714 }
7715 }
7716 } else {
7717 specialEasing[ name ] = easing;
7718 }
7719 }
7720}
7721
7722function Animation( elem, properties, options ) {
7723 var result,
7724 stopped,
7725 index = 0,
7726 length = Animation.prefilters.length,
7727 deferred = jQuery.Deferred().always( function() {
7728
7729 // don't match elem in the :animated selector
7730 delete tick.elem;
7731 } ),
7732 tick = function() {
7733 if ( stopped ) {
7734 return false;
7735 }
7736 var currentTime = fxNow || createFxNow(),
7737 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
7738
7739 // Support: Android 2.3
7740 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
7741 temp = remaining / animation.duration || 0,
7742 percent = 1 - temp,
7743 index = 0,
7744 length = animation.tweens.length;
7745
7746 for ( ; index < length ; index++ ) {
7747 animation.tweens[ index ].run( percent );
7748 }
7749
7750 deferred.notifyWith( elem, [ animation, percent, remaining ] );
7751
7752 if ( percent < 1 && length ) {
7753 return remaining;
7754 } else {
7755 deferred.resolveWith( elem, [ animation ] );
7756 return false;
7757 }
7758 },
7759 animation = deferred.promise( {
7760 elem: elem,
7761 props: jQuery.extend( {}, properties ),
7762 opts: jQuery.extend( true, {
7763 specialEasing: {},
7764 easing: jQuery.easing._default
7765 }, options ),
7766 originalProperties: properties,
7767 originalOptions: options,
7768 startTime: fxNow || createFxNow(),
7769 duration: options.duration,
7770 tweens: [],
7771 createTween: function( prop, end ) {
7772 var tween = jQuery.Tween( elem, animation.opts, prop, end,
7773 animation.opts.specialEasing[ prop ] || animation.opts.easing );
7774 animation.tweens.push( tween );
7775 return tween;
7776 },
7777 stop: function( gotoEnd ) {
7778 var index = 0,
7779
7780 // if we are going to the end, we want to run all the tweens
7781 // otherwise we skip this part
7782 length = gotoEnd ? animation.tweens.length : 0;
7783 if ( stopped ) {
7784 return this;
7785 }
7786 stopped = true;
7787 for ( ; index < length ; index++ ) {
7788 animation.tweens[ index ].run( 1 );
7789 }
7790
7791 // resolve when we played the last frame
7792 // otherwise, reject
7793 if ( gotoEnd ) {
7794 deferred.notifyWith( elem, [ animation, 1, 0 ] );
7795 deferred.resolveWith( elem, [ animation, gotoEnd ] );
7796 } else {
7797 deferred.rejectWith( elem, [ animation, gotoEnd ] );
7798 }
7799 return this;
7800 }
7801 } ),
7802 props = animation.props;
7803
7804 propFilter( props, animation.opts.specialEasing );
7805
7806 for ( ; index < length ; index++ ) {
7807 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
7808 if ( result ) {
7809 if ( jQuery.isFunction( result.stop ) ) {
7810 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
7811 jQuery.proxy( result.stop, result );
7812 }
7813 return result;
7814 }
7815 }
7816
7817 jQuery.map( props, createTween, animation );
7818
7819 if ( jQuery.isFunction( animation.opts.start ) ) {
7820 animation.opts.start.call( elem, animation );
7821 }
7822
7823 jQuery.fx.timer(
7824 jQuery.extend( tick, {
7825 elem: elem,
7826 anim: animation,
7827 queue: animation.opts.queue
7828 } )
7829 );
7830
7831 // attach callbacks from options
7832 return animation.progress( animation.opts.progress )
7833 .done( animation.opts.done, animation.opts.complete )
7834 .fail( animation.opts.fail )
7835 .always( animation.opts.always );
7836}
7837
7838jQuery.Animation = jQuery.extend( Animation, {
7839
7840 tweeners: {
7841 "*": [ function( prop, value ) {
7842 var tween = this.createTween( prop, value );
7843 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
7844 return tween;
7845 } ]
7846 },
7847
7848 tweener: function( props, callback ) {
7849 if ( jQuery.isFunction( props ) ) {
7850 callback = props;
7851 props = [ "*" ];
7852 } else {
7853 props = props.match( rnotwhite );
7854 }
7855
7856 var prop,
7857 index = 0,
7858 length = props.length;
7859
7860 for ( ; index < length ; index++ ) {
7861 prop = props[ index ];
7862 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
7863 Animation.tweeners[ prop ].unshift( callback );
7864 }
7865 },
7866
7867 prefilters: [ defaultPrefilter ],
7868
7869 prefilter: function( callback, prepend ) {
7870 if ( prepend ) {
7871 Animation.prefilters.unshift( callback );
7872 } else {
7873 Animation.prefilters.push( callback );
7874 }
7875 }
7876} );
7877
7878jQuery.speed = function( speed, easing, fn ) {
7879 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
7880 complete: fn || !fn && easing ||
7881 jQuery.isFunction( speed ) && speed,
7882 duration: speed,
7883 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
7884 };
7885
7886 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
7887 opt.duration in jQuery.fx.speeds ?
7888 jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
7889
7890 // normalize opt.queue - true/undefined/null -> "fx"
7891 if ( opt.queue == null || opt.queue === true ) {
7892 opt.queue = "fx";
7893 }
7894
7895 // Queueing
7896 opt.old = opt.complete;
7897
7898 opt.complete = function() {
7899 if ( jQuery.isFunction( opt.old ) ) {
7900 opt.old.call( this );
7901 }
7902
7903 if ( opt.queue ) {
7904 jQuery.dequeue( this, opt.queue );
7905 }
7906 };
7907
7908 return opt;
7909};
7910
7911jQuery.fn.extend( {
7912 fadeTo: function( speed, to, easing, callback ) {
7913
7914 // show any hidden elements after setting opacity to 0
7915 return this.filter( isHidden ).css( "opacity", 0 ).show()
7916
7917 // animate to the value specified
7918 .end().animate( { opacity: to }, speed, easing, callback );
7919 },
7920 animate: function( prop, speed, easing, callback ) {
7921 var empty = jQuery.isEmptyObject( prop ),
7922 optall = jQuery.speed( speed, easing, callback ),
7923 doAnimation = function() {
7924
7925 // Operate on a copy of prop so per-property easing won't be lost
7926 var anim = Animation( this, jQuery.extend( {}, prop ), optall );
7927
7928 // Empty animations, or finishing resolves immediately
7929 if ( empty || jQuery._data( this, "finish" ) ) {
7930 anim.stop( true );
7931 }
7932 };
7933 doAnimation.finish = doAnimation;
7934
7935 return empty || optall.queue === false ?
7936 this.each( doAnimation ) :
7937 this.queue( optall.queue, doAnimation );
7938 },
7939 stop: function( type, clearQueue, gotoEnd ) {
7940 var stopQueue = function( hooks ) {
7941 var stop = hooks.stop;
7942 delete hooks.stop;
7943 stop( gotoEnd );
7944 };
7945
7946 if ( typeof type !== "string" ) {
7947 gotoEnd = clearQueue;
7948 clearQueue = type;
7949 type = undefined;
7950 }
7951 if ( clearQueue && type !== false ) {
7952 this.queue( type || "fx", [] );
7953 }
7954
7955 return this.each( function() {
7956 var dequeue = true,
7957 index = type != null && type + "queueHooks",
7958 timers = jQuery.timers,
7959 data = jQuery._data( this );
7960
7961 if ( index ) {
7962 if ( data[ index ] && data[ index ].stop ) {
7963 stopQueue( data[ index ] );
7964 }
7965 } else {
7966 for ( index in data ) {
7967 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
7968 stopQueue( data[ index ] );
7969 }
7970 }
7971 }
7972
7973 for ( index = timers.length; index--; ) {
7974 if ( timers[ index ].elem === this &&
7975 ( type == null || timers[ index ].queue === type ) ) {
7976
7977 timers[ index ].anim.stop( gotoEnd );
7978 dequeue = false;
7979 timers.splice( index, 1 );
7980 }
7981 }
7982
7983 // start the next in the queue if the last step wasn't forced
7984 // timers currently will call their complete callbacks, which will dequeue
7985 // but only if they were gotoEnd
7986 if ( dequeue || !gotoEnd ) {
7987 jQuery.dequeue( this, type );
7988 }
7989 } );
7990 },
7991 finish: function( type ) {
7992 if ( type !== false ) {
7993 type = type || "fx";
7994 }
7995 return this.each( function() {
7996 var index,
7997 data = jQuery._data( this ),
7998 queue = data[ type + "queue" ],
7999 hooks = data[ type + "queueHooks" ],
8000 timers = jQuery.timers,
8001 length = queue ? queue.length : 0;
8002
8003 // enable finishing flag on private data
8004 data.finish = true;
8005
8006 // empty the queue first
8007 jQuery.queue( this, type, [] );
8008
8009 if ( hooks && hooks.stop ) {
8010 hooks.stop.call( this, true );
8011 }
8012
8013 // look for any active animations, and finish them
8014 for ( index = timers.length; index--; ) {
8015 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
8016 timers[ index ].anim.stop( true );
8017 timers.splice( index, 1 );
8018 }
8019 }
8020
8021 // look for any animations in the old queue and finish them
8022 for ( index = 0; index < length; index++ ) {
8023 if ( queue[ index ] && queue[ index ].finish ) {
8024 queue[ index ].finish.call( this );
8025 }
8026 }
8027
8028 // turn off finishing flag
8029 delete data.finish;
8030 } );
8031 }
8032} );
8033
8034jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
8035 var cssFn = jQuery.fn[ name ];
8036 jQuery.fn[ name ] = function( speed, easing, callback ) {
8037 return speed == null || typeof speed === "boolean" ?
8038 cssFn.apply( this, arguments ) :
8039 this.animate( genFx( name, true ), speed, easing, callback );
8040 };
8041} );
8042
8043// Generate shortcuts for custom animations
8044jQuery.each( {
8045 slideDown: genFx( "show" ),
8046 slideUp: genFx( "hide" ),
8047 slideToggle: genFx( "toggle" ),
8048 fadeIn: { opacity: "show" },
8049 fadeOut: { opacity: "hide" },
8050 fadeToggle: { opacity: "toggle" }
8051}, function( name, props ) {
8052 jQuery.fn[ name ] = function( speed, easing, callback ) {
8053 return this.animate( props, speed, easing, callback );
8054 };
8055} );
8056
8057jQuery.timers = [];
8058jQuery.fx.tick = function() {
8059 var timer,
8060 timers = jQuery.timers,
8061 i = 0;
8062
8063 fxNow = jQuery.now();
8064
8065 for ( ; i < timers.length; i++ ) {
8066 timer = timers[ i ];
8067
8068 // Checks the timer has not already been removed
8069 if ( !timer() && timers[ i ] === timer ) {
8070 timers.splice( i--, 1 );
8071 }
8072 }
8073
8074 if ( !timers.length ) {
8075 jQuery.fx.stop();
8076 }
8077 fxNow = undefined;
8078};
8079
8080jQuery.fx.timer = function( timer ) {
8081 jQuery.timers.push( timer );
8082 if ( timer() ) {
8083 jQuery.fx.start();
8084 } else {
8085 jQuery.timers.pop();
8086 }
8087};
8088
8089jQuery.fx.interval = 13;
8090
8091jQuery.fx.start = function() {
8092 if ( !timerId ) {
8093 timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
8094 }
8095};
8096
8097jQuery.fx.stop = function() {
8098 window.clearInterval( timerId );
8099 timerId = null;
8100};
8101
8102jQuery.fx.speeds = {
8103 slow: 600,
8104 fast: 200,
8105
8106 // Default speed
8107 _default: 400
8108};
8109
8110
8111// Based off of the plugin by Clint Helfers, with permission.
8112// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
8113jQuery.fn.delay = function( time, type ) {
8114 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
8115 type = type || "fx";
8116
8117 return this.queue( type, function( next, hooks ) {
8118 var timeout = window.setTimeout( next, time );
8119 hooks.stop = function() {
8120 window.clearTimeout( timeout );
8121 };
8122 } );
8123};
8124
8125
8126( function() {
8127 var a,
8128 input = document.createElement( "input" ),
8129 div = document.createElement( "div" ),
8130 select = document.createElement( "select" ),
8131 opt = select.appendChild( document.createElement( "option" ) );
8132
8133 // Setup
8134 div = document.createElement( "div" );
8135 div.setAttribute( "className", "t" );
8136 div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
8137 a = div.getElementsByTagName( "a" )[ 0 ];
8138
8139 // Support: Windows Web Apps (WWA)
8140 // `type` must use .setAttribute for WWA (#14901)
8141 input.setAttribute( "type", "checkbox" );
8142 div.appendChild( input );
8143
8144 a = div.getElementsByTagName( "a" )[ 0 ];
8145
8146 // First batch of tests.
8147 a.style.cssText = "top:1px";
8148
8149 // Test setAttribute on camelCase class.
8150 // If it works, we need attrFixes when doing get/setAttribute (ie6/7)
8151 support.getSetAttribute = div.className !== "t";
8152
8153 // Get the style information from getAttribute
8154 // (IE uses .cssText instead)
8155 support.style = /top/.test( a.getAttribute( "style" ) );
8156
8157 // Make sure that URLs aren't manipulated
8158 // (IE normalizes it by default)
8159 support.hrefNormalized = a.getAttribute( "href" ) === "/a";
8160
8161 // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
8162 support.checkOn = !!input.value;
8163
8164 // Make sure that a selected-by-default option has a working selected property.
8165 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
8166 support.optSelected = opt.selected;
8167
8168 // Tests for enctype support on a form (#6743)
8169 support.enctype = !!document.createElement( "form" ).enctype;
8170
8171 // Make sure that the options inside disabled selects aren't marked as disabled
8172 // (WebKit marks them as disabled)
8173 select.disabled = true;
8174 support.optDisabled = !opt.disabled;
8175
8176 // Support: IE8 only
8177 // Check if we can trust getAttribute("value")
8178 input = document.createElement( "input" );
8179 input.setAttribute( "value", "" );
8180 support.input = input.getAttribute( "value" ) === "";
8181
8182 // Check if an input maintains its value after becoming a radio
8183 input.value = "t";
8184 input.setAttribute( "type", "radio" );
8185 support.radioValue = input.value === "t";
8186} )();
8187
8188
8189var rreturn = /\r/g,
8190 rspaces = /[\x20\t\r\n\f]+/g;
8191
8192jQuery.fn.extend( {
8193 val: function( value ) {
8194 var hooks, ret, isFunction,
8195 elem = this[ 0 ];
8196
8197 if ( !arguments.length ) {
8198 if ( elem ) {
8199 hooks = jQuery.valHooks[ elem.type ] ||
8200 jQuery.valHooks[ elem.nodeName.toLowerCase() ];
8201
8202 if (
8203 hooks &&
8204 "get" in hooks &&
8205 ( ret = hooks.get( elem, "value" ) ) !== undefined
8206 ) {
8207 return ret;
8208 }
8209
8210 ret = elem.value;
8211
8212 return typeof ret === "string" ?
8213
8214 // handle most common string cases
8215 ret.replace( rreturn, "" ) :
8216
8217 // handle cases where value is null/undef or number
8218 ret == null ? "" : ret;
8219 }
8220
8221 return;
8222 }
8223
8224 isFunction = jQuery.isFunction( value );
8225
8226 return this.each( function( i ) {
8227 var val;
8228
8229 if ( this.nodeType !== 1 ) {
8230 return;
8231 }
8232
8233 if ( isFunction ) {
8234 val = value.call( this, i, jQuery( this ).val() );
8235 } else {
8236 val = value;
8237 }
8238
8239 // Treat null/undefined as ""; convert numbers to string
8240 if ( val == null ) {
8241 val = "";
8242 } else if ( typeof val === "number" ) {
8243 val += "";
8244 } else if ( jQuery.isArray( val ) ) {
8245 val = jQuery.map( val, function( value ) {
8246 return value == null ? "" : value + "";
8247 } );
8248 }
8249
8250 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
8251
8252 // If set returns undefined, fall back to normal setting
8253 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
8254 this.value = val;
8255 }
8256 } );
8257 }
8258} );
8259
8260jQuery.extend( {
8261 valHooks: {
8262 option: {
8263 get: function( elem ) {
8264 var val = jQuery.find.attr( elem, "value" );
8265 return val != null ?
8266 val :
8267
8268 // Support: IE10-11+
8269 // option.text throws exceptions (#14686, #14858)
8270 // Strip and collapse whitespace
8271 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
8272 jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
8273 }
8274 },
8275 select: {
8276 get: function( elem ) {
8277 var value, option,
8278 options = elem.options,
8279 index = elem.selectedIndex,
8280 one = elem.type === "select-one" || index < 0,
8281 values = one ? null : [],
8282 max = one ? index + 1 : options.length,
8283 i = index < 0 ?
8284 max :
8285 one ? index : 0;
8286
8287 // Loop through all the selected options
8288 for ( ; i < max; i++ ) {
8289 option = options[ i ];
8290
8291 // oldIE doesn't update selected after form reset (#2551)
8292 if ( ( option.selected || i === index ) &&
8293
8294 // Don't return options that are disabled or in a disabled optgroup
8295 ( support.optDisabled ?
8296 !option.disabled :
8297 option.getAttribute( "disabled" ) === null ) &&
8298 ( !option.parentNode.disabled ||
8299 !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
8300
8301 // Get the specific value for the option
8302 value = jQuery( option ).val();
8303
8304 // We don't need an array for one selects
8305 if ( one ) {
8306 return value;
8307 }
8308
8309 // Multi-Selects return an array
8310 values.push( value );
8311 }
8312 }
8313
8314 return values;
8315 },
8316
8317 set: function( elem, value ) {
8318 var optionSet, option,
8319 options = elem.options,
8320 values = jQuery.makeArray( value ),
8321 i = options.length;
8322
8323 while ( i-- ) {
8324 option = options[ i ];
8325
8326 if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 ) {
8327
8328 // Support: IE6
8329 // When new option element is added to select box we need to
8330 // force reflow of newly added node in order to workaround delay
8331 // of initialization properties
8332 try {
8333 option.selected = optionSet = true;
8334
8335 } catch ( _ ) {
8336
8337 // Will be executed only in IE6
8338 option.scrollHeight;
8339 }
8340
8341 } else {
8342 option.selected = false;
8343 }
8344 }
8345
8346 // Force browsers to behave consistently when non-matching value is set
8347 if ( !optionSet ) {
8348 elem.selectedIndex = -1;
8349 }
8350
8351 return options;
8352 }
8353 }
8354 }
8355} );
8356
8357// Radios and checkboxes getter/setter
8358jQuery.each( [ "radio", "checkbox" ], function() {
8359 jQuery.valHooks[ this ] = {
8360 set: function( elem, value ) {
8361 if ( jQuery.isArray( value ) ) {
8362 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
8363 }
8364 }
8365 };
8366 if ( !support.checkOn ) {
8367 jQuery.valHooks[ this ].get = function( elem ) {
8368 return elem.getAttribute( "value" ) === null ? "on" : elem.value;
8369 };
8370 }
8371} );
8372
8373
8374
8375
8376var nodeHook, boolHook,
8377 attrHandle = jQuery.expr.attrHandle,
8378 ruseDefault = /^(?:checked|selected)$/i,
8379 getSetAttribute = support.getSetAttribute,
8380 getSetInput = support.input;
8381
8382jQuery.fn.extend( {
8383 attr: function( name, value ) {
8384 return access( this, jQuery.attr, name, value, arguments.length > 1 );
8385 },
8386
8387 removeAttr: function( name ) {
8388 return this.each( function() {
8389 jQuery.removeAttr( this, name );
8390 } );
8391 }
8392} );
8393
8394jQuery.extend( {
8395 attr: function( elem, name, value ) {
8396 var ret, hooks,
8397 nType = elem.nodeType;
8398
8399 // Don't get/set attributes on text, comment and attribute nodes
8400 if ( nType === 3 || nType === 8 || nType === 2 ) {
8401 return;
8402 }
8403
8404 // Fallback to prop when attributes are not supported
8405 if ( typeof elem.getAttribute === "undefined" ) {
8406 return jQuery.prop( elem, name, value );
8407 }
8408
8409 // All attributes are lowercase
8410 // Grab necessary hook if one is defined
8411 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8412 name = name.toLowerCase();
8413 hooks = jQuery.attrHooks[ name ] ||
8414 ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
8415 }
8416
8417 if ( value !== undefined ) {
8418 if ( value === null ) {
8419 jQuery.removeAttr( elem, name );
8420 return;
8421 }
8422
8423 if ( hooks && "set" in hooks &&
8424 ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8425 return ret;
8426 }
8427
8428 elem.setAttribute( name, value + "" );
8429 return value;
8430 }
8431
8432 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8433 return ret;
8434 }
8435
8436 ret = jQuery.find.attr( elem, name );
8437
8438 // Non-existent attributes return null, we normalize to undefined
8439 return ret == null ? undefined : ret;
8440 },
8441
8442 attrHooks: {
8443 type: {
8444 set: function( elem, value ) {
8445 if ( !support.radioValue && value === "radio" &&
8446 jQuery.nodeName( elem, "input" ) ) {
8447
8448 // Setting the type on a radio button after the value resets the value in IE8-9
8449 // Reset value to default in case type is set after value during creation
8450 var val = elem.value;
8451 elem.setAttribute( "type", value );
8452 if ( val ) {
8453 elem.value = val;
8454 }
8455 return value;
8456 }
8457 }
8458 }
8459 },
8460
8461 removeAttr: function( elem, value ) {
8462 var name, propName,
8463 i = 0,
8464 attrNames = value && value.match( rnotwhite );
8465
8466 if ( attrNames && elem.nodeType === 1 ) {
8467 while ( ( name = attrNames[ i++ ] ) ) {
8468 propName = jQuery.propFix[ name ] || name;
8469
8470 // Boolean attributes get special treatment (#10870)
8471 if ( jQuery.expr.match.bool.test( name ) ) {
8472
8473 // Set corresponding property to false
8474 if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8475 elem[ propName ] = false;
8476
8477 // Support: IE<9
8478 // Also clear defaultChecked/defaultSelected (if appropriate)
8479 } else {
8480 elem[ jQuery.camelCase( "default-" + name ) ] =
8481 elem[ propName ] = false;
8482 }
8483
8484 // See #9699 for explanation of this approach (setting first, then removal)
8485 } else {
8486 jQuery.attr( elem, name, "" );
8487 }
8488
8489 elem.removeAttribute( getSetAttribute ? name : propName );
8490 }
8491 }
8492 }
8493} );
8494
8495// Hooks for boolean attributes
8496boolHook = {
8497 set: function( elem, value, name ) {
8498 if ( value === false ) {
8499
8500 // Remove boolean attributes when set to false
8501 jQuery.removeAttr( elem, name );
8502 } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8503
8504 // IE<8 needs the *property* name
8505 elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
8506
8507 } else {
8508
8509 // Support: IE<9
8510 // Use defaultChecked and defaultSelected for oldIE
8511 elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
8512 }
8513 return name;
8514 }
8515};
8516
8517jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
8518 var getter = attrHandle[ name ] || jQuery.find.attr;
8519
8520 if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8521 attrHandle[ name ] = function( elem, name, isXML ) {
8522 var ret, handle;
8523 if ( !isXML ) {
8524
8525 // Avoid an infinite loop by temporarily removing this function from the getter
8526 handle = attrHandle[ name ];
8527 attrHandle[ name ] = ret;
8528 ret = getter( elem, name, isXML ) != null ?
8529 name.toLowerCase() :
8530 null;
8531 attrHandle[ name ] = handle;
8532 }
8533 return ret;
8534 };
8535 } else {
8536 attrHandle[ name ] = function( elem, name, isXML ) {
8537 if ( !isXML ) {
8538 return elem[ jQuery.camelCase( "default-" + name ) ] ?
8539 name.toLowerCase() :
8540 null;
8541 }
8542 };
8543 }
8544} );
8545
8546// fix oldIE attroperties
8547if ( !getSetInput || !getSetAttribute ) {
8548 jQuery.attrHooks.value = {
8549 set: function( elem, value, name ) {
8550 if ( jQuery.nodeName( elem, "input" ) ) {
8551
8552 // Does not return so that setAttribute is also used
8553 elem.defaultValue = value;
8554 } else {
8555
8556 // Use nodeHook if defined (#1954); otherwise setAttribute is fine
8557 return nodeHook && nodeHook.set( elem, value, name );
8558 }
8559 }
8560 };
8561}
8562
8563// IE6/7 do not support getting/setting some attributes with get/setAttribute
8564if ( !getSetAttribute ) {
8565
8566 // Use this for any attribute in IE6/7
8567 // This fixes almost every IE6/7 issue
8568 nodeHook = {
8569 set: function( elem, value, name ) {
8570
8571 // Set the existing or create a new attribute node
8572 var ret = elem.getAttributeNode( name );
8573 if ( !ret ) {
8574 elem.setAttributeNode(
8575 ( ret = elem.ownerDocument.createAttribute( name ) )
8576 );
8577 }
8578
8579 ret.value = value += "";
8580
8581 // Break association with cloned elements by also using setAttribute (#9646)
8582 if ( name === "value" || value === elem.getAttribute( name ) ) {
8583 return value;
8584 }
8585 }
8586 };
8587
8588 // Some attributes are constructed with empty-string values when not defined
8589 attrHandle.id = attrHandle.name = attrHandle.coords =
8590 function( elem, name, isXML ) {
8591 var ret;
8592 if ( !isXML ) {
8593 return ( ret = elem.getAttributeNode( name ) ) && ret.value !== "" ?
8594 ret.value :
8595 null;
8596 }
8597 };
8598
8599 // Fixing value retrieval on a button requires this module
8600 jQuery.valHooks.button = {
8601 get: function( elem, name ) {
8602 var ret = elem.getAttributeNode( name );
8603 if ( ret && ret.specified ) {
8604 return ret.value;
8605 }
8606 },
8607 set: nodeHook.set
8608 };
8609
8610 // Set contenteditable to false on removals(#10429)
8611 // Setting to empty string throws an error as an invalid value
8612 jQuery.attrHooks.contenteditable = {
8613 set: function( elem, value, name ) {
8614 nodeHook.set( elem, value === "" ? false : value, name );
8615 }
8616 };
8617
8618 // Set width and height to auto instead of 0 on empty string( Bug #8150 )
8619 // This is for removals
8620 jQuery.each( [ "width", "height" ], function( i, name ) {
8621 jQuery.attrHooks[ name ] = {
8622 set: function( elem, value ) {
8623 if ( value === "" ) {
8624 elem.setAttribute( name, "auto" );
8625 return value;
8626 }
8627 }
8628 };
8629 } );
8630}
8631
8632if ( !support.style ) {
8633 jQuery.attrHooks.style = {
8634 get: function( elem ) {
8635
8636 // Return undefined in the case of empty string
8637 // Note: IE uppercases css property names, but if we were to .toLowerCase()
8638 // .cssText, that would destroy case sensitivity in URL's, like in "background"
8639 return elem.style.cssText || undefined;
8640 },
8641 set: function( elem, value ) {
8642 return ( elem.style.cssText = value + "" );
8643 }
8644 };
8645}
8646
8647
8648
8649
8650var rfocusable = /^(?:input|select|textarea|button|object)$/i,
8651 rclickable = /^(?:a|area)$/i;
8652
8653jQuery.fn.extend( {
8654 prop: function( name, value ) {
8655 return access( this, jQuery.prop, name, value, arguments.length > 1 );
8656 },
8657
8658 removeProp: function( name ) {
8659 name = jQuery.propFix[ name ] || name;
8660 return this.each( function() {
8661
8662 // try/catch handles cases where IE balks (such as removing a property on window)
8663 try {
8664 this[ name ] = undefined;
8665 delete this[ name ];
8666 } catch ( e ) {}
8667 } );
8668 }
8669} );
8670
8671jQuery.extend( {
8672 prop: function( elem, name, value ) {
8673 var ret, hooks,
8674 nType = elem.nodeType;
8675
8676 // Don't get/set properties on text, comment and attribute nodes
8677 if ( nType === 3 || nType === 8 || nType === 2 ) {
8678 return;
8679 }
8680
8681 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8682
8683 // Fix name and attach hooks
8684 name = jQuery.propFix[ name ] || name;
8685 hooks = jQuery.propHooks[ name ];
8686 }
8687
8688 if ( value !== undefined ) {
8689 if ( hooks && "set" in hooks &&
8690 ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8691 return ret;
8692 }
8693
8694 return ( elem[ name ] = value );
8695 }
8696
8697 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8698 return ret;
8699 }
8700
8701 return elem[ name ];
8702 },
8703
8704 propHooks: {
8705 tabIndex: {
8706 get: function( elem ) {
8707
8708 // elem.tabIndex doesn't always return the
8709 // correct value when it hasn't been explicitly set
8710 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
8711 // Use proper attribute retrieval(#12072)
8712 var tabindex = jQuery.find.attr( elem, "tabindex" );
8713
8714 return tabindex ?
8715 parseInt( tabindex, 10 ) :
8716 rfocusable.test( elem.nodeName ) ||
8717 rclickable.test( elem.nodeName ) && elem.href ?
8718 0 :
8719 -1;
8720 }
8721 }
8722 },
8723
8724 propFix: {
8725 "for": "htmlFor",
8726 "class": "className"
8727 }
8728} );
8729
8730// Some attributes require a special call on IE
8731// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
8732if ( !support.hrefNormalized ) {
8733
8734 // href/src property should get the full normalized URL (#10299/#12915)
8735 jQuery.each( [ "href", "src" ], function( i, name ) {
8736 jQuery.propHooks[ name ] = {
8737 get: function( elem ) {
8738 return elem.getAttribute( name, 4 );
8739 }
8740 };
8741 } );
8742}
8743
8744// Support: Safari, IE9+
8745// Accessing the selectedIndex property
8746// forces the browser to respect setting selected
8747// on the option
8748// The getter ensures a default option is selected
8749// when in an optgroup
8750if ( !support.optSelected ) {
8751 jQuery.propHooks.selected = {
8752 get: function( elem ) {
8753 var parent = elem.parentNode;
8754
8755 if ( parent ) {
8756 parent.selectedIndex;
8757
8758 // Make sure that it also works with optgroups, see #5701
8759 if ( parent.parentNode ) {
8760 parent.parentNode.selectedIndex;
8761 }
8762 }
8763 return null;
8764 },
8765 set: function( elem ) {
8766 var parent = elem.parentNode;
8767 if ( parent ) {
8768 parent.selectedIndex;
8769
8770 if ( parent.parentNode ) {
8771 parent.parentNode.selectedIndex;
8772 }
8773 }
8774 }
8775 };
8776}
8777
8778jQuery.each( [
8779 "tabIndex",
8780 "readOnly",
8781 "maxLength",
8782 "cellSpacing",
8783 "cellPadding",
8784 "rowSpan",
8785 "colSpan",
8786 "useMap",
8787 "frameBorder",
8788 "contentEditable"
8789], function() {
8790 jQuery.propFix[ this.toLowerCase() ] = this;
8791} );
8792
8793// IE6/7 call enctype encoding
8794if ( !support.enctype ) {
8795 jQuery.propFix.enctype = "encoding";
8796}
8797
8798
8799
8800
8801var rclass = /[\t\r\n\f]/g;
8802
8803function getClass( elem ) {
8804 return jQuery.attr( elem, "class" ) || "";
8805}
8806
8807jQuery.fn.extend( {
8808 addClass: function( value ) {
8809 var classes, elem, cur, curValue, clazz, j, finalValue,
8810 i = 0;
8811
8812 if ( jQuery.isFunction( value ) ) {
8813 return this.each( function( j ) {
8814 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
8815 } );
8816 }
8817
8818 if ( typeof value === "string" && value ) {
8819 classes = value.match( rnotwhite ) || [];
8820
8821 while ( ( elem = this[ i++ ] ) ) {
8822 curValue = getClass( elem );
8823 cur = elem.nodeType === 1 &&
8824 ( " " + curValue + " " ).replace( rclass, " " );
8825
8826 if ( cur ) {
8827 j = 0;
8828 while ( ( clazz = classes[ j++ ] ) ) {
8829 if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
8830 cur += clazz + " ";
8831 }
8832 }
8833
8834 // only assign if different to avoid unneeded rendering.
8835 finalValue = jQuery.trim( cur );
8836 if ( curValue !== finalValue ) {
8837 jQuery.attr( elem, "class", finalValue );
8838 }
8839 }
8840 }
8841 }
8842
8843 return this;
8844 },
8845
8846 removeClass: function( value ) {
8847 var classes, elem, cur, curValue, clazz, j, finalValue,
8848 i = 0;
8849
8850 if ( jQuery.isFunction( value ) ) {
8851 return this.each( function( j ) {
8852 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
8853 } );
8854 }
8855
8856 if ( !arguments.length ) {
8857 return this.attr( "class", "" );
8858 }
8859
8860 if ( typeof value === "string" && value ) {
8861 classes = value.match( rnotwhite ) || [];
8862
8863 while ( ( elem = this[ i++ ] ) ) {
8864 curValue = getClass( elem );
8865
8866 // This expression is here for better compressibility (see addClass)
8867 cur = elem.nodeType === 1 &&
8868 ( " " + curValue + " " ).replace( rclass, " " );
8869
8870 if ( cur ) {
8871 j = 0;
8872 while ( ( clazz = classes[ j++ ] ) ) {
8873
8874 // Remove *all* instances
8875 while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
8876 cur = cur.replace( " " + clazz + " ", " " );
8877 }
8878 }
8879
8880 // Only assign if different to avoid unneeded rendering.
8881 finalValue = jQuery.trim( cur );
8882 if ( curValue !== finalValue ) {
8883 jQuery.attr( elem, "class", finalValue );
8884 }
8885 }
8886 }
8887 }
8888
8889 return this;
8890 },
8891
8892 toggleClass: function( value, stateVal ) {
8893 var type = typeof value;
8894
8895 if ( typeof stateVal === "boolean" && type === "string" ) {
8896 return stateVal ? this.addClass( value ) : this.removeClass( value );
8897 }
8898
8899 if ( jQuery.isFunction( value ) ) {
8900 return this.each( function( i ) {
8901 jQuery( this ).toggleClass(
8902 value.call( this, i, getClass( this ), stateVal ),
8903 stateVal
8904 );
8905 } );
8906 }
8907
8908 return this.each( function() {
8909 var className, i, self, classNames;
8910
8911 if ( type === "string" ) {
8912
8913 // Toggle individual class names
8914 i = 0;
8915 self = jQuery( this );
8916 classNames = value.match( rnotwhite ) || [];
8917
8918 while ( ( className = classNames[ i++ ] ) ) {
8919
8920 // Check each className given, space separated list
8921 if ( self.hasClass( className ) ) {
8922 self.removeClass( className );
8923 } else {
8924 self.addClass( className );
8925 }
8926 }
8927
8928 // Toggle whole class name
8929 } else if ( value === undefined || type === "boolean" ) {
8930 className = getClass( this );
8931 if ( className ) {
8932
8933 // store className if set
8934 jQuery._data( this, "__className__", className );
8935 }
8936
8937 // If the element has a class name or if we're passed "false",
8938 // then remove the whole classname (if there was one, the above saved it).
8939 // Otherwise bring back whatever was previously saved (if anything),
8940 // falling back to the empty string if nothing was stored.
8941 jQuery.attr( this, "class",
8942 className || value === false ?
8943 "" :
8944 jQuery._data( this, "__className__" ) || ""
8945 );
8946 }
8947 } );
8948 },
8949
8950 hasClass: function( selector ) {
8951 var className, elem,
8952 i = 0;
8953
8954 className = " " + selector + " ";
8955 while ( ( elem = this[ i++ ] ) ) {
8956 if ( elem.nodeType === 1 &&
8957 ( " " + getClass( elem ) + " " ).replace( rclass, " " )
8958 .indexOf( className ) > -1
8959 ) {
8960 return true;
8961 }
8962 }
8963
8964 return false;
8965 }
8966} );
8967
8968
8969
8970
8971// Return jQuery for attributes-only inclusion
8972
8973
8974jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
8975 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
8976 "change select submit keydown keypress keyup error contextmenu" ).split( " " ),
8977 function( i, name ) {
8978
8979 // Handle event binding
8980 jQuery.fn[ name ] = function( data, fn ) {
8981 return arguments.length > 0 ?
8982 this.on( name, null, data, fn ) :
8983 this.trigger( name );
8984 };
8985} );
8986
8987jQuery.fn.extend( {
8988 hover: function( fnOver, fnOut ) {
8989 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
8990 }
8991} );
8992
8993
8994var location = window.location;
8995
8996var nonce = jQuery.now();
8997
8998var rquery = ( /\?/ );
8999
9000
9001
9002var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
9003
9004jQuery.parseJSON = function( data ) {
9005
9006 // Attempt to parse using the native JSON parser first
9007 if ( window.JSON && window.JSON.parse ) {
9008
9009 // Support: Android 2.3
9010 // Workaround failure to string-cast null input
9011 return window.JSON.parse( data + "" );
9012 }
9013
9014 var requireNonComma,
9015 depth = null,
9016 str = jQuery.trim( data + "" );
9017
9018 // Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
9019 // after removing valid tokens
9020 return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {
9021
9022 // Force termination if we see a misplaced comma
9023 if ( requireNonComma && comma ) {
9024 depth = 0;
9025 }
9026
9027 // Perform no more replacements after returning to outermost depth
9028 if ( depth === 0 ) {
9029 return token;
9030 }
9031
9032 // Commas must not follow "[", "{", or ","
9033 requireNonComma = open || comma;
9034
9035 // Determine new depth
9036 // array/object open ("[" or "{"): depth += true - false (increment)
9037 // array/object close ("]" or "}"): depth += false - true (decrement)
9038 // other cases ("," or primitive): depth += true - true (numeric cast)
9039 depth += !close - !open;
9040
9041 // Remove this token
9042 return "";
9043 } ) ) ?
9044 ( Function( "return " + str ) )() :
9045 jQuery.error( "Invalid JSON: " + data );
9046};
9047
9048
9049// Cross-browser xml parsing
9050jQuery.parseXML = function( data ) {
9051 var xml, tmp;
9052 if ( !data || typeof data !== "string" ) {
9053 return null;
9054 }
9055 try {
9056 if ( window.DOMParser ) { // Standard
9057 tmp = new window.DOMParser();
9058 xml = tmp.parseFromString( data, "text/xml" );
9059 } else { // IE
9060 xml = new window.ActiveXObject( "Microsoft.XMLDOM" );
9061 xml.async = "false";
9062 xml.loadXML( data );
9063 }
9064 } catch ( e ) {
9065 xml = undefined;
9066 }
9067 if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
9068 jQuery.error( "Invalid XML: " + data );
9069 }
9070 return xml;
9071};
9072
9073
9074var
9075 rhash = /#.*$/,
9076 rts = /([?&])_=[^&]*/,
9077
9078 // IE leaves an \r character at EOL
9079 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg,
9080
9081 // #7653, #8125, #8152: local protocol detection
9082 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
9083 rnoContent = /^(?:GET|HEAD)$/,
9084 rprotocol = /^\/\//,
9085 rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
9086
9087 /* Prefilters
9088 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
9089 * 2) These are called:
9090 * - BEFORE asking for a transport
9091 * - AFTER param serialization (s.data is a string if s.processData is true)
9092 * 3) key is the dataType
9093 * 4) the catchall symbol "*" can be used
9094 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
9095 */
9096 prefilters = {},
9097
9098 /* Transports bindings
9099 * 1) key is the dataType
9100 * 2) the catchall symbol "*" can be used
9101 * 3) selection will start with transport dataType and THEN go to "*" if needed
9102 */
9103 transports = {},
9104
9105 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
9106 allTypes = "*/".concat( "*" ),
9107
9108 // Document location
9109 ajaxLocation = location.href,
9110
9111 // Segment location into parts
9112 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
9113
9114// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
9115function addToPrefiltersOrTransports( structure ) {
9116
9117 // dataTypeExpression is optional and defaults to "*"
9118 return function( dataTypeExpression, func ) {
9119
9120 if ( typeof dataTypeExpression !== "string" ) {
9121 func = dataTypeExpression;
9122 dataTypeExpression = "*";
9123 }
9124
9125 var dataType,
9126 i = 0,
9127 dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
9128
9129 if ( jQuery.isFunction( func ) ) {
9130
9131 // For each dataType in the dataTypeExpression
9132 while ( ( dataType = dataTypes[ i++ ] ) ) {
9133
9134 // Prepend if requested
9135 if ( dataType.charAt( 0 ) === "+" ) {
9136 dataType = dataType.slice( 1 ) || "*";
9137 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
9138
9139 // Otherwise append
9140 } else {
9141 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
9142 }
9143 }
9144 }
9145 };
9146}
9147
9148// Base inspection function for prefilters and transports
9149function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
9150
9151 var inspected = {},
9152 seekingTransport = ( structure === transports );
9153
9154 function inspect( dataType ) {
9155 var selected;
9156 inspected[ dataType ] = true;
9157 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
9158 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
9159 if ( typeof dataTypeOrTransport === "string" &&
9160 !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
9161
9162 options.dataTypes.unshift( dataTypeOrTransport );
9163 inspect( dataTypeOrTransport );
9164 return false;
9165 } else if ( seekingTransport ) {
9166 return !( selected = dataTypeOrTransport );
9167 }
9168 } );
9169 return selected;
9170 }
9171
9172 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
9173}
9174
9175// A special extend for ajax options
9176// that takes "flat" options (not to be deep extended)
9177// Fixes #9887
9178function ajaxExtend( target, src ) {
9179 var deep, key,
9180 flatOptions = jQuery.ajaxSettings.flatOptions || {};
9181
9182 for ( key in src ) {
9183 if ( src[ key ] !== undefined ) {
9184 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
9185 }
9186 }
9187 if ( deep ) {
9188 jQuery.extend( true, target, deep );
9189 }
9190
9191 return target;
9192}
9193
9194/* Handles responses to an ajax request:
9195 * - finds the right dataType (mediates between content-type and expected dataType)
9196 * - returns the corresponding response
9197 */
9198function ajaxHandleResponses( s, jqXHR, responses ) {
9199 var firstDataType, ct, finalDataType, type,
9200 contents = s.contents,
9201 dataTypes = s.dataTypes;
9202
9203 // Remove auto dataType and get content-type in the process
9204 while ( dataTypes[ 0 ] === "*" ) {
9205 dataTypes.shift();
9206 if ( ct === undefined ) {
9207 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
9208 }
9209 }
9210
9211 // Check if we're dealing with a known content-type
9212 if ( ct ) {
9213 for ( type in contents ) {
9214 if ( contents[ type ] && contents[ type ].test( ct ) ) {
9215 dataTypes.unshift( type );
9216 break;
9217 }
9218 }
9219 }
9220
9221 // Check to see if we have a response for the expected dataType
9222 if ( dataTypes[ 0 ] in responses ) {
9223 finalDataType = dataTypes[ 0 ];
9224 } else {
9225
9226 // Try convertible dataTypes
9227 for ( type in responses ) {
9228 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
9229 finalDataType = type;
9230 break;
9231 }
9232 if ( !firstDataType ) {
9233 firstDataType = type;
9234 }
9235 }
9236
9237 // Or just use first one
9238 finalDataType = finalDataType || firstDataType;
9239 }
9240
9241 // If we found a dataType
9242 // We add the dataType to the list if needed
9243 // and return the corresponding response
9244 if ( finalDataType ) {
9245 if ( finalDataType !== dataTypes[ 0 ] ) {
9246 dataTypes.unshift( finalDataType );
9247 }
9248 return responses[ finalDataType ];
9249 }
9250}
9251
9252/* Chain conversions given the request and the original response
9253 * Also sets the responseXXX fields on the jqXHR instance
9254 */
9255function ajaxConvert( s, response, jqXHR, isSuccess ) {
9256 var conv2, current, conv, tmp, prev,
9257 converters = {},
9258
9259 // Work with a copy of dataTypes in case we need to modify it for conversion
9260 dataTypes = s.dataTypes.slice();
9261
9262 // Create converters map with lowercased keys
9263 if ( dataTypes[ 1 ] ) {
9264 for ( conv in s.converters ) {
9265 converters[ conv.toLowerCase() ] = s.converters[ conv ];
9266 }
9267 }
9268
9269 current = dataTypes.shift();
9270
9271 // Convert to each sequential dataType
9272 while ( current ) {
9273
9274 if ( s.responseFields[ current ] ) {
9275 jqXHR[ s.responseFields[ current ] ] = response;
9276 }
9277
9278 // Apply the dataFilter if provided
9279 if ( !prev && isSuccess && s.dataFilter ) {
9280 response = s.dataFilter( response, s.dataType );
9281 }
9282
9283 prev = current;
9284 current = dataTypes.shift();
9285
9286 if ( current ) {
9287
9288 // There's only work to do if current dataType is non-auto
9289 if ( current === "*" ) {
9290
9291 current = prev;
9292
9293 // Convert response if prev dataType is non-auto and differs from current
9294 } else if ( prev !== "*" && prev !== current ) {
9295
9296 // Seek a direct converter
9297 conv = converters[ prev + " " + current ] || converters[ "* " + current ];
9298
9299 // If none found, seek a pair
9300 if ( !conv ) {
9301 for ( conv2 in converters ) {
9302
9303 // If conv2 outputs current
9304 tmp = conv2.split( " " );
9305 if ( tmp[ 1 ] === current ) {
9306
9307 // If prev can be converted to accepted input
9308 conv = converters[ prev + " " + tmp[ 0 ] ] ||
9309 converters[ "* " + tmp[ 0 ] ];
9310 if ( conv ) {
9311
9312 // Condense equivalence converters
9313 if ( conv === true ) {
9314 conv = converters[ conv2 ];
9315
9316 // Otherwise, insert the intermediate dataType
9317 } else if ( converters[ conv2 ] !== true ) {
9318 current = tmp[ 0 ];
9319 dataTypes.unshift( tmp[ 1 ] );
9320 }
9321 break;
9322 }
9323 }
9324 }
9325 }
9326
9327 // Apply converter (if not an equivalence)
9328 if ( conv !== true ) {
9329
9330 // Unless errors are allowed to bubble, catch and return them
9331 if ( conv && s[ "throws" ] ) { // jscs:ignore requireDotNotation
9332 response = conv( response );
9333 } else {
9334 try {
9335 response = conv( response );
9336 } catch ( e ) {
9337 return {
9338 state: "parsererror",
9339 error: conv ? e : "No conversion from " + prev + " to " + current
9340 };
9341 }
9342 }
9343 }
9344 }
9345 }
9346 }
9347
9348 return { state: "success", data: response };
9349}
9350
9351jQuery.extend( {
9352
9353 // Counter for holding the number of active queries
9354 active: 0,
9355
9356 // Last-Modified header cache for next request
9357 lastModified: {},
9358 etag: {},
9359
9360 ajaxSettings: {
9361 url: ajaxLocation,
9362 type: "GET",
9363 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
9364 global: true,
9365 processData: true,
9366 async: true,
9367 contentType: "application/x-www-form-urlencoded; charset=UTF-8",
9368 /*
9369 timeout: 0,
9370 data: null,
9371 dataType: null,
9372 username: null,
9373 password: null,
9374 cache: null,
9375 throws: false,
9376 traditional: false,
9377 headers: {},
9378 */
9379
9380 accepts: {
9381 "*": allTypes,
9382 text: "text/plain",
9383 html: "text/html",
9384 xml: "application/xml, text/xml",
9385 json: "application/json, text/javascript"
9386 },
9387
9388 contents: {
9389 xml: /\bxml\b/,
9390 html: /\bhtml/,
9391 json: /\bjson\b/
9392 },
9393
9394 responseFields: {
9395 xml: "responseXML",
9396 text: "responseText",
9397 json: "responseJSON"
9398 },
9399
9400 // Data converters
9401 // Keys separate source (or catchall "*") and destination types with a single space
9402 converters: {
9403
9404 // Convert anything to text
9405 "* text": String,
9406
9407 // Text to html (true = no transformation)
9408 "text html": true,
9409
9410 // Evaluate text as a json expression
9411 "text json": jQuery.parseJSON,
9412
9413 // Parse text as xml
9414 "text xml": jQuery.parseXML
9415 },
9416
9417 // For options that shouldn't be deep extended:
9418 // you can add your own custom options here if
9419 // and when you create one that shouldn't be
9420 // deep extended (see ajaxExtend)
9421 flatOptions: {
9422 url: true,
9423 context: true
9424 }
9425 },
9426
9427 // Creates a full fledged settings object into target
9428 // with both ajaxSettings and settings fields.
9429 // If target is omitted, writes into ajaxSettings.
9430 ajaxSetup: function( target, settings ) {
9431 return settings ?
9432
9433 // Building a settings object
9434 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
9435
9436 // Extending ajaxSettings
9437 ajaxExtend( jQuery.ajaxSettings, target );
9438 },
9439
9440 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
9441 ajaxTransport: addToPrefiltersOrTransports( transports ),
9442
9443 // Main method
9444 ajax: function( url, options ) {
9445
9446 // If url is an object, simulate pre-1.5 signature
9447 if ( typeof url === "object" ) {
9448 options = url;
9449 url = undefined;
9450 }
9451
9452 // Force options to be an object
9453 options = options || {};
9454
9455 var
9456
9457 // Cross-domain detection vars
9458 parts,
9459
9460 // Loop variable
9461 i,
9462
9463 // URL without anti-cache param
9464 cacheURL,
9465
9466 // Response headers as string
9467 responseHeadersString,
9468
9469 // timeout handle
9470 timeoutTimer,
9471
9472 // To know if global events are to be dispatched
9473 fireGlobals,
9474
9475 transport,
9476
9477 // Response headers
9478 responseHeaders,
9479
9480 // Create the final options object
9481 s = jQuery.ajaxSetup( {}, options ),
9482
9483 // Callbacks context
9484 callbackContext = s.context || s,
9485
9486 // Context for global events is callbackContext if it is a DOM node or jQuery collection
9487 globalEventContext = s.context &&
9488 ( callbackContext.nodeType || callbackContext.jquery ) ?
9489 jQuery( callbackContext ) :
9490 jQuery.event,
9491
9492 // Deferreds
9493 deferred = jQuery.Deferred(),
9494 completeDeferred = jQuery.Callbacks( "once memory" ),
9495
9496 // Status-dependent callbacks
9497 statusCode = s.statusCode || {},
9498
9499 // Headers (they are sent all at once)
9500 requestHeaders = {},
9501 requestHeadersNames = {},
9502
9503 // The jqXHR state
9504 state = 0,
9505
9506 // Default abort message
9507 strAbort = "canceled",
9508
9509 // Fake xhr
9510 jqXHR = {
9511 readyState: 0,
9512
9513 // Builds headers hashtable if needed
9514 getResponseHeader: function( key ) {
9515 var match;
9516 if ( state === 2 ) {
9517 if ( !responseHeaders ) {
9518 responseHeaders = {};
9519 while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
9520 responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
9521 }
9522 }
9523 match = responseHeaders[ key.toLowerCase() ];
9524 }
9525 return match == null ? null : match;
9526 },
9527
9528 // Raw string
9529 getAllResponseHeaders: function() {
9530 return state === 2 ? responseHeadersString : null;
9531 },
9532
9533 // Caches the header
9534 setRequestHeader: function( name, value ) {
9535 var lname = name.toLowerCase();
9536 if ( !state ) {
9537 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
9538 requestHeaders[ name ] = value;
9539 }
9540 return this;
9541 },
9542
9543 // Overrides response content-type header
9544 overrideMimeType: function( type ) {
9545 if ( !state ) {
9546 s.mimeType = type;
9547 }
9548 return this;
9549 },
9550
9551 // Status-dependent callbacks
9552 statusCode: function( map ) {
9553 var code;
9554 if ( map ) {
9555 if ( state < 2 ) {
9556 for ( code in map ) {
9557
9558 // Lazy-add the new callback in a way that preserves old ones
9559 statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
9560 }
9561 } else {
9562
9563 // Execute the appropriate callbacks
9564 jqXHR.always( map[ jqXHR.status ] );
9565 }
9566 }
9567 return this;
9568 },
9569
9570 // Cancel the request
9571 abort: function( statusText ) {
9572 var finalText = statusText || strAbort;
9573 if ( transport ) {
9574 transport.abort( finalText );
9575 }
9576 done( 0, finalText );
9577 return this;
9578 }
9579 };
9580
9581 // Attach deferreds
9582 deferred.promise( jqXHR ).complete = completeDeferred.add;
9583 jqXHR.success = jqXHR.done;
9584 jqXHR.error = jqXHR.fail;
9585
9586 // Remove hash character (#7531: and string promotion)
9587 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
9588 // Handle falsy url in the settings object (#10093: consistency with old signature)
9589 // We also use the url parameter if available
9590 s.url = ( ( url || s.url || ajaxLocation ) + "" )
9591 .replace( rhash, "" )
9592 .replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
9593
9594 // Alias method option to type as per ticket #12004
9595 s.type = options.method || options.type || s.method || s.type;
9596
9597 // Extract dataTypes list
9598 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
9599
9600 // A cross-domain request is in order when we have a protocol:host:port mismatch
9601 if ( s.crossDomain == null ) {
9602 parts = rurl.exec( s.url.toLowerCase() );
9603 s.crossDomain = !!( parts &&
9604 ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
9605 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
9606 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
9607 );
9608 }
9609
9610 // Convert data if not already a string
9611 if ( s.data && s.processData && typeof s.data !== "string" ) {
9612 s.data = jQuery.param( s.data, s.traditional );
9613 }
9614
9615 // Apply prefilters
9616 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
9617
9618 // If request was aborted inside a prefilter, stop there
9619 if ( state === 2 ) {
9620 return jqXHR;
9621 }
9622
9623 // We can fire global events as of now if asked to
9624 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
9625 fireGlobals = jQuery.event && s.global;
9626
9627 // Watch for a new set of requests
9628 if ( fireGlobals && jQuery.active++ === 0 ) {
9629 jQuery.event.trigger( "ajaxStart" );
9630 }
9631
9632 // Uppercase the type
9633 s.type = s.type.toUpperCase();
9634
9635 // Determine if request has content
9636 s.hasContent = !rnoContent.test( s.type );
9637
9638 // Save the URL in case we're toying with the If-Modified-Since
9639 // and/or If-None-Match header later on
9640 cacheURL = s.url;
9641
9642 // More options handling for requests with no content
9643 if ( !s.hasContent ) {
9644
9645 // If data is available, append data to url
9646 if ( s.data ) {
9647 cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
9648
9649 // #9682: remove data so that it's not used in an eventual retry
9650 delete s.data;
9651 }
9652
9653 // Add anti-cache in url if needed
9654 if ( s.cache === false ) {
9655 s.url = rts.test( cacheURL ) ?
9656
9657 // If there is already a '_' parameter, set its value
9658 cacheURL.replace( rts, "$1_=" + nonce++ ) :
9659
9660 // Otherwise add one to the end
9661 cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
9662 }
9663 }
9664
9665 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9666 if ( s.ifModified ) {
9667 if ( jQuery.lastModified[ cacheURL ] ) {
9668 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
9669 }
9670 if ( jQuery.etag[ cacheURL ] ) {
9671 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
9672 }
9673 }
9674
9675 // Set the correct header, if data is being sent
9676 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
9677 jqXHR.setRequestHeader( "Content-Type", s.contentType );
9678 }
9679
9680 // Set the Accepts header for the server, depending on the dataType
9681 jqXHR.setRequestHeader(
9682 "Accept",
9683 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
9684 s.accepts[ s.dataTypes[ 0 ] ] +
9685 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
9686 s.accepts[ "*" ]
9687 );
9688
9689 // Check for headers option
9690 for ( i in s.headers ) {
9691 jqXHR.setRequestHeader( i, s.headers[ i ] );
9692 }
9693
9694 // Allow custom headers/mimetypes and early abort
9695 if ( s.beforeSend &&
9696 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
9697
9698 // Abort if not done already and return
9699 return jqXHR.abort();
9700 }
9701
9702 // aborting is no longer a cancellation
9703 strAbort = "abort";
9704
9705 // Install callbacks on deferreds
9706 for ( i in { success: 1, error: 1, complete: 1 } ) {
9707 jqXHR[ i ]( s[ i ] );
9708 }
9709
9710 // Get transport
9711 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
9712
9713 // If no transport, we auto-abort
9714 if ( !transport ) {
9715 done( -1, "No Transport" );
9716 } else {
9717 jqXHR.readyState = 1;
9718
9719 // Send global event
9720 if ( fireGlobals ) {
9721 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
9722 }
9723
9724 // If request was aborted inside ajaxSend, stop there
9725 if ( state === 2 ) {
9726 return jqXHR;
9727 }
9728
9729 // Timeout
9730 if ( s.async && s.timeout > 0 ) {
9731 timeoutTimer = window.setTimeout( function() {
9732 jqXHR.abort( "timeout" );
9733 }, s.timeout );
9734 }
9735
9736 try {
9737 state = 1;
9738 transport.send( requestHeaders, done );
9739 } catch ( e ) {
9740
9741 // Propagate exception as error if not done
9742 if ( state < 2 ) {
9743 done( -1, e );
9744
9745 // Simply rethrow otherwise
9746 } else {
9747 throw e;
9748 }
9749 }
9750 }
9751
9752 // Callback for when everything is done
9753 function done( status, nativeStatusText, responses, headers ) {
9754 var isSuccess, success, error, response, modified,
9755 statusText = nativeStatusText;
9756
9757 // Called once
9758 if ( state === 2 ) {
9759 return;
9760 }
9761
9762 // State is "done" now
9763 state = 2;
9764
9765 // Clear timeout if it exists
9766 if ( timeoutTimer ) {
9767 window.clearTimeout( timeoutTimer );
9768 }
9769
9770 // Dereference transport for early garbage collection
9771 // (no matter how long the jqXHR object will be used)
9772 transport = undefined;
9773
9774 // Cache response headers
9775 responseHeadersString = headers || "";
9776
9777 // Set readyState
9778 jqXHR.readyState = status > 0 ? 4 : 0;
9779
9780 // Determine if successful
9781 isSuccess = status >= 200 && status < 300 || status === 304;
9782
9783 // Get response data
9784 if ( responses ) {
9785 response = ajaxHandleResponses( s, jqXHR, responses );
9786 }
9787
9788 // Convert no matter what (that way responseXXX fields are always set)
9789 response = ajaxConvert( s, response, jqXHR, isSuccess );
9790
9791 // If successful, handle type chaining
9792 if ( isSuccess ) {
9793
9794 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9795 if ( s.ifModified ) {
9796 modified = jqXHR.getResponseHeader( "Last-Modified" );
9797 if ( modified ) {
9798 jQuery.lastModified[ cacheURL ] = modified;
9799 }
9800 modified = jqXHR.getResponseHeader( "etag" );
9801 if ( modified ) {
9802 jQuery.etag[ cacheURL ] = modified;
9803 }
9804 }
9805
9806 // if no content
9807 if ( status === 204 || s.type === "HEAD" ) {
9808 statusText = "nocontent";
9809
9810 // if not modified
9811 } else if ( status === 304 ) {
9812 statusText = "notmodified";
9813
9814 // If we have data, let's convert it
9815 } else {
9816 statusText = response.state;
9817 success = response.data;
9818 error = response.error;
9819 isSuccess = !error;
9820 }
9821 } else {
9822
9823 // We extract error from statusText
9824 // then normalize statusText and status for non-aborts
9825 error = statusText;
9826 if ( status || !statusText ) {
9827 statusText = "error";
9828 if ( status < 0 ) {
9829 status = 0;
9830 }
9831 }
9832 }
9833
9834 // Set data for the fake xhr object
9835 jqXHR.status = status;
9836 jqXHR.statusText = ( nativeStatusText || statusText ) + "";
9837
9838 // Success/Error
9839 if ( isSuccess ) {
9840 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
9841 } else {
9842 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
9843 }
9844
9845 // Status-dependent callbacks
9846 jqXHR.statusCode( statusCode );
9847 statusCode = undefined;
9848
9849 if ( fireGlobals ) {
9850 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
9851 [ jqXHR, s, isSuccess ? success : error ] );
9852 }
9853
9854 // Complete
9855 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
9856
9857 if ( fireGlobals ) {
9858 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
9859
9860 // Handle the global AJAX counter
9861 if ( !( --jQuery.active ) ) {
9862 jQuery.event.trigger( "ajaxStop" );
9863 }
9864 }
9865 }
9866
9867 return jqXHR;
9868 },
9869
9870 getJSON: function( url, data, callback ) {
9871 return jQuery.get( url, data, callback, "json" );
9872 },
9873
9874 getScript: function( url, callback ) {
9875 return jQuery.get( url, undefined, callback, "script" );
9876 }
9877} );
9878
9879jQuery.each( [ "get", "post" ], function( i, method ) {
9880 jQuery[ method ] = function( url, data, callback, type ) {
9881
9882 // shift arguments if data argument was omitted
9883 if ( jQuery.isFunction( data ) ) {
9884 type = type || callback;
9885 callback = data;
9886 data = undefined;
9887 }
9888
9889 // The url can be an options object (which then must have .url)
9890 return jQuery.ajax( jQuery.extend( {
9891 url: url,
9892 type: method,
9893 dataType: type,
9894 data: data,
9895 success: callback
9896 }, jQuery.isPlainObject( url ) && url ) );
9897 };
9898} );
9899
9900
9901jQuery._evalUrl = function( url ) {
9902 return jQuery.ajax( {
9903 url: url,
9904
9905 // Make this explicit, since user can override this through ajaxSetup (#11264)
9906 type: "GET",
9907 dataType: "script",
9908 cache: true,
9909 async: false,
9910 global: false,
9911 "throws": true
9912 } );
9913};
9914
9915
9916jQuery.fn.extend( {
9917 wrapAll: function( html ) {
9918 if ( jQuery.isFunction( html ) ) {
9919 return this.each( function( i ) {
9920 jQuery( this ).wrapAll( html.call( this, i ) );
9921 } );
9922 }
9923
9924 if ( this[ 0 ] ) {
9925
9926 // The elements to wrap the target around
9927 var wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
9928
9929 if ( this[ 0 ].parentNode ) {
9930 wrap.insertBefore( this[ 0 ] );
9931 }
9932
9933 wrap.map( function() {
9934 var elem = this;
9935
9936 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
9937 elem = elem.firstChild;
9938 }
9939
9940 return elem;
9941 } ).append( this );
9942 }
9943
9944 return this;
9945 },
9946
9947 wrapInner: function( html ) {
9948 if ( jQuery.isFunction( html ) ) {
9949 return this.each( function( i ) {
9950 jQuery( this ).wrapInner( html.call( this, i ) );
9951 } );
9952 }
9953
9954 return this.each( function() {
9955 var self = jQuery( this ),
9956 contents = self.contents();
9957
9958 if ( contents.length ) {
9959 contents.wrapAll( html );
9960
9961 } else {
9962 self.append( html );
9963 }
9964 } );
9965 },
9966
9967 wrap: function( html ) {
9968 var isFunction = jQuery.isFunction( html );
9969
9970 return this.each( function( i ) {
9971 jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
9972 } );
9973 },
9974
9975 unwrap: function() {
9976 return this.parent().each( function() {
9977 if ( !jQuery.nodeName( this, "body" ) ) {
9978 jQuery( this ).replaceWith( this.childNodes );
9979 }
9980 } ).end();
9981 }
9982} );
9983
9984
9985function getDisplay( elem ) {
9986 return elem.style && elem.style.display || jQuery.css( elem, "display" );
9987}
9988
9989function filterHidden( elem ) {
9990
9991 // Disconnected elements are considered hidden
9992 if ( !jQuery.contains( elem.ownerDocument || document, elem ) ) {
9993 return true;
9994 }
9995 while ( elem && elem.nodeType === 1 ) {
9996 if ( getDisplay( elem ) === "none" || elem.type === "hidden" ) {
9997 return true;
9998 }
9999 elem = elem.parentNode;
10000 }
10001 return false;
10002}
10003
10004jQuery.expr.filters.hidden = function( elem ) {
10005
10006 // Support: Opera <= 12.12
10007 // Opera reports offsetWidths and offsetHeights less than zero on some elements
10008 return support.reliableHiddenOffsets() ?
10009 ( elem.offsetWidth <= 0 && elem.offsetHeight <= 0 &&
10010 !elem.getClientRects().length ) :
10011 filterHidden( elem );
10012};
10013
10014jQuery.expr.filters.visible = function( elem ) {
10015 return !jQuery.expr.filters.hidden( elem );
10016};
10017
10018
10019
10020
10021var r20 = /%20/g,
10022 rbracket = /\[\]$/,
10023 rCRLF = /\r?\n/g,
10024 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
10025 rsubmittable = /^(?:input|select|textarea|keygen)/i;
10026
10027function buildParams( prefix, obj, traditional, add ) {
10028 var name;
10029
10030 if ( jQuery.isArray( obj ) ) {
10031
10032 // Serialize array item.
10033 jQuery.each( obj, function( i, v ) {
10034 if ( traditional || rbracket.test( prefix ) ) {
10035
10036 // Treat each array item as a scalar.
10037 add( prefix, v );
10038
10039 } else {
10040
10041 // Item is non-scalar (array or object), encode its numeric index.
10042 buildParams(
10043 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
10044 v,
10045 traditional,
10046 add
10047 );
10048 }
10049 } );
10050
10051 } else if ( !traditional && jQuery.type( obj ) === "object" ) {
10052
10053 // Serialize object item.
10054 for ( name in obj ) {
10055 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
10056 }
10057
10058 } else {
10059
10060 // Serialize scalar item.
10061 add( prefix, obj );
10062 }
10063}
10064
10065// Serialize an array of form elements or a set of
10066// key/values into a query string
10067jQuery.param = function( a, traditional ) {
10068 var prefix,
10069 s = [],
10070 add = function( key, value ) {
10071
10072 // If value is a function, invoke it and return its value
10073 value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
10074 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
10075 };
10076
10077 // Set traditional to true for jQuery <= 1.3.2 behavior.
10078 if ( traditional === undefined ) {
10079 traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
10080 }
10081
10082 // If an array was passed in, assume that it is an array of form elements.
10083 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
10084
10085 // Serialize the form elements
10086 jQuery.each( a, function() {
10087 add( this.name, this.value );
10088 } );
10089
10090 } else {
10091
10092 // If traditional, encode the "old" way (the way 1.3.2 or older
10093 // did it), otherwise encode params recursively.
10094 for ( prefix in a ) {
10095 buildParams( prefix, a[ prefix ], traditional, add );
10096 }
10097 }
10098
10099 // Return the resulting serialization
10100 return s.join( "&" ).replace( r20, "+" );
10101};
10102
10103jQuery.fn.extend( {
10104 serialize: function() {
10105 return jQuery.param( this.serializeArray() );
10106 },
10107 serializeArray: function() {
10108 return this.map( function() {
10109
10110 // Can add propHook for "elements" to filter or add form elements
10111 var elements = jQuery.prop( this, "elements" );
10112 return elements ? jQuery.makeArray( elements ) : this;
10113 } )
10114 .filter( function() {
10115 var type = this.type;
10116
10117 // Use .is(":disabled") so that fieldset[disabled] works
10118 return this.name && !jQuery( this ).is( ":disabled" ) &&
10119 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
10120 ( this.checked || !rcheckableType.test( type ) );
10121 } )
10122 .map( function( i, elem ) {
10123 var val = jQuery( this ).val();
10124
10125 return val == null ?
10126 null :
10127 jQuery.isArray( val ) ?
10128 jQuery.map( val, function( val ) {
10129 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
10130 } ) :
10131 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
10132 } ).get();
10133 }
10134} );
10135
10136
10137// Create the request object
10138// (This is still attached to ajaxSettings for backward compatibility)
10139jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
10140
10141 // Support: IE6-IE8
10142 function() {
10143
10144 // XHR cannot access local files, always use ActiveX for that case
10145 if ( this.isLocal ) {
10146 return createActiveXHR();
10147 }
10148
10149 // Support: IE 9-11
10150 // IE seems to error on cross-domain PATCH requests when ActiveX XHR
10151 // is used. In IE 9+ always use the native XHR.
10152 // Note: this condition won't catch Edge as it doesn't define
10153 // document.documentMode but it also doesn't support ActiveX so it won't
10154 // reach this code.
10155 if ( document.documentMode > 8 ) {
10156 return createStandardXHR();
10157 }
10158
10159 // Support: IE<9
10160 // oldIE XHR does not support non-RFC2616 methods (#13240)
10161 // See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
10162 // and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
10163 // Although this check for six methods instead of eight
10164 // since IE also does not support "trace" and "connect"
10165 return /^(get|post|head|put|delete|options)$/i.test( this.type ) &&
10166 createStandardXHR() || createActiveXHR();
10167 } :
10168
10169 // For all other browsers, use the standard XMLHttpRequest object
10170 createStandardXHR;
10171
10172var xhrId = 0,
10173 xhrCallbacks = {},
10174 xhrSupported = jQuery.ajaxSettings.xhr();
10175
10176// Support: IE<10
10177// Open requests must be manually aborted on unload (#5280)
10178// See https://support.microsoft.com/kb/2856746 for more info
10179if ( window.attachEvent ) {
10180 window.attachEvent( "onunload", function() {
10181 for ( var key in xhrCallbacks ) {
10182 xhrCallbacks[ key ]( undefined, true );
10183 }
10184 } );
10185}
10186
10187// Determine support properties
10188support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
10189xhrSupported = support.ajax = !!xhrSupported;
10190
10191// Create transport if the browser can provide an xhr
10192if ( xhrSupported ) {
10193
10194 jQuery.ajaxTransport( function( options ) {
10195
10196 // Cross domain only allowed if supported through XMLHttpRequest
10197 if ( !options.crossDomain || support.cors ) {
10198
10199 var callback;
10200
10201 return {
10202 send: function( headers, complete ) {
10203 var i,
10204 xhr = options.xhr(),
10205 id = ++xhrId;
10206
10207 // Open the socket
10208 xhr.open(
10209 options.type,
10210 options.url,
10211 options.async,
10212 options.username,
10213 options.password
10214 );
10215
10216 // Apply custom fields if provided
10217 if ( options.xhrFields ) {
10218 for ( i in options.xhrFields ) {
10219 xhr[ i ] = options.xhrFields[ i ];
10220 }
10221 }
10222
10223 // Override mime type if needed
10224 if ( options.mimeType && xhr.overrideMimeType ) {
10225 xhr.overrideMimeType( options.mimeType );
10226 }
10227
10228 // X-Requested-With header
10229 // For cross-domain requests, seeing as conditions for a preflight are
10230 // akin to a jigsaw puzzle, we simply never set it to be sure.
10231 // (it can always be set on a per-request basis or even using ajaxSetup)
10232 // For same-domain requests, won't change header if already provided.
10233 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
10234 headers[ "X-Requested-With" ] = "XMLHttpRequest";
10235 }
10236
10237 // Set headers
10238 for ( i in headers ) {
10239
10240 // Support: IE<9
10241 // IE's ActiveXObject throws a 'Type Mismatch' exception when setting
10242 // request header to a null-value.
10243 //
10244 // To keep consistent with other XHR implementations, cast the value
10245 // to string and ignore `undefined`.
10246 if ( headers[ i ] !== undefined ) {
10247 xhr.setRequestHeader( i, headers[ i ] + "" );
10248 }
10249 }
10250
10251 // Do send the request
10252 // This may raise an exception which is actually
10253 // handled in jQuery.ajax (so no try/catch here)
10254 xhr.send( ( options.hasContent && options.data ) || null );
10255
10256 // Listener
10257 callback = function( _, isAbort ) {
10258 var status, statusText, responses;
10259
10260 // Was never called and is aborted or complete
10261 if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
10262
10263 // Clean up
10264 delete xhrCallbacks[ id ];
10265 callback = undefined;
10266 xhr.onreadystatechange = jQuery.noop;
10267
10268 // Abort manually if needed
10269 if ( isAbort ) {
10270 if ( xhr.readyState !== 4 ) {
10271 xhr.abort();
10272 }
10273 } else {
10274 responses = {};
10275 status = xhr.status;
10276
10277 // Support: IE<10
10278 // Accessing binary-data responseText throws an exception
10279 // (#11426)
10280 if ( typeof xhr.responseText === "string" ) {
10281 responses.text = xhr.responseText;
10282 }
10283
10284 // Firefox throws an exception when accessing
10285 // statusText for faulty cross-domain requests
10286 try {
10287 statusText = xhr.statusText;
10288 } catch ( e ) {
10289
10290 // We normalize with Webkit giving an empty statusText
10291 statusText = "";
10292 }
10293
10294 // Filter status for non standard behaviors
10295
10296 // If the request is local and we have data: assume a success
10297 // (success with no data won't get notified, that's the best we
10298 // can do given current implementations)
10299 if ( !status && options.isLocal && !options.crossDomain ) {
10300 status = responses.text ? 200 : 404;
10301
10302 // IE - #1450: sometimes returns 1223 when it should be 204
10303 } else if ( status === 1223 ) {
10304 status = 204;
10305 }
10306 }
10307 }
10308
10309 // Call complete if needed
10310 if ( responses ) {
10311 complete( status, statusText, responses, xhr.getAllResponseHeaders() );
10312 }
10313 };
10314
10315 // Do send the request
10316 // `xhr.send` may raise an exception, but it will be
10317 // handled in jQuery.ajax (so no try/catch here)
10318 if ( !options.async ) {
10319
10320 // If we're in sync mode we fire the callback
10321 callback();
10322 } else if ( xhr.readyState === 4 ) {
10323
10324 // (IE6 & IE7) if it's in cache and has been
10325 // retrieved directly we need to fire the callback
10326 window.setTimeout( callback );
10327 } else {
10328
10329 // Register the callback, but delay it in case `xhr.send` throws
10330 // Add to the list of active xhr callbacks
10331 xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
10332 }
10333 },
10334
10335 abort: function() {
10336 if ( callback ) {
10337 callback( undefined, true );
10338 }
10339 }
10340 };
10341 }
10342 } );
10343}
10344
10345// Functions to create xhrs
10346function createStandardXHR() {
10347 try {
10348 return new window.XMLHttpRequest();
10349 } catch ( e ) {}
10350}
10351
10352function createActiveXHR() {
10353 try {
10354 return new window.ActiveXObject( "Microsoft.XMLHTTP" );
10355 } catch ( e ) {}
10356}
10357
10358
10359
10360
10361// Install script dataType
10362jQuery.ajaxSetup( {
10363 accepts: {
10364 script: "text/javascript, application/javascript, " +
10365 "application/ecmascript, application/x-ecmascript"
10366 },
10367 contents: {
10368 script: /\b(?:java|ecma)script\b/
10369 },
10370 converters: {
10371 "text script": function( text ) {
10372 jQuery.globalEval( text );
10373 return text;
10374 }
10375 }
10376} );
10377
10378// Handle cache's special case and global
10379jQuery.ajaxPrefilter( "script", function( s ) {
10380 if ( s.cache === undefined ) {
10381 s.cache = false;
10382 }
10383 if ( s.crossDomain ) {
10384 s.type = "GET";
10385 s.global = false;
10386 }
10387} );
10388
10389// Bind script tag hack transport
10390jQuery.ajaxTransport( "script", function( s ) {
10391
10392 // This transport only deals with cross domain requests
10393 if ( s.crossDomain ) {
10394
10395 var script,
10396 head = document.head || jQuery( "head" )[ 0 ] || document.documentElement;
10397
10398 return {
10399
10400 send: function( _, callback ) {
10401
10402 script = document.createElement( "script" );
10403
10404 script.async = true;
10405
10406 if ( s.scriptCharset ) {
10407 script.charset = s.scriptCharset;
10408 }
10409
10410 script.src = s.url;
10411
10412 // Attach handlers for all browsers
10413 script.onload = script.onreadystatechange = function( _, isAbort ) {
10414
10415 if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
10416
10417 // Handle memory leak in IE
10418 script.onload = script.onreadystatechange = null;
10419
10420 // Remove the script
10421 if ( script.parentNode ) {
10422 script.parentNode.removeChild( script );
10423 }
10424
10425 // Dereference the script
10426 script = null;
10427
10428 // Callback if not abort
10429 if ( !isAbort ) {
10430 callback( 200, "success" );
10431 }
10432 }
10433 };
10434
10435 // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
10436 // Use native DOM manipulation to avoid our domManip AJAX trickery
10437 head.insertBefore( script, head.firstChild );
10438 },
10439
10440 abort: function() {
10441 if ( script ) {
10442 script.onload( undefined, true );
10443 }
10444 }
10445 };
10446 }
10447} );
10448
10449
10450
10451
10452var oldCallbacks = [],
10453 rjsonp = /(=)\?(?=&|$)|\?\?/;
10454
10455// Default jsonp settings
10456jQuery.ajaxSetup( {
10457 jsonp: "callback",
10458 jsonpCallback: function() {
10459 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
10460 this[ callback ] = true;
10461 return callback;
10462 }
10463} );
10464
10465// Detect, normalize options and install callbacks for jsonp requests
10466jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
10467
10468 var callbackName, overwritten, responseContainer,
10469 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
10470 "url" :
10471 typeof s.data === "string" &&
10472 ( s.contentType || "" )
10473 .indexOf( "application/x-www-form-urlencoded" ) === 0 &&
10474 rjsonp.test( s.data ) && "data"
10475 );
10476
10477 // Handle iff the expected data type is "jsonp" or we have a parameter to set
10478 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
10479
10480 // Get callback name, remembering preexisting value associated with it
10481 callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
10482 s.jsonpCallback() :
10483 s.jsonpCallback;
10484
10485 // Insert callback into url or form data
10486 if ( jsonProp ) {
10487 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
10488 } else if ( s.jsonp !== false ) {
10489 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
10490 }
10491
10492 // Use data converter to retrieve json after script execution
10493 s.converters[ "script json" ] = function() {
10494 if ( !responseContainer ) {
10495 jQuery.error( callbackName + " was not called" );
10496 }
10497 return responseContainer[ 0 ];
10498 };
10499
10500 // force json dataType
10501 s.dataTypes[ 0 ] = "json";
10502
10503 // Install callback
10504 overwritten = window[ callbackName ];
10505 window[ callbackName ] = function() {
10506 responseContainer = arguments;
10507 };
10508
10509 // Clean-up function (fires after converters)
10510 jqXHR.always( function() {
10511
10512 // If previous value didn't exist - remove it
10513 if ( overwritten === undefined ) {
10514 jQuery( window ).removeProp( callbackName );
10515
10516 // Otherwise restore preexisting value
10517 } else {
10518 window[ callbackName ] = overwritten;
10519 }
10520
10521 // Save back as free
10522 if ( s[ callbackName ] ) {
10523
10524 // make sure that re-using the options doesn't screw things around
10525 s.jsonpCallback = originalSettings.jsonpCallback;
10526
10527 // save the callback name for future use
10528 oldCallbacks.push( callbackName );
10529 }
10530
10531 // Call if it was a function and we have a response
10532 if ( responseContainer && jQuery.isFunction( overwritten ) ) {
10533 overwritten( responseContainer[ 0 ] );
10534 }
10535
10536 responseContainer = overwritten = undefined;
10537 } );
10538
10539 // Delegate to script
10540 return "script";
10541 }
10542} );
10543
10544
10545
10546
10547// data: string of html
10548// context (optional): If specified, the fragment will be created in this context,
10549// defaults to document
10550// keepScripts (optional): If true, will include scripts passed in the html string
10551jQuery.parseHTML = function( data, context, keepScripts ) {
10552 if ( !data || typeof data !== "string" ) {
10553 return null;
10554 }
10555 if ( typeof context === "boolean" ) {
10556 keepScripts = context;
10557 context = false;
10558 }
10559 context = context || document;
10560
10561 var parsed = rsingleTag.exec( data ),
10562 scripts = !keepScripts && [];
10563
10564 // Single tag
10565 if ( parsed ) {
10566 return [ context.createElement( parsed[ 1 ] ) ];
10567 }
10568
10569 parsed = buildFragment( [ data ], context, scripts );
10570
10571 if ( scripts && scripts.length ) {
10572 jQuery( scripts ).remove();
10573 }
10574
10575 return jQuery.merge( [], parsed.childNodes );
10576};
10577
10578
10579// Keep a copy of the old load method
10580var _load = jQuery.fn.load;
10581
10582/**
10583 * Load a url into a page
10584 */
10585jQuery.fn.load = function( url, params, callback ) {
10586 if ( typeof url !== "string" && _load ) {
10587 return _load.apply( this, arguments );
10588 }
10589
10590 var selector, type, response,
10591 self = this,
10592 off = url.indexOf( " " );
10593
10594 if ( off > -1 ) {
10595 selector = jQuery.trim( url.slice( off, url.length ) );
10596 url = url.slice( 0, off );
10597 }
10598
10599 // If it's a function
10600 if ( jQuery.isFunction( params ) ) {
10601
10602 // We assume that it's the callback
10603 callback = params;
10604 params = undefined;
10605
10606 // Otherwise, build a param string
10607 } else if ( params && typeof params === "object" ) {
10608 type = "POST";
10609 }
10610
10611 // If we have elements to modify, make the request
10612 if ( self.length > 0 ) {
10613 jQuery.ajax( {
10614 url: url,
10615
10616 // If "type" variable is undefined, then "GET" method will be used.
10617 // Make value of this field explicit since
10618 // user can override it through ajaxSetup method
10619 type: type || "GET",
10620 dataType: "html",
10621 data: params
10622 } ).done( function( responseText ) {
10623
10624 // Save response for use in complete callback
10625 response = arguments;
10626
10627 self.html( selector ?
10628
10629 // If a selector was specified, locate the right elements in a dummy div
10630 // Exclude scripts to avoid IE 'Permission Denied' errors
10631 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
10632
10633 // Otherwise use the full result
10634 responseText );
10635
10636 // If the request succeeds, this function gets "data", "status", "jqXHR"
10637 // but they are ignored because response was set above.
10638 // If it fails, this function gets "jqXHR", "status", "error"
10639 } ).always( callback && function( jqXHR, status ) {
10640 self.each( function() {
10641 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
10642 } );
10643 } );
10644 }
10645
10646 return this;
10647};
10648
10649
10650
10651
10652// Attach a bunch of functions for handling common AJAX events
10653jQuery.each( [
10654 "ajaxStart",
10655 "ajaxStop",
10656 "ajaxComplete",
10657 "ajaxError",
10658 "ajaxSuccess",
10659 "ajaxSend"
10660], function( i, type ) {
10661 jQuery.fn[ type ] = function( fn ) {
10662 return this.on( type, fn );
10663 };
10664} );
10665
10666
10667
10668
10669jQuery.expr.filters.animated = function( elem ) {
10670 return jQuery.grep( jQuery.timers, function( fn ) {
10671 return elem === fn.elem;
10672 } ).length;
10673};
10674
10675
10676
10677
10678
10679/**
10680 * Gets a window from an element
10681 */
10682function getWindow( elem ) {
10683 return jQuery.isWindow( elem ) ?
10684 elem :
10685 elem.nodeType === 9 ?
10686 elem.defaultView || elem.parentWindow :
10687 false;
10688}
10689
10690jQuery.offset = {
10691 setOffset: function( elem, options, i ) {
10692 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
10693 position = jQuery.css( elem, "position" ),
10694 curElem = jQuery( elem ),
10695 props = {};
10696
10697 // set position first, in-case top/left are set even on static elem
10698 if ( position === "static" ) {
10699 elem.style.position = "relative";
10700 }
10701
10702 curOffset = curElem.offset();
10703 curCSSTop = jQuery.css( elem, "top" );
10704 curCSSLeft = jQuery.css( elem, "left" );
10705 calculatePosition = ( position === "absolute" || position === "fixed" ) &&
10706 jQuery.inArray( "auto", [ curCSSTop, curCSSLeft ] ) > -1;
10707
10708 // need to be able to calculate position if either top or left
10709 // is auto and position is either absolute or fixed
10710 if ( calculatePosition ) {
10711 curPosition = curElem.position();
10712 curTop = curPosition.top;
10713 curLeft = curPosition.left;
10714 } else {
10715 curTop = parseFloat( curCSSTop ) || 0;
10716 curLeft = parseFloat( curCSSLeft ) || 0;
10717 }
10718
10719 if ( jQuery.isFunction( options ) ) {
10720
10721 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
10722 options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
10723 }
10724
10725 if ( options.top != null ) {
10726 props.top = ( options.top - curOffset.top ) + curTop;
10727 }
10728 if ( options.left != null ) {
10729 props.left = ( options.left - curOffset.left ) + curLeft;
10730 }
10731
10732 if ( "using" in options ) {
10733 options.using.call( elem, props );
10734 } else {
10735 curElem.css( props );
10736 }
10737 }
10738};
10739
10740jQuery.fn.extend( {
10741 offset: function( options ) {
10742 if ( arguments.length ) {
10743 return options === undefined ?
10744 this :
10745 this.each( function( i ) {
10746 jQuery.offset.setOffset( this, options, i );
10747 } );
10748 }
10749
10750 var docElem, win,
10751 box = { top: 0, left: 0 },
10752 elem = this[ 0 ],
10753 doc = elem && elem.ownerDocument;
10754
10755 if ( !doc ) {
10756 return;
10757 }
10758
10759 docElem = doc.documentElement;
10760
10761 // Make sure it's not a disconnected DOM node
10762 if ( !jQuery.contains( docElem, elem ) ) {
10763 return box;
10764 }
10765
10766 // If we don't have gBCR, just use 0,0 rather than error
10767 // BlackBerry 5, iOS 3 (original iPhone)
10768 if ( typeof elem.getBoundingClientRect !== "undefined" ) {
10769 box = elem.getBoundingClientRect();
10770 }
10771 win = getWindow( doc );
10772 return {
10773 top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
10774 left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
10775 };
10776 },
10777
10778 position: function() {
10779 if ( !this[ 0 ] ) {
10780 return;
10781 }
10782
10783 var offsetParent, offset,
10784 parentOffset = { top: 0, left: 0 },
10785 elem = this[ 0 ];
10786
10787 // Fixed elements are offset from window (parentOffset = {top:0, left: 0},
10788 // because it is its only offset parent
10789 if ( jQuery.css( elem, "position" ) === "fixed" ) {
10790
10791 // we assume that getBoundingClientRect is available when computed position is fixed
10792 offset = elem.getBoundingClientRect();
10793 } else {
10794
10795 // Get *real* offsetParent
10796 offsetParent = this.offsetParent();
10797
10798 // Get correct offsets
10799 offset = this.offset();
10800 if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
10801 parentOffset = offsetParent.offset();
10802 }
10803
10804 // Add offsetParent borders
10805 parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
10806 parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
10807 }
10808
10809 // Subtract parent offsets and element margins
10810 // note: when an element has margin: auto the offsetLeft and marginLeft
10811 // are the same in Safari causing offset.left to incorrectly be 0
10812 return {
10813 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
10814 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
10815 };
10816 },
10817
10818 offsetParent: function() {
10819 return this.map( function() {
10820 var offsetParent = this.offsetParent;
10821
10822 while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) &&
10823 jQuery.css( offsetParent, "position" ) === "static" ) ) {
10824 offsetParent = offsetParent.offsetParent;
10825 }
10826 return offsetParent || documentElement;
10827 } );
10828 }
10829} );
10830
10831// Create scrollLeft and scrollTop methods
10832jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
10833 var top = /Y/.test( prop );
10834
10835 jQuery.fn[ method ] = function( val ) {
10836 return access( this, function( elem, method, val ) {
10837 var win = getWindow( elem );
10838
10839 if ( val === undefined ) {
10840 return win ? ( prop in win ) ? win[ prop ] :
10841 win.document.documentElement[ method ] :
10842 elem[ method ];
10843 }
10844
10845 if ( win ) {
10846 win.scrollTo(
10847 !top ? val : jQuery( win ).scrollLeft(),
10848 top ? val : jQuery( win ).scrollTop()
10849 );
10850
10851 } else {
10852 elem[ method ] = val;
10853 }
10854 }, method, val, arguments.length, null );
10855 };
10856} );
10857
10858// Support: Safari<7-8+, Chrome<37-44+
10859// Add the top/left cssHooks using jQuery.fn.position
10860// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10861// getComputedStyle returns percent when specified for top/left/bottom/right
10862// rather than make the css module depend on the offset module, we just check for it here
10863jQuery.each( [ "top", "left" ], function( i, prop ) {
10864 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
10865 function( elem, computed ) {
10866 if ( computed ) {
10867 computed = curCSS( elem, prop );
10868
10869 // if curCSS returns percentage, fallback to offset
10870 return rnumnonpx.test( computed ) ?
10871 jQuery( elem ).position()[ prop ] + "px" :
10872 computed;
10873 }
10874 }
10875 );
10876} );
10877
10878
10879// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10880jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
10881 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
10882 function( defaultExtra, funcName ) {
10883
10884 // margin is only for outerHeight, outerWidth
10885 jQuery.fn[ funcName ] = function( margin, value ) {
10886 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
10887 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
10888
10889 return access( this, function( elem, type, value ) {
10890 var doc;
10891
10892 if ( jQuery.isWindow( elem ) ) {
10893
10894 // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
10895 // isn't a whole lot we can do. See pull request at this URL for discussion:
10896 // https://github.com/jquery/jquery/pull/764
10897 return elem.document.documentElement[ "client" + name ];
10898 }
10899
10900 // Get document width or height
10901 if ( elem.nodeType === 9 ) {
10902 doc = elem.documentElement;
10903
10904 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
10905 // whichever is greatest
10906 // unfortunately, this causes bug #3838 in IE6/8 only,
10907 // but there is currently no good, small way to fix it.
10908 return Math.max(
10909 elem.body[ "scroll" + name ], doc[ "scroll" + name ],
10910 elem.body[ "offset" + name ], doc[ "offset" + name ],
10911 doc[ "client" + name ]
10912 );
10913 }
10914
10915 return value === undefined ?
10916
10917 // Get width or height on the element, requesting but not forcing parseFloat
10918 jQuery.css( elem, type, extra ) :
10919
10920 // Set width or height on the element
10921 jQuery.style( elem, type, value, extra );
10922 }, type, chainable ? margin : undefined, chainable, null );
10923 };
10924 } );
10925} );
10926
10927
10928jQuery.fn.extend( {
10929
10930 bind: function( types, data, fn ) {
10931 return this.on( types, null, data, fn );
10932 },
10933 unbind: function( types, fn ) {
10934 return this.off( types, null, fn );
10935 },
10936
10937 delegate: function( selector, types, data, fn ) {
10938 return this.on( types, selector, data, fn );
10939 },
10940 undelegate: function( selector, types, fn ) {
10941
10942 // ( namespace ) or ( selector, types [, fn] )
10943 return arguments.length === 1 ?
10944 this.off( selector, "**" ) :
10945 this.off( types, selector || "**", fn );
10946 }
10947} );
10948
10949// The number of elements contained in the matched element set
10950jQuery.fn.size = function() {
10951 return this.length;
10952};
10953
10954jQuery.fn.andSelf = jQuery.fn.addBack;
10955
10956
10957
10958
10959// Register as a named AMD module, since jQuery can be concatenated with other
10960// files that may use define, but not via a proper concatenation script that
10961// understands anonymous AMD modules. A named AMD is safest and most robust
10962// way to register. Lowercase jquery is used because AMD module names are
10963// derived from file names, and jQuery is normally delivered in a lowercase
10964// file name. Do this after creating the global so that if an AMD module wants
10965// to call noConflict to hide this version of jQuery, it will work.
10966
10967// Note that for maximum portability, libraries that are not jQuery should
10968// declare themselves as anonymous modules, and avoid setting a global if an
10969// AMD loader is present. jQuery is a special case. For more information, see
10970// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
10971
10972if ( typeof define === "function" && define.amd ) {
10973 define( "jquery", [], function() {
10974 return jQuery;
10975 } );
10976}
10977
10978
10979
10980var
10981
10982 // Map over jQuery in case of overwrite
10983 _jQuery = window.jQuery,
10984
10985 // Map over the $ in case of overwrite
10986 _$ = window.$;
10987
10988jQuery.noConflict = function( deep ) {
10989 if ( window.$ === jQuery ) {
10990 window.$ = _$;
10991 }
10992
10993 if ( deep && window.jQuery === jQuery ) {
10994 window.jQuery = _jQuery;
10995 }
10996
10997 return jQuery;
10998};
10999
11000// Expose jQuery and $ identifiers, even in
11001// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
11002// and CommonJS for browser emulators (#13566)
11003if ( !noGlobal ) {
11004 window.jQuery = window.$ = jQuery;
11005}
11006
11007return jQuery;
11008}));
11009/* jshint node: true */
11010
11011/**
11012 * Unobtrusive scripting adapter for jQuery
11013 * https://github.com/rails/jquery-ujs
11014 *
11015 * Requires jQuery 1.8.0 or later.
11016 *
11017 * Released under the MIT license
11018 *
11019 */
11020
11021(function() {
11022 'use strict';
11023
11024 var jqueryUjsInit = function($, undefined) {
11025
11026 // Cut down on the number of issues from people inadvertently including jquery_ujs twice
11027 // by detecting and raising an error when it happens.
11028 if ( $.rails !== undefined ) {
11029 $.error('jquery-ujs has already been loaded!');
11030 }
11031
11032 // Shorthand to make it a little easier to call public rails functions from within rails.js
11033 var rails;
11034 var $document = $(document);
11035
11036 $.rails = rails = {
11037 // Link elements bound by jquery-ujs
11038 linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]',
11039
11040 // Button elements bound by jquery-ujs
11041 buttonClickSelector: 'button[data-remote]:not([form]):not(form button), button[data-confirm]:not([form]):not(form button)',
11042
11043 // Select elements bound by jquery-ujs
11044 inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',
11045
11046 // Form elements bound by jquery-ujs
11047 formSubmitSelector: 'form:not([data-turbo=true])',
11048
11049 // Form input elements bound by jquery-ujs
11050 formInputClickSelector: 'form:not([data-turbo=true]) input[type=submit], form:not([data-turbo=true]) input[type=image], form:not([data-turbo=true]) button[type=submit], form:not([data-turbo=true]) button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])',
11051
11052 // Form input elements disabled during form submission
11053 disableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled',
11054
11055 // Form input elements re-enabled after form submission
11056 enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled',
11057
11058 // Form required input elements
11059 requiredInputSelector: 'input[name][required]:not([disabled]), textarea[name][required]:not([disabled])',
11060
11061 // Form file input elements
11062 fileInputSelector: 'input[name][type=file]:not([disabled])',
11063
11064 // Link onClick disable selector with possible reenable after remote submission
11065 linkDisableSelector: 'a[data-disable-with], a[data-disable]',
11066
11067 // Button onClick disable selector with possible reenable after remote submission
11068 buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]',
11069
11070 // Up-to-date Cross-Site Request Forgery token
11071 csrfToken: function() {
11072 return $('meta[name=csrf-token]').attr('content');
11073 },
11074
11075 // URL param that must contain the CSRF token
11076 csrfParam: function() {
11077 return $('meta[name=csrf-param]').attr('content');
11078 },
11079
11080 // Make sure that every Ajax request sends the CSRF token
11081 CSRFProtection: function(xhr) {
11082 var token = rails.csrfToken();
11083 if (token) xhr.setRequestHeader('X-CSRF-Token', token);
11084 },
11085
11086 // Make sure that all forms have actual up-to-date tokens (cached forms contain old ones)
11087 refreshCSRFTokens: function(){
11088 $('form input[name="' + rails.csrfParam() + '"]').val(rails.csrfToken());
11089 },
11090
11091 // Triggers an event on an element and returns false if the event result is false
11092 fire: function(obj, name, data) {
11093 var event = $.Event(name);
11094 obj.trigger(event, data);
11095 return event.result !== false;
11096 },
11097
11098 // Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm
11099 confirm: function(message) {
11100 return confirm(message);
11101 },
11102
11103 // Default ajax function, may be overridden with custom function in $.rails.ajax
11104 ajax: function(options) {
11105 return $.ajax(options);
11106 },
11107
11108 // Default way to get an element's href. May be overridden at $.rails.href.
11109 href: function(element) {
11110 return element[0].href;
11111 },
11112
11113 // Checks "data-remote" if true to handle the request through a XHR request.
11114 isRemote: function(element) {
11115 return element.data('remote') !== undefined && element.data('remote') !== false;
11116 },
11117
11118 // Submits "remote" forms and links with ajax
11119 handleRemote: function(element) {
11120 var method, url, data, withCredentials, dataType, options;
11121
11122 if (rails.fire(element, 'ajax:before')) {
11123 withCredentials = element.data('with-credentials') || null;
11124 dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType);
11125
11126 if (element.is('form')) {
11127 method = element.data('ujs:submit-button-formmethod') || element.attr('method');
11128 url = element.data('ujs:submit-button-formaction') || element.attr('action');
11129 data = $(element[0]).serializeArray();
11130 // memoized value from clicked submit button
11131 var button = element.data('ujs:submit-button');
11132 if (button) {
11133 data.push(button);
11134 element.data('ujs:submit-button', null);
11135 }
11136 element.data('ujs:submit-button-formmethod', null);
11137 element.data('ujs:submit-button-formaction', null);
11138 } else if (element.is(rails.inputChangeSelector)) {
11139 method = element.data('method');
11140 url = element.data('url');
11141 data = element.serialize();
11142 if (element.data('params')) data = data + '&' + element.data('params');
11143 } else if (element.is(rails.buttonClickSelector)) {
11144 method = element.data('method') || 'get';
11145 url = element.data('url');
11146 data = element.serialize();
11147 if (element.data('params')) data = data + '&' + element.data('params');
11148 } else {
11149 method = element.data('method');
11150 url = rails.href(element);
11151 data = element.data('params') || null;
11152 }
11153
11154 options = {
11155 type: method || 'GET', data: data, dataType: dataType,
11156 // stopping the "ajax:beforeSend" event will cancel the ajax request
11157 beforeSend: function(xhr, settings) {
11158 if (settings.dataType === undefined) {
11159 xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
11160 }
11161 if (rails.fire(element, 'ajax:beforeSend', [xhr, settings])) {
11162 element.trigger('ajax:send', xhr);
11163 } else {
11164 return false;
11165 }
11166 },
11167 success: function(data, status, xhr) {
11168 element.trigger('ajax:success', [data, status, xhr]);
11169 },
11170 complete: function(xhr, status) {
11171 element.trigger('ajax:complete', [xhr, status]);
11172 },
11173 error: function(xhr, status, error) {
11174 element.trigger('ajax:error', [xhr, status, error]);
11175 },
11176 crossDomain: rails.isCrossDomain(url)
11177 };
11178
11179 // There is no withCredentials for IE6-8 when
11180 // "Enable native XMLHTTP support" is disabled
11181 if (withCredentials) {
11182 options.xhrFields = {
11183 withCredentials: withCredentials
11184 };
11185 }
11186
11187 // Only pass url to `ajax` options if not blank
11188 if (url) { options.url = url; }
11189
11190 return rails.ajax(options);
11191 } else {
11192 return false;
11193 }
11194 },
11195
11196 // Determines if the request is a cross domain request.
11197 isCrossDomain: function(url) {
11198 var originAnchor = document.createElement('a');
11199 originAnchor.href = location.href;
11200 var urlAnchor = document.createElement('a');
11201
11202 try {
11203 urlAnchor.href = url;
11204 // This is a workaround to a IE bug.
11205 urlAnchor.href = urlAnchor.href;
11206
11207 // If URL protocol is false or is a string containing a single colon
11208 // *and* host are false, assume it is not a cross-domain request
11209 // (should only be the case for IE7 and IE compatibility mode).
11210 // Otherwise, evaluate protocol and host of the URL against the origin
11211 // protocol and host.
11212 return !(((!urlAnchor.protocol || urlAnchor.protocol === ':') && !urlAnchor.host) ||
11213 (originAnchor.protocol + '//' + originAnchor.host ===
11214 urlAnchor.protocol + '//' + urlAnchor.host));
11215 } catch (e) {
11216 // If there is an error parsing the URL, assume it is crossDomain.
11217 return true;
11218 }
11219 },
11220
11221 // Handles "data-method" on links such as:
11222 // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
11223 handleMethod: function(link) {
11224 var href = rails.href(link),
11225 method = link.data('method'),
11226 target = link.attr('target'),
11227 csrfToken = rails.csrfToken(),
11228 csrfParam = rails.csrfParam(),
11229 form = $('<form method="post" action="' + href + '"></form>'),
11230 metadataInput = '<input name="_method" value="' + method + '" type="hidden" />';
11231
11232 if (csrfParam !== undefined && csrfToken !== undefined && !rails.isCrossDomain(href)) {
11233 metadataInput += '<input name="' + csrfParam + '" value="' + csrfToken + '" type="hidden" />';
11234 }
11235
11236 if (target) { form.attr('target', target); }
11237
11238 form.hide().append(metadataInput).appendTo('body');
11239 form.submit();
11240 },
11241
11242 // Helper function that returns form elements that match the specified CSS selector
11243 // If form is actually a "form" element this will return associated elements outside the from that have
11244 // the html form attribute set
11245 formElements: function(form, selector) {
11246 return form.is('form') ? $(form[0].elements).filter(selector) : form.find(selector);
11247 },
11248
11249 /* Disables form elements:
11250 - Caches element value in 'ujs:enable-with' data store
11251 - Replaces element text with value of 'data-disable-with' attribute
11252 - Sets disabled property to true
11253 */
11254 disableFormElements: function(form) {
11255 rails.formElements(form, rails.disableSelector).each(function() {
11256 rails.disableFormElement($(this));
11257 });
11258 },
11259
11260 disableFormElement: function(element) {
11261 var method, replacement;
11262
11263 method = element.is('button') ? 'html' : 'val';
11264 replacement = element.data('disable-with');
11265
11266 if (replacement !== undefined) {
11267 element.data('ujs:enable-with', element[method]());
11268 element[method](replacement);
11269 }
11270
11271 element.prop('disabled', true);
11272 element.data('ujs:disabled', true);
11273 },
11274
11275 /* Re-enables disabled form elements:
11276 - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
11277 - Sets disabled property to false
11278 */
11279 enableFormElements: function(form) {
11280 rails.formElements(form, rails.enableSelector).each(function() {
11281 rails.enableFormElement($(this));
11282 });
11283 },
11284
11285 enableFormElement: function(element) {
11286 var method = element.is('button') ? 'html' : 'val';
11287 if (element.data('ujs:enable-with') !== undefined) {
11288 element[method](element.data('ujs:enable-with'));
11289 element.removeData('ujs:enable-with'); // clean up cache
11290 }
11291 element.prop('disabled', false);
11292 element.removeData('ujs:disabled');
11293 },
11294
11295 /* For 'data-confirm' attribute:
11296 - Fires `confirm` event
11297 - Shows the confirmation dialog
11298 - Fires the `confirm:complete` event
11299
11300 Returns `true` if no function stops the chain and user chose yes; `false` otherwise.
11301 Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog.
11302 Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function
11303 return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog.
11304 */
11305 allowAction: function(element) {
11306 var message = element.data('confirm'),
11307 answer = false, callback;
11308 if (!message) { return true; }
11309
11310 if (rails.fire(element, 'confirm')) {
11311 try {
11312 answer = rails.confirm(message);
11313 } catch (e) {
11314 (console.error || console.log).call(console, e.stack || e);
11315 }
11316 callback = rails.fire(element, 'confirm:complete', [answer]);
11317 }
11318 return answer && callback;
11319 },
11320
11321 // Helper function which checks for blank inputs in a form that match the specified CSS selector
11322 blankInputs: function(form, specifiedSelector, nonBlank) {
11323 var foundInputs = $(),
11324 input,
11325 valueToCheck,
11326 radiosForNameWithNoneSelected,
11327 radioName,
11328 selector = specifiedSelector || 'input,textarea',
11329 requiredInputs = form.find(selector),
11330 checkedRadioButtonNames = {};
11331
11332 requiredInputs.each(function() {
11333 input = $(this);
11334 if (input.is('input[type=radio]')) {
11335
11336 // Don't count unchecked required radio as blank if other radio with same name is checked,
11337 // regardless of whether same-name radio input has required attribute or not. The spec
11338 // states https://www.w3.org/TR/html5/forms.html#the-required-attribute
11339 radioName = input.attr('name');
11340
11341 // Skip if we've already seen the radio with this name.
11342 if (!checkedRadioButtonNames[radioName]) {
11343
11344 // If none checked
11345 if (form.find('input[type=radio]:checked[name="' + radioName + '"]').length === 0) {
11346 radiosForNameWithNoneSelected = form.find(
11347 'input[type=radio][name="' + radioName + '"]');
11348 foundInputs = foundInputs.add(radiosForNameWithNoneSelected);
11349 }
11350
11351 // We only need to check each name once.
11352 checkedRadioButtonNames[radioName] = radioName;
11353 }
11354 } else {
11355 valueToCheck = input.is('input[type=checkbox],input[type=radio]') ? input.is(':checked') : !!input.val();
11356 if (valueToCheck === nonBlank) {
11357 foundInputs = foundInputs.add(input);
11358 }
11359 }
11360 });
11361 return foundInputs.length ? foundInputs : false;
11362 },
11363
11364 // Helper function which checks for non-blank inputs in a form that match the specified CSS selector
11365 nonBlankInputs: function(form, specifiedSelector) {
11366 return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank
11367 },
11368
11369 // Helper function, needed to provide consistent behavior in IE
11370 stopEverything: function(e) {
11371 $(e.target).trigger('ujs:everythingStopped');
11372 e.stopImmediatePropagation();
11373 return false;
11374 },
11375
11376 // Replace element's html with the 'data-disable-with' after storing original html
11377 // and prevent clicking on it
11378 disableElement: function(element) {
11379 var replacement = element.data('disable-with');
11380
11381 if (replacement !== undefined) {
11382 element.data('ujs:enable-with', element.html()); // store enabled state
11383 element.html(replacement);
11384 }
11385
11386 element.on('click.railsDisable', function(e) { // prevent further clicking
11387 return rails.stopEverything(e);
11388 });
11389 element.data('ujs:disabled', true);
11390 },
11391
11392 // Restore element to its original state which was disabled by 'disableElement' above
11393 enableElement: function(element) {
11394 if (element.data('ujs:enable-with') !== undefined) {
11395 element.html(element.data('ujs:enable-with')); // set to old enabled state
11396 element.removeData('ujs:enable-with'); // clean up cache
11397 }
11398 element.off('click.railsDisable'); // enable element
11399 element.removeData('ujs:disabled');
11400 }
11401 };
11402
11403 if (rails.fire($document, 'rails:attachBindings')) {
11404
11405 $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }});
11406
11407 // This event works the same as the load event, except that it fires every
11408 // time the page is loaded.
11409 //
11410 // See https://github.com/rails/jquery-ujs/issues/357
11411 // See https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching
11412 $(window).on('pageshow.rails', function () {
11413 $($.rails.enableSelector).each(function () {
11414 var element = $(this);
11415
11416 if (element.data('ujs:disabled')) {
11417 $.rails.enableFormElement(element);
11418 }
11419 });
11420
11421 $($.rails.linkDisableSelector).each(function () {
11422 var element = $(this);
11423
11424 if (element.data('ujs:disabled')) {
11425 $.rails.enableElement(element);
11426 }
11427 });
11428 });
11429
11430 $document.on('ajax:complete', rails.linkDisableSelector, function() {
11431 rails.enableElement($(this));
11432 });
11433
11434 $document.on('ajax:complete', rails.buttonDisableSelector, function() {
11435 rails.enableFormElement($(this));
11436 });
11437
11438 $document.on('click.rails', rails.linkClickSelector, function(e) {
11439 var link = $(this), method = link.data('method'), data = link.data('params'), metaClick = e.metaKey || e.ctrlKey;
11440 if (!rails.allowAction(link)) return rails.stopEverything(e);
11441
11442 if (!metaClick && link.is(rails.linkDisableSelector)) rails.disableElement(link);
11443
11444 if (rails.isRemote(link)) {
11445 if (metaClick && (!method || method === 'GET') && !data) { return true; }
11446
11447 var handleRemote = rails.handleRemote(link);
11448 // Response from rails.handleRemote() will either be false or a deferred object promise.
11449 if (handleRemote === false) {
11450 rails.enableElement(link);
11451 } else {
11452 handleRemote.fail( function() { rails.enableElement(link); } );
11453 }
11454 return false;
11455
11456 } else if (method) {
11457 rails.handleMethod(link);
11458 return false;
11459 }
11460 });
11461
11462 $document.on('click.rails', rails.buttonClickSelector, function(e) {
11463 var button = $(this);
11464
11465 if (!rails.allowAction(button) || !rails.isRemote(button)) return rails.stopEverything(e);
11466
11467 if (button.is(rails.buttonDisableSelector)) rails.disableFormElement(button);
11468
11469 var handleRemote = rails.handleRemote(button);
11470 // Response from rails.handleRemote() will either be false or a deferred object promise.
11471 if (handleRemote === false) {
11472 rails.enableFormElement(button);
11473 } else {
11474 handleRemote.fail( function() { rails.enableFormElement(button); } );
11475 }
11476 return false;
11477 });
11478
11479 $document.on('change.rails', rails.inputChangeSelector, function(e) {
11480 var link = $(this);
11481 if (!rails.allowAction(link) || !rails.isRemote(link)) return rails.stopEverything(e);
11482
11483 rails.handleRemote(link);
11484 return false;
11485 });
11486
11487 $document.on('submit.rails', rails.formSubmitSelector, function(e) {
11488 var form = $(this),
11489 remote = rails.isRemote(form),
11490 blankRequiredInputs,
11491 nonBlankFileInputs;
11492
11493 if (!rails.allowAction(form)) return rails.stopEverything(e);
11494
11495 // Skip other logic when required values are missing or file upload is present
11496 if (form.attr('novalidate') === undefined) {
11497 if (form.data('ujs:formnovalidate-button') === undefined) {
11498 blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector, false);
11499 if (blankRequiredInputs && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) {
11500 return rails.stopEverything(e);
11501 }
11502 } else {
11503 // Clear the formnovalidate in case the next button click is not on a formnovalidate button
11504 // Not strictly necessary to do here, since it is also reset on each button click, but just to be certain
11505 form.data('ujs:formnovalidate-button', undefined);
11506 }
11507 }
11508
11509 if (remote) {
11510 nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector);
11511 if (nonBlankFileInputs) {
11512 // Slight timeout so that the submit button gets properly serialized
11513 // (make it easy for event handler to serialize form without disabled values)
11514 setTimeout(function(){ rails.disableFormElements(form); }, 13);
11515 var aborted = rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]);
11516
11517 // Re-enable form elements if event bindings return false (canceling normal form submission)
11518 if (!aborted) { setTimeout(function(){ rails.enableFormElements(form); }, 13); }
11519
11520 return aborted;
11521 }
11522
11523 rails.handleRemote(form);
11524 return false;
11525
11526 } else {
11527 // Slight timeout so that the submit button gets properly serialized
11528 setTimeout(function(){ rails.disableFormElements(form); }, 13);
11529 }
11530 });
11531
11532 $document.on('click.rails', rails.formInputClickSelector, function(event) {
11533 var button = $(this);
11534
11535 if (!rails.allowAction(button)) return rails.stopEverything(event);
11536
11537 // Register the pressed submit button
11538 var name = button.attr('name'),
11539 data = name ? {name:name, value:button.val()} : null;
11540
11541 var form = button.closest('form');
11542 if (form.length === 0) {
11543 form = $('#' + button.attr('form'));
11544 }
11545 form.data('ujs:submit-button', data);
11546
11547 // Save attributes from button
11548 form.data('ujs:formnovalidate-button', button.attr('formnovalidate'));
11549 form.data('ujs:submit-button-formaction', button.attr('formaction'));
11550 form.data('ujs:submit-button-formmethod', button.attr('formmethod'));
11551 });
11552
11553 $document.on('ajax:send.rails', rails.formSubmitSelector, function(event) {
11554 if (this === event.target) rails.disableFormElements($(this));
11555 });
11556
11557 $document.on('ajax:complete.rails', rails.formSubmitSelector, function(event) {
11558 if (this === event.target) rails.enableFormElements($(this));
11559 });
11560
11561 $(function(){
11562 rails.refreshCSRFTokens();
11563 });
11564 }
11565
11566 };
11567
11568 if (window.jQuery) {
11569 jqueryUjsInit(jQuery);
11570 } else if (typeof exports === 'object' && typeof module === 'object') {
11571 module.exports = jqueryUjsInit;
11572 }
11573})();
11574( function( factory ) {
11575 "use strict";
11576
11577 if ( typeof define === "function" && define.amd ) {
11578
11579 // AMD. Register as an anonymous module.
11580 define( [ "jquery" ], factory );
11581 } else {
11582
11583 // Browser globals
11584 factory( jQuery );
11585 }
11586} )( function( $ ) {
11587"use strict";
11588
11589$.ui = $.ui || {};
11590
11591return $.ui.version = "1.14.1";
11592
11593} );
11594
11595
11596/*!
11597 * jQuery UI :data 1.14.1
11598 * https://jqueryui.com
11599 *
11600 * Copyright OpenJS Foundation and other contributors
11601 * Released under the MIT license.
11602 * https://jquery.org/license
11603 */
11604
11605//>>label: :data Selector
11606//>>group: Core
11607//>>description: Selects elements which have data stored under the specified key.
11608//>>docs: https://api.jqueryui.com/data-selector/
11609
11610( function( factory ) {
11611 "use strict";
11612
11613 if ( typeof define === "function" && define.amd ) {
11614
11615 // AMD. Register as an anonymous module.
11616 define( [ "jquery", "./version" ], factory );
11617 } else {
11618
11619 // Browser globals
11620 factory( jQuery );
11621 }
11622} )( function( $ ) {
11623"use strict";
11624
11625return $.extend( $.expr.pseudos, {
11626 data: $.expr.createPseudo( function( dataName ) {
11627 return function( elem ) {
11628 return !!$.data( elem, dataName );
11629 };
11630 } )
11631} );
11632} );
11633
11634
11635/*!
11636 * jQuery UI Disable Selection 1.14.1
11637 * https://jqueryui.com
11638 *
11639 * Copyright OpenJS Foundation and other contributors
11640 * Released under the MIT license.
11641 * https://jquery.org/license
11642 */
11643
11644//>>label: disableSelection
11645//>>group: Core
11646//>>description: Disable selection of text content within the set of matched elements.
11647//>>docs: https://api.jqueryui.com/disableSelection/
11648
11649// This file is deprecated
11650( function( factory ) {
11651 "use strict";
11652
11653 if ( typeof define === "function" && define.amd ) {
11654
11655 // AMD. Register as an anonymous module.
11656 define( [ "jquery", "./version" ], factory );
11657 } else {
11658
11659 // Browser globals
11660 factory( jQuery );
11661 }
11662} )( function( $ ) {
11663"use strict";
11664
11665return $.fn.extend( {
11666 disableSelection: ( function() {
11667 var eventType = "onselectstart" in document.createElement( "div" ) ?
11668 "selectstart" :
11669 "mousedown";
11670
11671 return function() {
11672 return this.on( eventType + ".ui-disableSelection", function( event ) {
11673 event.preventDefault();
11674 } );
11675 };
11676 } )(),
11677
11678 enableSelection: function() {
11679 return this.off( ".ui-disableSelection" );
11680 }
11681} );
11682
11683} );
11684
11685( function( factory ) {
11686 "use strict";
11687
11688 if ( typeof define === "function" && define.amd ) {
11689
11690 // AMD. Register as an anonymous module.
11691 define( [ "jquery", "./version" ], factory );
11692 } else {
11693
11694 // Browser globals
11695 factory( jQuery );
11696 }
11697} )( function( $ ) {
11698 "use strict";
11699
11700// Create a local jQuery because jQuery Color relies on it and the
11701// global may not exist with AMD and a custom build (#10199).
11702// This module is a noop if used as a regular AMD module.
11703// eslint-disable-next-line no-unused-vars
11704var jQuery = $;
11705
11706} );
11707/*!
11708 * jQuery Color Animations v3.0.0
11709 * https://github.com/jquery/jquery-color
11710 *
11711 * Copyright OpenJS Foundation and other contributors
11712 * Released under the MIT license.
11713 * https://jquery.org/license
11714 *
11715 * Date: Wed May 15 16:49:44 2024 +0200
11716 */
11717
11718( function( root, factory ) {
11719 "use strict";
11720
11721 if ( typeof define === "function" && define.amd ) {
11722
11723 // AMD. Register as an anonymous module.
11724 define( [ "jquery" ], factory );
11725 } else if ( typeof exports === "object" ) {
11726 module.exports = factory( require( "jquery" ) );
11727 } else {
11728 factory( root.jQuery );
11729 }
11730} )( this, function( jQuery, undefined ) {
11731 "use strict";
11732
11733 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
11734 "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
11735
11736 class2type = {},
11737 toString = class2type.toString,
11738
11739 // plusequals test for += 100 -= 100
11740 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
11741
11742 // a set of RE's that can match strings and generate color tuples.
11743 stringParsers = [ {
11744 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
11745 parse: function( execResult ) {
11746 return [
11747 execResult[ 1 ],
11748 execResult[ 2 ],
11749 execResult[ 3 ],
11750 execResult[ 4 ]
11751 ];
11752 }
11753 }, {
11754 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
11755 parse: function( execResult ) {
11756 return [
11757 execResult[ 1 ] * 2.55,
11758 execResult[ 2 ] * 2.55,
11759 execResult[ 3 ] * 2.55,
11760 execResult[ 4 ]
11761 ];
11762 }
11763 }, {
11764
11765 // this regex ignores A-F because it's compared against an already lowercased string
11766 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/,
11767 parse: function( execResult ) {
11768 return [
11769 parseInt( execResult[ 1 ], 16 ),
11770 parseInt( execResult[ 2 ], 16 ),
11771 parseInt( execResult[ 3 ], 16 ),
11772 execResult[ 4 ] ?
11773 ( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) :
11774 1
11775 ];
11776 }
11777 }, {
11778
11779 // this regex ignores A-F because it's compared against an already lowercased string
11780 re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/,
11781 parse: function( execResult ) {
11782 return [
11783 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
11784 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
11785 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ),
11786 execResult[ 4 ] ?
11787 ( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 )
11788 .toFixed( 2 ) :
11789 1
11790 ];
11791 }
11792 }, {
11793 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
11794 space: "hsla",
11795 parse: function( execResult ) {
11796 return [
11797 execResult[ 1 ],
11798 execResult[ 2 ] / 100,
11799 execResult[ 3 ] / 100,
11800 execResult[ 4 ]
11801 ];
11802 }
11803 } ],
11804
11805 // jQuery.Color( )
11806 color = jQuery.Color = function( color, green, blue, alpha ) {
11807 return new jQuery.Color.fn.parse( color, green, blue, alpha );
11808 },
11809 spaces = {
11810 rgba: {
11811 props: {
11812 red: {
11813 idx: 0,
11814 type: "byte"
11815 },
11816 green: {
11817 idx: 1,
11818 type: "byte"
11819 },
11820 blue: {
11821 idx: 2,
11822 type: "byte"
11823 }
11824 }
11825 },
11826
11827 hsla: {
11828 props: {
11829 hue: {
11830 idx: 0,
11831 type: "degrees"
11832 },
11833 saturation: {
11834 idx: 1,
11835 type: "percent"
11836 },
11837 lightness: {
11838 idx: 2,
11839 type: "percent"
11840 }
11841 }
11842 }
11843 },
11844 propTypes = {
11845 "byte": {
11846 floor: true,
11847 max: 255
11848 },
11849 "percent": {
11850 max: 1
11851 },
11852 "degrees": {
11853 mod: 360,
11854 floor: true
11855 }
11856 },
11857
11858 // colors = jQuery.Color.names
11859 colors,
11860
11861 // local aliases of functions called often
11862 each = jQuery.each;
11863
11864// define cache name and alpha properties
11865// for rgba and hsla spaces
11866each( spaces, function( spaceName, space ) {
11867 space.cache = "_" + spaceName;
11868 space.props.alpha = {
11869 idx: 3,
11870 type: "percent",
11871 def: 1
11872 };
11873} );
11874
11875// Populate the class2type map
11876jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
11877 function( _i, name ) {
11878 class2type[ "[object " + name + "]" ] = name.toLowerCase();
11879 } );
11880
11881function getType( obj ) {
11882 if ( obj == null ) {
11883 return obj + "";
11884 }
11885
11886 return typeof obj === "object" ?
11887 class2type[ toString.call( obj ) ] || "object" :
11888 typeof obj;
11889}
11890
11891function clamp( value, prop, allowEmpty ) {
11892 var type = propTypes[ prop.type ] || {};
11893
11894 if ( value == null ) {
11895 return ( allowEmpty || !prop.def ) ? null : prop.def;
11896 }
11897
11898 // ~~ is an short way of doing floor for positive numbers
11899 value = type.floor ? ~~value : parseFloat( value );
11900
11901 if ( type.mod ) {
11902
11903 // we add mod before modding to make sure that negatives values
11904 // get converted properly: -10 -> 350
11905 return ( value + type.mod ) % type.mod;
11906 }
11907
11908 // for now all property types without mod have min and max
11909 return Math.min( type.max, Math.max( 0, value ) );
11910}
11911
11912function stringParse( string ) {
11913 var inst = color(),
11914 rgba = inst._rgba = [];
11915
11916 string = string.toLowerCase();
11917
11918 each( stringParsers, function( _i, parser ) {
11919 var parsed,
11920 match = parser.re.exec( string ),
11921 values = match && parser.parse( match ),
11922 spaceName = parser.space || "rgba";
11923
11924 if ( values ) {
11925 parsed = inst[ spaceName ]( values );
11926
11927 // if this was an rgba parse the assignment might happen twice
11928 // oh well....
11929 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
11930 rgba = inst._rgba = parsed._rgba;
11931
11932 // exit each( stringParsers ) here because we matched
11933 return false;
11934 }
11935 } );
11936
11937 // Found a stringParser that handled it
11938 if ( rgba.length ) {
11939
11940 // if this came from a parsed string, force "transparent" when alpha is 0
11941 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
11942 if ( rgba.join() === "0,0,0,0" ) {
11943 jQuery.extend( rgba, colors.transparent );
11944 }
11945 return inst;
11946 }
11947
11948 // named colors
11949 return colors[ string ];
11950}
11951
11952color.fn = jQuery.extend( color.prototype, {
11953 parse: function( red, green, blue, alpha ) {
11954 if ( red === undefined ) {
11955 this._rgba = [ null, null, null, null ];
11956 return this;
11957 }
11958 if ( red.jquery || red.nodeType ) {
11959 red = jQuery( red ).css( green );
11960 green = undefined;
11961 }
11962
11963 var inst = this,
11964 type = getType( red ),
11965 rgba = this._rgba = [];
11966
11967 // more than 1 argument specified - assume ( red, green, blue, alpha )
11968 if ( green !== undefined ) {
11969 red = [ red, green, blue, alpha ];
11970 type = "array";
11971 }
11972
11973 if ( type === "string" ) {
11974 return this.parse( stringParse( red ) || colors._default );
11975 }
11976
11977 if ( type === "array" ) {
11978 each( spaces.rgba.props, function( _key, prop ) {
11979 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
11980 } );
11981 return this;
11982 }
11983
11984 if ( type === "object" ) {
11985 if ( red instanceof color ) {
11986 each( spaces, function( _spaceName, space ) {
11987 if ( red[ space.cache ] ) {
11988 inst[ space.cache ] = red[ space.cache ].slice();
11989 }
11990 } );
11991 } else {
11992 each( spaces, function( _spaceName, space ) {
11993 var cache = space.cache;
11994 each( space.props, function( key, prop ) {
11995
11996 // if the cache doesn't exist, and we know how to convert
11997 if ( !inst[ cache ] && space.to ) {
11998
11999 // if the value was null, we don't need to copy it
12000 // if the key was alpha, we don't need to copy it either
12001 if ( key === "alpha" || red[ key ] == null ) {
12002 return;
12003 }
12004 inst[ cache ] = space.to( inst._rgba );
12005 }
12006
12007 // this is the only case where we allow nulls for ALL properties.
12008 // call clamp with alwaysAllowEmpty
12009 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
12010 } );
12011
12012 // everything defined but alpha?
12013 if ( inst[ cache ] && jQuery.inArray(
12014 null,
12015 inst[ cache ].slice( 0, 3 )
12016 ) < 0 ) {
12017
12018 // use the default of 1
12019 if ( inst[ cache ][ 3 ] == null ) {
12020 inst[ cache ][ 3 ] = 1;
12021 }
12022
12023 if ( space.from ) {
12024 inst._rgba = space.from( inst[ cache ] );
12025 }
12026 }
12027 } );
12028 }
12029 return this;
12030 }
12031 },
12032 is: function( compare ) {
12033 var is = color( compare ),
12034 same = true,
12035 inst = this;
12036
12037 each( spaces, function( _, space ) {
12038 var localCache,
12039 isCache = is[ space.cache ];
12040 if ( isCache ) {
12041 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
12042 each( space.props, function( _, prop ) {
12043 if ( isCache[ prop.idx ] != null ) {
12044 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
12045 return same;
12046 }
12047 } );
12048 }
12049 return same;
12050 } );
12051 return same;
12052 },
12053 _space: function() {
12054 var used = [],
12055 inst = this;
12056 each( spaces, function( spaceName, space ) {
12057 if ( inst[ space.cache ] ) {
12058 used.push( spaceName );
12059 }
12060 } );
12061 return used.pop();
12062 },
12063 transition: function( other, distance ) {
12064 var end = color( other ),
12065 spaceName = end._space(),
12066 space = spaces[ spaceName ],
12067 startColor = this.alpha() === 0 ? color( "transparent" ) : this,
12068 start = startColor[ space.cache ] || space.to( startColor._rgba ),
12069 result = start.slice();
12070
12071 end = end[ space.cache ];
12072 each( space.props, function( _key, prop ) {
12073 var index = prop.idx,
12074 startValue = start[ index ],
12075 endValue = end[ index ],
12076 type = propTypes[ prop.type ] || {};
12077
12078 // if null, don't override start value
12079 if ( endValue === null ) {
12080 return;
12081 }
12082
12083 // if null - use end
12084 if ( startValue === null ) {
12085 result[ index ] = endValue;
12086 } else {
12087 if ( type.mod ) {
12088 if ( endValue - startValue > type.mod / 2 ) {
12089 startValue += type.mod;
12090 } else if ( startValue - endValue > type.mod / 2 ) {
12091 startValue -= type.mod;
12092 }
12093 }
12094 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
12095 }
12096 } );
12097 return this[ spaceName ]( result );
12098 },
12099 blend: function( opaque ) {
12100
12101 // if we are already opaque - return ourself
12102 if ( this._rgba[ 3 ] === 1 ) {
12103 return this;
12104 }
12105
12106 var rgb = this._rgba.slice(),
12107 a = rgb.pop(),
12108 blend = color( opaque )._rgba;
12109
12110 return color( jQuery.map( rgb, function( v, i ) {
12111 return ( 1 - a ) * blend[ i ] + a * v;
12112 } ) );
12113 },
12114 toRgbaString: function() {
12115 var prefix = "rgba(",
12116 rgba = jQuery.map( this._rgba, function( v, i ) {
12117 if ( v != null ) {
12118 return v;
12119 }
12120 return i > 2 ? 1 : 0;
12121 } );
12122
12123 if ( rgba[ 3 ] === 1 ) {
12124 rgba.pop();
12125 prefix = "rgb(";
12126 }
12127
12128 return prefix + rgba.join( ", " ) + ")";
12129 },
12130 toHslaString: function() {
12131 var prefix = "hsla(",
12132 hsla = jQuery.map( this.hsla(), function( v, i ) {
12133 if ( v == null ) {
12134 v = i > 2 ? 1 : 0;
12135 }
12136
12137 // catch 1 and 2
12138 if ( i && i < 3 ) {
12139 v = Math.round( v * 100 ) + "%";
12140 }
12141 return v;
12142 } );
12143
12144 if ( hsla[ 3 ] === 1 ) {
12145 hsla.pop();
12146 prefix = "hsl(";
12147 }
12148 return prefix + hsla.join( ", " ) + ")";
12149 },
12150 toHexString: function( includeAlpha ) {
12151 var rgba = this._rgba.slice(),
12152 alpha = rgba.pop();
12153
12154 if ( includeAlpha ) {
12155 rgba.push( ~~( alpha * 255 ) );
12156 }
12157
12158 return "#" + jQuery.map( rgba, function( v ) {
12159
12160 // default to 0 when nulls exist
12161 return ( "0" + ( v || 0 ).toString( 16 ) ).substr( -2 );
12162 } ).join( "" );
12163 },
12164 toString: function() {
12165 return this.toRgbaString();
12166 }
12167} );
12168color.fn.parse.prototype = color.fn;
12169
12170// hsla conversions adapted from:
12171// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
12172
12173function hue2rgb( p, q, h ) {
12174 h = ( h + 1 ) % 1;
12175 if ( h * 6 < 1 ) {
12176 return p + ( q - p ) * h * 6;
12177 }
12178 if ( h * 2 < 1 ) {
12179 return q;
12180 }
12181 if ( h * 3 < 2 ) {
12182 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
12183 }
12184 return p;
12185}
12186
12187spaces.hsla.to = function( rgba ) {
12188 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
12189 return [ null, null, null, rgba[ 3 ] ];
12190 }
12191 var r = rgba[ 0 ] / 255,
12192 g = rgba[ 1 ] / 255,
12193 b = rgba[ 2 ] / 255,
12194 a = rgba[ 3 ],
12195 max = Math.max( r, g, b ),
12196 min = Math.min( r, g, b ),
12197 diff = max - min,
12198 add = max + min,
12199 l = add * 0.5,
12200 h, s;
12201
12202 if ( min === max ) {
12203 h = 0;
12204 } else if ( r === max ) {
12205 h = ( 60 * ( g - b ) / diff ) + 360;
12206 } else if ( g === max ) {
12207 h = ( 60 * ( b - r ) / diff ) + 120;
12208 } else {
12209 h = ( 60 * ( r - g ) / diff ) + 240;
12210 }
12211
12212 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
12213 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
12214 if ( diff === 0 ) {
12215 s = 0;
12216 } else if ( l <= 0.5 ) {
12217 s = diff / add;
12218 } else {
12219 s = diff / ( 2 - add );
12220 }
12221 return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
12222};
12223
12224spaces.hsla.from = function( hsla ) {
12225 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
12226 return [ null, null, null, hsla[ 3 ] ];
12227 }
12228 var h = hsla[ 0 ] / 360,
12229 s = hsla[ 1 ],
12230 l = hsla[ 2 ],
12231 a = hsla[ 3 ],
12232 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
12233 p = 2 * l - q;
12234
12235 return [
12236 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
12237 Math.round( hue2rgb( p, q, h ) * 255 ),
12238 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
12239 a
12240 ];
12241};
12242
12243
12244each( spaces, function( spaceName, space ) {
12245 var props = space.props,
12246 cache = space.cache,
12247 to = space.to,
12248 from = space.from;
12249
12250 // makes rgba() and hsla()
12251 color.fn[ spaceName ] = function( value ) {
12252
12253 // generate a cache for this space if it doesn't exist
12254 if ( to && !this[ cache ] ) {
12255 this[ cache ] = to( this._rgba );
12256 }
12257 if ( value === undefined ) {
12258 return this[ cache ].slice();
12259 }
12260
12261 var ret,
12262 type = getType( value ),
12263 arr = ( type === "array" || type === "object" ) ? value : arguments,
12264 local = this[ cache ].slice();
12265
12266 each( props, function( key, prop ) {
12267 var val = arr[ type === "object" ? key : prop.idx ];
12268 if ( val == null ) {
12269 val = local[ prop.idx ];
12270 }
12271 local[ prop.idx ] = clamp( val, prop );
12272 } );
12273
12274 if ( from ) {
12275 ret = color( from( local ) );
12276 ret[ cache ] = local;
12277 return ret;
12278 } else {
12279 return color( local );
12280 }
12281 };
12282
12283 // makes red() green() blue() alpha() hue() saturation() lightness()
12284 each( props, function( key, prop ) {
12285
12286 // alpha is included in more than one space
12287 if ( color.fn[ key ] ) {
12288 return;
12289 }
12290 color.fn[ key ] = function( value ) {
12291 var local, cur, match, fn,
12292 vtype = getType( value );
12293
12294 if ( key === "alpha" ) {
12295 fn = this._hsla ? "hsla" : "rgba";
12296 } else {
12297 fn = spaceName;
12298 }
12299 local = this[ fn ]();
12300 cur = local[ prop.idx ];
12301
12302 if ( vtype === "undefined" ) {
12303 return cur;
12304 }
12305
12306 if ( vtype === "function" ) {
12307 value = value.call( this, cur );
12308 vtype = getType( value );
12309 }
12310 if ( value == null && prop.empty ) {
12311 return this;
12312 }
12313 if ( vtype === "string" ) {
12314 match = rplusequals.exec( value );
12315 if ( match ) {
12316 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
12317 }
12318 }
12319 local[ prop.idx ] = value;
12320 return this[ fn ]( local );
12321 };
12322 } );
12323} );
12324
12325// add cssHook and .fx.step function for each named hook.
12326// accept a space separated string of properties
12327color.hook = function( hook ) {
12328 var hooks = hook.split( " " );
12329 each( hooks, function( _i, hook ) {
12330 jQuery.cssHooks[ hook ] = {
12331 set: function( elem, value ) {
12332 var parsed;
12333
12334 if ( value !== "transparent" &&
12335 ( getType( value ) !== "string" ||
12336 ( parsed = stringParse( value ) ) ) ) {
12337 value = color( parsed || value );
12338 value = value.toRgbaString();
12339 }
12340 elem.style[ hook ] = value;
12341 }
12342 };
12343 jQuery.fx.step[ hook ] = function( fx ) {
12344 if ( !fx.colorInit ) {
12345 fx.start = color( fx.elem, hook );
12346 fx.end = color( fx.end );
12347 fx.colorInit = true;
12348 }
12349 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
12350 };
12351 } );
12352
12353};
12354
12355color.hook( stepHooks );
12356
12357jQuery.cssHooks.borderColor = {
12358 expand: function( value ) {
12359 var expanded = {};
12360
12361 each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) {
12362 expanded[ "border" + part + "Color" ] = value;
12363 } );
12364 return expanded;
12365 }
12366};
12367
12368// Basic color names only.
12369// Usage of any of the other color names requires adding yourself or including
12370// jquery.color.svg-names.js.
12371colors = jQuery.Color.names = {
12372
12373 // 4.1. Basic color keywords
12374 aqua: "#00ffff",
12375 black: "#000000",
12376 blue: "#0000ff",
12377 fuchsia: "#ff00ff",
12378 gray: "#808080",
12379 green: "#008000",
12380 lime: "#00ff00",
12381 maroon: "#800000",
12382 navy: "#000080",
12383 olive: "#808000",
12384 purple: "#800080",
12385 red: "#ff0000",
12386 silver: "#c0c0c0",
12387 teal: "#008080",
12388 white: "#ffffff",
12389 yellow: "#ffff00",
12390
12391 // 4.2.3. "transparent" color keyword
12392 transparent: [ null, null, null, 0 ],
12393
12394 _default: "#ffffff"
12395};
12396
12397} );
12398
12399
12400
12401
12402/*!
12403 * jQuery UI Effects 1.14.1
12404 * https://jqueryui.com
12405 *
12406 * Copyright OpenJS Foundation and other contributors
12407 * Released under the MIT license.
12408 * https://jquery.org/license
12409 */
12410
12411//>>label: Effects Core
12412//>>group: Effects
12413/* eslint-disable max-len */
12414//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
12415/* eslint-enable max-len */
12416//>>docs: https://api.jqueryui.com/category/effects-core/
12417//>>demos: https://jqueryui.com/effect/
12418
12419( function( factory ) {
12420 "use strict";
12421
12422 if ( typeof define === "function" && define.amd ) {
12423
12424 // AMD. Register as an anonymous module.
12425 define( [
12426 "jquery",
12427 "./jquery-var-for-color",
12428 "./vendor/jquery-color/jquery.color",
12429 "./version"
12430 ], factory );
12431 } else {
12432
12433 // Browser globals
12434 factory( jQuery );
12435 }
12436} )( function( $ ) {
12437"use strict";
12438
12439var dataSpace = "ui-effects-",
12440 dataSpaceStyle = "ui-effects-style",
12441 dataSpaceAnimated = "ui-effects-animated";
12442
12443$.effects = {
12444 effect: {}
12445};
12446
12447/******************************************************************************/
12448/****************************** CLASS ANIMATIONS ******************************/
12449/******************************************************************************/
12450( function() {
12451
12452var classAnimationActions = [ "add", "remove", "toggle" ],
12453 shorthandStyles = {
12454 border: 1,
12455 borderBottom: 1,
12456 borderColor: 1,
12457 borderLeft: 1,
12458 borderRight: 1,
12459 borderTop: 1,
12460 borderWidth: 1,
12461 margin: 1,
12462 padding: 1
12463 };
12464
12465$.each(
12466 [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
12467 function( _, prop ) {
12468 $.fx.step[ prop ] = function( fx ) {
12469 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
12470 jQuery.style( fx.elem, prop, fx.end );
12471 fx.setAttr = true;
12472 }
12473 };
12474 }
12475);
12476
12477function camelCase( string ) {
12478 return string.replace( /-([\da-z])/gi, function( all, letter ) {
12479 return letter.toUpperCase();
12480 } );
12481}
12482
12483function getElementStyles( elem ) {
12484 var key, len,
12485 style = elem.ownerDocument.defaultView.getComputedStyle( elem ),
12486 styles = {};
12487
12488 len = style.length;
12489 while ( len-- ) {
12490 key = style[ len ];
12491 if ( typeof style[ key ] === "string" ) {
12492 styles[ camelCase( key ) ] = style[ key ];
12493 }
12494 }
12495
12496 return styles;
12497}
12498
12499function styleDifference( oldStyle, newStyle ) {
12500 var diff = {},
12501 name, value;
12502
12503 for ( name in newStyle ) {
12504 value = newStyle[ name ];
12505 if ( oldStyle[ name ] !== value ) {
12506 if ( !shorthandStyles[ name ] ) {
12507 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
12508 diff[ name ] = value;
12509 }
12510 }
12511 }
12512 }
12513
12514 return diff;
12515}
12516
12517$.effects.animateClass = function( value, duration, easing, callback ) {
12518 var o = $.speed( duration, easing, callback );
12519
12520 return this.queue( function() {
12521 var animated = $( this ),
12522 baseClass = animated.attr( "class" ) || "",
12523 applyClassChange,
12524 allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
12525
12526 // Map the animated objects to store the original styles.
12527 allAnimations = allAnimations.map( function() {
12528 var el = $( this );
12529 return {
12530 el: el,
12531 start: getElementStyles( this )
12532 };
12533 } );
12534
12535 // Apply class change
12536 applyClassChange = function() {
12537 $.each( classAnimationActions, function( i, action ) {
12538 if ( value[ action ] ) {
12539 animated[ action + "Class" ]( value[ action ] );
12540 }
12541 } );
12542 };
12543 applyClassChange();
12544
12545 // Map all animated objects again - calculate new styles and diff
12546 allAnimations = allAnimations.map( function() {
12547 this.end = getElementStyles( this.el[ 0 ] );
12548 this.diff = styleDifference( this.start, this.end );
12549 return this;
12550 } );
12551
12552 // Apply original class
12553 animated.attr( "class", baseClass );
12554
12555 // Map all animated objects again - this time collecting a promise
12556 allAnimations = allAnimations.map( function() {
12557 var styleInfo = this,
12558 dfd = $.Deferred(),
12559 opts = $.extend( {}, o, {
12560 queue: false,
12561 complete: function() {
12562 dfd.resolve( styleInfo );
12563 }
12564 } );
12565
12566 this.el.animate( this.diff, opts );
12567 return dfd.promise();
12568 } );
12569
12570 // Once all animations have completed:
12571 $.when.apply( $, allAnimations.get() ).done( function() {
12572
12573 // Set the final class
12574 applyClassChange();
12575
12576 // For each animated element,
12577 // clear all css properties that were animated
12578 $.each( arguments, function() {
12579 var el = this.el;
12580 $.each( this.diff, function( key ) {
12581 el.css( key, "" );
12582 } );
12583 } );
12584
12585 // This is guarnteed to be there if you use jQuery.speed()
12586 // it also handles dequeuing the next anim...
12587 o.complete.call( animated[ 0 ] );
12588 } );
12589 } );
12590};
12591
12592$.fn.extend( {
12593 addClass: ( function( orig ) {
12594 return function( classNames, speed, easing, callback ) {
12595 return speed ?
12596 $.effects.animateClass.call( this,
12597 { add: classNames }, speed, easing, callback ) :
12598 orig.apply( this, arguments );
12599 };
12600 } )( $.fn.addClass ),
12601
12602 removeClass: ( function( orig ) {
12603 return function( classNames, speed, easing, callback ) {
12604 return arguments.length > 1 ?
12605 $.effects.animateClass.call( this,
12606 { remove: classNames }, speed, easing, callback ) :
12607 orig.apply( this, arguments );
12608 };
12609 } )( $.fn.removeClass ),
12610
12611 toggleClass: ( function( orig ) {
12612 return function( classNames, force, speed, easing, callback ) {
12613 if ( typeof force === "boolean" || force === undefined ) {
12614 if ( !speed ) {
12615
12616 // Without speed parameter
12617 return orig.apply( this, arguments );
12618 } else {
12619 return $.effects.animateClass.call( this,
12620 ( force ? { add: classNames } : { remove: classNames } ),
12621 speed, easing, callback );
12622 }
12623 } else {
12624
12625 // Without force parameter
12626 return $.effects.animateClass.call( this,
12627 { toggle: classNames }, force, speed, easing );
12628 }
12629 };
12630 } )( $.fn.toggleClass ),
12631
12632 switchClass: function( remove, add, speed, easing, callback ) {
12633 return $.effects.animateClass.call( this, {
12634 add: add,
12635 remove: remove
12636 }, speed, easing, callback );
12637 }
12638} );
12639
12640} )();
12641
12642/******************************************************************************/
12643/*********************************** EFFECTS **********************************/
12644/******************************************************************************/
12645
12646( function() {
12647
12648if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) {
12649 $.expr.pseudos.animated = ( function( orig ) {
12650 return function( elem ) {
12651 return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
12652 };
12653 } )( $.expr.pseudos.animated );
12654}
12655
12656if ( $.uiBackCompat === true ) {
12657 $.extend( $.effects, {
12658
12659 // Saves a set of properties in a data storage
12660 save: function( element, set ) {
12661 var i = 0, length = set.length;
12662 for ( ; i < length; i++ ) {
12663 if ( set[ i ] !== null ) {
12664 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
12665 }
12666 }
12667 },
12668
12669 // Restores a set of previously saved properties from a data storage
12670 restore: function( element, set ) {
12671 var val, i = 0, length = set.length;
12672 for ( ; i < length; i++ ) {
12673 if ( set[ i ] !== null ) {
12674 val = element.data( dataSpace + set[ i ] );
12675 element.css( set[ i ], val );
12676 }
12677 }
12678 },
12679
12680 setMode: function( el, mode ) {
12681 if ( mode === "toggle" ) {
12682 mode = el.is( ":hidden" ) ? "show" : "hide";
12683 }
12684 return mode;
12685 },
12686
12687 // Wraps the element around a wrapper that copies position properties
12688 createWrapper: function( element ) {
12689
12690 // If the element is already wrapped, return it
12691 if ( element.parent().is( ".ui-effects-wrapper" ) ) {
12692 return element.parent();
12693 }
12694
12695 // Wrap the element
12696 var props = {
12697 width: element.outerWidth( true ),
12698 height: element.outerHeight( true ),
12699 "float": element.css( "float" )
12700 },
12701 wrapper = $( "<div></div>" )
12702 .addClass( "ui-effects-wrapper" )
12703 .css( {
12704 fontSize: "100%",
12705 background: "transparent",
12706 border: "none",
12707 margin: 0,
12708 padding: 0
12709 } ),
12710
12711 // Store the size in case width/height are defined in % - Fixes #5245
12712 size = {
12713 width: element.width(),
12714 height: element.height()
12715 },
12716 active = document.activeElement;
12717
12718 // Support: Firefox
12719 // Firefox incorrectly exposes anonymous content
12720 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
12721 try {
12722 // eslint-disable-next-line no-unused-expressions
12723 active.id;
12724 } catch ( e ) {
12725 active = document.body;
12726 }
12727
12728 element.wrap( wrapper );
12729
12730 // Fixes #7595 - Elements lose focus when wrapped.
12731 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
12732 $( active ).trigger( "focus" );
12733 }
12734
12735 // Hotfix for jQuery 1.4 since some change in wrap() seems to actually
12736 // lose the reference to the wrapped element
12737 wrapper = element.parent();
12738
12739 // Transfer positioning properties to the wrapper
12740 if ( element.css( "position" ) === "static" ) {
12741 wrapper.css( { position: "relative" } );
12742 element.css( { position: "relative" } );
12743 } else {
12744 $.extend( props, {
12745 position: element.css( "position" ),
12746 zIndex: element.css( "z-index" )
12747 } );
12748 $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
12749 props[ pos ] = element.css( pos );
12750 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
12751 props[ pos ] = "auto";
12752 }
12753 } );
12754 element.css( {
12755 position: "relative",
12756 top: 0,
12757 left: 0,
12758 right: "auto",
12759 bottom: "auto"
12760 } );
12761 }
12762 element.css( size );
12763
12764 return wrapper.css( props ).show();
12765 },
12766
12767 removeWrapper: function( element ) {
12768 var active = document.activeElement;
12769
12770 if ( element.parent().is( ".ui-effects-wrapper" ) ) {
12771 element.parent().replaceWith( element );
12772
12773 // Fixes #7595 - Elements lose focus when wrapped.
12774 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
12775 $( active ).trigger( "focus" );
12776 }
12777 }
12778
12779 return element;
12780 }
12781 } );
12782}
12783
12784$.extend( $.effects, {
12785 version: "1.14.1",
12786
12787 define: function( name, mode, effect ) {
12788 if ( !effect ) {
12789 effect = mode;
12790 mode = "effect";
12791 }
12792
12793 $.effects.effect[ name ] = effect;
12794 $.effects.effect[ name ].mode = mode;
12795
12796 return effect;
12797 },
12798
12799 scaledDimensions: function( element, percent, direction ) {
12800 if ( percent === 0 ) {
12801 return {
12802 height: 0,
12803 width: 0,
12804 outerHeight: 0,
12805 outerWidth: 0
12806 };
12807 }
12808
12809 var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
12810 y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
12811
12812 return {
12813 height: element.height() * y,
12814 width: element.width() * x,
12815 outerHeight: element.outerHeight() * y,
12816 outerWidth: element.outerWidth() * x
12817 };
12818
12819 },
12820
12821 clipToBox: function( animation ) {
12822 return {
12823 width: animation.clip.right - animation.clip.left,
12824 height: animation.clip.bottom - animation.clip.top,
12825 left: animation.clip.left,
12826 top: animation.clip.top
12827 };
12828 },
12829
12830 // Injects recently queued functions to be first in line (after "inprogress")
12831 unshift: function( element, queueLength, count ) {
12832 var queue = element.queue();
12833
12834 if ( queueLength > 1 ) {
12835 queue.splice.apply( queue,
12836 [ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
12837 }
12838 element.dequeue();
12839 },
12840
12841 saveStyle: function( element ) {
12842 element.data( dataSpaceStyle, element[ 0 ].style.cssText );
12843 },
12844
12845 restoreStyle: function( element ) {
12846 element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
12847 element.removeData( dataSpaceStyle );
12848 },
12849
12850 mode: function( element, mode ) {
12851 var hidden = element.is( ":hidden" );
12852
12853 if ( mode === "toggle" ) {
12854 mode = hidden ? "show" : "hide";
12855 }
12856 if ( hidden ? mode === "hide" : mode === "show" ) {
12857 mode = "none";
12858 }
12859 return mode;
12860 },
12861
12862 // Translates a [top,left] array into a baseline value
12863 getBaseline: function( origin, original ) {
12864 var y, x;
12865
12866 switch ( origin[ 0 ] ) {
12867 case "top":
12868 y = 0;
12869 break;
12870 case "middle":
12871 y = 0.5;
12872 break;
12873 case "bottom":
12874 y = 1;
12875 break;
12876 default:
12877 y = origin[ 0 ] / original.height;
12878 }
12879
12880 switch ( origin[ 1 ] ) {
12881 case "left":
12882 x = 0;
12883 break;
12884 case "center":
12885 x = 0.5;
12886 break;
12887 case "right":
12888 x = 1;
12889 break;
12890 default:
12891 x = origin[ 1 ] / original.width;
12892 }
12893
12894 return {
12895 x: x,
12896 y: y
12897 };
12898 },
12899
12900 // Creates a placeholder element so that the original element can be made absolute
12901 createPlaceholder: function( element ) {
12902 var placeholder,
12903 cssPosition = element.css( "position" ),
12904 position = element.position();
12905
12906 // Lock in margins first to account for form elements, which
12907 // will change margin if you explicitly set height
12908 // see: https://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
12909 // Support: Safari
12910 element.css( {
12911 marginTop: element.css( "marginTop" ),
12912 marginBottom: element.css( "marginBottom" ),
12913 marginLeft: element.css( "marginLeft" ),
12914 marginRight: element.css( "marginRight" )
12915 } )
12916 .outerWidth( element.outerWidth() )
12917 .outerHeight( element.outerHeight() );
12918
12919 if ( /^(static|relative)/.test( cssPosition ) ) {
12920 cssPosition = "absolute";
12921
12922 placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
12923
12924 // Convert inline to inline block to account for inline elements
12925 // that turn to inline block based on content (like img)
12926 display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
12927 "inline-block" :
12928 "block",
12929 visibility: "hidden",
12930
12931 // Margins need to be set to account for margin collapse
12932 marginTop: element.css( "marginTop" ),
12933 marginBottom: element.css( "marginBottom" ),
12934 marginLeft: element.css( "marginLeft" ),
12935 marginRight: element.css( "marginRight" ),
12936 "float": element.css( "float" )
12937 } )
12938 .outerWidth( element.outerWidth() )
12939 .outerHeight( element.outerHeight() )
12940 .addClass( "ui-effects-placeholder" );
12941
12942 element.data( dataSpace + "placeholder", placeholder );
12943 }
12944
12945 element.css( {
12946 position: cssPosition,
12947 left: position.left,
12948 top: position.top
12949 } );
12950
12951 return placeholder;
12952 },
12953
12954 removePlaceholder: function( element ) {
12955 var dataKey = dataSpace + "placeholder",
12956 placeholder = element.data( dataKey );
12957
12958 if ( placeholder ) {
12959 placeholder.remove();
12960 element.removeData( dataKey );
12961 }
12962 },
12963
12964 // Removes a placeholder if it exists and restores
12965 // properties that were modified during placeholder creation
12966 cleanUp: function( element ) {
12967 $.effects.restoreStyle( element );
12968 $.effects.removePlaceholder( element );
12969 },
12970
12971 setTransition: function( element, list, factor, value ) {
12972 value = value || {};
12973 $.each( list, function( i, x ) {
12974 var unit = element.cssUnit( x );
12975 if ( unit[ 0 ] > 0 ) {
12976 value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
12977 }
12978 } );
12979 return value;
12980 }
12981} );
12982
12983// Return an effect options object for the given parameters:
12984function _normalizeArguments( effect, options, speed, callback ) {
12985
12986 // Allow passing all options as the first parameter
12987 if ( $.isPlainObject( effect ) ) {
12988 options = effect;
12989 effect = effect.effect;
12990 }
12991
12992 // Convert to an object
12993 effect = { effect: effect };
12994
12995 // Catch (effect, null, ...)
12996 if ( options == null ) {
12997 options = {};
12998 }
12999
13000 // Catch (effect, callback)
13001 if ( typeof options === "function" ) {
13002 callback = options;
13003 speed = null;
13004 options = {};
13005 }
13006
13007 // Catch (effect, speed, ?)
13008 if ( typeof options === "number" || $.fx.speeds[ options ] ) {
13009 callback = speed;
13010 speed = options;
13011 options = {};
13012 }
13013
13014 // Catch (effect, options, callback)
13015 if ( typeof speed === "function" ) {
13016 callback = speed;
13017 speed = null;
13018 }
13019
13020 // Add options to effect
13021 if ( options ) {
13022 $.extend( effect, options );
13023 }
13024
13025 speed = speed || options.duration;
13026 effect.duration = $.fx.off ? 0 :
13027 typeof speed === "number" ? speed :
13028 speed in $.fx.speeds ? $.fx.speeds[ speed ] :
13029 $.fx.speeds._default;
13030
13031 effect.complete = callback || options.complete;
13032
13033 return effect;
13034}
13035
13036function standardAnimationOption( option ) {
13037
13038 // Valid standard speeds (nothing, number, named speed)
13039 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
13040 return true;
13041 }
13042
13043 // Invalid strings - treat as "normal" speed
13044 if ( typeof option === "string" && !$.effects.effect[ option ] ) {
13045 return true;
13046 }
13047
13048 // Complete callback
13049 if ( typeof option === "function" ) {
13050 return true;
13051 }
13052
13053 // Options hash (but not naming an effect)
13054 if ( typeof option === "object" && !option.effect ) {
13055 return true;
13056 }
13057
13058 // Didn't match any standard API
13059 return false;
13060}
13061
13062$.fn.extend( {
13063 effect: function( /* effect, options, speed, callback */ ) {
13064 var args = _normalizeArguments.apply( this, arguments ),
13065 effectMethod = $.effects.effect[ args.effect ],
13066 defaultMode = effectMethod.mode,
13067 queue = args.queue,
13068 queueName = queue || "fx",
13069 complete = args.complete,
13070 mode = args.mode,
13071 modes = [],
13072 prefilter = function( next ) {
13073 var el = $( this ),
13074 normalizedMode = $.effects.mode( el, mode ) || defaultMode;
13075
13076 // Sentinel for duck-punching the :animated pseudo-selector
13077 el.data( dataSpaceAnimated, true );
13078
13079 // Save effect mode for later use,
13080 // we can't just call $.effects.mode again later,
13081 // as the .show() below destroys the initial state
13082 modes.push( normalizedMode );
13083
13084 // See $.uiBackCompat inside of run() for removal of defaultMode in 1.14
13085 if ( defaultMode && ( normalizedMode === "show" ||
13086 ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
13087 el.show();
13088 }
13089
13090 if ( !defaultMode || normalizedMode !== "none" ) {
13091 $.effects.saveStyle( el );
13092 }
13093
13094 if ( typeof next === "function" ) {
13095 next();
13096 }
13097 };
13098
13099 if ( $.fx.off || !effectMethod ) {
13100
13101 // Delegate to the original method (e.g., .show()) if possible
13102 if ( mode ) {
13103 return this[ mode ]( args.duration, complete );
13104 } else {
13105 return this.each( function() {
13106 if ( complete ) {
13107 complete.call( this );
13108 }
13109 } );
13110 }
13111 }
13112
13113 function run( next ) {
13114 var elem = $( this );
13115
13116 function cleanup() {
13117 elem.removeData( dataSpaceAnimated );
13118
13119 $.effects.cleanUp( elem );
13120
13121 if ( args.mode === "hide" ) {
13122 elem.hide();
13123 }
13124
13125 done();
13126 }
13127
13128 function done() {
13129 if ( typeof complete === "function" ) {
13130 complete.call( elem[ 0 ] );
13131 }
13132
13133 if ( typeof next === "function" ) {
13134 next();
13135 }
13136 }
13137
13138 // Override mode option on a per element basis,
13139 // as toggle can be either show or hide depending on element state
13140 args.mode = modes.shift();
13141
13142 if ( $.uiBackCompat === true && !defaultMode ) {
13143 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
13144
13145 // Call the core method to track "olddisplay" properly
13146 elem[ mode ]();
13147 done();
13148 } else {
13149 effectMethod.call( elem[ 0 ], args, done );
13150 }
13151 } else {
13152 if ( args.mode === "none" ) {
13153
13154 // Call the core method to track "olddisplay" properly
13155 elem[ mode ]();
13156 done();
13157 } else {
13158 effectMethod.call( elem[ 0 ], args, cleanup );
13159 }
13160 }
13161 }
13162
13163 // Run prefilter on all elements first to ensure that
13164 // any showing or hiding happens before placeholder creation,
13165 // which ensures that any layout changes are correctly captured.
13166 return queue === false ?
13167 this.each( prefilter ).each( run ) :
13168 this.queue( queueName, prefilter ).queue( queueName, run );
13169 },
13170
13171 show: ( function( orig ) {
13172 return function( option ) {
13173 if ( standardAnimationOption( option ) ) {
13174 return orig.apply( this, arguments );
13175 } else {
13176 var args = _normalizeArguments.apply( this, arguments );
13177 args.mode = "show";
13178 return this.effect.call( this, args );
13179 }
13180 };
13181 } )( $.fn.show ),
13182
13183 hide: ( function( orig ) {
13184 return function( option ) {
13185 if ( standardAnimationOption( option ) ) {
13186 return orig.apply( this, arguments );
13187 } else {
13188 var args = _normalizeArguments.apply( this, arguments );
13189 args.mode = "hide";
13190 return this.effect.call( this, args );
13191 }
13192 };
13193 } )( $.fn.hide ),
13194
13195 toggle: ( function( orig ) {
13196 return function( option ) {
13197 if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
13198 return orig.apply( this, arguments );
13199 } else {
13200 var args = _normalizeArguments.apply( this, arguments );
13201 args.mode = "toggle";
13202 return this.effect.call( this, args );
13203 }
13204 };
13205 } )( $.fn.toggle ),
13206
13207 cssUnit: function( key ) {
13208 var style = this.css( key ),
13209 val = [];
13210
13211 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
13212 if ( style.indexOf( unit ) > 0 ) {
13213 val = [ parseFloat( style ), unit ];
13214 }
13215 } );
13216 return val;
13217 },
13218
13219 cssClip: function( clipObj ) {
13220 if ( clipObj ) {
13221 return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
13222 clipObj.bottom + "px " + clipObj.left + "px)" );
13223 }
13224 return parseClip( this.css( "clip" ), this );
13225 },
13226
13227 transfer: function( options, done ) {
13228 var element = $( this ),
13229 target = $( options.to ),
13230 targetFixed = target.css( "position" ) === "fixed",
13231 body = $( "body" ),
13232 fixTop = targetFixed ? body.scrollTop() : 0,
13233 fixLeft = targetFixed ? body.scrollLeft() : 0,
13234 endPosition = target.offset(),
13235 animation = {
13236 top: endPosition.top - fixTop,
13237 left: endPosition.left - fixLeft,
13238 height: target.innerHeight(),
13239 width: target.innerWidth()
13240 },
13241 startPosition = element.offset(),
13242 transfer = $( "<div class='ui-effects-transfer'></div>" );
13243
13244 transfer
13245 .appendTo( "body" )
13246 .addClass( options.className )
13247 .css( {
13248 top: startPosition.top - fixTop,
13249 left: startPosition.left - fixLeft,
13250 height: element.innerHeight(),
13251 width: element.innerWidth(),
13252 position: targetFixed ? "fixed" : "absolute"
13253 } )
13254 .animate( animation, options.duration, options.easing, function() {
13255 transfer.remove();
13256 if ( typeof done === "function" ) {
13257 done();
13258 }
13259 } );
13260 }
13261} );
13262
13263function parseClip( str, element ) {
13264 var outerWidth = element.outerWidth(),
13265 outerHeight = element.outerHeight(),
13266 clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,
13267 values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
13268
13269 return {
13270 top: parseFloat( values[ 1 ] ) || 0,
13271 right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
13272 bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
13273 left: parseFloat( values[ 4 ] ) || 0
13274 };
13275}
13276
13277$.fx.step.clip = function( fx ) {
13278 if ( !fx.clipInit ) {
13279 fx.start = $( fx.elem ).cssClip();
13280 if ( typeof fx.end === "string" ) {
13281 fx.end = parseClip( fx.end, fx.elem );
13282 }
13283 fx.clipInit = true;
13284 }
13285
13286 $( fx.elem ).cssClip( {
13287 top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
13288 right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
13289 bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
13290 left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
13291 } );
13292};
13293
13294} )();
13295
13296/******************************************************************************/
13297/*********************************** EASING ***********************************/
13298/******************************************************************************/
13299
13300( function() {
13301
13302// Based on easing equations from Robert Penner (http://robertpenner.com/easing)
13303
13304var baseEasings = {};
13305
13306$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
13307 baseEasings[ name ] = function( p ) {
13308 return Math.pow( p, i + 2 );
13309 };
13310} );
13311
13312$.extend( baseEasings, {
13313 Sine: function( p ) {
13314 return 1 - Math.cos( p * Math.PI / 2 );
13315 },
13316 Circ: function( p ) {
13317 return 1 - Math.sqrt( 1 - p * p );
13318 },
13319 Elastic: function( p ) {
13320 return p === 0 || p === 1 ? p :
13321 -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
13322 },
13323 Back: function( p ) {
13324 return p * p * ( 3 * p - 2 );
13325 },
13326 Bounce: function( p ) {
13327 var pow2,
13328 bounce = 4;
13329
13330 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
13331 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
13332 }
13333} );
13334
13335$.each( baseEasings, function( name, easeIn ) {
13336 $.easing[ "easeIn" + name ] = easeIn;
13337 $.easing[ "easeOut" + name ] = function( p ) {
13338 return 1 - easeIn( 1 - p );
13339 };
13340 $.easing[ "easeInOut" + name ] = function( p ) {
13341 return p < 0.5 ?
13342 easeIn( p * 2 ) / 2 :
13343 1 - easeIn( p * -2 + 2 ) / 2;
13344 };
13345} );
13346
13347} )();
13348
13349return $.effects;
13350
13351} );
13352
13353
13354/*!
13355 * jQuery UI Focusable 1.14.1
13356 * https://jqueryui.com
13357 *
13358 * Copyright OpenJS Foundation and other contributors
13359 * Released under the MIT license.
13360 * https://jquery.org/license
13361 */
13362
13363//>>label: :focusable Selector
13364//>>group: Core
13365//>>description: Selects elements which can be focused.
13366//>>docs: https://api.jqueryui.com/focusable-selector/
13367
13368( function( factory ) {
13369 "use strict";
13370
13371 if ( typeof define === "function" && define.amd ) {
13372
13373 // AMD. Register as an anonymous module.
13374 define( [ "jquery", "./version" ], factory );
13375 } else {
13376
13377 // Browser globals
13378 factory( jQuery );
13379 }
13380} )( function( $ ) {
13381"use strict";
13382
13383// Selectors
13384$.ui.focusable = function( element, hasTabindex ) {
13385 var map, mapName, img, focusableIfVisible, fieldset,
13386 nodeName = element.nodeName.toLowerCase();
13387
13388 if ( "area" === nodeName ) {
13389 map = element.parentNode;
13390 mapName = map.name;
13391 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
13392 return false;
13393 }
13394 img = $( "img[usemap='#" + mapName + "']" );
13395 return img.length > 0 && img.is( ":visible" );
13396 }
13397
13398 if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
13399 focusableIfVisible = !element.disabled;
13400
13401 if ( focusableIfVisible ) {
13402
13403 // Form controls within a disabled fieldset are disabled.
13404 // However, controls within the fieldset's legend do not get disabled.
13405 // Since controls generally aren't placed inside legends, we skip
13406 // this portion of the check.
13407 fieldset = $( element ).closest( "fieldset" )[ 0 ];
13408 if ( fieldset ) {
13409 focusableIfVisible = !fieldset.disabled;
13410 }
13411 }
13412 } else if ( "a" === nodeName ) {
13413 focusableIfVisible = element.href || hasTabindex;
13414 } else {
13415 focusableIfVisible = hasTabindex;
13416 }
13417
13418 return focusableIfVisible && $( element ).is( ":visible" ) &&
13419 $( element ).css( "visibility" ) === "visible";
13420};
13421
13422$.extend( $.expr.pseudos, {
13423 focusable: function( element ) {
13424 return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
13425 }
13426} );
13427
13428return $.ui.focusable;
13429
13430} );
13431
13432
13433/*!
13434 * jQuery UI Form Reset Mixin 1.14.1
13435 * https://jqueryui.com
13436 *
13437 * Copyright OpenJS Foundation and other contributors
13438 * Released under the MIT license.
13439 * https://jquery.org/license
13440 */
13441
13442//>>label: Form Reset Mixin
13443//>>group: Core
13444//>>description: Refresh input widgets when their form is reset
13445//>>docs: https://api.jqueryui.com/form-reset-mixin/
13446
13447( function( factory ) {
13448 "use strict";
13449
13450 if ( typeof define === "function" && define.amd ) {
13451
13452 // AMD. Register as an anonymous module.
13453 define( [
13454 "jquery",
13455 "./version"
13456 ], factory );
13457 } else {
13458
13459 // Browser globals
13460 factory( jQuery );
13461 }
13462} )( function( $ ) {
13463"use strict";
13464
13465return $.ui.formResetMixin = {
13466 _formResetHandler: function() {
13467 var form = $( this );
13468
13469 // Wait for the form reset to actually happen before refreshing
13470 setTimeout( function() {
13471 var instances = form.data( "ui-form-reset-instances" );
13472 $.each( instances, function() {
13473 this.refresh();
13474 } );
13475 } );
13476 },
13477
13478 _bindFormResetHandler: function() {
13479 this.form = $( this.element.prop( "form" ) );
13480 if ( !this.form.length ) {
13481 return;
13482 }
13483
13484 var instances = this.form.data( "ui-form-reset-instances" ) || [];
13485 if ( !instances.length ) {
13486
13487 // We don't use _on() here because we use a single event handler per form
13488 this.form.on( "reset.ui-form-reset", this._formResetHandler );
13489 }
13490 instances.push( this );
13491 this.form.data( "ui-form-reset-instances", instances );
13492 },
13493
13494 _unbindFormResetHandler: function() {
13495 if ( !this.form.length ) {
13496 return;
13497 }
13498
13499 var instances = this.form.data( "ui-form-reset-instances" );
13500 instances.splice( $.inArray( this, instances ), 1 );
13501 if ( instances.length ) {
13502 this.form.data( "ui-form-reset-instances", instances );
13503 } else {
13504 this.form
13505 .removeData( "ui-form-reset-instances" )
13506 .off( "reset.ui-form-reset" );
13507 }
13508 }
13509};
13510
13511} );
13512
13513
13514/*!
13515 * jQuery UI Legacy jQuery Core patches 1.14.1
13516 * https://jqueryui.com
13517 *
13518 * Copyright OpenJS Foundation and other contributors
13519 * Released under the MIT license.
13520 * https://jquery.org/license
13521 *
13522 */
13523
13524//>>label: Legacy jQuery Core patches
13525//>>group: Core
13526//>>description: Backport `.even()`, `.odd()` and `$.escapeSelector` to older jQuery Core versions (deprecated)
13527
13528( function( factory ) {
13529"use strict";
13530
13531 if ( typeof define === "function" && define.amd ) {
13532
13533 // AMD. Register as an anonymous module.
13534 define( [ "jquery", "./version" ], factory );
13535 } else {
13536
13537 // Browser globals
13538 factory( jQuery );
13539 }
13540} )( function( $ ) {
13541"use strict";
13542
13543// Support: jQuery 2.2.x or older.
13544// This method has been defined in jQuery 3.0.0.
13545// Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js
13546if ( !$.escapeSelector ) {
13547 $.escapeSelector = function( id ) {
13548 return CSS.escape( id + "" );
13549 };
13550}
13551
13552// Support: jQuery 3.4.x or older
13553// These methods have been defined in jQuery 3.5.0.
13554if ( !$.fn.even || !$.fn.odd ) {
13555 $.fn.extend( {
13556 even: function() {
13557 return this.filter( function( i ) {
13558 return i % 2 === 0;
13559 } );
13560 },
13561 odd: function() {
13562 return this.filter( function( i ) {
13563 return i % 2 === 1;
13564 } );
13565 }
13566 } );
13567}
13568
13569} );
13570
13571
13572/*!
13573 * jQuery UI Keycode 1.14.1
13574 * https://jqueryui.com
13575 *
13576 * Copyright OpenJS Foundation and other contributors
13577 * Released under the MIT license.
13578 * https://jquery.org/license
13579 */
13580
13581//>>label: Keycode
13582//>>group: Core
13583//>>description: Provide keycodes as keynames
13584//>>docs: https://api.jqueryui.com/jQuery.ui.keyCode/
13585
13586( function( factory ) {
13587 "use strict";
13588
13589 if ( typeof define === "function" && define.amd ) {
13590
13591 // AMD. Register as an anonymous module.
13592 define( [ "jquery", "./version" ], factory );
13593 } else {
13594
13595 // Browser globals
13596 factory( jQuery );
13597 }
13598} )( function( $ ) {
13599"use strict";
13600
13601return $.ui.keyCode = {
13602 BACKSPACE: 8,
13603 COMMA: 188,
13604 DELETE: 46,
13605 DOWN: 40,
13606 END: 35,
13607 ENTER: 13,
13608 ESCAPE: 27,
13609 HOME: 36,
13610 LEFT: 37,
13611 PAGE_DOWN: 34,
13612 PAGE_UP: 33,
13613 PERIOD: 190,
13614 RIGHT: 39,
13615 SPACE: 32,
13616 TAB: 9,
13617 UP: 38
13618};
13619
13620} );
13621
13622
13623/*!
13624 * jQuery UI Labels 1.14.1
13625 * https://jqueryui.com
13626 *
13627 * Copyright OpenJS Foundation and other contributors
13628 * Released under the MIT license.
13629 * https://jquery.org/license
13630 */
13631
13632//>>label: labels
13633//>>group: Core
13634//>>description: Find all the labels associated with a given input
13635//>>docs: https://api.jqueryui.com/labels/
13636
13637( function( factory ) {
13638 "use strict";
13639
13640 if ( typeof define === "function" && define.amd ) {
13641
13642 // AMD. Register as an anonymous module.
13643 define( [ "jquery", "./version" ], factory );
13644 } else {
13645
13646 // Browser globals
13647 factory( jQuery );
13648 }
13649} )( function( $ ) {
13650"use strict";
13651
13652return $.fn.labels = function() {
13653 var ancestor, selector, id, labels, ancestors;
13654
13655 if ( !this.length ) {
13656 return this.pushStack( [] );
13657 }
13658
13659 // Check control.labels first
13660 if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
13661 return this.pushStack( this[ 0 ].labels );
13662 }
13663
13664 // If `control.labels` is empty - e.g. inside of document fragments - find
13665 // the labels manually
13666 labels = this.eq( 0 ).parents( "label" );
13667
13668 // Look for the label based on the id
13669 id = this.attr( "id" );
13670 if ( id ) {
13671
13672 // We don't search against the document in case the element
13673 // is disconnected from the DOM
13674 ancestor = this.eq( 0 ).parents().last();
13675
13676 // Get a full set of top level ancestors
13677 ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
13678
13679 // Create a selector for the label based on the id
13680 selector = "label[for='" + CSS.escape( id ) + "']";
13681
13682 labels = labels.add( ancestors.find( selector ).addBack( selector ) );
13683
13684 }
13685
13686 // Return whatever we have found for labels
13687 return this.pushStack( labels );
13688};
13689
13690} );
13691
13692( function( factory ) {
13693 "use strict";
13694
13695 if ( typeof define === "function" && define.amd ) {
13696
13697 // AMD. Register as an anonymous module.
13698 define( [ "jquery", "./version" ], factory );
13699 } else {
13700
13701 // Browser globals
13702 factory( jQuery );
13703 }
13704} )( function( $ ) {
13705"use strict";
13706
13707// $.ui.plugin is deprecated. Use $.widget() extensions instead.
13708return $.ui.plugin = {
13709 add: function( module, option, set ) {
13710 var i,
13711 proto = $.ui[ module ].prototype;
13712 for ( i in set ) {
13713 proto.plugins[ i ] = proto.plugins[ i ] || [];
13714 proto.plugins[ i ].push( [ option, set[ i ] ] );
13715 }
13716 },
13717 call: function( instance, name, args, allowDisconnected ) {
13718 var i,
13719 set = instance.plugins[ name ];
13720
13721 if ( !set ) {
13722 return;
13723 }
13724
13725 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
13726 instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
13727 return;
13728 }
13729
13730 for ( i = 0; i < set.length; i++ ) {
13731 if ( instance.options[ set[ i ][ 0 ] ] ) {
13732 set[ i ][ 1 ].apply( instance.element, args );
13733 }
13734 }
13735 }
13736};
13737
13738} );
13739
13740
13741/*!
13742 * jQuery UI Position 1.14.1
13743 * https://jqueryui.com
13744 *
13745 * Copyright OpenJS Foundation and other contributors
13746 * Released under the MIT license.
13747 * https://jquery.org/license
13748 *
13749 * https://api.jqueryui.com/position/
13750 */
13751
13752//>>label: Position
13753//>>group: Core
13754//>>description: Positions elements relative to other elements.
13755//>>docs: https://api.jqueryui.com/position/
13756//>>demos: https://jqueryui.com/position/
13757
13758( function( factory ) {
13759 "use strict";
13760
13761 if ( typeof define === "function" && define.amd ) {
13762
13763 // AMD. Register as an anonymous module.
13764 define( [ "jquery", "./version" ], factory );
13765 } else {
13766
13767 // Browser globals
13768 factory( jQuery );
13769 }
13770} )( function( $ ) {
13771"use strict";
13772
13773( function() {
13774var cachedScrollbarWidth,
13775 max = Math.max,
13776 abs = Math.abs,
13777 rhorizontal = /left|center|right/,
13778 rvertical = /top|center|bottom/,
13779 roffset = /[\+\-]\d+(\.[\d]+)?%?/,
13780 rposition = /^\w+/,
13781 rpercent = /%$/,
13782 _position = $.fn.position;
13783
13784function getOffsets( offsets, width, height ) {
13785 return [
13786 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
13787 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
13788 ];
13789}
13790
13791function parseCss( element, property ) {
13792 return parseInt( $.css( element, property ), 10 ) || 0;
13793}
13794
13795function isWindow( obj ) {
13796 return obj != null && obj === obj.window;
13797}
13798
13799function getDimensions( elem ) {
13800 var raw = elem[ 0 ];
13801 if ( raw.nodeType === 9 ) {
13802 return {
13803 width: elem.width(),
13804 height: elem.height(),
13805 offset: { top: 0, left: 0 }
13806 };
13807 }
13808 if ( isWindow( raw ) ) {
13809 return {
13810 width: elem.width(),
13811 height: elem.height(),
13812 offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
13813 };
13814 }
13815 if ( raw.preventDefault ) {
13816 return {
13817 width: 0,
13818 height: 0,
13819 offset: { top: raw.pageY, left: raw.pageX }
13820 };
13821 }
13822 return {
13823 width: elem.outerWidth(),
13824 height: elem.outerHeight(),
13825 offset: elem.offset()
13826 };
13827}
13828
13829$.position = {
13830 scrollbarWidth: function() {
13831 if ( cachedScrollbarWidth !== undefined ) {
13832 return cachedScrollbarWidth;
13833 }
13834 var w1, w2,
13835 div = $( "<div style=" +
13836 "'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" +
13837 "<div style='height:300px;width:auto;'></div></div>" ),
13838 innerDiv = div.children()[ 0 ];
13839
13840 $( "body" ).append( div );
13841 w1 = innerDiv.offsetWidth;
13842 div.css( "overflow", "scroll" );
13843
13844 w2 = innerDiv.offsetWidth;
13845
13846 if ( w1 === w2 ) {
13847 w2 = div[ 0 ].clientWidth;
13848 }
13849
13850 div.remove();
13851
13852 return ( cachedScrollbarWidth = w1 - w2 );
13853 },
13854 getScrollInfo: function( within ) {
13855 var overflowX = within.isWindow || within.isDocument ? "" :
13856 within.element.css( "overflow-x" ),
13857 overflowY = within.isWindow || within.isDocument ? "" :
13858 within.element.css( "overflow-y" ),
13859 hasOverflowX = overflowX === "scroll" ||
13860 ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
13861 hasOverflowY = overflowY === "scroll" ||
13862 ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
13863 return {
13864 width: hasOverflowY ? $.position.scrollbarWidth() : 0,
13865 height: hasOverflowX ? $.position.scrollbarWidth() : 0
13866 };
13867 },
13868 getWithinInfo: function( element ) {
13869 var withinElement = $( element || window ),
13870 isElemWindow = isWindow( withinElement[ 0 ] ),
13871 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
13872 hasOffset = !isElemWindow && !isDocument;
13873 return {
13874 element: withinElement,
13875 isWindow: isElemWindow,
13876 isDocument: isDocument,
13877 offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
13878 scrollLeft: withinElement.scrollLeft(),
13879 scrollTop: withinElement.scrollTop(),
13880 width: withinElement.outerWidth(),
13881 height: withinElement.outerHeight()
13882 };
13883 }
13884};
13885
13886$.fn.position = function( options ) {
13887 if ( !options || !options.of ) {
13888 return _position.apply( this, arguments );
13889 }
13890
13891 // Make a copy, we don't want to modify arguments
13892 options = $.extend( {}, options );
13893
13894 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
13895
13896 // Make sure string options are treated as CSS selectors
13897 target = typeof options.of === "string" ?
13898 $( document ).find( options.of ) :
13899 $( options.of ),
13900
13901 within = $.position.getWithinInfo( options.within ),
13902 scrollInfo = $.position.getScrollInfo( within ),
13903 collision = ( options.collision || "flip" ).split( " " ),
13904 offsets = {};
13905
13906 dimensions = getDimensions( target );
13907 if ( target[ 0 ].preventDefault ) {
13908
13909 // Force left top to allow flipping
13910 options.at = "left top";
13911 }
13912 targetWidth = dimensions.width;
13913 targetHeight = dimensions.height;
13914 targetOffset = dimensions.offset;
13915
13916 // Clone to reuse original targetOffset later
13917 basePosition = $.extend( {}, targetOffset );
13918
13919 // Force my and at to have valid horizontal and vertical positions
13920 // if a value is missing or invalid, it will be converted to center
13921 $.each( [ "my", "at" ], function() {
13922 var pos = ( options[ this ] || "" ).split( " " ),
13923 horizontalOffset,
13924 verticalOffset;
13925
13926 if ( pos.length === 1 ) {
13927 pos = rhorizontal.test( pos[ 0 ] ) ?
13928 pos.concat( [ "center" ] ) :
13929 rvertical.test( pos[ 0 ] ) ?
13930 [ "center" ].concat( pos ) :
13931 [ "center", "center" ];
13932 }
13933 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
13934 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
13935
13936 // Calculate offsets
13937 horizontalOffset = roffset.exec( pos[ 0 ] );
13938 verticalOffset = roffset.exec( pos[ 1 ] );
13939 offsets[ this ] = [
13940 horizontalOffset ? horizontalOffset[ 0 ] : 0,
13941 verticalOffset ? verticalOffset[ 0 ] : 0
13942 ];
13943
13944 // Reduce to just the positions without the offsets
13945 options[ this ] = [
13946 rposition.exec( pos[ 0 ] )[ 0 ],
13947 rposition.exec( pos[ 1 ] )[ 0 ]
13948 ];
13949 } );
13950
13951 // Normalize collision option
13952 if ( collision.length === 1 ) {
13953 collision[ 1 ] = collision[ 0 ];
13954 }
13955
13956 if ( options.at[ 0 ] === "right" ) {
13957 basePosition.left += targetWidth;
13958 } else if ( options.at[ 0 ] === "center" ) {
13959 basePosition.left += targetWidth / 2;
13960 }
13961
13962 if ( options.at[ 1 ] === "bottom" ) {
13963 basePosition.top += targetHeight;
13964 } else if ( options.at[ 1 ] === "center" ) {
13965 basePosition.top += targetHeight / 2;
13966 }
13967
13968 atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
13969 basePosition.left += atOffset[ 0 ];
13970 basePosition.top += atOffset[ 1 ];
13971
13972 return this.each( function() {
13973 var collisionPosition, using,
13974 elem = $( this ),
13975 elemWidth = elem.outerWidth(),
13976 elemHeight = elem.outerHeight(),
13977 marginLeft = parseCss( this, "marginLeft" ),
13978 marginTop = parseCss( this, "marginTop" ),
13979 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
13980 scrollInfo.width,
13981 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
13982 scrollInfo.height,
13983 position = $.extend( {}, basePosition ),
13984 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
13985
13986 if ( options.my[ 0 ] === "right" ) {
13987 position.left -= elemWidth;
13988 } else if ( options.my[ 0 ] === "center" ) {
13989 position.left -= elemWidth / 2;
13990 }
13991
13992 if ( options.my[ 1 ] === "bottom" ) {
13993 position.top -= elemHeight;
13994 } else if ( options.my[ 1 ] === "center" ) {
13995 position.top -= elemHeight / 2;
13996 }
13997
13998 position.left += myOffset[ 0 ];
13999 position.top += myOffset[ 1 ];
14000
14001 collisionPosition = {
14002 marginLeft: marginLeft,
14003 marginTop: marginTop
14004 };
14005
14006 $.each( [ "left", "top" ], function( i, dir ) {
14007 if ( $.ui.position[ collision[ i ] ] ) {
14008 $.ui.position[ collision[ i ] ][ dir ]( position, {
14009 targetWidth: targetWidth,
14010 targetHeight: targetHeight,
14011 elemWidth: elemWidth,
14012 elemHeight: elemHeight,
14013 collisionPosition: collisionPosition,
14014 collisionWidth: collisionWidth,
14015 collisionHeight: collisionHeight,
14016 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
14017 my: options.my,
14018 at: options.at,
14019 within: within,
14020 elem: elem
14021 } );
14022 }
14023 } );
14024
14025 if ( options.using ) {
14026
14027 // Adds feedback as second argument to using callback, if present
14028 using = function( props ) {
14029 var left = targetOffset.left - position.left,
14030 right = left + targetWidth - elemWidth,
14031 top = targetOffset.top - position.top,
14032 bottom = top + targetHeight - elemHeight,
14033 feedback = {
14034 target: {
14035 element: target,
14036 left: targetOffset.left,
14037 top: targetOffset.top,
14038 width: targetWidth,
14039 height: targetHeight
14040 },
14041 element: {
14042 element: elem,
14043 left: position.left,
14044 top: position.top,
14045 width: elemWidth,
14046 height: elemHeight
14047 },
14048 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
14049 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
14050 };
14051 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
14052 feedback.horizontal = "center";
14053 }
14054 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
14055 feedback.vertical = "middle";
14056 }
14057 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
14058 feedback.important = "horizontal";
14059 } else {
14060 feedback.important = "vertical";
14061 }
14062 options.using.call( this, props, feedback );
14063 };
14064 }
14065
14066 elem.offset( $.extend( position, { using: using } ) );
14067 } );
14068};
14069
14070$.ui.position = {
14071 fit: {
14072 left: function( position, data ) {
14073 var within = data.within,
14074 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
14075 outerWidth = within.width,
14076 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
14077 overLeft = withinOffset - collisionPosLeft,
14078 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
14079 newOverRight;
14080
14081 // Element is wider than within
14082 if ( data.collisionWidth > outerWidth ) {
14083
14084 // Element is initially over the left side of within
14085 if ( overLeft > 0 && overRight <= 0 ) {
14086 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
14087 withinOffset;
14088 position.left += overLeft - newOverRight;
14089
14090 // Element is initially over right side of within
14091 } else if ( overRight > 0 && overLeft <= 0 ) {
14092 position.left = withinOffset;
14093
14094 // Element is initially over both left and right sides of within
14095 } else {
14096 if ( overLeft > overRight ) {
14097 position.left = withinOffset + outerWidth - data.collisionWidth;
14098 } else {
14099 position.left = withinOffset;
14100 }
14101 }
14102
14103 // Too far left -> align with left edge
14104 } else if ( overLeft > 0 ) {
14105 position.left += overLeft;
14106
14107 // Too far right -> align with right edge
14108 } else if ( overRight > 0 ) {
14109 position.left -= overRight;
14110
14111 // Adjust based on position and margin
14112 } else {
14113 position.left = max( position.left - collisionPosLeft, position.left );
14114 }
14115 },
14116 top: function( position, data ) {
14117 var within = data.within,
14118 withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
14119 outerHeight = data.within.height,
14120 collisionPosTop = position.top - data.collisionPosition.marginTop,
14121 overTop = withinOffset - collisionPosTop,
14122 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
14123 newOverBottom;
14124
14125 // Element is taller than within
14126 if ( data.collisionHeight > outerHeight ) {
14127
14128 // Element is initially over the top of within
14129 if ( overTop > 0 && overBottom <= 0 ) {
14130 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
14131 withinOffset;
14132 position.top += overTop - newOverBottom;
14133
14134 // Element is initially over bottom of within
14135 } else if ( overBottom > 0 && overTop <= 0 ) {
14136 position.top = withinOffset;
14137
14138 // Element is initially over both top and bottom of within
14139 } else {
14140 if ( overTop > overBottom ) {
14141 position.top = withinOffset + outerHeight - data.collisionHeight;
14142 } else {
14143 position.top = withinOffset;
14144 }
14145 }
14146
14147 // Too far up -> align with top
14148 } else if ( overTop > 0 ) {
14149 position.top += overTop;
14150
14151 // Too far down -> align with bottom edge
14152 } else if ( overBottom > 0 ) {
14153 position.top -= overBottom;
14154
14155 // Adjust based on position and margin
14156 } else {
14157 position.top = max( position.top - collisionPosTop, position.top );
14158 }
14159 }
14160 },
14161 flip: {
14162 left: function( position, data ) {
14163 var within = data.within,
14164 withinOffset = within.offset.left + within.scrollLeft,
14165 outerWidth = within.width,
14166 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
14167 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
14168 overLeft = collisionPosLeft - offsetLeft,
14169 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
14170 myOffset = data.my[ 0 ] === "left" ?
14171 -data.elemWidth :
14172 data.my[ 0 ] === "right" ?
14173 data.elemWidth :
14174 0,
14175 atOffset = data.at[ 0 ] === "left" ?
14176 data.targetWidth :
14177 data.at[ 0 ] === "right" ?
14178 -data.targetWidth :
14179 0,
14180 offset = -2 * data.offset[ 0 ],
14181 newOverRight,
14182 newOverLeft;
14183
14184 if ( overLeft < 0 ) {
14185 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
14186 outerWidth - withinOffset;
14187 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
14188 position.left += myOffset + atOffset + offset;
14189 }
14190 } else if ( overRight > 0 ) {
14191 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
14192 atOffset + offset - offsetLeft;
14193 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
14194 position.left += myOffset + atOffset + offset;
14195 }
14196 }
14197 },
14198 top: function( position, data ) {
14199 var within = data.within,
14200 withinOffset = within.offset.top + within.scrollTop,
14201 outerHeight = within.height,
14202 offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
14203 collisionPosTop = position.top - data.collisionPosition.marginTop,
14204 overTop = collisionPosTop - offsetTop,
14205 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
14206 top = data.my[ 1 ] === "top",
14207 myOffset = top ?
14208 -data.elemHeight :
14209 data.my[ 1 ] === "bottom" ?
14210 data.elemHeight :
14211 0,
14212 atOffset = data.at[ 1 ] === "top" ?
14213 data.targetHeight :
14214 data.at[ 1 ] === "bottom" ?
14215 -data.targetHeight :
14216 0,
14217 offset = -2 * data.offset[ 1 ],
14218 newOverTop,
14219 newOverBottom;
14220 if ( overTop < 0 ) {
14221 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
14222 outerHeight - withinOffset;
14223 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
14224 position.top += myOffset + atOffset + offset;
14225 }
14226 } else if ( overBottom > 0 ) {
14227 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
14228 offset - offsetTop;
14229 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
14230 position.top += myOffset + atOffset + offset;
14231 }
14232 }
14233 }
14234 },
14235 flipfit: {
14236 left: function() {
14237 $.ui.position.flip.left.apply( this, arguments );
14238 $.ui.position.fit.left.apply( this, arguments );
14239 },
14240 top: function() {
14241 $.ui.position.flip.top.apply( this, arguments );
14242 $.ui.position.fit.top.apply( this, arguments );
14243 }
14244 }
14245};
14246
14247} )();
14248
14249return $.ui.position;
14250
14251} );
14252
14253
14254/*!
14255 * jQuery UI Scroll Parent 1.14.1
14256 * https://jqueryui.com
14257 *
14258 * Copyright OpenJS Foundation and other contributors
14259 * Released under the MIT license.
14260 * https://jquery.org/license
14261 */
14262
14263//>>label: scrollParent
14264//>>group: Core
14265//>>description: Get the closest ancestor element that is scrollable.
14266//>>docs: https://api.jqueryui.com/scrollParent/
14267
14268( function( factory ) {
14269 "use strict";
14270
14271 if ( typeof define === "function" && define.amd ) {
14272
14273 // AMD. Register as an anonymous module.
14274 define( [ "jquery", "./version" ], factory );
14275 } else {
14276
14277 // Browser globals
14278 factory( jQuery );
14279 }
14280} )( function( $ ) {
14281"use strict";
14282
14283return $.fn.scrollParent = function( includeHidden ) {
14284 var position = this.css( "position" ),
14285 excludeStaticParent = position === "absolute",
14286 overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
14287 scrollParent = this.parents().filter( function() {
14288 var parent = $( this );
14289 if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
14290 return false;
14291 }
14292 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
14293 parent.css( "overflow-x" ) );
14294 } ).eq( 0 );
14295
14296 return position === "fixed" || !scrollParent.length ?
14297 $( this[ 0 ].ownerDocument || document ) :
14298 scrollParent;
14299};
14300
14301} );
14302
14303
14304
14305/*!
14306 * jQuery UI Tabbable 1.14.1
14307 * https://jqueryui.com
14308 *
14309 * Copyright OpenJS Foundation and other contributors
14310 * Released under the MIT license.
14311 * https://jquery.org/license
14312 */
14313
14314//>>label: :tabbable Selector
14315//>>group: Core
14316//>>description: Selects elements which can be tabbed to.
14317//>>docs: https://api.jqueryui.com/tabbable-selector/
14318
14319( function( factory ) {
14320 "use strict";
14321
14322 if ( typeof define === "function" && define.amd ) {
14323
14324 // AMD. Register as an anonymous module.
14325 define( [ "jquery", "./version", "./focusable" ], factory );
14326 } else {
14327
14328 // Browser globals
14329 factory( jQuery );
14330 }
14331} )( function( $ ) {
14332"use strict";
14333
14334return $.extend( $.expr.pseudos, {
14335 tabbable: function( element ) {
14336 var tabIndex = $.attr( element, "tabindex" ),
14337 hasTabindex = tabIndex != null;
14338 return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
14339 }
14340} );
14341
14342} );
14343
14344
14345/*!
14346 * jQuery UI Unique ID 1.14.1
14347 * https://jqueryui.com
14348 *
14349 * Copyright OpenJS Foundation and other contributors
14350 * Released under the MIT license.
14351 * https://jquery.org/license
14352 */
14353
14354//>>label: uniqueId
14355//>>group: Core
14356//>>description: Functions to generate and remove uniqueId's
14357//>>docs: https://api.jqueryui.com/uniqueId/
14358
14359( function( factory ) {
14360 "use strict";
14361
14362 if ( typeof define === "function" && define.amd ) {
14363
14364 // AMD. Register as an anonymous module.
14365 define( [ "jquery", "./version" ], factory );
14366 } else {
14367
14368 // Browser globals
14369 factory( jQuery );
14370 }
14371} )( function( $ ) {
14372"use strict";
14373
14374return $.fn.extend( {
14375 uniqueId: ( function() {
14376 var uuid = 0;
14377
14378 return function() {
14379 return this.each( function() {
14380 if ( !this.id ) {
14381 this.id = "ui-id-" + ( ++uuid );
14382 }
14383 } );
14384 };
14385 } )(),
14386
14387 removeUniqueId: function() {
14388 return this.each( function() {
14389 if ( /^ui-id-\d+$/.test( this.id ) ) {
14390 $( this ).removeAttr( "id" );
14391 }
14392 } );
14393 }
14394} );
14395
14396} );
14397
14398
14399/*!
14400 * jQuery UI Widget 1.14.1
14401 * https://jqueryui.com
14402 *
14403 * Copyright OpenJS Foundation and other contributors
14404 * Released under the MIT license.
14405 * https://jquery.org/license
14406 */
14407
14408//>>label: Widget
14409//>>group: Core
14410//>>description: Provides a factory for creating stateful widgets with a common API.
14411//>>docs: https://api.jqueryui.com/jQuery.widget/
14412//>>demos: https://jqueryui.com/widget/
14413
14414( function( factory ) {
14415 "use strict";
14416
14417 if ( typeof define === "function" && define.amd ) {
14418
14419 // AMD. Register as an anonymous module.
14420 define( [ "jquery", "./version" ], factory );
14421 } else {
14422
14423 // Browser globals
14424 factory( jQuery );
14425 }
14426} )( function( $ ) {
14427"use strict";
14428
14429var widgetUuid = 0;
14430var widgetHasOwnProperty = Array.prototype.hasOwnProperty;
14431var widgetSlice = Array.prototype.slice;
14432
14433$.cleanData = ( function( orig ) {
14434 return function( elems ) {
14435 var events, elem, i;
14436 for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
14437
14438 // Only trigger remove when necessary to save time
14439 events = $._data( elem, "events" );
14440 if ( events && events.remove ) {
14441 $( elem ).triggerHandler( "remove" );
14442 }
14443 }
14444 orig( elems );
14445 };
14446} )( $.cleanData );
14447
14448$.widget = function( name, base, prototype ) {
14449 var existingConstructor, constructor, basePrototype;
14450
14451 // ProxiedPrototype allows the provided prototype to remain unmodified
14452 // so that it can be used as a mixin for multiple widgets (#8876)
14453 var proxiedPrototype = {};
14454
14455 var namespace = name.split( "." )[ 0 ];
14456 name = name.split( "." )[ 1 ];
14457 if ( name === "__proto__" || name === "constructor" ) {
14458 return $.error( "Invalid widget name: " + name );
14459 }
14460 var fullName = namespace + "-" + name;
14461
14462 if ( !prototype ) {
14463 prototype = base;
14464 base = $.Widget;
14465 }
14466
14467 if ( Array.isArray( prototype ) ) {
14468 prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
14469 }
14470
14471 // Create selector for plugin
14472 $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) {
14473 return !!$.data( elem, fullName );
14474 };
14475
14476 $[ namespace ] = $[ namespace ] || {};
14477 existingConstructor = $[ namespace ][ name ];
14478 constructor = $[ namespace ][ name ] = function( options, element ) {
14479
14480 // Allow instantiation without "new" keyword
14481 if ( !this || !this._createWidget ) {
14482 return new constructor( options, element );
14483 }
14484
14485 // Allow instantiation without initializing for simple inheritance
14486 // must use "new" keyword (the code above always passes args)
14487 if ( arguments.length ) {
14488 this._createWidget( options, element );
14489 }
14490 };
14491
14492 // Extend with the existing constructor to carry over any static properties
14493 $.extend( constructor, existingConstructor, {
14494 version: prototype.version,
14495
14496 // Copy the object used to create the prototype in case we need to
14497 // redefine the widget later
14498 _proto: $.extend( {}, prototype ),
14499
14500 // Track widgets that inherit from this widget in case this widget is
14501 // redefined after a widget inherits from it
14502 _childConstructors: []
14503 } );
14504
14505 basePrototype = new base();
14506
14507 // We need to make the options hash a property directly on the new instance
14508 // otherwise we'll modify the options hash on the prototype that we're
14509 // inheriting from
14510 basePrototype.options = $.widget.extend( {}, basePrototype.options );
14511 $.each( prototype, function( prop, value ) {
14512 if ( typeof value !== "function" ) {
14513 proxiedPrototype[ prop ] = value;
14514 return;
14515 }
14516 proxiedPrototype[ prop ] = ( function() {
14517 function _super() {
14518 return base.prototype[ prop ].apply( this, arguments );
14519 }
14520
14521 function _superApply( args ) {
14522 return base.prototype[ prop ].apply( this, args );
14523 }
14524
14525 return function() {
14526 var __super = this._super;
14527 var __superApply = this._superApply;
14528 var returnValue;
14529
14530 this._super = _super;
14531 this._superApply = _superApply;
14532
14533 returnValue = value.apply( this, arguments );
14534
14535 this._super = __super;
14536 this._superApply = __superApply;
14537
14538 return returnValue;
14539 };
14540 } )();
14541 } );
14542 constructor.prototype = $.widget.extend( basePrototype, {
14543
14544 // TODO: remove support for widgetEventPrefix
14545 // always use the name + a colon as the prefix, e.g., draggable:start
14546 // don't prefix for widgets that aren't DOM-based
14547 widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
14548 }, proxiedPrototype, {
14549 constructor: constructor,
14550 namespace: namespace,
14551 widgetName: name,
14552 widgetFullName: fullName
14553 } );
14554
14555 // If this widget is being redefined then we need to find all widgets that
14556 // are inheriting from it and redefine all of them so that they inherit from
14557 // the new version of this widget. We're essentially trying to replace one
14558 // level in the prototype chain.
14559 if ( existingConstructor ) {
14560 $.each( existingConstructor._childConstructors, function( i, child ) {
14561 var childPrototype = child.prototype;
14562
14563 // Redefine the child widget using the same prototype that was
14564 // originally used, but inherit from the new version of the base
14565 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
14566 child._proto );
14567 } );
14568
14569 // Remove the list of existing child constructors from the old constructor
14570 // so the old child constructors can be garbage collected
14571 delete existingConstructor._childConstructors;
14572 } else {
14573 base._childConstructors.push( constructor );
14574 }
14575
14576 $.widget.bridge( name, constructor );
14577
14578 return constructor;
14579};
14580
14581$.widget.extend = function( target ) {
14582 var input = widgetSlice.call( arguments, 1 );
14583 var inputIndex = 0;
14584 var inputLength = input.length;
14585 var key;
14586 var value;
14587
14588 for ( ; inputIndex < inputLength; inputIndex++ ) {
14589 for ( key in input[ inputIndex ] ) {
14590 value = input[ inputIndex ][ key ];
14591 if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) {
14592
14593 // Clone objects
14594 if ( $.isPlainObject( value ) ) {
14595 target[ key ] = $.isPlainObject( target[ key ] ) ?
14596 $.widget.extend( {}, target[ key ], value ) :
14597
14598 // Don't extend strings, arrays, etc. with objects
14599 $.widget.extend( {}, value );
14600
14601 // Copy everything else by reference
14602 } else {
14603 target[ key ] = value;
14604 }
14605 }
14606 }
14607 }
14608 return target;
14609};
14610
14611$.widget.bridge = function( name, object ) {
14612 var fullName = object.prototype.widgetFullName || name;
14613 $.fn[ name ] = function( options ) {
14614 var isMethodCall = typeof options === "string";
14615 var args = widgetSlice.call( arguments, 1 );
14616 var returnValue = this;
14617
14618 if ( isMethodCall ) {
14619
14620 // If this is an empty collection, we need to have the instance method
14621 // return undefined instead of the jQuery instance
14622 if ( !this.length && options === "instance" ) {
14623 returnValue = undefined;
14624 } else {
14625 this.each( function() {
14626 var methodValue;
14627 var instance = $.data( this, fullName );
14628
14629 if ( options === "instance" ) {
14630 returnValue = instance;
14631 return false;
14632 }
14633
14634 if ( !instance ) {
14635 return $.error( "cannot call methods on " + name +
14636 " prior to initialization; " +
14637 "attempted to call method '" + options + "'" );
14638 }
14639
14640 if ( typeof instance[ options ] !== "function" ||
14641 options.charAt( 0 ) === "_" ) {
14642 return $.error( "no such method '" + options + "' for " + name +
14643 " widget instance" );
14644 }
14645
14646 methodValue = instance[ options ].apply( instance, args );
14647
14648 if ( methodValue !== instance && methodValue !== undefined ) {
14649 returnValue = methodValue && methodValue.jquery ?
14650 returnValue.pushStack( methodValue.get() ) :
14651 methodValue;
14652 return false;
14653 }
14654 } );
14655 }
14656 } else {
14657
14658 // Allow multiple hashes to be passed on init
14659 if ( args.length ) {
14660 options = $.widget.extend.apply( null, [ options ].concat( args ) );
14661 }
14662
14663 this.each( function() {
14664 var instance = $.data( this, fullName );
14665 if ( instance ) {
14666 instance.option( options || {} );
14667 if ( instance._init ) {
14668 instance._init();
14669 }
14670 } else {
14671 $.data( this, fullName, new object( options, this ) );
14672 }
14673 } );
14674 }
14675
14676 return returnValue;
14677 };
14678};
14679
14680$.Widget = function( /* options, element */ ) {};
14681$.Widget._childConstructors = [];
14682
14683$.Widget.prototype = {
14684 widgetName: "widget",
14685 widgetEventPrefix: "",
14686 defaultElement: "<div>",
14687
14688 options: {
14689 classes: {},
14690 disabled: false,
14691
14692 // Callbacks
14693 create: null
14694 },
14695
14696 _createWidget: function( options, element ) {
14697 element = $( element || this.defaultElement || this )[ 0 ];
14698 this.element = $( element );
14699 this.uuid = widgetUuid++;
14700 this.eventNamespace = "." + this.widgetName + this.uuid;
14701
14702 this.bindings = $();
14703 this.hoverable = $();
14704 this.focusable = $();
14705 this.classesElementLookup = {};
14706
14707 if ( element !== this ) {
14708 $.data( element, this.widgetFullName, this );
14709 this._on( true, this.element, {
14710 remove: function( event ) {
14711 if ( event.target === element ) {
14712 this.destroy();
14713 }
14714 }
14715 } );
14716 this.document = $( element.style ?
14717
14718 // Element within the document
14719 element.ownerDocument :
14720
14721 // Element is window or document
14722 element.document || element );
14723 this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
14724 }
14725
14726 this.options = $.widget.extend( {},
14727 this.options,
14728 this._getCreateOptions(),
14729 options );
14730
14731 this._create();
14732
14733 if ( this.options.disabled ) {
14734 this._setOptionDisabled( this.options.disabled );
14735 }
14736
14737 this._trigger( "create", null, this._getCreateEventData() );
14738 this._init();
14739 },
14740
14741 _getCreateOptions: function() {
14742 return {};
14743 },
14744
14745 _getCreateEventData: $.noop,
14746
14747 _create: $.noop,
14748
14749 _init: $.noop,
14750
14751 destroy: function() {
14752 var that = this;
14753
14754 this._destroy();
14755 $.each( this.classesElementLookup, function( key, value ) {
14756 that._removeClass( value, key );
14757 } );
14758
14759 // We can probably remove the unbind calls in 2.0
14760 // all event bindings should go through this._on()
14761 this.element
14762 .off( this.eventNamespace )
14763 .removeData( this.widgetFullName );
14764 this.widget()
14765 .off( this.eventNamespace )
14766 .removeAttr( "aria-disabled" );
14767
14768 // Clean up events and states
14769 this.bindings.off( this.eventNamespace );
14770 },
14771
14772 _destroy: $.noop,
14773
14774 widget: function() {
14775 return this.element;
14776 },
14777
14778 option: function( key, value ) {
14779 var options = key;
14780 var parts;
14781 var curOption;
14782 var i;
14783
14784 if ( arguments.length === 0 ) {
14785
14786 // Don't return a reference to the internal hash
14787 return $.widget.extend( {}, this.options );
14788 }
14789
14790 if ( typeof key === "string" ) {
14791
14792 // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
14793 options = {};
14794 parts = key.split( "." );
14795 key = parts.shift();
14796 if ( parts.length ) {
14797 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
14798 for ( i = 0; i < parts.length - 1; i++ ) {
14799 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
14800 curOption = curOption[ parts[ i ] ];
14801 }
14802 key = parts.pop();
14803 if ( arguments.length === 1 ) {
14804 return curOption[ key ] === undefined ? null : curOption[ key ];
14805 }
14806 curOption[ key ] = value;
14807 } else {
14808 if ( arguments.length === 1 ) {
14809 return this.options[ key ] === undefined ? null : this.options[ key ];
14810 }
14811 options[ key ] = value;
14812 }
14813 }
14814
14815 this._setOptions( options );
14816
14817 return this;
14818 },
14819
14820 _setOptions: function( options ) {
14821 var key;
14822
14823 for ( key in options ) {
14824 this._setOption( key, options[ key ] );
14825 }
14826
14827 return this;
14828 },
14829
14830 _setOption: function( key, value ) {
14831 if ( key === "classes" ) {
14832 this._setOptionClasses( value );
14833 }
14834
14835 this.options[ key ] = value;
14836
14837 if ( key === "disabled" ) {
14838 this._setOptionDisabled( value );
14839 }
14840
14841 return this;
14842 },
14843
14844 _setOptionClasses: function( value ) {
14845 var classKey, elements, currentElements;
14846
14847 for ( classKey in value ) {
14848 currentElements = this.classesElementLookup[ classKey ];
14849 if ( value[ classKey ] === this.options.classes[ classKey ] ||
14850 !currentElements ||
14851 !currentElements.length ) {
14852 continue;
14853 }
14854
14855 // We are doing this to create a new jQuery object because the _removeClass() call
14856 // on the next line is going to destroy the reference to the current elements being
14857 // tracked. We need to save a copy of this collection so that we can add the new classes
14858 // below.
14859 elements = $( currentElements.get() );
14860 this._removeClass( currentElements, classKey );
14861
14862 // We don't use _addClass() here, because that uses this.options.classes
14863 // for generating the string of classes. We want to use the value passed in from
14864 // _setOption(), this is the new value of the classes option which was passed to
14865 // _setOption(). We pass this value directly to _classes().
14866 elements.addClass( this._classes( {
14867 element: elements,
14868 keys: classKey,
14869 classes: value,
14870 add: true
14871 } ) );
14872 }
14873 },
14874
14875 _setOptionDisabled: function( value ) {
14876 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
14877
14878 // If the widget is becoming disabled, then nothing is interactive
14879 if ( value ) {
14880 this._removeClass( this.hoverable, null, "ui-state-hover" );
14881 this._removeClass( this.focusable, null, "ui-state-focus" );
14882 }
14883 },
14884
14885 enable: function() {
14886 return this._setOptions( { disabled: false } );
14887 },
14888
14889 disable: function() {
14890 return this._setOptions( { disabled: true } );
14891 },
14892
14893 _classes: function( options ) {
14894 var full = [];
14895 var that = this;
14896
14897 options = $.extend( {
14898 element: this.element,
14899 classes: this.options.classes || {}
14900 }, options );
14901
14902 function bindRemoveEvent() {
14903 var nodesToBind = [];
14904
14905 options.element.each( function( _, element ) {
14906 var isTracked = $.map( that.classesElementLookup, function( elements ) {
14907 return elements;
14908 } )
14909 .some( function( elements ) {
14910 return elements.is( element );
14911 } );
14912
14913 if ( !isTracked ) {
14914 nodesToBind.push( element );
14915 }
14916 } );
14917
14918 that._on( $( nodesToBind ), {
14919 remove: "_untrackClassesElement"
14920 } );
14921 }
14922
14923 function processClassString( classes, checkOption ) {
14924 var current, i;
14925 for ( i = 0; i < classes.length; i++ ) {
14926 current = that.classesElementLookup[ classes[ i ] ] || $();
14927 if ( options.add ) {
14928 bindRemoveEvent();
14929 current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) );
14930 } else {
14931 current = $( current.not( options.element ).get() );
14932 }
14933 that.classesElementLookup[ classes[ i ] ] = current;
14934 full.push( classes[ i ] );
14935 if ( checkOption && options.classes[ classes[ i ] ] ) {
14936 full.push( options.classes[ classes[ i ] ] );
14937 }
14938 }
14939 }
14940
14941 if ( options.keys ) {
14942 processClassString( options.keys.match( /\S+/g ) || [], true );
14943 }
14944 if ( options.extra ) {
14945 processClassString( options.extra.match( /\S+/g ) || [] );
14946 }
14947
14948 return full.join( " " );
14949 },
14950
14951 _untrackClassesElement: function( event ) {
14952 var that = this;
14953 $.each( that.classesElementLookup, function( key, value ) {
14954 if ( $.inArray( event.target, value ) !== -1 ) {
14955 that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
14956 }
14957 } );
14958
14959 this._off( $( event.target ) );
14960 },
14961
14962 _removeClass: function( element, keys, extra ) {
14963 return this._toggleClass( element, keys, extra, false );
14964 },
14965
14966 _addClass: function( element, keys, extra ) {
14967 return this._toggleClass( element, keys, extra, true );
14968 },
14969
14970 _toggleClass: function( element, keys, extra, add ) {
14971 add = ( typeof add === "boolean" ) ? add : extra;
14972 var shift = ( typeof element === "string" || element === null ),
14973 options = {
14974 extra: shift ? keys : extra,
14975 keys: shift ? element : keys,
14976 element: shift ? this.element : element,
14977 add: add
14978 };
14979 options.element.toggleClass( this._classes( options ), add );
14980 return this;
14981 },
14982
14983 _on: function( suppressDisabledCheck, element, handlers ) {
14984 var delegateElement;
14985 var instance = this;
14986
14987 // No suppressDisabledCheck flag, shuffle arguments
14988 if ( typeof suppressDisabledCheck !== "boolean" ) {
14989 handlers = element;
14990 element = suppressDisabledCheck;
14991 suppressDisabledCheck = false;
14992 }
14993
14994 // No element argument, shuffle and use this.element
14995 if ( !handlers ) {
14996 handlers = element;
14997 element = this.element;
14998 delegateElement = this.widget();
14999 } else {
15000 element = delegateElement = $( element );
15001 this.bindings = this.bindings.add( element );
15002 }
15003
15004 $.each( handlers, function( event, handler ) {
15005 function handlerProxy() {
15006
15007 // Allow widgets to customize the disabled handling
15008 // - disabled as an array instead of boolean
15009 // - disabled class as method for disabling individual parts
15010 if ( !suppressDisabledCheck &&
15011 ( instance.options.disabled === true ||
15012 $( this ).hasClass( "ui-state-disabled" ) ) ) {
15013 return;
15014 }
15015 return ( typeof handler === "string" ? instance[ handler ] : handler )
15016 .apply( instance, arguments );
15017 }
15018
15019 // Copy the guid so direct unbinding works
15020 if ( typeof handler !== "string" ) {
15021 handlerProxy.guid = handler.guid =
15022 handler.guid || handlerProxy.guid || $.guid++;
15023 }
15024
15025 var match = event.match( /^([\w:-]*)\s*(.*)$/ );
15026 var eventName = match[ 1 ] + instance.eventNamespace;
15027 var selector = match[ 2 ];
15028
15029 if ( selector ) {
15030 delegateElement.on( eventName, selector, handlerProxy );
15031 } else {
15032 element.on( eventName, handlerProxy );
15033 }
15034 } );
15035 },
15036
15037 _off: function( element, eventName ) {
15038 eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
15039 this.eventNamespace;
15040 element.off( eventName );
15041
15042 // Clear the stack to avoid memory leaks (#10056)
15043 this.bindings = $( this.bindings.not( element ).get() );
15044 this.focusable = $( this.focusable.not( element ).get() );
15045 this.hoverable = $( this.hoverable.not( element ).get() );
15046 },
15047
15048 _delay: function( handler, delay ) {
15049 function handlerProxy() {
15050 return ( typeof handler === "string" ? instance[ handler ] : handler )
15051 .apply( instance, arguments );
15052 }
15053 var instance = this;
15054 return setTimeout( handlerProxy, delay || 0 );
15055 },
15056
15057 _hoverable: function( element ) {
15058 this.hoverable = this.hoverable.add( element );
15059 this._on( element, {
15060 mouseenter: function( event ) {
15061 this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
15062 },
15063 mouseleave: function( event ) {
15064 this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
15065 }
15066 } );
15067 },
15068
15069 _focusable: function( element ) {
15070 this.focusable = this.focusable.add( element );
15071 this._on( element, {
15072 focusin: function( event ) {
15073 this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
15074 },
15075 focusout: function( event ) {
15076 this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
15077 }
15078 } );
15079 },
15080
15081 _trigger: function( type, event, data ) {
15082 var prop, orig;
15083 var callback = this.options[ type ];
15084
15085 data = data || {};
15086 event = $.Event( event );
15087 event.type = ( type === this.widgetEventPrefix ?
15088 type :
15089 this.widgetEventPrefix + type ).toLowerCase();
15090
15091 // The original event may come from any element
15092 // so we need to reset the target on the new event
15093 event.target = this.element[ 0 ];
15094
15095 // Copy original event properties over to the new event
15096 orig = event.originalEvent;
15097 if ( orig ) {
15098 for ( prop in orig ) {
15099 if ( !( prop in event ) ) {
15100 event[ prop ] = orig[ prop ];
15101 }
15102 }
15103 }
15104
15105 this.element.trigger( event, data );
15106 return !( typeof callback === "function" &&
15107 callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
15108 event.isDefaultPrevented() );
15109 }
15110};
15111
15112$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
15113 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
15114 if ( typeof options === "string" ) {
15115 options = { effect: options };
15116 }
15117
15118 var hasOptions;
15119 var effectName = !options ?
15120 method :
15121 options === true || typeof options === "number" ?
15122 defaultEffect :
15123 options.effect || defaultEffect;
15124
15125 options = options || {};
15126 if ( typeof options === "number" ) {
15127 options = { duration: options };
15128 } else if ( options === true ) {
15129 options = {};
15130 }
15131
15132 hasOptions = !$.isEmptyObject( options );
15133 options.complete = callback;
15134
15135 if ( options.delay ) {
15136 element.delay( options.delay );
15137 }
15138
15139 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
15140 element[ method ]( options );
15141 } else if ( effectName !== method && element[ effectName ] ) {
15142 element[ effectName ]( options.duration, options.easing, callback );
15143 } else {
15144 element.queue( function( next ) {
15145 $( this )[ method ]();
15146 if ( callback ) {
15147 callback.call( element[ 0 ] );
15148 }
15149 next();
15150 } );
15151 }
15152 };
15153} );
15154
15155return $.widget;
15156
15157} );
15158
15159
15160
15161/*!
15162 * jQuery UI Effects Blind 1.14.1
15163 * https://jqueryui.com
15164 *
15165 * Copyright OpenJS Foundation and other contributors
15166 * Released under the MIT license.
15167 * https://jquery.org/license
15168 */
15169
15170//>>label: Blind Effect
15171//>>group: Effects
15172//>>description: Blinds the element.
15173//>>docs: https://api.jqueryui.com/blind-effect/
15174//>>demos: https://jqueryui.com/effect/
15175
15176( function( factory ) {
15177 "use strict";
15178
15179 if ( typeof define === "function" && define.amd ) {
15180
15181 // AMD. Register as an anonymous module.
15182 define( [
15183 "jquery",
15184 "../version",
15185 "../effect"
15186 ], factory );
15187 } else {
15188
15189 // Browser globals
15190 factory( jQuery );
15191 }
15192} )( function( $ ) {
15193"use strict";
15194
15195return $.effects.define( "blind", "hide", function( options, done ) {
15196 var map = {
15197 up: [ "bottom", "top" ],
15198 vertical: [ "bottom", "top" ],
15199 down: [ "top", "bottom" ],
15200 left: [ "right", "left" ],
15201 horizontal: [ "right", "left" ],
15202 right: [ "left", "right" ]
15203 },
15204 element = $( this ),
15205 direction = options.direction || "up",
15206 start = element.cssClip(),
15207 animate = { clip: $.extend( {}, start ) },
15208 placeholder = $.effects.createPlaceholder( element );
15209
15210 animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
15211
15212 if ( options.mode === "show" ) {
15213 element.cssClip( animate.clip );
15214 if ( placeholder ) {
15215 placeholder.css( $.effects.clipToBox( animate ) );
15216 }
15217
15218 animate.clip = start;
15219 }
15220
15221 if ( placeholder ) {
15222 placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
15223 }
15224
15225 element.animate( animate, {
15226 queue: false,
15227 duration: options.duration,
15228 easing: options.easing,
15229 complete: done
15230 } );
15231} );
15232
15233} );
15234
15235
15236
15237/*!
15238 * jQuery UI Effects Bounce 1.14.1
15239 * https://jqueryui.com
15240 *
15241 * Copyright OpenJS Foundation and other contributors
15242 * Released under the MIT license.
15243 * https://jquery.org/license
15244 */
15245
15246//>>label: Bounce Effect
15247//>>group: Effects
15248//>>description: Bounces an element horizontally or vertically n times.
15249//>>docs: https://api.jqueryui.com/bounce-effect/
15250//>>demos: https://jqueryui.com/effect/
15251
15252( function( factory ) {
15253 "use strict";
15254
15255 if ( typeof define === "function" && define.amd ) {
15256
15257 // AMD. Register as an anonymous module.
15258 define( [
15259 "jquery",
15260 "../version",
15261 "../effect"
15262 ], factory );
15263 } else {
15264
15265 // Browser globals
15266 factory( jQuery );
15267 }
15268} )( function( $ ) {
15269"use strict";
15270
15271return $.effects.define( "bounce", function( options, done ) {
15272 var upAnim, downAnim, refValue,
15273 element = $( this ),
15274
15275 // Defaults:
15276 mode = options.mode,
15277 hide = mode === "hide",
15278 show = mode === "show",
15279 direction = options.direction || "up",
15280 distance = options.distance,
15281 times = options.times || 5,
15282
15283 // Number of internal animations
15284 anims = times * 2 + ( show || hide ? 1 : 0 ),
15285 speed = options.duration / anims,
15286 easing = options.easing,
15287
15288 // Utility:
15289 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
15290 motion = ( direction === "up" || direction === "left" ),
15291 i = 0,
15292
15293 queuelen = element.queue().length;
15294
15295 $.effects.createPlaceholder( element );
15296
15297 refValue = element.css( ref );
15298
15299 // Default distance for the BIGGEST bounce is the outer Distance / 3
15300 if ( !distance ) {
15301 distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
15302 }
15303
15304 if ( show ) {
15305 downAnim = { opacity: 1 };
15306 downAnim[ ref ] = refValue;
15307
15308 // If we are showing, force opacity 0 and set the initial position
15309 // then do the "first" animation
15310 element
15311 .css( "opacity", 0 )
15312 .css( ref, motion ? -distance * 2 : distance * 2 )
15313 .animate( downAnim, speed, easing );
15314 }
15315
15316 // Start at the smallest distance if we are hiding
15317 if ( hide ) {
15318 distance = distance / Math.pow( 2, times - 1 );
15319 }
15320
15321 downAnim = {};
15322 downAnim[ ref ] = refValue;
15323
15324 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
15325 for ( ; i < times; i++ ) {
15326 upAnim = {};
15327 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
15328
15329 element
15330 .animate( upAnim, speed, easing )
15331 .animate( downAnim, speed, easing );
15332
15333 distance = hide ? distance * 2 : distance / 2;
15334 }
15335
15336 // Last Bounce when Hiding
15337 if ( hide ) {
15338 upAnim = { opacity: 0 };
15339 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
15340
15341 element.animate( upAnim, speed, easing );
15342 }
15343
15344 element.queue( done );
15345
15346 $.effects.unshift( element, queuelen, anims + 1 );
15347} );
15348
15349} );
15350
15351
15352
15353/*!
15354 * jQuery UI Effects Clip 1.14.1
15355 * https://jqueryui.com
15356 *
15357 * Copyright OpenJS Foundation and other contributors
15358 * Released under the MIT license.
15359 * https://jquery.org/license
15360 */
15361
15362//>>label: Clip Effect
15363//>>group: Effects
15364//>>description: Clips the element on and off like an old TV.
15365//>>docs: https://api.jqueryui.com/clip-effect/
15366//>>demos: https://jqueryui.com/effect/
15367
15368( function( factory ) {
15369 "use strict";
15370
15371 if ( typeof define === "function" && define.amd ) {
15372
15373 // AMD. Register as an anonymous module.
15374 define( [
15375 "jquery",
15376 "../version",
15377 "../effect"
15378 ], factory );
15379 } else {
15380
15381 // Browser globals
15382 factory( jQuery );
15383 }
15384} )( function( $ ) {
15385"use strict";
15386
15387return $.effects.define( "clip", "hide", function( options, done ) {
15388 var start,
15389 animate = {},
15390 element = $( this ),
15391 direction = options.direction || "vertical",
15392 both = direction === "both",
15393 horizontal = both || direction === "horizontal",
15394 vertical = both || direction === "vertical";
15395
15396 start = element.cssClip();
15397 animate.clip = {
15398 top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
15399 right: horizontal ? ( start.right - start.left ) / 2 : start.right,
15400 bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
15401 left: horizontal ? ( start.right - start.left ) / 2 : start.left
15402 };
15403
15404 $.effects.createPlaceholder( element );
15405
15406 if ( options.mode === "show" ) {
15407 element.cssClip( animate.clip );
15408 animate.clip = start;
15409 }
15410
15411 element.animate( animate, {
15412 queue: false,
15413 duration: options.duration,
15414 easing: options.easing,
15415 complete: done
15416 } );
15417
15418} );
15419
15420} );
15421
15422
15423
15424/*!
15425 * jQuery UI Effects Drop 1.14.1
15426 * https://jqueryui.com
15427 *
15428 * Copyright OpenJS Foundation and other contributors
15429 * Released under the MIT license.
15430 * https://jquery.org/license
15431 */
15432
15433//>>label: Drop Effect
15434//>>group: Effects
15435//>>description: Moves an element in one direction and hides it at the same time.
15436//>>docs: https://api.jqueryui.com/drop-effect/
15437//>>demos: https://jqueryui.com/effect/
15438
15439( function( factory ) {
15440 "use strict";
15441
15442 if ( typeof define === "function" && define.amd ) {
15443
15444 // AMD. Register as an anonymous module.
15445 define( [
15446 "jquery",
15447 "../version",
15448 "../effect"
15449 ], factory );
15450 } else {
15451
15452 // Browser globals
15453 factory( jQuery );
15454 }
15455} )( function( $ ) {
15456"use strict";
15457
15458return $.effects.define( "drop", "hide", function( options, done ) {
15459
15460 var distance,
15461 element = $( this ),
15462 mode = options.mode,
15463 show = mode === "show",
15464 direction = options.direction || "left",
15465 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
15466 motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
15467 oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
15468 animation = {
15469 opacity: 0
15470 };
15471
15472 $.effects.createPlaceholder( element );
15473
15474 distance = options.distance ||
15475 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
15476
15477 animation[ ref ] = motion + distance;
15478
15479 if ( show ) {
15480 element.css( animation );
15481
15482 animation[ ref ] = oppositeMotion + distance;
15483 animation.opacity = 1;
15484 }
15485
15486 // Animate
15487 element.animate( animation, {
15488 queue: false,
15489 duration: options.duration,
15490 easing: options.easing,
15491 complete: done
15492 } );
15493} );
15494
15495} );
15496
15497
15498
15499/*!
15500 * jQuery UI Effects Explode 1.14.1
15501 * https://jqueryui.com
15502 *
15503 * Copyright OpenJS Foundation and other contributors
15504 * Released under the MIT license.
15505 * https://jquery.org/license
15506 */
15507
15508//>>label: Explode Effect
15509//>>group: Effects
15510/* eslint-disable max-len */
15511//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
15512/* eslint-enable max-len */
15513//>>docs: https://api.jqueryui.com/explode-effect/
15514//>>demos: https://jqueryui.com/effect/
15515
15516( function( factory ) {
15517 "use strict";
15518
15519 if ( typeof define === "function" && define.amd ) {
15520
15521 // AMD. Register as an anonymous module.
15522 define( [
15523 "jquery",
15524 "../version",
15525 "../effect"
15526 ], factory );
15527 } else {
15528
15529 // Browser globals
15530 factory( jQuery );
15531 }
15532} )( function( $ ) {
15533"use strict";
15534
15535return $.effects.define( "explode", "hide", function( options, done ) {
15536
15537 var i, j, left, top, mx, my,
15538 rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
15539 cells = rows,
15540 element = $( this ),
15541 mode = options.mode,
15542 show = mode === "show",
15543
15544 // Show and then visibility:hidden the element before calculating offset
15545 offset = element.show().css( "visibility", "hidden" ).offset(),
15546
15547 // Width and height of a piece
15548 width = Math.ceil( element.outerWidth() / cells ),
15549 height = Math.ceil( element.outerHeight() / rows ),
15550 pieces = [];
15551
15552 // Children animate complete:
15553 function childComplete() {
15554 pieces.push( this );
15555 if ( pieces.length === rows * cells ) {
15556 animComplete();
15557 }
15558 }
15559
15560 // Clone the element for each row and cell.
15561 for ( i = 0; i < rows; i++ ) { // ===>
15562 top = offset.top + i * height;
15563 my = i - ( rows - 1 ) / 2;
15564
15565 for ( j = 0; j < cells; j++ ) { // |||
15566 left = offset.left + j * width;
15567 mx = j - ( cells - 1 ) / 2;
15568
15569 // Create a clone of the now hidden main element that will be absolute positioned
15570 // within a wrapper div off the -left and -top equal to size of our pieces
15571 element
15572 .clone()
15573 .appendTo( "body" )
15574 .wrap( "<div></div>" )
15575 .css( {
15576 position: "absolute",
15577 visibility: "visible",
15578 left: -j * width,
15579 top: -i * height
15580 } )
15581
15582 // Select the wrapper - make it overflow: hidden and absolute positioned based on
15583 // where the original was located +left and +top equal to the size of pieces
15584 .parent()
15585 .addClass( "ui-effects-explode" )
15586 .css( {
15587 position: "absolute",
15588 overflow: "hidden",
15589 width: width,
15590 height: height,
15591 left: left + ( show ? mx * width : 0 ),
15592 top: top + ( show ? my * height : 0 ),
15593 opacity: show ? 0 : 1
15594 } )
15595 .animate( {
15596 left: left + ( show ? 0 : mx * width ),
15597 top: top + ( show ? 0 : my * height ),
15598 opacity: show ? 1 : 0
15599 }, options.duration || 500, options.easing, childComplete );
15600 }
15601 }
15602
15603 function animComplete() {
15604 element.css( {
15605 visibility: "visible"
15606 } );
15607 $( pieces ).remove();
15608 done();
15609 }
15610} );
15611
15612} );
15613
15614
15615
15616/*!
15617 * jQuery UI Effects Fade 1.14.1
15618 * https://jqueryui.com
15619 *
15620 * Copyright OpenJS Foundation and other contributors
15621 * Released under the MIT license.
15622 * https://jquery.org/license
15623 */
15624
15625//>>label: Fade Effect
15626//>>group: Effects
15627//>>description: Fades the element.
15628//>>docs: https://api.jqueryui.com/fade-effect/
15629//>>demos: https://jqueryui.com/effect/
15630
15631( function( factory ) {
15632 "use strict";
15633
15634 if ( typeof define === "function" && define.amd ) {
15635
15636 // AMD. Register as an anonymous module.
15637 define( [
15638 "jquery",
15639 "../version",
15640 "../effect"
15641 ], factory );
15642 } else {
15643
15644 // Browser globals
15645 factory( jQuery );
15646 }
15647} )( function( $ ) {
15648"use strict";
15649
15650return $.effects.define( "fade", "toggle", function( options, done ) {
15651 var show = options.mode === "show";
15652
15653 $( this )
15654 .css( "opacity", show ? 0 : 1 )
15655 .animate( {
15656 opacity: show ? 1 : 0
15657 }, {
15658 queue: false,
15659 duration: options.duration,
15660 easing: options.easing,
15661 complete: done
15662 } );
15663} );
15664
15665} );
15666
15667
15668
15669/*!
15670 * jQuery UI Effects Fold 1.14.1
15671 * https://jqueryui.com
15672 *
15673 * Copyright OpenJS Foundation and other contributors
15674 * Released under the MIT license.
15675 * https://jquery.org/license
15676 */
15677
15678//>>label: Fold Effect
15679//>>group: Effects
15680//>>description: Folds an element first horizontally and then vertically.
15681//>>docs: https://api.jqueryui.com/fold-effect/
15682//>>demos: https://jqueryui.com/effect/
15683
15684( function( factory ) {
15685 "use strict";
15686
15687 if ( typeof define === "function" && define.amd ) {
15688
15689 // AMD. Register as an anonymous module.
15690 define( [
15691 "jquery",
15692 "../version",
15693 "../effect"
15694 ], factory );
15695 } else {
15696
15697 // Browser globals
15698 factory( jQuery );
15699 }
15700} )( function( $ ) {
15701"use strict";
15702
15703return $.effects.define( "fold", "hide", function( options, done ) {
15704
15705 // Create element
15706 var element = $( this ),
15707 mode = options.mode,
15708 show = mode === "show",
15709 hide = mode === "hide",
15710 size = options.size || 15,
15711 percent = /([0-9]+)%/.exec( size ),
15712 horizFirst = !!options.horizFirst,
15713 ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
15714 duration = options.duration / 2,
15715
15716 placeholder = $.effects.createPlaceholder( element ),
15717
15718 start = element.cssClip(),
15719 animation1 = { clip: $.extend( {}, start ) },
15720 animation2 = { clip: $.extend( {}, start ) },
15721
15722 distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
15723
15724 queuelen = element.queue().length;
15725
15726 if ( percent ) {
15727 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
15728 }
15729 animation1.clip[ ref[ 0 ] ] = size;
15730 animation2.clip[ ref[ 0 ] ] = size;
15731 animation2.clip[ ref[ 1 ] ] = 0;
15732
15733 if ( show ) {
15734 element.cssClip( animation2.clip );
15735 if ( placeholder ) {
15736 placeholder.css( $.effects.clipToBox( animation2 ) );
15737 }
15738
15739 animation2.clip = start;
15740 }
15741
15742 // Animate
15743 element
15744 .queue( function( next ) {
15745 if ( placeholder ) {
15746 placeholder
15747 .animate( $.effects.clipToBox( animation1 ), duration, options.easing )
15748 .animate( $.effects.clipToBox( animation2 ), duration, options.easing );
15749 }
15750
15751 next();
15752 } )
15753 .animate( animation1, duration, options.easing )
15754 .animate( animation2, duration, options.easing )
15755 .queue( done );
15756
15757 $.effects.unshift( element, queuelen, 4 );
15758} );
15759
15760} );
15761
15762
15763
15764/*!
15765 * jQuery UI Effects Highlight 1.14.1
15766 * https://jqueryui.com
15767 *
15768 * Copyright OpenJS Foundation and other contributors
15769 * Released under the MIT license.
15770 * https://jquery.org/license
15771 */
15772
15773//>>label: Highlight Effect
15774//>>group: Effects
15775//>>description: Highlights the background of an element in a defined color for a custom duration.
15776//>>docs: https://api.jqueryui.com/highlight-effect/
15777//>>demos: https://jqueryui.com/effect/
15778
15779( function( factory ) {
15780 "use strict";
15781
15782 if ( typeof define === "function" && define.amd ) {
15783
15784 // AMD. Register as an anonymous module.
15785 define( [
15786 "jquery",
15787 "../version",
15788 "../effect"
15789 ], factory );
15790 } else {
15791
15792 // Browser globals
15793 factory( jQuery );
15794 }
15795} )( function( $ ) {
15796"use strict";
15797
15798return $.effects.define( "highlight", "show", function( options, done ) {
15799 var element = $( this ),
15800 animation = {
15801 backgroundColor: element.css( "backgroundColor" )
15802 };
15803
15804 if ( options.mode === "hide" ) {
15805 animation.opacity = 0;
15806 }
15807
15808 $.effects.saveStyle( element );
15809
15810 element
15811 .css( {
15812 backgroundImage: "none",
15813 backgroundColor: options.color || "#ffff99"
15814 } )
15815 .animate( animation, {
15816 queue: false,
15817 duration: options.duration,
15818 easing: options.easing,
15819 complete: done
15820 } );
15821} );
15822
15823} );
15824
15825
15826
15827/*!
15828 * jQuery UI Effects Size 1.14.1
15829 * https://jqueryui.com
15830 *
15831 * Copyright OpenJS Foundation and other contributors
15832 * Released under the MIT license.
15833 * https://jquery.org/license
15834 */
15835
15836//>>label: Size Effect
15837//>>group: Effects
15838//>>description: Resize an element to a specified width and height.
15839//>>docs: https://api.jqueryui.com/size-effect/
15840//>>demos: https://jqueryui.com/effect/
15841
15842( function( factory ) {
15843 "use strict";
15844
15845 if ( typeof define === "function" && define.amd ) {
15846
15847 // AMD. Register as an anonymous module.
15848 define( [
15849 "jquery",
15850 "../version",
15851 "../effect"
15852 ], factory );
15853 } else {
15854
15855 // Browser globals
15856 factory( jQuery );
15857 }
15858} )( function( $ ) {
15859"use strict";
15860
15861return $.effects.define( "size", function( options, done ) {
15862
15863 // Create element
15864 var baseline, factor, temp,
15865 element = $( this ),
15866
15867 // Copy for children
15868 cProps = [ "fontSize" ],
15869 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
15870 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
15871
15872 // Set options
15873 mode = options.mode,
15874 restore = mode !== "effect",
15875 scale = options.scale || "both",
15876 origin = options.origin || [ "middle", "center" ],
15877 position = element.css( "position" ),
15878 pos = element.position(),
15879 original = $.effects.scaledDimensions( element ),
15880 from = options.from || original,
15881 to = options.to || $.effects.scaledDimensions( element, 0 );
15882
15883 $.effects.createPlaceholder( element );
15884
15885 if ( mode === "show" ) {
15886 temp = from;
15887 from = to;
15888 to = temp;
15889 }
15890
15891 // Set scaling factor
15892 factor = {
15893 from: {
15894 y: from.height / original.height,
15895 x: from.width / original.width
15896 },
15897 to: {
15898 y: to.height / original.height,
15899 x: to.width / original.width
15900 }
15901 };
15902
15903 // Scale the css box
15904 if ( scale === "box" || scale === "both" ) {
15905
15906 // Vertical props scaling
15907 if ( factor.from.y !== factor.to.y ) {
15908 from = $.effects.setTransition( element, vProps, factor.from.y, from );
15909 to = $.effects.setTransition( element, vProps, factor.to.y, to );
15910 }
15911
15912 // Horizontal props scaling
15913 if ( factor.from.x !== factor.to.x ) {
15914 from = $.effects.setTransition( element, hProps, factor.from.x, from );
15915 to = $.effects.setTransition( element, hProps, factor.to.x, to );
15916 }
15917 }
15918
15919 // Scale the content
15920 if ( scale === "content" || scale === "both" ) {
15921
15922 // Vertical props scaling
15923 if ( factor.from.y !== factor.to.y ) {
15924 from = $.effects.setTransition( element, cProps, factor.from.y, from );
15925 to = $.effects.setTransition( element, cProps, factor.to.y, to );
15926 }
15927 }
15928
15929 // Adjust the position properties based on the provided origin points
15930 if ( origin ) {
15931 baseline = $.effects.getBaseline( origin, original );
15932 from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
15933 from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
15934 to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
15935 to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
15936 }
15937 delete from.outerHeight;
15938 delete from.outerWidth;
15939 element.css( from );
15940
15941 // Animate the children if desired
15942 if ( scale === "content" || scale === "both" ) {
15943
15944 vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
15945 hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
15946
15947 // Only animate children with width attributes specified
15948 // TODO: is this right? should we include anything with css width specified as well
15949 element.find( "*[width]" ).each( function() {
15950 var child = $( this ),
15951 childOriginal = $.effects.scaledDimensions( child ),
15952 childFrom = {
15953 height: childOriginal.height * factor.from.y,
15954 width: childOriginal.width * factor.from.x,
15955 outerHeight: childOriginal.outerHeight * factor.from.y,
15956 outerWidth: childOriginal.outerWidth * factor.from.x
15957 },
15958 childTo = {
15959 height: childOriginal.height * factor.to.y,
15960 width: childOriginal.width * factor.to.x,
15961 outerHeight: childOriginal.height * factor.to.y,
15962 outerWidth: childOriginal.width * factor.to.x
15963 };
15964
15965 // Vertical props scaling
15966 if ( factor.from.y !== factor.to.y ) {
15967 childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
15968 childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
15969 }
15970
15971 // Horizontal props scaling
15972 if ( factor.from.x !== factor.to.x ) {
15973 childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
15974 childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
15975 }
15976
15977 if ( restore ) {
15978 $.effects.saveStyle( child );
15979 }
15980
15981 // Animate children
15982 child.css( childFrom );
15983 child.animate( childTo, options.duration, options.easing, function() {
15984
15985 // Restore children
15986 if ( restore ) {
15987 $.effects.restoreStyle( child );
15988 }
15989 } );
15990 } );
15991 }
15992
15993 // Animate
15994 element.animate( to, {
15995 queue: false,
15996 duration: options.duration,
15997 easing: options.easing,
15998 complete: function() {
15999
16000 var offset = element.offset();
16001
16002 if ( to.opacity === 0 ) {
16003 element.css( "opacity", from.opacity );
16004 }
16005
16006 if ( !restore ) {
16007 element
16008 .css( "position", position === "static" ? "relative" : position )
16009 .offset( offset );
16010
16011 // Need to save style here so that automatic style restoration
16012 // doesn't restore to the original styles from before the animation.
16013 $.effects.saveStyle( element );
16014 }
16015
16016 done();
16017 }
16018 } );
16019
16020} );
16021
16022} );
16023
16024
16025
16026
16027/*!
16028 * jQuery UI Effects Scale 1.14.1
16029 * https://jqueryui.com
16030 *
16031 * Copyright OpenJS Foundation and other contributors
16032 * Released under the MIT license.
16033 * https://jquery.org/license
16034 */
16035
16036//>>label: Scale Effect
16037//>>group: Effects
16038//>>description: Grows or shrinks an element and its content.
16039//>>docs: https://api.jqueryui.com/scale-effect/
16040//>>demos: https://jqueryui.com/effect/
16041
16042( function( factory ) {
16043 "use strict";
16044
16045 if ( typeof define === "function" && define.amd ) {
16046
16047 // AMD. Register as an anonymous module.
16048 define( [
16049 "jquery",
16050 "../version",
16051 "../effect",
16052 "./effect-size"
16053 ], factory );
16054 } else {
16055
16056 // Browser globals
16057 factory( jQuery );
16058 }
16059} )( function( $ ) {
16060"use strict";
16061
16062return $.effects.define( "scale", function( options, done ) {
16063
16064 // Create element
16065 var el = $( this ),
16066 mode = options.mode,
16067 percent = parseInt( options.percent, 10 ) ||
16068 ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
16069
16070 newOptions = $.extend( true, {
16071 from: $.effects.scaledDimensions( el ),
16072 to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
16073 origin: options.origin || [ "middle", "center" ]
16074 }, options );
16075
16076 // Fade option to support puff
16077 if ( options.fade ) {
16078 newOptions.from.opacity = 1;
16079 newOptions.to.opacity = 0;
16080 }
16081
16082 $.effects.effect.size.call( this, newOptions, done );
16083} );
16084
16085} );
16086
16087
16088
16089
16090/*!
16091 * jQuery UI Effects Puff 1.14.1
16092 * https://jqueryui.com
16093 *
16094 * Copyright OpenJS Foundation and other contributors
16095 * Released under the MIT license.
16096 * https://jquery.org/license
16097 */
16098
16099//>>label: Puff Effect
16100//>>group: Effects
16101//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
16102//>>docs: https://api.jqueryui.com/puff-effect/
16103//>>demos: https://jqueryui.com/effect/
16104
16105( function( factory ) {
16106 "use strict";
16107
16108 if ( typeof define === "function" && define.amd ) {
16109
16110 // AMD. Register as an anonymous module.
16111 define( [
16112 "jquery",
16113 "../version",
16114 "../effect",
16115 "./effect-scale"
16116 ], factory );
16117 } else {
16118
16119 // Browser globals
16120 factory( jQuery );
16121 }
16122} )( function( $ ) {
16123"use strict";
16124
16125return $.effects.define( "puff", "hide", function( options, done ) {
16126 var newOptions = $.extend( true, {}, options, {
16127 fade: true,
16128 percent: parseInt( options.percent, 10 ) || 150
16129 } );
16130
16131 $.effects.effect.scale.call( this, newOptions, done );
16132} );
16133
16134} );
16135
16136
16137
16138/*!
16139 * jQuery UI Effects Pulsate 1.14.1
16140 * https://jqueryui.com
16141 *
16142 * Copyright OpenJS Foundation and other contributors
16143 * Released under the MIT license.
16144 * https://jquery.org/license
16145 */
16146
16147//>>label: Pulsate Effect
16148//>>group: Effects
16149//>>description: Pulsates an element n times by changing the opacity to zero and back.
16150//>>docs: https://api.jqueryui.com/pulsate-effect/
16151//>>demos: https://jqueryui.com/effect/
16152
16153( function( factory ) {
16154 "use strict";
16155
16156 if ( typeof define === "function" && define.amd ) {
16157
16158 // AMD. Register as an anonymous module.
16159 define( [
16160 "jquery",
16161 "../version",
16162 "../effect"
16163 ], factory );
16164 } else {
16165
16166 // Browser globals
16167 factory( jQuery );
16168 }
16169} )( function( $ ) {
16170"use strict";
16171
16172return $.effects.define( "pulsate", "show", function( options, done ) {
16173 var element = $( this ),
16174 mode = options.mode,
16175 show = mode === "show",
16176 hide = mode === "hide",
16177 showhide = show || hide,
16178
16179 // Showing or hiding leaves off the "last" animation
16180 anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
16181 duration = options.duration / anims,
16182 animateTo = 0,
16183 i = 1,
16184 queuelen = element.queue().length;
16185
16186 if ( show || !element.is( ":visible" ) ) {
16187 element.css( "opacity", 0 ).show();
16188 animateTo = 1;
16189 }
16190
16191 // Anims - 1 opacity "toggles"
16192 for ( ; i < anims; i++ ) {
16193 element.animate( { opacity: animateTo }, duration, options.easing );
16194 animateTo = 1 - animateTo;
16195 }
16196
16197 element.animate( { opacity: animateTo }, duration, options.easing );
16198
16199 element.queue( done );
16200
16201 $.effects.unshift( element, queuelen, anims + 1 );
16202} );
16203
16204} );
16205
16206
16207
16208/*!
16209 * jQuery UI Effects Shake 1.14.1
16210 * https://jqueryui.com
16211 *
16212 * Copyright OpenJS Foundation and other contributors
16213 * Released under the MIT license.
16214 * https://jquery.org/license
16215 */
16216
16217//>>label: Shake Effect
16218//>>group: Effects
16219//>>description: Shakes an element horizontally or vertically n times.
16220//>>docs: https://api.jqueryui.com/shake-effect/
16221//>>demos: https://jqueryui.com/effect/
16222
16223( function( factory ) {
16224 "use strict";
16225
16226 if ( typeof define === "function" && define.amd ) {
16227
16228 // AMD. Register as an anonymous module.
16229 define( [
16230 "jquery",
16231 "../version",
16232 "../effect"
16233 ], factory );
16234 } else {
16235
16236 // Browser globals
16237 factory( jQuery );
16238 }
16239} )( function( $ ) {
16240"use strict";
16241
16242return $.effects.define( "shake", function( options, done ) {
16243
16244 var i = 1,
16245 element = $( this ),
16246 direction = options.direction || "left",
16247 distance = options.distance || 20,
16248 times = options.times || 3,
16249 anims = times * 2 + 1,
16250 speed = Math.round( options.duration / anims ),
16251 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
16252 positiveMotion = ( direction === "up" || direction === "left" ),
16253 animation = {},
16254 animation1 = {},
16255 animation2 = {},
16256
16257 queuelen = element.queue().length;
16258
16259 $.effects.createPlaceholder( element );
16260
16261 // Animation
16262 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
16263 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
16264 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
16265
16266 // Animate
16267 element.animate( animation, speed, options.easing );
16268
16269 // Shakes
16270 for ( ; i < times; i++ ) {
16271 element
16272 .animate( animation1, speed, options.easing )
16273 .animate( animation2, speed, options.easing );
16274 }
16275
16276 element
16277 .animate( animation1, speed, options.easing )
16278 .animate( animation, speed / 2, options.easing )
16279 .queue( done );
16280
16281 $.effects.unshift( element, queuelen, anims + 1 );
16282} );
16283
16284} );
16285
16286
16287
16288/*!
16289 * jQuery UI Effects Slide 1.14.1
16290 * https://jqueryui.com
16291 *
16292 * Copyright OpenJS Foundation and other contributors
16293 * Released under the MIT license.
16294 * https://jquery.org/license
16295 */
16296
16297//>>label: Slide Effect
16298//>>group: Effects
16299//>>description: Slides an element in and out of the viewport.
16300//>>docs: https://api.jqueryui.com/slide-effect/
16301//>>demos: https://jqueryui.com/effect/
16302
16303( function( factory ) {
16304 "use strict";
16305
16306 if ( typeof define === "function" && define.amd ) {
16307
16308 // AMD. Register as an anonymous module.
16309 define( [
16310 "jquery",
16311 "../version",
16312 "../effect"
16313 ], factory );
16314 } else {
16315
16316 // Browser globals
16317 factory( jQuery );
16318 }
16319} )( function( $ ) {
16320"use strict";
16321
16322return $.effects.define( "slide", "show", function( options, done ) {
16323 var startClip, startRef,
16324 element = $( this ),
16325 map = {
16326 up: [ "bottom", "top" ],
16327 down: [ "top", "bottom" ],
16328 left: [ "right", "left" ],
16329 right: [ "left", "right" ]
16330 },
16331 mode = options.mode,
16332 direction = options.direction || "left",
16333 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
16334 positiveMotion = ( direction === "up" || direction === "left" ),
16335 distance = options.distance ||
16336 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
16337 animation = {};
16338
16339 $.effects.createPlaceholder( element );
16340
16341 startClip = element.cssClip();
16342 startRef = element.position()[ ref ];
16343
16344 // Define hide animation
16345 animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
16346 animation.clip = element.cssClip();
16347 animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
16348
16349 // Reverse the animation if we're showing
16350 if ( mode === "show" ) {
16351 element.cssClip( animation.clip );
16352 element.css( ref, animation[ ref ] );
16353 animation.clip = startClip;
16354 animation[ ref ] = startRef;
16355 }
16356
16357 // Actually animate
16358 element.animate( animation, {
16359 queue: false,
16360 duration: options.duration,
16361 easing: options.easing,
16362 complete: done
16363 } );
16364} );
16365
16366} );
16367
16368
16369
16370/*!
16371 * jQuery UI Effects Transfer 1.14.1
16372 * https://jqueryui.com
16373 *
16374 * Copyright OpenJS Foundation and other contributors
16375 * Released under the MIT license.
16376 * https://jquery.org/license
16377 */
16378
16379//>>label: Transfer Effect
16380//>>group: Effects
16381//>>description: Displays a transfer effect from one element to another.
16382//>>docs: https://api.jqueryui.com/transfer-effect/
16383//>>demos: https://jqueryui.com/effect/
16384
16385( function( factory ) {
16386 "use strict";
16387
16388 if ( typeof define === "function" && define.amd ) {
16389
16390 // AMD. Register as an anonymous module.
16391 define( [
16392 "jquery",
16393 "../version",
16394 "../effect"
16395 ], factory );
16396 } else {
16397
16398 // Browser globals
16399 factory( jQuery );
16400 }
16401} )( function( $ ) {
16402"use strict";
16403
16404var effect;
16405if ( $.uiBackCompat === true ) {
16406 effect = $.effects.define( "transfer", function( options, done ) {
16407 $( this ).transfer( options, done );
16408 } );
16409}
16410return effect;
16411
16412} );
16413
16414
16415
16416
16417
16418/*!
16419 * jQuery UI Accordion 1.14.1
16420 * https://jqueryui.com
16421 *
16422 * Copyright OpenJS Foundation and other contributors
16423 * Released under the MIT license.
16424 * https://jquery.org/license
16425 */
16426
16427//>>label: Accordion
16428//>>group: Widgets
16429/* eslint-disable max-len */
16430//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
16431/* eslint-enable max-len */
16432//>>docs: https://api.jqueryui.com/accordion/
16433//>>demos: https://jqueryui.com/accordion/
16434//>>css.structure: ../../themes/base/core.css
16435//>>css.structure: ../../themes/base/accordion.css
16436//>>css.theme: ../../themes/base/theme.css
16437
16438( function( factory ) {
16439 "use strict";
16440
16441 if ( typeof define === "function" && define.amd ) {
16442
16443 // AMD. Register as an anonymous module.
16444 define( [
16445 "jquery",
16446 "../version",
16447 "../keycode",
16448 "../unique-id",
16449 "../widget"
16450 ], factory );
16451 } else {
16452
16453 // Browser globals
16454 factory( jQuery );
16455 }
16456} )( function( $ ) {
16457"use strict";
16458
16459return $.widget( "ui.accordion", {
16460 version: "1.14.1",
16461 options: {
16462 active: 0,
16463 animate: {},
16464 classes: {
16465 "ui-accordion-header": "ui-corner-top",
16466 "ui-accordion-header-collapsed": "ui-corner-all",
16467 "ui-accordion-content": "ui-corner-bottom"
16468 },
16469 collapsible: false,
16470 event: "click",
16471 header: function( elem ) {
16472 return elem
16473 .find( "> li > :first-child" )
16474 .add(
16475 elem.find( "> :not(li)" )
16476
16477 // Support: jQuery <3.5 only
16478 // We could use `.even()` but that's unavailable in older jQuery.
16479 .filter( function( i ) {
16480 return i % 2 === 0;
16481 } )
16482 );
16483 },
16484 heightStyle: "auto",
16485 icons: {
16486 activeHeader: "ui-icon-triangle-1-s",
16487 header: "ui-icon-triangle-1-e"
16488 },
16489
16490 // Callbacks
16491 activate: null,
16492 beforeActivate: null
16493 },
16494
16495 hideProps: {
16496 borderTopWidth: "hide",
16497 borderBottomWidth: "hide",
16498 paddingTop: "hide",
16499 paddingBottom: "hide",
16500 height: "hide"
16501 },
16502
16503 showProps: {
16504 borderTopWidth: "show",
16505 borderBottomWidth: "show",
16506 paddingTop: "show",
16507 paddingBottom: "show",
16508 height: "show"
16509 },
16510
16511 _create: function() {
16512 var options = this.options;
16513
16514 this.prevShow = this.prevHide = $();
16515 this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
16516 this.element.attr( "role", "tablist" );
16517
16518 // Don't allow collapsible: false and active: false / null
16519 if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
16520 options.active = 0;
16521 }
16522
16523 this._processPanels();
16524
16525 // handle negative values
16526 if ( options.active < 0 ) {
16527 options.active += this.headers.length;
16528 }
16529 this._refresh();
16530 },
16531
16532 _getCreateEventData: function() {
16533 return {
16534 header: this.active,
16535 panel: !this.active.length ? $() : this.active.next()
16536 };
16537 },
16538
16539 _createIcons: function() {
16540 var icon, children,
16541 icons = this.options.icons;
16542
16543 if ( icons ) {
16544 icon = $( "<span>" );
16545 this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
16546 icon.prependTo( this.headers );
16547 children = this.active.children( ".ui-accordion-header-icon" );
16548 this._removeClass( children, icons.header )
16549 ._addClass( children, null, icons.activeHeader )
16550 ._addClass( this.headers, "ui-accordion-icons" );
16551 }
16552 },
16553
16554 _destroyIcons: function() {
16555 this._removeClass( this.headers, "ui-accordion-icons" );
16556 this.headers.children( ".ui-accordion-header-icon" ).remove();
16557 },
16558
16559 _destroy: function() {
16560 var contents;
16561
16562 // Clean up main element
16563 this.element.removeAttr( "role" );
16564
16565 // Clean up headers
16566 this.headers
16567 .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
16568 .removeUniqueId();
16569
16570 this._destroyIcons();
16571
16572 // Clean up content panels
16573 contents = this.headers.next()
16574 .css( "display", "" )
16575 .removeAttr( "role aria-hidden aria-labelledby" )
16576 .removeUniqueId();
16577
16578 if ( this.options.heightStyle !== "content" ) {
16579 contents.css( "height", "" );
16580 }
16581 },
16582
16583 _setOption: function( key, value ) {
16584 if ( key === "active" ) {
16585
16586 // _activate() will handle invalid values and update this.options
16587 this._activate( value );
16588 return;
16589 }
16590
16591 if ( key === "event" ) {
16592 if ( this.options.event ) {
16593 this._off( this.headers, this.options.event );
16594 }
16595 this._setupEvents( value );
16596 }
16597
16598 this._super( key, value );
16599
16600 // Setting collapsible: false while collapsed; open first panel
16601 if ( key === "collapsible" && !value && this.options.active === false ) {
16602 this._activate( 0 );
16603 }
16604
16605 if ( key === "icons" ) {
16606 this._destroyIcons();
16607 if ( value ) {
16608 this._createIcons();
16609 }
16610 }
16611 },
16612
16613 _setOptionDisabled: function( value ) {
16614 this._super( value );
16615
16616 this.element.attr( "aria-disabled", value );
16617 this._toggleClass( null, "ui-state-disabled", !!value );
16618 },
16619
16620 _keydown: function( event ) {
16621 if ( event.altKey || event.ctrlKey ) {
16622 return;
16623 }
16624
16625 var keyCode = $.ui.keyCode,
16626 length = this.headers.length,
16627 currentIndex = this.headers.index( event.target ),
16628 toFocus = false;
16629
16630 switch ( event.keyCode ) {
16631 case keyCode.RIGHT:
16632 case keyCode.DOWN:
16633 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
16634 break;
16635 case keyCode.LEFT:
16636 case keyCode.UP:
16637 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
16638 break;
16639 case keyCode.SPACE:
16640 case keyCode.ENTER:
16641 this._eventHandler( event );
16642 break;
16643 case keyCode.HOME:
16644 toFocus = this.headers[ 0 ];
16645 break;
16646 case keyCode.END:
16647 toFocus = this.headers[ length - 1 ];
16648 break;
16649 }
16650
16651 if ( toFocus ) {
16652 $( event.target ).attr( "tabIndex", -1 );
16653 $( toFocus ).attr( "tabIndex", 0 );
16654 $( toFocus ).trigger( "focus" );
16655 event.preventDefault();
16656 }
16657 },
16658
16659 _panelKeyDown: function( event ) {
16660 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
16661 $( event.currentTarget ).prev().trigger( "focus" );
16662 }
16663 },
16664
16665 refresh: function() {
16666 var options = this.options;
16667 this._processPanels();
16668
16669 // Was collapsed or no panel
16670 if ( ( options.active === false && options.collapsible === true ) ||
16671 !this.headers.length ) {
16672 options.active = false;
16673 this.active = $();
16674
16675 // active false only when collapsible is true
16676 } else if ( options.active === false ) {
16677 this._activate( 0 );
16678
16679 // was active, but active panel is gone
16680 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
16681
16682 // all remaining panel are disabled
16683 if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
16684 options.active = false;
16685 this.active = $();
16686
16687 // activate previous panel
16688 } else {
16689 this._activate( Math.max( 0, options.active - 1 ) );
16690 }
16691
16692 // was active, active panel still exists
16693 } else {
16694
16695 // make sure active index is correct
16696 options.active = this.headers.index( this.active );
16697 }
16698
16699 this._destroyIcons();
16700
16701 this._refresh();
16702 },
16703
16704 _processPanels: function() {
16705 var prevHeaders = this.headers,
16706 prevPanels = this.panels;
16707
16708 if ( typeof this.options.header === "function" ) {
16709 this.headers = this.options.header( this.element );
16710 } else {
16711 this.headers = this.element.find( this.options.header );
16712 }
16713 this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
16714 "ui-state-default" );
16715
16716 this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
16717 this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
16718
16719 // Avoid memory leaks (#10056)
16720 if ( prevPanels ) {
16721 this._off( prevHeaders.not( this.headers ) );
16722 this._off( prevPanels.not( this.panels ) );
16723 }
16724 },
16725
16726 _refresh: function() {
16727 var maxHeight,
16728 options = this.options,
16729 heightStyle = options.heightStyle,
16730 parent = this.element.parent();
16731
16732 this.active = this._findActive( options.active );
16733 this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
16734 ._removeClass( this.active, "ui-accordion-header-collapsed" );
16735 this._addClass( this.active.next(), "ui-accordion-content-active" );
16736 this.active.next().show();
16737
16738 this.headers
16739 .attr( "role", "tab" )
16740 .each( function() {
16741 var header = $( this ),
16742 headerId = header.uniqueId().attr( "id" ),
16743 panel = header.next(),
16744 panelId = panel.uniqueId().attr( "id" );
16745 header.attr( "aria-controls", panelId );
16746 panel.attr( "aria-labelledby", headerId );
16747 } )
16748 .next()
16749 .attr( "role", "tabpanel" );
16750
16751 this.headers
16752 .not( this.active )
16753 .attr( {
16754 "aria-selected": "false",
16755 "aria-expanded": "false",
16756 tabIndex: -1
16757 } )
16758 .next()
16759 .attr( {
16760 "aria-hidden": "true"
16761 } )
16762 .hide();
16763
16764 // Make sure at least one header is in the tab order
16765 if ( !this.active.length ) {
16766 this.headers.eq( 0 ).attr( "tabIndex", 0 );
16767 } else {
16768 this.active.attr( {
16769 "aria-selected": "true",
16770 "aria-expanded": "true",
16771 tabIndex: 0
16772 } )
16773 .next()
16774 .attr( {
16775 "aria-hidden": "false"
16776 } );
16777 }
16778
16779 this._createIcons();
16780
16781 this._setupEvents( options.event );
16782
16783 if ( heightStyle === "fill" ) {
16784 maxHeight = parent.height();
16785 this.element.siblings( ":visible" ).each( function() {
16786 var elem = $( this ),
16787 position = elem.css( "position" );
16788
16789 if ( position === "absolute" || position === "fixed" ) {
16790 return;
16791 }
16792 maxHeight -= elem.outerHeight( true );
16793 } );
16794
16795 this.headers.each( function() {
16796 maxHeight -= $( this ).outerHeight( true );
16797 } );
16798
16799 this.headers.next()
16800 .each( function() {
16801 $( this ).height( Math.max( 0, maxHeight -
16802 $( this ).innerHeight() + $( this ).height() ) );
16803 } )
16804 .css( "overflow", "auto" );
16805 } else if ( heightStyle === "auto" ) {
16806 maxHeight = 0;
16807 this.headers.next()
16808 .each( function() {
16809 var isVisible = $( this ).is( ":visible" );
16810 if ( !isVisible ) {
16811 $( this ).show();
16812 }
16813 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
16814 if ( !isVisible ) {
16815 $( this ).hide();
16816 }
16817 } )
16818 .height( maxHeight );
16819 }
16820 },
16821
16822 _activate: function( index ) {
16823 var active = this._findActive( index )[ 0 ];
16824
16825 // Trying to activate the already active panel
16826 if ( active === this.active[ 0 ] ) {
16827 return;
16828 }
16829
16830 // Trying to collapse, simulate a click on the currently active header
16831 active = active || this.active[ 0 ];
16832
16833 this._eventHandler( {
16834 target: active,
16835 currentTarget: active,
16836 preventDefault: $.noop
16837 } );
16838 },
16839
16840 _findActive: function( selector ) {
16841 return typeof selector === "number" ? this.headers.eq( selector ) : $();
16842 },
16843
16844 _setupEvents: function( event ) {
16845 var events = {
16846 keydown: "_keydown"
16847 };
16848 if ( event ) {
16849 $.each( event.split( " " ), function( index, eventName ) {
16850 events[ eventName ] = "_eventHandler";
16851 } );
16852 }
16853
16854 this._off( this.headers.add( this.headers.next() ) );
16855 this._on( this.headers, events );
16856 this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
16857 this._hoverable( this.headers );
16858 this._focusable( this.headers );
16859 },
16860
16861 _eventHandler: function( event ) {
16862 var activeChildren, clickedChildren,
16863 options = this.options,
16864 active = this.active,
16865 clicked = $( event.currentTarget ),
16866 clickedIsActive = clicked[ 0 ] === active[ 0 ],
16867 collapsing = clickedIsActive && options.collapsible,
16868 toShow = collapsing ? $() : clicked.next(),
16869 toHide = active.next(),
16870 eventData = {
16871 oldHeader: active,
16872 oldPanel: toHide,
16873 newHeader: collapsing ? $() : clicked,
16874 newPanel: toShow
16875 };
16876
16877 event.preventDefault();
16878
16879 if (
16880
16881 // click on active header, but not collapsible
16882 ( clickedIsActive && !options.collapsible ) ||
16883
16884 // allow canceling activation
16885 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
16886 return;
16887 }
16888
16889 options.active = collapsing ? false : this.headers.index( clicked );
16890
16891 // When the call to ._toggle() comes after the class changes
16892 // it causes a very odd bug in IE 8 (see #6720)
16893 this.active = clickedIsActive ? $() : clicked;
16894 this._toggle( eventData );
16895
16896 // Switch classes
16897 // corner classes on the previously active header stay after the animation
16898 this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
16899 if ( options.icons ) {
16900 activeChildren = active.children( ".ui-accordion-header-icon" );
16901 this._removeClass( activeChildren, null, options.icons.activeHeader )
16902 ._addClass( activeChildren, null, options.icons.header );
16903 }
16904
16905 if ( !clickedIsActive ) {
16906 this._removeClass( clicked, "ui-accordion-header-collapsed" )
16907 ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
16908 if ( options.icons ) {
16909 clickedChildren = clicked.children( ".ui-accordion-header-icon" );
16910 this._removeClass( clickedChildren, null, options.icons.header )
16911 ._addClass( clickedChildren, null, options.icons.activeHeader );
16912 }
16913
16914 this._addClass( clicked.next(), "ui-accordion-content-active" );
16915 }
16916 },
16917
16918 _toggle: function( data ) {
16919 var toShow = data.newPanel,
16920 toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
16921
16922 // Handle activating a panel during the animation for another activation
16923 this.prevShow.add( this.prevHide ).stop( true, true );
16924 this.prevShow = toShow;
16925 this.prevHide = toHide;
16926
16927 if ( this.options.animate ) {
16928 this._animate( toShow, toHide, data );
16929 } else {
16930 toHide.hide();
16931 toShow.show();
16932 this._toggleComplete( data );
16933 }
16934
16935 toHide.attr( {
16936 "aria-hidden": "true"
16937 } );
16938 toHide.prev().attr( {
16939 "aria-selected": "false",
16940 "aria-expanded": "false"
16941 } );
16942
16943 // if we're switching panels, remove the old header from the tab order
16944 // if we're opening from collapsed state, remove the previous header from the tab order
16945 // if we're collapsing, then keep the collapsing header in the tab order
16946 if ( toShow.length && toHide.length ) {
16947 toHide.prev().attr( {
16948 "tabIndex": -1,
16949 "aria-expanded": "false"
16950 } );
16951 } else if ( toShow.length ) {
16952 this.headers.filter( function() {
16953 return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
16954 } )
16955 .attr( "tabIndex", -1 );
16956 }
16957
16958 toShow
16959 .attr( "aria-hidden", "false" )
16960 .prev()
16961 .attr( {
16962 "aria-selected": "true",
16963 "aria-expanded": "true",
16964 tabIndex: 0
16965 } );
16966 },
16967
16968 _animate: function( toShow, toHide, data ) {
16969 var total, easing, duration,
16970 that = this,
16971 adjust = 0,
16972 boxSizing = toShow.css( "box-sizing" ),
16973 down = toShow.length &&
16974 ( !toHide.length || ( toShow.index() < toHide.index() ) ),
16975 animate = this.options.animate || {},
16976 options = down && animate.down || animate,
16977 complete = function() {
16978 that._toggleComplete( data );
16979 };
16980
16981 if ( typeof options === "number" ) {
16982 duration = options;
16983 }
16984 if ( typeof options === "string" ) {
16985 easing = options;
16986 }
16987
16988 // fall back from options to animation in case of partial down settings
16989 easing = easing || options.easing || animate.easing;
16990 duration = duration || options.duration || animate.duration;
16991
16992 if ( !toHide.length ) {
16993 return toShow.animate( this.showProps, duration, easing, complete );
16994 }
16995 if ( !toShow.length ) {
16996 return toHide.animate( this.hideProps, duration, easing, complete );
16997 }
16998
16999 total = toShow.show().outerHeight();
17000 toHide.animate( this.hideProps, {
17001 duration: duration,
17002 easing: easing,
17003 step: function( now, fx ) {
17004 fx.now = Math.round( now );
17005 }
17006 } );
17007 toShow
17008 .hide()
17009 .animate( this.showProps, {
17010 duration: duration,
17011 easing: easing,
17012 complete: complete,
17013 step: function( now, fx ) {
17014 fx.now = Math.round( now );
17015 if ( fx.prop !== "height" ) {
17016 if ( boxSizing === "content-box" ) {
17017 adjust += fx.now;
17018 }
17019 } else if ( that.options.heightStyle !== "content" ) {
17020 fx.now = Math.round( total - toHide.outerHeight() - adjust );
17021 adjust = 0;
17022 }
17023 }
17024 } );
17025 },
17026
17027 _toggleComplete: function( data ) {
17028 var toHide = data.oldPanel,
17029 prev = toHide.prev();
17030
17031 this._removeClass( toHide, "ui-accordion-content-active" );
17032 this._removeClass( prev, "ui-accordion-header-active" )
17033 ._addClass( prev, "ui-accordion-header-collapsed" );
17034
17035 this._trigger( "activate", null, data );
17036 }
17037} );
17038
17039} );
17040
17041
17042
17043
17044
17045
17046/*!
17047 * jQuery UI Menu 1.14.1
17048 * https://jqueryui.com
17049 *
17050 * Copyright OpenJS Foundation and other contributors
17051 * Released under the MIT license.
17052 * https://jquery.org/license
17053 */
17054
17055//>>label: Menu
17056//>>group: Widgets
17057//>>description: Creates nestable menus.
17058//>>docs: https://api.jqueryui.com/menu/
17059//>>demos: https://jqueryui.com/menu/
17060//>>css.structure: ../../themes/base/core.css
17061//>>css.structure: ../../themes/base/menu.css
17062//>>css.theme: ../../themes/base/theme.css
17063
17064( function( factory ) {
17065 "use strict";
17066
17067 if ( typeof define === "function" && define.amd ) {
17068
17069 // AMD. Register as an anonymous module.
17070 define( [
17071 "jquery",
17072 "../keycode",
17073 "../position",
17074 "../unique-id",
17075 "../version",
17076 "../widget"
17077 ], factory );
17078 } else {
17079
17080 // Browser globals
17081 factory( jQuery );
17082 }
17083} )( function( $ ) {
17084"use strict";
17085
17086return $.widget( "ui.menu", {
17087 version: "1.14.1",
17088 defaultElement: "<ul>",
17089 delay: 300,
17090 options: {
17091 icons: {
17092 submenu: "ui-icon-caret-1-e"
17093 },
17094 items: "> *",
17095 menus: "ul",
17096 position: {
17097 my: "left top",
17098 at: "right top"
17099 },
17100 role: "menu",
17101
17102 // Callbacks
17103 blur: null,
17104 focus: null,
17105 select: null
17106 },
17107
17108 _create: function() {
17109 this.activeMenu = this.element;
17110
17111 // Flag used to prevent firing of the click handler
17112 // as the event bubbles up through nested menus
17113 this.mouseHandled = false;
17114 this.lastMousePosition = { x: null, y: null };
17115 this.element
17116 .uniqueId()
17117 .attr( {
17118 role: this.options.role,
17119 tabIndex: 0
17120 } );
17121
17122 this._addClass( "ui-menu", "ui-widget ui-widget-content" );
17123 this._on( {
17124
17125 // Prevent focus from sticking to links inside menu after clicking
17126 // them (focus should always stay on UL during navigation).
17127 "mousedown .ui-menu-item": function( event ) {
17128 event.preventDefault();
17129
17130 this._activateItem( event );
17131 },
17132 "click .ui-menu-item": function( event ) {
17133 var target = $( event.target );
17134 var active = $( this.document[ 0 ].activeElement );
17135 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
17136 this.select( event );
17137
17138 // Only set the mouseHandled flag if the event will bubble, see #9469.
17139 if ( !event.isPropagationStopped() ) {
17140 this.mouseHandled = true;
17141 }
17142
17143 // Open submenu on click
17144 if ( target.has( ".ui-menu" ).length ) {
17145 this.expand( event );
17146 } else if ( !this.element.is( ":focus" ) &&
17147 active.closest( ".ui-menu" ).length ) {
17148
17149 // Redirect focus to the menu
17150 this.element.trigger( "focus", [ true ] );
17151
17152 // If the active item is on the top level, let it stay active.
17153 // Otherwise, blur the active item since it is no longer visible.
17154 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
17155 clearTimeout( this.timer );
17156 }
17157 }
17158 }
17159 },
17160 "mouseenter .ui-menu-item": "_activateItem",
17161 "mousemove .ui-menu-item": "_activateItem",
17162 mouseleave: "collapseAll",
17163 "mouseleave .ui-menu": "collapseAll",
17164 focus: function( event, keepActiveItem ) {
17165
17166 // If there's already an active item, keep it active
17167 // If not, activate the first item
17168 var item = this.active || this._menuItems().first();
17169
17170 if ( !keepActiveItem ) {
17171 this.focus( event, item );
17172 }
17173 },
17174 blur: function( event ) {
17175 this._delay( function() {
17176 var notContained = !$.contains(
17177 this.element[ 0 ],
17178 this.document[ 0 ].activeElement
17179 );
17180 if ( notContained ) {
17181 this.collapseAll( event );
17182 }
17183 } );
17184 },
17185 keydown: "_keydown"
17186 } );
17187
17188 this.refresh();
17189
17190 // Clicks outside of a menu collapse any open menus
17191 this._on( this.document, {
17192 click: function( event ) {
17193 if ( this._closeOnDocumentClick( event ) ) {
17194 this.collapseAll( event, true );
17195 }
17196
17197 // Reset the mouseHandled flag
17198 this.mouseHandled = false;
17199 }
17200 } );
17201 },
17202
17203 _activateItem: function( event ) {
17204
17205 // Ignore mouse events while typeahead is active, see #10458.
17206 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
17207 // is over an item in the menu
17208 if ( this.previousFilter ) {
17209 return;
17210 }
17211
17212 // If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356)
17213 if ( event.clientX === this.lastMousePosition.x &&
17214 event.clientY === this.lastMousePosition.y ) {
17215 return;
17216 }
17217
17218 this.lastMousePosition = {
17219 x: event.clientX,
17220 y: event.clientY
17221 };
17222
17223 var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
17224 target = $( event.currentTarget );
17225
17226 // Ignore bubbled events on parent items, see #11641
17227 if ( actualTarget[ 0 ] !== target[ 0 ] ) {
17228 return;
17229 }
17230
17231 // If the item is already active, there's nothing to do
17232 if ( target.is( ".ui-state-active" ) ) {
17233 return;
17234 }
17235
17236 // Remove ui-state-active class from siblings of the newly focused menu item
17237 // to avoid a jump caused by adjacent elements both having a class with a border
17238 this._removeClass( target.siblings().children( ".ui-state-active" ),
17239 null, "ui-state-active" );
17240 this.focus( event, target );
17241 },
17242
17243 _destroy: function() {
17244 var items = this.element.find( ".ui-menu-item" )
17245 .removeAttr( "role aria-disabled" ),
17246 submenus = items.children( ".ui-menu-item-wrapper" )
17247 .removeUniqueId()
17248 .removeAttr( "tabIndex role aria-haspopup" );
17249
17250 // Destroy (sub)menus
17251 this.element
17252 .removeAttr( "aria-activedescendant" )
17253 .find( ".ui-menu" ).addBack()
17254 .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
17255 "tabIndex" )
17256 .removeUniqueId()
17257 .show();
17258
17259 submenus.children().each( function() {
17260 var elem = $( this );
17261 if ( elem.data( "ui-menu-submenu-caret" ) ) {
17262 elem.remove();
17263 }
17264 } );
17265 },
17266
17267 _keydown: function( event ) {
17268 var match, prev, character, skip,
17269 preventDefault = true;
17270
17271 switch ( event.keyCode ) {
17272 case $.ui.keyCode.PAGE_UP:
17273 this.previousPage( event );
17274 break;
17275 case $.ui.keyCode.PAGE_DOWN:
17276 this.nextPage( event );
17277 break;
17278 case $.ui.keyCode.HOME:
17279 this._move( "first", "first", event );
17280 break;
17281 case $.ui.keyCode.END:
17282 this._move( "last", "last", event );
17283 break;
17284 case $.ui.keyCode.UP:
17285 this.previous( event );
17286 break;
17287 case $.ui.keyCode.DOWN:
17288 this.next( event );
17289 break;
17290 case $.ui.keyCode.LEFT:
17291 this.collapse( event );
17292 break;
17293 case $.ui.keyCode.RIGHT:
17294 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
17295 this.expand( event );
17296 }
17297 break;
17298 case $.ui.keyCode.ENTER:
17299 case $.ui.keyCode.SPACE:
17300 this._activate( event );
17301 break;
17302 case $.ui.keyCode.ESCAPE:
17303 this.collapse( event );
17304 break;
17305 default:
17306 preventDefault = false;
17307 prev = this.previousFilter || "";
17308 skip = false;
17309
17310 // Support number pad values
17311 character = event.keyCode >= 96 && event.keyCode <= 105 ?
17312 ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
17313
17314 clearTimeout( this.filterTimer );
17315
17316 if ( character === prev ) {
17317 skip = true;
17318 } else {
17319 character = prev + character;
17320 }
17321
17322 match = this._filterMenuItems( character );
17323 match = skip && match.index( this.active.next() ) !== -1 ?
17324 this.active.nextAll( ".ui-menu-item" ) :
17325 match;
17326
17327 // If no matches on the current filter, reset to the last character pressed
17328 // to move down the menu to the first item that starts with that character
17329 if ( !match.length ) {
17330 character = String.fromCharCode( event.keyCode );
17331 match = this._filterMenuItems( character );
17332 }
17333
17334 if ( match.length ) {
17335 this.focus( event, match );
17336 this.previousFilter = character;
17337 this.filterTimer = this._delay( function() {
17338 delete this.previousFilter;
17339 }, 1000 );
17340 } else {
17341 delete this.previousFilter;
17342 }
17343 }
17344
17345 if ( preventDefault ) {
17346 event.preventDefault();
17347 }
17348 },
17349
17350 _activate: function( event ) {
17351 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
17352 if ( this.active.children( "[aria-haspopup='true']" ).length ) {
17353 this.expand( event );
17354 } else {
17355 this.select( event );
17356 }
17357 }
17358 },
17359
17360 refresh: function() {
17361 var menus, items, newSubmenus, newItems, newWrappers,
17362 that = this,
17363 icon = this.options.icons.submenu,
17364 submenus = this.element.find( this.options.menus );
17365
17366 this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
17367
17368 // Initialize nested menus
17369 newSubmenus = submenus.filter( ":not(.ui-menu)" )
17370 .hide()
17371 .attr( {
17372 role: this.options.role,
17373 "aria-hidden": "true",
17374 "aria-expanded": "false"
17375 } )
17376 .each( function() {
17377 var menu = $( this ),
17378 item = menu.prev(),
17379 submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
17380
17381 that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
17382 item
17383 .attr( "aria-haspopup", "true" )
17384 .prepend( submenuCaret );
17385 menu.attr( "aria-labelledby", item.attr( "id" ) );
17386 } );
17387
17388 this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
17389
17390 menus = submenus.add( this.element );
17391 items = menus.find( this.options.items );
17392
17393 // Initialize menu-items containing spaces and/or dashes only as dividers
17394 items.not( ".ui-menu-item" ).each( function() {
17395 var item = $( this );
17396 if ( that._isDivider( item ) ) {
17397 that._addClass( item, "ui-menu-divider", "ui-widget-content" );
17398 }
17399 } );
17400
17401 // Don't refresh list items that are already adapted
17402 newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
17403 newWrappers = newItems.children()
17404 .not( ".ui-menu" )
17405 .uniqueId()
17406 .attr( {
17407 tabIndex: -1,
17408 role: this._itemRole()
17409 } );
17410 this._addClass( newItems, "ui-menu-item" )
17411 ._addClass( newWrappers, "ui-menu-item-wrapper" );
17412
17413 // Add aria-disabled attribute to any disabled menu item
17414 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
17415
17416 // If the active item has been removed, blur the menu
17417 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
17418 this.blur();
17419 }
17420 },
17421
17422 _itemRole: function() {
17423 return {
17424 menu: "menuitem",
17425 listbox: "option"
17426 }[ this.options.role ];
17427 },
17428
17429 _setOption: function( key, value ) {
17430 if ( key === "icons" ) {
17431 var icons = this.element.find( ".ui-menu-icon" );
17432 this._removeClass( icons, null, this.options.icons.submenu )
17433 ._addClass( icons, null, value.submenu );
17434 }
17435 this._super( key, value );
17436 },
17437
17438 _setOptionDisabled: function( value ) {
17439 this._super( value );
17440
17441 this.element.attr( "aria-disabled", String( value ) );
17442 this._toggleClass( null, "ui-state-disabled", !!value );
17443 },
17444
17445 focus: function( event, item ) {
17446 var nested, focused, activeParent;
17447 this.blur( event, event && event.type === "focus" );
17448
17449 this._scrollIntoView( item );
17450
17451 this.active = item.first();
17452
17453 focused = this.active.children( ".ui-menu-item-wrapper" );
17454 this._addClass( focused, null, "ui-state-active" );
17455
17456 // Only update aria-activedescendant if there's a role
17457 // otherwise we assume focus is managed elsewhere
17458 if ( this.options.role ) {
17459 this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
17460 }
17461
17462 // Highlight active parent menu item, if any
17463 activeParent = this.active
17464 .parent()
17465 .closest( ".ui-menu-item" )
17466 .children( ".ui-menu-item-wrapper" );
17467 this._addClass( activeParent, null, "ui-state-active" );
17468
17469 if ( event && event.type === "keydown" ) {
17470 this._close();
17471 } else {
17472 this.timer = this._delay( function() {
17473 this._close();
17474 }, this.delay );
17475 }
17476
17477 nested = item.children( ".ui-menu" );
17478 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
17479 this._startOpening( nested );
17480 }
17481 this.activeMenu = item.parent();
17482
17483 this._trigger( "focus", event, { item: item } );
17484 },
17485
17486 _scrollIntoView: function( item ) {
17487 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
17488 if ( this._hasScroll() ) {
17489 borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
17490 paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
17491 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
17492 scroll = this.activeMenu.scrollTop();
17493 elementHeight = this.activeMenu.height();
17494 itemHeight = item.outerHeight();
17495
17496 if ( offset < 0 ) {
17497 this.activeMenu.scrollTop( scroll + offset );
17498 } else if ( offset + itemHeight > elementHeight ) {
17499 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
17500 }
17501 }
17502 },
17503
17504 blur: function( event, fromFocus ) {
17505 if ( !fromFocus ) {
17506 clearTimeout( this.timer );
17507 }
17508
17509 if ( !this.active ) {
17510 return;
17511 }
17512
17513 this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
17514 null, "ui-state-active" );
17515
17516 this._trigger( "blur", event, { item: this.active } );
17517 this.active = null;
17518 },
17519
17520 _startOpening: function( submenu ) {
17521 clearTimeout( this.timer );
17522
17523 // Don't open if already open fixes a Firefox bug that caused a .5 pixel
17524 // shift in the submenu position when mousing over the caret icon
17525 if ( submenu.attr( "aria-hidden" ) !== "true" ) {
17526 return;
17527 }
17528
17529 this.timer = this._delay( function() {
17530 this._close();
17531 this._open( submenu );
17532 }, this.delay );
17533 },
17534
17535 _open: function( submenu ) {
17536 var position = $.extend( {
17537 of: this.active
17538 }, this.options.position );
17539
17540 clearTimeout( this.timer );
17541 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
17542 .hide()
17543 .attr( "aria-hidden", "true" );
17544
17545 submenu
17546 .show()
17547 .removeAttr( "aria-hidden" )
17548 .attr( "aria-expanded", "true" )
17549 .position( position );
17550 },
17551
17552 collapseAll: function( event, all ) {
17553 clearTimeout( this.timer );
17554 this.timer = this._delay( function() {
17555
17556 // If we were passed an event, look for the submenu that contains the event
17557 var currentMenu = all ? this.element :
17558 $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
17559
17560 // If we found no valid submenu ancestor, use the main menu to close all
17561 // sub menus anyway
17562 if ( !currentMenu.length ) {
17563 currentMenu = this.element;
17564 }
17565
17566 this._close( currentMenu );
17567
17568 this.blur( event );
17569
17570 // Work around active item staying active after menu is blurred
17571 this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
17572
17573 this.activeMenu = currentMenu;
17574 }, all ? 0 : this.delay );
17575 },
17576
17577 // With no arguments, closes the currently active menu - if nothing is active
17578 // it closes all menus. If passed an argument, it will search for menus BELOW
17579 _close: function( startMenu ) {
17580 if ( !startMenu ) {
17581 startMenu = this.active ? this.active.parent() : this.element;
17582 }
17583
17584 startMenu.find( ".ui-menu" )
17585 .hide()
17586 .attr( "aria-hidden", "true" )
17587 .attr( "aria-expanded", "false" );
17588 },
17589
17590 _closeOnDocumentClick: function( event ) {
17591 return !$( event.target ).closest( ".ui-menu" ).length;
17592 },
17593
17594 _isDivider: function( item ) {
17595
17596 // Match hyphen, em dash, en dash
17597 return !/[^\-\u2014\u2013\s]/.test( item.text() );
17598 },
17599
17600 collapse: function( event ) {
17601 var newItem = this.active &&
17602 this.active.parent().closest( ".ui-menu-item", this.element );
17603 if ( newItem && newItem.length ) {
17604 this._close();
17605 this.focus( event, newItem );
17606 }
17607 },
17608
17609 expand: function( event ) {
17610 var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first();
17611
17612 if ( newItem && newItem.length ) {
17613 this._open( newItem.parent() );
17614
17615 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
17616 this._delay( function() {
17617 this.focus( event, newItem );
17618 } );
17619 }
17620 },
17621
17622 next: function( event ) {
17623 this._move( "next", "first", event );
17624 },
17625
17626 previous: function( event ) {
17627 this._move( "prev", "last", event );
17628 },
17629
17630 isFirstItem: function() {
17631 return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
17632 },
17633
17634 isLastItem: function() {
17635 return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
17636 },
17637
17638 _menuItems: function( menu ) {
17639 return ( menu || this.element )
17640 .find( this.options.items )
17641 .filter( ".ui-menu-item" );
17642 },
17643
17644 _move: function( direction, filter, event ) {
17645 var next;
17646 if ( this.active ) {
17647 if ( direction === "first" || direction === "last" ) {
17648 next = this.active
17649 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
17650 .last();
17651 } else {
17652 next = this.active
17653 [ direction + "All" ]( ".ui-menu-item" )
17654 .first();
17655 }
17656 }
17657 if ( !next || !next.length || !this.active ) {
17658 next = this._menuItems( this.activeMenu )[ filter ]();
17659 }
17660
17661 this.focus( event, next );
17662 },
17663
17664 nextPage: function( event ) {
17665 var item, base, height;
17666
17667 if ( !this.active ) {
17668 this.next( event );
17669 return;
17670 }
17671 if ( this.isLastItem() ) {
17672 return;
17673 }
17674 if ( this._hasScroll() ) {
17675 base = this.active.offset().top;
17676 height = this.element.innerHeight();
17677
17678 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
17679 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
17680 height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
17681 }
17682
17683 this.active.nextAll( ".ui-menu-item" ).each( function() {
17684 item = $( this );
17685 return item.offset().top - base - height < 0;
17686 } );
17687
17688 this.focus( event, item );
17689 } else {
17690 this.focus( event, this._menuItems( this.activeMenu )
17691 [ !this.active ? "first" : "last" ]() );
17692 }
17693 },
17694
17695 previousPage: function( event ) {
17696 var item, base, height;
17697 if ( !this.active ) {
17698 this.next( event );
17699 return;
17700 }
17701 if ( this.isFirstItem() ) {
17702 return;
17703 }
17704 if ( this._hasScroll() ) {
17705 base = this.active.offset().top;
17706 height = this.element.innerHeight();
17707
17708 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
17709 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
17710 height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
17711 }
17712
17713 this.active.prevAll( ".ui-menu-item" ).each( function() {
17714 item = $( this );
17715 return item.offset().top - base + height > 0;
17716 } );
17717
17718 this.focus( event, item );
17719 } else {
17720 this.focus( event, this._menuItems( this.activeMenu ).first() );
17721 }
17722 },
17723
17724 _hasScroll: function() {
17725 return this.element.outerHeight() < this.element.prop( "scrollHeight" );
17726 },
17727
17728 select: function( event ) {
17729
17730 // TODO: It should never be possible to not have an active item at this
17731 // point, but the tests don't trigger mouseenter before click.
17732 this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
17733 var ui = { item: this.active };
17734 if ( !this.active.has( ".ui-menu" ).length ) {
17735 this.collapseAll( event, true );
17736 }
17737 this._trigger( "select", event, ui );
17738 },
17739
17740 _filterMenuItems: function( character ) {
17741 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
17742 regex = new RegExp( "^" + escapedCharacter, "i" );
17743
17744 return this.activeMenu
17745 .find( this.options.items )
17746
17747 // Only match on items, not dividers or other content (#10571)
17748 .filter( ".ui-menu-item" )
17749 .filter( function() {
17750 return regex.test(
17751 String.prototype.trim.call(
17752 $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
17753 } );
17754 }
17755} );
17756
17757} );
17758
17759
17760
17761
17762
17763
17764/*!
17765 * jQuery UI Autocomplete 1.14.1
17766 * https://jqueryui.com
17767 *
17768 * Copyright OpenJS Foundation and other contributors
17769 * Released under the MIT license.
17770 * https://jquery.org/license
17771 */
17772
17773//>>label: Autocomplete
17774//>>group: Widgets
17775//>>description: Lists suggested words as the user is typing.
17776//>>docs: https://api.jqueryui.com/autocomplete/
17777//>>demos: https://jqueryui.com/autocomplete/
17778//>>css.structure: ../../themes/base/core.css
17779//>>css.structure: ../../themes/base/autocomplete.css
17780//>>css.theme: ../../themes/base/theme.css
17781
17782( function( factory ) {
17783 "use strict";
17784
17785 if ( typeof define === "function" && define.amd ) {
17786
17787 // AMD. Register as an anonymous module.
17788 define( [
17789 "jquery",
17790 "./menu",
17791 "../keycode",
17792 "../position",
17793 "../version",
17794 "../widget"
17795 ], factory );
17796 } else {
17797
17798 // Browser globals
17799 factory( jQuery );
17800 }
17801} )( function( $ ) {
17802"use strict";
17803
17804$.widget( "ui.autocomplete", {
17805 version: "1.14.1",
17806 defaultElement: "<input>",
17807 options: {
17808 appendTo: null,
17809 autoFocus: false,
17810 delay: 300,
17811 minLength: 1,
17812 position: {
17813 my: "left top",
17814 at: "left bottom",
17815 collision: "none"
17816 },
17817 source: null,
17818
17819 // Callbacks
17820 change: null,
17821 close: null,
17822 focus: null,
17823 open: null,
17824 response: null,
17825 search: null,
17826 select: null
17827 },
17828
17829 requestIndex: 0,
17830 pending: 0,
17831 liveRegionTimer: null,
17832
17833 _create: function() {
17834
17835 // Some browsers only repeat keydown events, not keypress events,
17836 // so we use the suppressKeyPress flag to determine if we've already
17837 // handled the keydown event. #7269
17838 // Unfortunately the code for & in keypress is the same as the up arrow,
17839 // so we use the suppressKeyPressRepeat flag to avoid handling keypress
17840 // events when we know the keydown event was used to modify the
17841 // search term. #7799
17842 var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
17843 nodeName = this.element[ 0 ].nodeName.toLowerCase(),
17844 isTextarea = nodeName === "textarea",
17845 isInput = nodeName === "input";
17846
17847 // Textareas are always multi-line
17848 // Inputs are always single-line, even if inside a contentEditable element
17849 // All other element types are determined by whether they're contentEditable
17850 this.isMultiLine = isTextarea ||
17851 !isInput && this.element.prop( "contentEditable" ) === "true";
17852
17853 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
17854 this.isNewMenu = true;
17855
17856 this._addClass( "ui-autocomplete-input" );
17857 this.element.attr( "autocomplete", "off" );
17858
17859 this._on( this.element, {
17860 keydown: function( event ) {
17861 if ( this.element.prop( "readOnly" ) ) {
17862 suppressKeyPress = true;
17863 suppressInput = true;
17864 suppressKeyPressRepeat = true;
17865 return;
17866 }
17867
17868 suppressKeyPress = false;
17869 suppressInput = false;
17870 suppressKeyPressRepeat = false;
17871 var keyCode = $.ui.keyCode;
17872 switch ( event.keyCode ) {
17873 case keyCode.PAGE_UP:
17874 suppressKeyPress = true;
17875 this._move( "previousPage", event );
17876 break;
17877 case keyCode.PAGE_DOWN:
17878 suppressKeyPress = true;
17879 this._move( "nextPage", event );
17880 break;
17881 case keyCode.UP:
17882 suppressKeyPress = true;
17883 this._keyEvent( "previous", event );
17884 break;
17885 case keyCode.DOWN:
17886 suppressKeyPress = true;
17887 this._keyEvent( "next", event );
17888 break;
17889 case keyCode.ENTER:
17890
17891 // when menu is open and has focus
17892 if ( this.menu.active ) {
17893
17894 // #6055 - Opera still allows the keypress to occur
17895 // which causes forms to submit
17896 suppressKeyPress = true;
17897 event.preventDefault();
17898 this.menu.select( event );
17899 }
17900 break;
17901 case keyCode.TAB:
17902 if ( this.menu.active ) {
17903 this.menu.select( event );
17904 }
17905 break;
17906 case keyCode.ESCAPE:
17907 if ( this.menu.element.is( ":visible" ) ) {
17908 if ( !this.isMultiLine ) {
17909 this._value( this.term );
17910 }
17911 this.close( event );
17912
17913 // Different browsers have different default behavior for escape
17914 // Single press can mean undo or clear
17915 event.preventDefault();
17916 }
17917 break;
17918 default:
17919 suppressKeyPressRepeat = true;
17920
17921 // search timeout should be triggered before the input value is changed
17922 this._searchTimeout( event );
17923 break;
17924 }
17925 },
17926 keypress: function( event ) {
17927 if ( suppressKeyPress ) {
17928 suppressKeyPress = false;
17929 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
17930 event.preventDefault();
17931 }
17932 return;
17933 }
17934 if ( suppressKeyPressRepeat ) {
17935 return;
17936 }
17937
17938 // Replicate some key handlers to allow them to repeat in Firefox and Opera
17939 var keyCode = $.ui.keyCode;
17940 switch ( event.keyCode ) {
17941 case keyCode.PAGE_UP:
17942 this._move( "previousPage", event );
17943 break;
17944 case keyCode.PAGE_DOWN:
17945 this._move( "nextPage", event );
17946 break;
17947 case keyCode.UP:
17948 this._keyEvent( "previous", event );
17949 break;
17950 case keyCode.DOWN:
17951 this._keyEvent( "next", event );
17952 break;
17953 }
17954 },
17955 input: function( event ) {
17956 if ( suppressInput ) {
17957 suppressInput = false;
17958 event.preventDefault();
17959 return;
17960 }
17961 this._searchTimeout( event );
17962 },
17963 focus: function() {
17964 this.selectedItem = null;
17965 this.previous = this._value();
17966 },
17967 blur: function( event ) {
17968 clearTimeout( this.searching );
17969 this.close( event );
17970 this._change( event );
17971 }
17972 } );
17973
17974 this._initSource();
17975 this.menu = $( "<ul>" )
17976 .appendTo( this._appendTo() )
17977 .menu( {
17978
17979 // disable ARIA support, the live region takes care of that
17980 role: null
17981 } )
17982 .hide()
17983 .menu( "instance" );
17984
17985 this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
17986 this._on( this.menu.element, {
17987 mousedown: function( event ) {
17988
17989 // Prevent moving focus out of the text field
17990 event.preventDefault();
17991 },
17992 menufocus: function( event, ui ) {
17993 var label, item;
17994
17995 // Support: Firefox
17996 // Prevent accidental activation of menu items in Firefox (#7024 #9118)
17997 if ( this.isNewMenu ) {
17998 this.isNewMenu = false;
17999 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
18000 this.menu.blur();
18001
18002 this.document.one( "mousemove", function() {
18003 $( event.target ).trigger( event.originalEvent );
18004 } );
18005
18006 return;
18007 }
18008 }
18009
18010 item = ui.item.data( "ui-autocomplete-item" );
18011 if ( false !== this._trigger( "focus", event, { item: item } ) ) {
18012
18013 // use value to match what will end up in the input, if it was a key event
18014 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
18015 this._value( item.value );
18016 }
18017 }
18018
18019 // Announce the value in the liveRegion
18020 label = ui.item.attr( "aria-label" ) || item.value;
18021 if ( label && String.prototype.trim.call( label ).length ) {
18022 clearTimeout( this.liveRegionTimer );
18023 this.liveRegionTimer = this._delay( function() {
18024 this.liveRegion.html( $( "<div>" ).text( label ) );
18025 }, 100 );
18026 }
18027 },
18028 menuselect: function( event, ui ) {
18029 var item = ui.item.data( "ui-autocomplete-item" ),
18030 previous = this.previous;
18031
18032 // Only trigger when focus was lost (click on menu)
18033 if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
18034 this.element.trigger( "focus" );
18035 this.previous = previous;
18036 }
18037
18038 if ( false !== this._trigger( "select", event, { item: item } ) ) {
18039 this._value( item.value );
18040 }
18041
18042 // reset the term after the select event
18043 // this allows custom select handling to work properly
18044 this.term = this._value();
18045
18046 this.close( event );
18047 this.selectedItem = item;
18048 }
18049 } );
18050
18051 this.liveRegion = $( "<div>", {
18052 role: "status",
18053 "aria-live": "assertive",
18054 "aria-relevant": "additions"
18055 } )
18056 .appendTo( this.document[ 0 ].body );
18057
18058 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
18059
18060 // Turning off autocomplete prevents the browser from remembering the
18061 // value when navigating through history, so we re-enable autocomplete
18062 // if the page is unloaded before the widget is destroyed. #7790
18063 this._on( this.window, {
18064 beforeunload: function() {
18065 this.element.removeAttr( "autocomplete" );
18066 }
18067 } );
18068 },
18069
18070 _destroy: function() {
18071 clearTimeout( this.searching );
18072 this.element.removeAttr( "autocomplete" );
18073 this.menu.element.remove();
18074 this.liveRegion.remove();
18075 },
18076
18077 _setOption: function( key, value ) {
18078 this._super( key, value );
18079 if ( key === "source" ) {
18080 this._initSource();
18081 }
18082 if ( key === "appendTo" ) {
18083 this.menu.element.appendTo( this._appendTo() );
18084 }
18085 if ( key === "disabled" && value && this.xhr ) {
18086 this.xhr.abort();
18087 }
18088 },
18089
18090 _isEventTargetInWidget: function( event ) {
18091 var menuElement = this.menu.element[ 0 ];
18092
18093 return event.target === this.element[ 0 ] ||
18094 event.target === menuElement ||
18095 $.contains( menuElement, event.target );
18096 },
18097
18098 _closeOnClickOutside: function( event ) {
18099 if ( !this._isEventTargetInWidget( event ) ) {
18100 this.close();
18101 }
18102 },
18103
18104 _appendTo: function() {
18105 var element = this.options.appendTo;
18106
18107 if ( element ) {
18108 element = element.jquery || element.nodeType ?
18109 $( element ) :
18110 this.document.find( element ).eq( 0 );
18111 }
18112
18113 if ( !element || !element[ 0 ] ) {
18114 element = this.element.closest( ".ui-front, dialog" );
18115 }
18116
18117 if ( !element.length ) {
18118 element = this.document[ 0 ].body;
18119 }
18120
18121 return element;
18122 },
18123
18124 _initSource: function() {
18125 var array, url,
18126 that = this;
18127 if ( Array.isArray( this.options.source ) ) {
18128 array = this.options.source;
18129 this.source = function( request, response ) {
18130 response( $.ui.autocomplete.filter( array, request.term ) );
18131 };
18132 } else if ( typeof this.options.source === "string" ) {
18133 url = this.options.source;
18134 this.source = function( request, response ) {
18135 if ( that.xhr ) {
18136 that.xhr.abort();
18137 }
18138 that.xhr = $.ajax( {
18139 url: url,
18140 data: request,
18141 dataType: "json",
18142 success: function( data ) {
18143 response( data );
18144 },
18145 error: function() {
18146 response( [] );
18147 }
18148 } );
18149 };
18150 } else {
18151 this.source = this.options.source;
18152 }
18153 },
18154
18155 _searchTimeout: function( event ) {
18156 clearTimeout( this.searching );
18157 this.searching = this._delay( function() {
18158
18159 // Search if the value has changed, or if the user retypes the same value (see #7434)
18160 var equalValues = this.term === this._value(),
18161 menuVisible = this.menu.element.is( ":visible" ),
18162 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
18163
18164 if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
18165 this.selectedItem = null;
18166 this.search( null, event );
18167 }
18168 }, this.options.delay );
18169 },
18170
18171 search: function( value, event ) {
18172 value = value != null ? value : this._value();
18173
18174 // Always save the actual value, not the one passed as an argument
18175 this.term = this._value();
18176
18177 if ( value.length < this.options.minLength ) {
18178 return this.close( event );
18179 }
18180
18181 if ( this._trigger( "search", event ) === false ) {
18182 return;
18183 }
18184
18185 return this._search( value );
18186 },
18187
18188 _search: function( value ) {
18189 this.pending++;
18190 this._addClass( "ui-autocomplete-loading" );
18191 this.cancelSearch = false;
18192
18193 this.source( { term: value }, this._response() );
18194 },
18195
18196 _response: function() {
18197 var index = ++this.requestIndex;
18198
18199 return function( content ) {
18200 if ( index === this.requestIndex ) {
18201 this.__response( content );
18202 }
18203
18204 this.pending--;
18205 if ( !this.pending ) {
18206 this._removeClass( "ui-autocomplete-loading" );
18207 }
18208 }.bind( this );
18209 },
18210
18211 __response: function( content ) {
18212 if ( content ) {
18213 content = this._normalize( content );
18214 }
18215 this._trigger( "response", null, { content: content } );
18216 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
18217 this._suggest( content );
18218 this._trigger( "open" );
18219 } else {
18220
18221 // use ._close() instead of .close() so we don't cancel future searches
18222 this._close();
18223 }
18224 },
18225
18226 close: function( event ) {
18227 this.cancelSearch = true;
18228 this._close( event );
18229 },
18230
18231 _close: function( event ) {
18232
18233 // Remove the handler that closes the menu on outside clicks
18234 this._off( this.document, "mousedown" );
18235
18236 if ( this.menu.element.is( ":visible" ) ) {
18237 this.menu.element.hide();
18238 this.menu.blur();
18239 this.isNewMenu = true;
18240 this._trigger( "close", event );
18241 }
18242 },
18243
18244 _change: function( event ) {
18245 if ( this.previous !== this._value() ) {
18246 this._trigger( "change", event, { item: this.selectedItem } );
18247 }
18248 },
18249
18250 _normalize: function( items ) {
18251
18252 // assume all items have the right format when the first item is complete
18253 if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
18254 return items;
18255 }
18256 return $.map( items, function( item ) {
18257 if ( typeof item === "string" ) {
18258 return {
18259 label: item,
18260 value: item
18261 };
18262 }
18263 return $.extend( {}, item, {
18264 label: item.label || item.value,
18265 value: item.value || item.label
18266 } );
18267 } );
18268 },
18269
18270 _suggest: function( items ) {
18271 var ul = this.menu.element.empty();
18272 this._renderMenu( ul, items );
18273 this.isNewMenu = true;
18274 this.menu.refresh();
18275
18276 // Size and position menu
18277 ul.show();
18278 this._resizeMenu();
18279 ul.position( $.extend( {
18280 of: this.element
18281 }, this.options.position ) );
18282
18283 if ( this.options.autoFocus ) {
18284 this.menu.next();
18285 }
18286
18287 // Listen for interactions outside of the widget (#6642)
18288 this._on( this.document, {
18289 mousedown: "_closeOnClickOutside"
18290 } );
18291 },
18292
18293 _resizeMenu: function() {
18294 var ul = this.menu.element;
18295 ul.outerWidth( Math.max(
18296
18297 // Firefox wraps long text (possibly a rounding bug)
18298 // so we add 1px to avoid the wrapping (#7513)
18299 ul.width( "" ).outerWidth() + 1,
18300 this.element.outerWidth()
18301 ) );
18302 },
18303
18304 _renderMenu: function( ul, items ) {
18305 var that = this;
18306 $.each( items, function( index, item ) {
18307 that._renderItemData( ul, item );
18308 } );
18309 },
18310
18311 _renderItemData: function( ul, item ) {
18312 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
18313 },
18314
18315 _renderItem: function( ul, item ) {
18316 return $( "<li>" )
18317 .append( $( "<div>" ).text( item.label ) )
18318 .appendTo( ul );
18319 },
18320
18321 _move: function( direction, event ) {
18322 if ( !this.menu.element.is( ":visible" ) ) {
18323 this.search( null, event );
18324 return;
18325 }
18326 if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
18327 this.menu.isLastItem() && /^next/.test( direction ) ) {
18328
18329 if ( !this.isMultiLine ) {
18330 this._value( this.term );
18331 }
18332
18333 this.menu.blur();
18334 return;
18335 }
18336 this.menu[ direction ]( event );
18337 },
18338
18339 widget: function() {
18340 return this.menu.element;
18341 },
18342
18343 _value: function() {
18344 return this.valueMethod.apply( this.element, arguments );
18345 },
18346
18347 _keyEvent: function( keyEvent, event ) {
18348 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
18349 this._move( keyEvent, event );
18350
18351 // Prevents moving cursor to beginning/end of the text field in some browsers
18352 event.preventDefault();
18353 }
18354 }
18355} );
18356
18357$.extend( $.ui.autocomplete, {
18358 escapeRegex: function( value ) {
18359 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
18360 },
18361 filter: function( array, term ) {
18362 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
18363 return $.grep( array, function( value ) {
18364 return matcher.test( value.label || value.value || value );
18365 } );
18366 }
18367} );
18368
18369// Live region extension, adding a `messages` option
18370// NOTE: This is an experimental API. We are still investigating
18371// a full solution for string manipulation and internationalization.
18372$.widget( "ui.autocomplete", $.ui.autocomplete, {
18373 options: {
18374 messages: {
18375 noResults: "No search results.",
18376 results: function( amount ) {
18377 return amount + ( amount > 1 ? " results are" : " result is" ) +
18378 " available, use up and down arrow keys to navigate.";
18379 }
18380 }
18381 },
18382
18383 __response: function( content ) {
18384 var message;
18385 this._superApply( arguments );
18386 if ( this.options.disabled || this.cancelSearch ) {
18387 return;
18388 }
18389 if ( content && content.length ) {
18390 message = this.options.messages.results( content.length );
18391 } else {
18392 message = this.options.messages.noResults;
18393 }
18394 clearTimeout( this.liveRegionTimer );
18395 this.liveRegionTimer = this._delay( function() {
18396 this.liveRegion.html( $( "<div>" ).text( message ) );
18397 }, 100 );
18398 }
18399} );
18400
18401return $.ui.autocomplete;
18402
18403} );
18404
18405
18406/*!
18407 * jQuery UI Controlgroup 1.14.1
18408 * https://jqueryui.com
18409 *
18410 * Copyright OpenJS Foundation and other contributors
18411 * Released under the MIT license.
18412 * https://jquery.org/license
18413 */
18414
18415//>>label: Controlgroup
18416//>>group: Widgets
18417//>>description: Visually groups form control widgets
18418//>>docs: https://api.jqueryui.com/controlgroup/
18419//>>demos: https://jqueryui.com/controlgroup/
18420//>>css.structure: ../../themes/base/core.css
18421//>>css.structure: ../../themes/base/controlgroup.css
18422//>>css.theme: ../../themes/base/theme.css
18423
18424( function( factory ) {
18425 "use strict";
18426
18427 if ( typeof define === "function" && define.amd ) {
18428
18429 // AMD. Register as an anonymous module.
18430 define( [
18431 "jquery",
18432 "../widget"
18433 ], factory );
18434 } else {
18435
18436 // Browser globals
18437 factory( jQuery );
18438 }
18439} )( function( $ ) {
18440"use strict";
18441
18442var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
18443
18444return $.widget( "ui.controlgroup", {
18445 version: "1.14.1",
18446 defaultElement: "<div>",
18447 options: {
18448 direction: "horizontal",
18449 disabled: null,
18450 onlyVisible: true,
18451 items: {
18452 "button": "input[type=button], input[type=submit], input[type=reset], button, a",
18453 "controlgroupLabel": ".ui-controlgroup-label",
18454 "checkboxradio": "input[type='checkbox'], input[type='radio']",
18455 "selectmenu": "select",
18456 "spinner": ".ui-spinner-input"
18457 }
18458 },
18459
18460 _create: function() {
18461 this._enhance();
18462 },
18463
18464 // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
18465 _enhance: function() {
18466 this.element.attr( "role", "toolbar" );
18467 this.refresh();
18468 },
18469
18470 _destroy: function() {
18471 this._callChildMethod( "destroy" );
18472 this.childWidgets.removeData( "ui-controlgroup-data" );
18473 this.element.removeAttr( "role" );
18474 if ( this.options.items.controlgroupLabel ) {
18475 this.element
18476 .find( this.options.items.controlgroupLabel )
18477 .find( ".ui-controlgroup-label-contents" )
18478 .contents().unwrap();
18479 }
18480 },
18481
18482 _initWidgets: function() {
18483 var that = this,
18484 childWidgets = [];
18485
18486 // First we iterate over each of the items options
18487 $.each( this.options.items, function( widget, selector ) {
18488 var labels;
18489 var options = {};
18490
18491 // Make sure the widget has a selector set
18492 if ( !selector ) {
18493 return;
18494 }
18495
18496 if ( widget === "controlgroupLabel" ) {
18497 labels = that.element.find( selector );
18498 labels.each( function() {
18499 var element = $( this );
18500
18501 if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
18502 return;
18503 }
18504 element.contents()
18505 .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
18506 } );
18507 that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
18508 childWidgets = childWidgets.concat( labels.get() );
18509 return;
18510 }
18511
18512 // Make sure the widget actually exists
18513 if ( !$.fn[ widget ] ) {
18514 return;
18515 }
18516
18517 // We assume everything is in the middle to start because we can't determine
18518 // first / last elements until all enhancments are done.
18519 if ( that[ "_" + widget + "Options" ] ) {
18520 options = that[ "_" + widget + "Options" ]( "middle" );
18521 } else {
18522 options = { classes: {} };
18523 }
18524
18525 // Find instances of this widget inside controlgroup and init them
18526 that.element
18527 .find( selector )
18528 .each( function() {
18529 var element = $( this );
18530 var instance = element[ widget ]( "instance" );
18531
18532 // We need to clone the default options for this type of widget to avoid
18533 // polluting the variable options which has a wider scope than a single widget.
18534 var instanceOptions = $.widget.extend( {}, options );
18535
18536 // If the button is the child of a spinner ignore it
18537 // TODO: Find a more generic solution
18538 if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
18539 return;
18540 }
18541
18542 // Create the widget if it doesn't exist
18543 if ( !instance ) {
18544 instance = element[ widget ]()[ widget ]( "instance" );
18545 }
18546 if ( instance ) {
18547 instanceOptions.classes =
18548 that._resolveClassesValues( instanceOptions.classes, instance );
18549 }
18550 element[ widget ]( instanceOptions );
18551
18552 // Store an instance of the controlgroup to be able to reference
18553 // from the outermost element for changing options and refresh
18554 var widgetElement = element[ widget ]( "widget" );
18555 $.data( widgetElement[ 0 ], "ui-controlgroup-data",
18556 instance ? instance : element[ widget ]( "instance" ) );
18557
18558 childWidgets.push( widgetElement[ 0 ] );
18559 } );
18560 } );
18561
18562 this.childWidgets = $( $.uniqueSort( childWidgets ) );
18563 this._addClass( this.childWidgets, "ui-controlgroup-item" );
18564 },
18565
18566 _callChildMethod: function( method ) {
18567 this.childWidgets.each( function() {
18568 var element = $( this ),
18569 data = element.data( "ui-controlgroup-data" );
18570 if ( data && data[ method ] ) {
18571 data[ method ]();
18572 }
18573 } );
18574 },
18575
18576 _updateCornerClass: function( element, position ) {
18577 var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
18578 var add = this._buildSimpleOptions( position, "label" ).classes.label;
18579
18580 this._removeClass( element, null, remove );
18581 this._addClass( element, null, add );
18582 },
18583
18584 _buildSimpleOptions: function( position, key ) {
18585 var direction = this.options.direction === "vertical";
18586 var result = {
18587 classes: {}
18588 };
18589 result.classes[ key ] = {
18590 "middle": "",
18591 "first": "ui-corner-" + ( direction ? "top" : "left" ),
18592 "last": "ui-corner-" + ( direction ? "bottom" : "right" ),
18593 "only": "ui-corner-all"
18594 }[ position ];
18595
18596 return result;
18597 },
18598
18599 _spinnerOptions: function( position ) {
18600 var options = this._buildSimpleOptions( position, "ui-spinner" );
18601
18602 options.classes[ "ui-spinner-up" ] = "";
18603 options.classes[ "ui-spinner-down" ] = "";
18604
18605 return options;
18606 },
18607
18608 _buttonOptions: function( position ) {
18609 return this._buildSimpleOptions( position, "ui-button" );
18610 },
18611
18612 _checkboxradioOptions: function( position ) {
18613 return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
18614 },
18615
18616 _selectmenuOptions: function( position ) {
18617 var direction = this.options.direction === "vertical";
18618 return {
18619 width: direction ? "auto" : false,
18620 classes: {
18621 middle: {
18622 "ui-selectmenu-button-open": "",
18623 "ui-selectmenu-button-closed": ""
18624 },
18625 first: {
18626 "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
18627 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
18628 },
18629 last: {
18630 "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
18631 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
18632 },
18633 only: {
18634 "ui-selectmenu-button-open": "ui-corner-top",
18635 "ui-selectmenu-button-closed": "ui-corner-all"
18636 }
18637
18638 }[ position ]
18639 };
18640 },
18641
18642 _resolveClassesValues: function( classes, instance ) {
18643 var result = {};
18644 $.each( classes, function( key ) {
18645 var current = instance.options.classes[ key ] || "";
18646 current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) );
18647 result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
18648 } );
18649 return result;
18650 },
18651
18652 _setOption: function( key, value ) {
18653 if ( key === "direction" ) {
18654 this._removeClass( "ui-controlgroup-" + this.options.direction );
18655 }
18656
18657 this._super( key, value );
18658 if ( key === "disabled" ) {
18659 this._callChildMethod( value ? "disable" : "enable" );
18660 return;
18661 }
18662
18663 this.refresh();
18664 },
18665
18666 refresh: function() {
18667 var children,
18668 that = this;
18669
18670 this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
18671
18672 if ( this.options.direction === "horizontal" ) {
18673 this._addClass( null, "ui-helper-clearfix" );
18674 }
18675 this._initWidgets();
18676
18677 children = this.childWidgets;
18678
18679 // We filter here because we need to track all childWidgets not just the visible ones
18680 if ( this.options.onlyVisible ) {
18681 children = children.filter( ":visible" );
18682 }
18683
18684 if ( children.length ) {
18685
18686 // We do this last because we need to make sure all enhancment is done
18687 // before determining first and last
18688 $.each( [ "first", "last" ], function( index, value ) {
18689 var instance = children[ value ]().data( "ui-controlgroup-data" );
18690
18691 if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
18692 var options = that[ "_" + instance.widgetName + "Options" ](
18693 children.length === 1 ? "only" : value
18694 );
18695 options.classes = that._resolveClassesValues( options.classes, instance );
18696 instance.element[ instance.widgetName ]( options );
18697 } else {
18698 that._updateCornerClass( children[ value ](), value );
18699 }
18700 } );
18701
18702 // Finally call the refresh method on each of the child widgets.
18703 this._callChildMethod( "refresh" );
18704 }
18705 }
18706} );
18707} );
18708
18709
18710
18711
18712/*!
18713 * jQuery UI Checkboxradio 1.14.1
18714 * https://jqueryui.com
18715 *
18716 * Copyright OpenJS Foundation and other contributors
18717 * Released under the MIT license.
18718 * https://jquery.org/license
18719 */
18720
18721//>>label: Checkboxradio
18722//>>group: Widgets
18723//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
18724//>>docs: https://api.jqueryui.com/checkboxradio/
18725//>>demos: https://jqueryui.com/checkboxradio/
18726//>>css.structure: ../../themes/base/core.css
18727//>>css.structure: ../../themes/base/button.css
18728//>>css.structure: ../../themes/base/checkboxradio.css
18729//>>css.theme: ../../themes/base/theme.css
18730
18731( function( factory ) {
18732 "use strict";
18733
18734 if ( typeof define === "function" && define.amd ) {
18735
18736 // AMD. Register as an anonymous module.
18737 define( [
18738 "jquery",
18739 "../form-reset-mixin",
18740 "../labels",
18741 "../widget"
18742 ], factory );
18743 } else {
18744
18745 // Browser globals
18746 factory( jQuery );
18747 }
18748} )( function( $ ) {
18749"use strict";
18750
18751$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
18752 version: "1.14.1",
18753 options: {
18754 disabled: null,
18755 label: null,
18756 icon: true,
18757 classes: {
18758 "ui-checkboxradio-label": "ui-corner-all",
18759 "ui-checkboxradio-icon": "ui-corner-all"
18760 }
18761 },
18762
18763 _getCreateOptions: function() {
18764 var disabled, labels, labelContents;
18765 var options = this._super() || {};
18766
18767 // We read the type here, because it makes more sense to throw a element type error first,
18768 // rather then the error for lack of a label. Often if its the wrong type, it
18769 // won't have a label (e.g. calling on a div, btn, etc)
18770 this._readType();
18771
18772 labels = this.element.labels();
18773
18774 // If there are multiple labels, use the last one
18775 this.label = $( labels[ labels.length - 1 ] );
18776 if ( !this.label.length ) {
18777 $.error( "No label found for checkboxradio widget" );
18778 }
18779
18780 this.originalLabel = "";
18781
18782 // We need to get the label text but this may also need to make sure it does not contain the
18783 // input itself.
18784 // The label contents could be text, html, or a mix. We wrap all elements
18785 // and read the wrapper's `innerHTML` to get a string representation of
18786 // the label, without the input as part of it.
18787 labelContents = this.label.contents().not( this.element[ 0 ] );
18788
18789 if ( labelContents.length ) {
18790 this.originalLabel += labelContents
18791 .clone()
18792 .wrapAll( "<div></div>" )
18793 .parent()
18794 .html();
18795 }
18796
18797 // Set the label option if we found label text
18798 if ( this.originalLabel ) {
18799 options.label = this.originalLabel;
18800 }
18801
18802 disabled = this.element[ 0 ].disabled;
18803 if ( disabled != null ) {
18804 options.disabled = disabled;
18805 }
18806 return options;
18807 },
18808
18809 _create: function() {
18810 var checked = this.element[ 0 ].checked;
18811
18812 this._bindFormResetHandler();
18813
18814 if ( this.options.disabled == null ) {
18815 this.options.disabled = this.element[ 0 ].disabled;
18816 }
18817
18818 this._setOption( "disabled", this.options.disabled );
18819 this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
18820 this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
18821
18822 if ( this.type === "radio" ) {
18823 this._addClass( this.label, "ui-checkboxradio-radio-label" );
18824 }
18825
18826 if ( this.options.label && this.options.label !== this.originalLabel ) {
18827 this._updateLabel();
18828 } else if ( this.originalLabel ) {
18829 this.options.label = this.originalLabel;
18830 }
18831
18832 this._enhance();
18833
18834 if ( checked ) {
18835 this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
18836 }
18837
18838 this._on( {
18839 change: "_toggleClasses",
18840 focus: function() {
18841 this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
18842 },
18843 blur: function() {
18844 this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
18845 }
18846 } );
18847 },
18848
18849 _readType: function() {
18850 var nodeName = this.element[ 0 ].nodeName.toLowerCase();
18851 this.type = this.element[ 0 ].type;
18852 if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
18853 $.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
18854 " and element.type=" + this.type );
18855 }
18856 },
18857
18858 // Support jQuery Mobile enhanced option
18859 _enhance: function() {
18860 this._updateIcon( this.element[ 0 ].checked );
18861 },
18862
18863 widget: function() {
18864 return this.label;
18865 },
18866
18867 _getRadioGroup: function() {
18868 var group;
18869 var name = this.element[ 0 ].name;
18870 var nameSelector = "input[name='" + CSS.escape( name ) + "']";
18871
18872 if ( !name ) {
18873 return $( [] );
18874 }
18875
18876 if ( this.form.length ) {
18877 group = $( this.form[ 0 ].elements ).filter( nameSelector );
18878 } else {
18879
18880 // Not inside a form, check all inputs that also are not inside a form
18881 group = $( nameSelector ).filter( function() {
18882 return $( $( this ).prop( "form" ) ).length === 0;
18883 } );
18884 }
18885
18886 return group.not( this.element );
18887 },
18888
18889 _toggleClasses: function() {
18890 var checked = this.element[ 0 ].checked;
18891 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
18892
18893 if ( this.options.icon && this.type === "checkbox" ) {
18894 this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
18895 ._toggleClass( this.icon, null, "ui-icon-blank", !checked );
18896 }
18897
18898 if ( this.type === "radio" ) {
18899 this._getRadioGroup()
18900 .each( function() {
18901 var instance = $( this ).checkboxradio( "instance" );
18902
18903 if ( instance ) {
18904 instance._removeClass( instance.label,
18905 "ui-checkboxradio-checked", "ui-state-active" );
18906 }
18907 } );
18908 }
18909 },
18910
18911 _destroy: function() {
18912 this._unbindFormResetHandler();
18913
18914 if ( this.icon ) {
18915 this.icon.remove();
18916 this.iconSpace.remove();
18917 }
18918 },
18919
18920 _setOption: function( key, value ) {
18921
18922 // We don't allow the value to be set to nothing
18923 if ( key === "label" && !value ) {
18924 return;
18925 }
18926
18927 this._super( key, value );
18928
18929 if ( key === "disabled" ) {
18930 this._toggleClass( this.label, null, "ui-state-disabled", value );
18931 this.element[ 0 ].disabled = value;
18932
18933 // Don't refresh when setting disabled
18934 return;
18935 }
18936 this.refresh();
18937 },
18938
18939 _updateIcon: function( checked ) {
18940 var toAdd = "ui-icon ui-icon-background ";
18941
18942 if ( this.options.icon ) {
18943 if ( !this.icon ) {
18944 this.icon = $( "<span>" );
18945 this.iconSpace = $( "<span> </span>" );
18946 this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
18947 }
18948
18949 if ( this.type === "checkbox" ) {
18950 toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
18951 this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
18952 } else {
18953 toAdd += "ui-icon-blank";
18954 }
18955 this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
18956 if ( !checked ) {
18957 this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
18958 }
18959 this.icon.prependTo( this.label ).after( this.iconSpace );
18960 } else if ( this.icon !== undefined ) {
18961 this.icon.remove();
18962 this.iconSpace.remove();
18963 delete this.icon;
18964 }
18965 },
18966
18967 _updateLabel: function() {
18968
18969 // Remove the contents of the label ( minus the icon, icon space, and input )
18970 var contents = this.label.contents().not( this.element[ 0 ] );
18971 if ( this.icon ) {
18972 contents = contents.not( this.icon[ 0 ] );
18973 }
18974 if ( this.iconSpace ) {
18975 contents = contents.not( this.iconSpace[ 0 ] );
18976 }
18977 contents.remove();
18978
18979 this.label.append( this.options.label );
18980 },
18981
18982 refresh: function() {
18983 var checked = this.element[ 0 ].checked,
18984 isDisabled = this.element[ 0 ].disabled;
18985
18986 this._updateIcon( checked );
18987 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
18988 if ( this.options.label !== null ) {
18989 this._updateLabel();
18990 }
18991
18992 if ( isDisabled !== this.options.disabled ) {
18993 this._setOptions( { "disabled": isDisabled } );
18994 }
18995 }
18996
18997} ] );
18998
18999return $.ui.checkboxradio;
19000
19001} );
19002
19003
19004
19005
19006
19007/*!
19008 * jQuery UI Button 1.14.1
19009 * https://jqueryui.com
19010 *
19011 * Copyright OpenJS Foundation and other contributors
19012 * Released under the MIT license.
19013 * https://jquery.org/license
19014 */
19015
19016//>>label: Button
19017//>>group: Widgets
19018//>>description: Enhances a form with themeable buttons.
19019//>>docs: https://api.jqueryui.com/button/
19020//>>demos: https://jqueryui.com/button/
19021//>>css.structure: ../../themes/base/core.css
19022//>>css.structure: ../../themes/base/button.css
19023//>>css.theme: ../../themes/base/theme.css
19024
19025( function( factory ) {
19026 "use strict";
19027
19028 if ( typeof define === "function" && define.amd ) {
19029
19030 // AMD. Register as an anonymous module.
19031 define( [
19032 "jquery",
19033
19034 // These are only for backcompat
19035 // TODO: Remove after 1.12
19036 "./controlgroup",
19037 "./checkboxradio",
19038
19039 "../keycode",
19040 "../widget"
19041 ], factory );
19042 } else {
19043
19044 // Browser globals
19045 factory( jQuery );
19046 }
19047} )( function( $ ) {
19048"use strict";
19049
19050$.widget( "ui.button", {
19051 version: "1.14.1",
19052 defaultElement: "<button>",
19053 options: {
19054 classes: {
19055 "ui-button": "ui-corner-all"
19056 },
19057 disabled: null,
19058 icon: null,
19059 iconPosition: "beginning",
19060 label: null,
19061 showLabel: true
19062 },
19063
19064 _getCreateOptions: function() {
19065 var disabled,
19066
19067 // This is to support cases like in jQuery Mobile where the base widget does have
19068 // an implementation of _getCreateOptions
19069 options = this._super() || {};
19070
19071 this.isInput = this.element.is( "input" );
19072
19073 disabled = this.element[ 0 ].disabled;
19074 if ( disabled != null ) {
19075 options.disabled = disabled;
19076 }
19077
19078 this.originalLabel = this.isInput ? this.element.val() : this.element.html();
19079 if ( this.originalLabel ) {
19080 options.label = this.originalLabel;
19081 }
19082
19083 return options;
19084 },
19085
19086 _create: function() {
19087 if ( !this.option.showLabel & !this.options.icon ) {
19088 this.options.showLabel = true;
19089 }
19090
19091 // We have to check the option again here even though we did in _getCreateOptions,
19092 // because null may have been passed on init which would override what was set in
19093 // _getCreateOptions
19094 if ( this.options.disabled == null ) {
19095 this.options.disabled = this.element[ 0 ].disabled || false;
19096 }
19097
19098 this.hasTitle = !!this.element.attr( "title" );
19099
19100 // Check to see if the label needs to be set or if its already correct
19101 if ( this.options.label && this.options.label !== this.originalLabel ) {
19102 if ( this.isInput ) {
19103 this.element.val( this.options.label );
19104 } else {
19105 this.element.html( this.options.label );
19106 }
19107 }
19108 this._addClass( "ui-button", "ui-widget" );
19109 this._setOption( "disabled", this.options.disabled );
19110 this._enhance();
19111
19112 if ( this.element.is( "a" ) ) {
19113 this._on( {
19114 "keyup": function( event ) {
19115 if ( event.keyCode === $.ui.keyCode.SPACE ) {
19116 event.preventDefault();
19117
19118 // If a native click is available use it, so we
19119 // actually cause navigation. Otherwise, just trigger
19120 // a click event.
19121 if ( this.element[ 0 ].click ) {
19122 this.element[ 0 ].click();
19123 } else {
19124 this.element.trigger( "click" );
19125 }
19126 }
19127 }
19128 } );
19129 }
19130 },
19131
19132 _enhance: function() {
19133 if ( !this.element.is( "button" ) ) {
19134 this.element.attr( "role", "button" );
19135 }
19136
19137 if ( this.options.icon ) {
19138 this._updateIcon( "icon", this.options.icon );
19139 this._updateTooltip();
19140 }
19141 },
19142
19143 _updateTooltip: function() {
19144 this.title = this.element.attr( "title" );
19145
19146 if ( !this.options.showLabel && !this.title ) {
19147 this.element.attr( "title", this.options.label );
19148 }
19149 },
19150
19151 _updateIcon: function( option, value ) {
19152 var icon = option !== "iconPosition",
19153 position = icon ? this.options.iconPosition : value,
19154 displayBlock = position === "top" || position === "bottom";
19155
19156 // Create icon
19157 if ( !this.icon ) {
19158 this.icon = $( "<span>" );
19159
19160 this._addClass( this.icon, "ui-button-icon", "ui-icon" );
19161
19162 if ( !this.options.showLabel ) {
19163 this._addClass( "ui-button-icon-only" );
19164 }
19165 } else if ( icon ) {
19166
19167 // If we are updating the icon remove the old icon class
19168 this._removeClass( this.icon, null, this.options.icon );
19169 }
19170
19171 // If we are updating the icon add the new icon class
19172 if ( icon ) {
19173 this._addClass( this.icon, null, value );
19174 }
19175
19176 this._attachIcon( position );
19177
19178 // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
19179 // the iconSpace if there is one.
19180 if ( displayBlock ) {
19181 this._addClass( this.icon, null, "ui-widget-icon-block" );
19182 if ( this.iconSpace ) {
19183 this.iconSpace.remove();
19184 }
19185 } else {
19186
19187 // Position is beginning or end so remove the ui-widget-icon-block class and add the
19188 // space if it does not exist
19189 if ( !this.iconSpace ) {
19190 this.iconSpace = $( "<span> </span>" );
19191 this._addClass( this.iconSpace, "ui-button-icon-space" );
19192 }
19193 this._removeClass( this.icon, null, "ui-wiget-icon-block" );
19194 this._attachIconSpace( position );
19195 }
19196 },
19197
19198 _destroy: function() {
19199 this.element.removeAttr( "role" );
19200
19201 if ( this.icon ) {
19202 this.icon.remove();
19203 }
19204 if ( this.iconSpace ) {
19205 this.iconSpace.remove();
19206 }
19207 if ( !this.hasTitle ) {
19208 this.element.removeAttr( "title" );
19209 }
19210 },
19211
19212 _attachIconSpace: function( iconPosition ) {
19213 this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
19214 },
19215
19216 _attachIcon: function( iconPosition ) {
19217 this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
19218 },
19219
19220 _setOptions: function( options ) {
19221 var newShowLabel = options.showLabel === undefined ?
19222 this.options.showLabel :
19223 options.showLabel,
19224 newIcon = options.icon === undefined ? this.options.icon : options.icon;
19225
19226 if ( !newShowLabel && !newIcon ) {
19227 options.showLabel = true;
19228 }
19229 this._super( options );
19230 },
19231
19232 _setOption: function( key, value ) {
19233 if ( key === "icon" ) {
19234 if ( value ) {
19235 this._updateIcon( key, value );
19236 } else if ( this.icon ) {
19237 this.icon.remove();
19238 if ( this.iconSpace ) {
19239 this.iconSpace.remove();
19240 }
19241 }
19242 }
19243
19244 if ( key === "iconPosition" ) {
19245 this._updateIcon( key, value );
19246 }
19247
19248 // Make sure we can't end up with a button that has neither text nor icon
19249 if ( key === "showLabel" ) {
19250 this._toggleClass( "ui-button-icon-only", null, !value );
19251 this._updateTooltip();
19252 }
19253
19254 if ( key === "label" ) {
19255 if ( this.isInput ) {
19256 this.element.val( value );
19257 } else {
19258
19259 // If there is an icon, append it, else nothing then append the value
19260 // this avoids removal of the icon when setting label text
19261 this.element.html( value );
19262 if ( this.icon ) {
19263 this._attachIcon( this.options.iconPosition );
19264 this._attachIconSpace( this.options.iconPosition );
19265 }
19266 }
19267 }
19268
19269 this._super( key, value );
19270
19271 if ( key === "disabled" ) {
19272 this._toggleClass( null, "ui-state-disabled", value );
19273 this.element[ 0 ].disabled = value;
19274 if ( value ) {
19275 this.element.trigger( "blur" );
19276 }
19277 }
19278 },
19279
19280 refresh: function() {
19281
19282 // Make sure to only check disabled if its an element that supports this otherwise
19283 // check for the disabled class to determine state
19284 var isDisabled = this.element.is( "input, button" ) ?
19285 this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
19286
19287 if ( isDisabled !== this.options.disabled ) {
19288 this._setOptions( { disabled: isDisabled } );
19289 }
19290
19291 this._updateTooltip();
19292 }
19293} );
19294
19295// DEPRECATED
19296if ( $.uiBackCompat === true ) {
19297
19298 // Text and Icons options
19299 $.widget( "ui.button", $.ui.button, {
19300 options: {
19301 text: true,
19302 icons: {
19303 primary: null,
19304 secondary: null
19305 }
19306 },
19307
19308 _create: function() {
19309 if ( this.options.showLabel && !this.options.text ) {
19310 this.options.showLabel = this.options.text;
19311 }
19312 if ( !this.options.showLabel && this.options.text ) {
19313 this.options.text = this.options.showLabel;
19314 }
19315 if ( !this.options.icon && ( this.options.icons.primary ||
19316 this.options.icons.secondary ) ) {
19317 if ( this.options.icons.primary ) {
19318 this.options.icon = this.options.icons.primary;
19319 } else {
19320 this.options.icon = this.options.icons.secondary;
19321 this.options.iconPosition = "end";
19322 }
19323 } else if ( this.options.icon ) {
19324 this.options.icons.primary = this.options.icon;
19325 }
19326 this._super();
19327 },
19328
19329 _setOption: function( key, value ) {
19330 if ( key === "text" ) {
19331 this._super( "showLabel", value );
19332 return;
19333 }
19334 if ( key === "showLabel" ) {
19335 this.options.text = value;
19336 }
19337 if ( key === "icon" ) {
19338 this.options.icons.primary = value;
19339 }
19340 if ( key === "icons" ) {
19341 if ( value.primary ) {
19342 this._super( "icon", value.primary );
19343 this._super( "iconPosition", "beginning" );
19344 } else if ( value.secondary ) {
19345 this._super( "icon", value.secondary );
19346 this._super( "iconPosition", "end" );
19347 }
19348 }
19349 this._superApply( arguments );
19350 }
19351 } );
19352
19353 $.fn.button = ( function( orig ) {
19354 return function( options ) {
19355 var isMethodCall = typeof options === "string";
19356 var args = Array.prototype.slice.call( arguments, 1 );
19357 var returnValue = this;
19358
19359 if ( isMethodCall ) {
19360
19361 // If this is an empty collection, we need to have the instance method
19362 // return undefined instead of the jQuery instance
19363 if ( !this.length && options === "instance" ) {
19364 returnValue = undefined;
19365 } else {
19366 this.each( function() {
19367 var methodValue;
19368 var type = $( this ).attr( "type" );
19369 var name = type !== "checkbox" && type !== "radio" ?
19370 "button" :
19371 "checkboxradio";
19372 var instance = $.data( this, "ui-" + name );
19373
19374 if ( options === "instance" ) {
19375 returnValue = instance;
19376 return false;
19377 }
19378
19379 if ( !instance ) {
19380 return $.error( "cannot call methods on button" +
19381 " prior to initialization; " +
19382 "attempted to call method '" + options + "'" );
19383 }
19384
19385 if ( typeof instance[ options ] !== "function" ||
19386 options.charAt( 0 ) === "_" ) {
19387 return $.error( "no such method '" + options + "' for button" +
19388 " widget instance" );
19389 }
19390
19391 methodValue = instance[ options ].apply( instance, args );
19392
19393 if ( methodValue !== instance && methodValue !== undefined ) {
19394 returnValue = methodValue && methodValue.jquery ?
19395 returnValue.pushStack( methodValue.get() ) :
19396 methodValue;
19397 return false;
19398 }
19399 } );
19400 }
19401 } else {
19402
19403 // Allow multiple hashes to be passed on init
19404 if ( args.length ) {
19405 options = $.widget.extend.apply( null, [ options ].concat( args ) );
19406 }
19407
19408 this.each( function() {
19409 var type = $( this ).attr( "type" );
19410 var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio";
19411 var instance = $.data( this, "ui-" + name );
19412
19413 if ( instance ) {
19414 instance.option( options || {} );
19415 if ( instance._init ) {
19416 instance._init();
19417 }
19418 } else {
19419 if ( name === "button" ) {
19420 orig.call( $( this ), options );
19421 return;
19422 }
19423
19424 $( this ).checkboxradio( $.extend( { icon: false }, options ) );
19425 }
19426 } );
19427 }
19428
19429 return returnValue;
19430 };
19431 } )( $.fn.button );
19432
19433 $.fn.buttonset = function() {
19434 if ( !$.ui.controlgroup ) {
19435 $.error( "Controlgroup widget missing" );
19436 }
19437 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
19438 return this.controlgroup.apply( this,
19439 [ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
19440 }
19441 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
19442 return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
19443 }
19444 if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
19445 arguments[ 0 ].items = {
19446 button: arguments[ 0 ].items
19447 };
19448 }
19449 return this.controlgroup.apply( this, arguments );
19450 };
19451}
19452
19453return $.ui.button;
19454
19455} );
19456
19457
19458
19459/* eslint-disable max-len, camelcase */
19460/*!
19461 * jQuery UI Datepicker 1.14.1
19462 * https://jqueryui.com
19463 *
19464 * Copyright OpenJS Foundation and other contributors
19465 * Released under the MIT license.
19466 * https://jquery.org/license
19467 */
19468
19469//>>label: Datepicker
19470//>>group: Widgets
19471//>>description: Displays a calendar from an input or inline for selecting dates.
19472//>>docs: https://api.jqueryui.com/datepicker/
19473//>>demos: https://jqueryui.com/datepicker/
19474//>>css.structure: ../../themes/base/core.css
19475//>>css.structure: ../../themes/base/datepicker.css
19476//>>css.theme: ../../themes/base/theme.css
19477
19478( function( factory ) {
19479 "use strict";
19480
19481 if ( typeof define === "function" && define.amd ) {
19482
19483 // AMD. Register as an anonymous module.
19484 define( [
19485 "jquery",
19486 "../version",
19487 "../keycode"
19488 ], factory );
19489 } else {
19490
19491 // Browser globals
19492 factory( jQuery );
19493 }
19494} )( function( $ ) {
19495"use strict";
19496
19497$.extend( $.ui, { datepicker: { version: "1.14.1" } } );
19498
19499var datepicker_instActive;
19500
19501function datepicker_getZindex( elem ) {
19502 var position, value;
19503 while ( elem.length && elem[ 0 ] !== document ) {
19504
19505 // Ignore z-index if position is set to a value where z-index is ignored by the browser
19506 // This makes behavior of this function consistent across browsers
19507 // WebKit always returns auto if the element is positioned
19508 position = elem.css( "position" );
19509 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
19510
19511 // IE returns 0 when zIndex is not specified
19512 // other browsers return a string
19513 // we ignore the case of nested elements with an explicit value of 0
19514 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
19515 value = parseInt( elem.css( "zIndex" ), 10 );
19516 if ( !isNaN( value ) && value !== 0 ) {
19517 return value;
19518 }
19519 }
19520 elem = elem.parent();
19521 }
19522
19523 return 0;
19524}
19525
19526/* Date picker manager.
19527 Use the singleton instance of this class, $.datepicker, to interact with the date picker.
19528 Settings for (groups of) date pickers are maintained in an instance object,
19529 allowing multiple different settings on the same page. */
19530
19531function Datepicker() {
19532 this._curInst = null; // The current instance in use
19533 this._keyEvent = false; // If the last event was a key event
19534 this._disabledInputs = []; // List of date picker inputs that have been disabled
19535 this._datepickerShowing = false; // True if the popup picker is showing , false if not
19536 this._inDialog = false; // True if showing within a "dialog", false if not
19537 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
19538 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
19539 this._appendClass = "ui-datepicker-append"; // The name of the append marker class
19540 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
19541 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
19542 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
19543 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
19544 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
19545 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
19546 this.regional = []; // Available regional settings, indexed by language code
19547 this.regional[ "" ] = { // Default regional settings
19548 closeText: "Done", // Display text for close link
19549 prevText: "Prev", // Display text for previous month link
19550 nextText: "Next", // Display text for next month link
19551 currentText: "Today", // Display text for current month link
19552 monthNames: [ "January", "February", "March", "April", "May", "June",
19553 "July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting
19554 monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
19555 dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
19556 dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
19557 dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday
19558 weekHeader: "Wk", // Column header for week of the year
19559 dateFormat: "mm/dd/yy", // See format options on parseDate
19560 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
19561 isRTL: false, // True if right-to-left language, false if left-to-right
19562 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
19563 yearSuffix: "", // Additional text to append to the year in the month headers,
19564 selectMonthLabel: "Select month", // Invisible label for month selector
19565 selectYearLabel: "Select year" // Invisible label for year selector
19566 };
19567 this._defaults = { // Global defaults for all the date picker instances
19568 showOn: "focus", // "focus" for popup on focus,
19569 // "button" for trigger button, or "both" for either
19570 showAnim: "fadeIn", // Name of jQuery animation for popup
19571 showOptions: {}, // Options for enhanced animations
19572 defaultDate: null, // Used when field is blank: actual date,
19573 // +/-number for offset from today, null for today
19574 appendText: "", // Display text following the input box, e.g. showing the format
19575 buttonText: "...", // Text for trigger button
19576 buttonImage: "", // URL for trigger button image
19577 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
19578 hideIfNoPrevNext: false, // True to hide next/previous month links
19579 // if not applicable, false to just disable them
19580 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
19581 gotoCurrent: false, // True if today link goes back to current selection instead
19582 changeMonth: false, // True if month can be selected directly, false if only prev/next
19583 changeYear: false, // True if year can be selected directly, false if only prev/next
19584 yearRange: "c-10:c+10", // Range of years to display in drop-down,
19585 // either relative to today's year (-nn:+nn), relative to currently displayed year
19586 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
19587 showOtherMonths: false, // True to show dates in other months, false to leave blank
19588 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
19589 showWeek: false, // True to show week of the year, false to not show it
19590 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
19591 // takes a Date and returns the number of the week for it
19592 shortYearCutoff: "+10", // Short year values < this are in the current century,
19593 // > this are in the previous century,
19594 // string value starting with "+" for current year + value
19595 minDate: null, // The earliest selectable date, or null for no limit
19596 maxDate: null, // The latest selectable date, or null for no limit
19597 duration: "fast", // Duration of display/closure
19598 beforeShowDay: null, // Function that takes a date and returns an array with
19599 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
19600 // [2] = cell title (optional), e.g. $.datepicker.noWeekends
19601 beforeShow: null, // Function that takes an input field and
19602 // returns a set of custom settings for the date picker
19603 onSelect: null, // Define a callback function when a date is selected
19604 onChangeMonthYear: null, // Define a callback function when the month or year is changed
19605 onClose: null, // Define a callback function when the datepicker is closed
19606 onUpdateDatepicker: null, // Define a callback function when the datepicker is updated
19607 numberOfMonths: 1, // Number of months to show at a time
19608 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
19609 stepMonths: 1, // Number of months to step back/forward
19610 stepBigMonths: 12, // Number of months to step back/forward for the big links
19611 altField: "", // Selector for an alternate field to store selected dates into
19612 altFormat: "", // The date format to use for the alternate field
19613 constrainInput: true, // The input is constrained by the current date format
19614 showButtonPanel: false, // True to show button panel, false to not show it
19615 autoSize: false, // True to size the input for the date format, false to leave as is
19616 disabled: false // The initial disabled state
19617 };
19618 $.extend( this._defaults, this.regional[ "" ] );
19619 this.regional.en = $.extend( true, {}, this.regional[ "" ] );
19620 this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
19621 this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
19622}
19623
19624$.extend( Datepicker.prototype, {
19625
19626 /* Class name added to elements to indicate already configured with a date picker. */
19627 markerClassName: "hasDatepicker",
19628
19629 //Keep track of the maximum number of rows displayed (see #7043)
19630 maxRows: 4,
19631
19632 // TODO rename to "widget" when switching to widget factory
19633 _widgetDatepicker: function() {
19634 return this.dpDiv;
19635 },
19636
19637 /* Override the default settings for all instances of the date picker.
19638 * @param settings object - the new settings to use as defaults (anonymous object)
19639 * @return the manager object
19640 */
19641 setDefaults: function( settings ) {
19642 datepicker_extendRemove( this._defaults, settings || {} );
19643 return this;
19644 },
19645
19646 /* Attach the date picker to a jQuery selection.
19647 * @param target element - the target input field or division or span
19648 * @param settings object - the new settings to use for this date picker instance (anonymous)
19649 */
19650 _attachDatepicker: function( target, settings ) {
19651 var nodeName, inline, inst;
19652 nodeName = target.nodeName.toLowerCase();
19653 inline = ( nodeName === "div" || nodeName === "span" );
19654 if ( !target.id ) {
19655 this.uuid += 1;
19656 target.id = "dp" + this.uuid;
19657 }
19658 inst = this._newInst( $( target ), inline );
19659 inst.settings = $.extend( {}, settings || {} );
19660 if ( nodeName === "input" ) {
19661 this._connectDatepicker( target, inst );
19662 } else if ( inline ) {
19663 this._inlineDatepicker( target, inst );
19664 }
19665 },
19666
19667 /* Create a new instance object. */
19668 _newInst: function( target, inline ) {
19669 var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
19670 return { id: id, input: target, // associated target
19671 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
19672 drawMonth: 0, drawYear: 0, // month being drawn
19673 inline: inline, // is datepicker inline or not
19674 dpDiv: ( !inline ? this.dpDiv : // presentation div
19675 datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
19676 },
19677
19678 /* Attach the date picker to an input field. */
19679 _connectDatepicker: function( target, inst ) {
19680 var input = $( target );
19681 inst.append = $( [] );
19682 inst.trigger = $( [] );
19683 if ( input.hasClass( this.markerClassName ) ) {
19684 return;
19685 }
19686 this._attachments( input, inst );
19687 input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
19688 on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
19689 this._autoSize( inst );
19690 $.data( target, "datepicker", inst );
19691
19692 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
19693 if ( inst.settings.disabled ) {
19694 this._disableDatepicker( target );
19695 }
19696 },
19697
19698 /* Make attachments based on settings. */
19699 _attachments: function( input, inst ) {
19700 var showOn, buttonText, buttonImage,
19701 appendText = this._get( inst, "appendText" ),
19702 isRTL = this._get( inst, "isRTL" );
19703
19704 if ( inst.append ) {
19705 inst.append.remove();
19706 }
19707 if ( appendText ) {
19708 inst.append = $( "<span>" )
19709 .addClass( this._appendClass )
19710 .text( appendText );
19711 input[ isRTL ? "before" : "after" ]( inst.append );
19712 }
19713
19714 input.off( "focus", this._showDatepicker );
19715
19716 if ( inst.trigger ) {
19717 inst.trigger.remove();
19718 }
19719
19720 showOn = this._get( inst, "showOn" );
19721 if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
19722 input.on( "focus", this._showDatepicker );
19723 }
19724 if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
19725 buttonText = this._get( inst, "buttonText" );
19726 buttonImage = this._get( inst, "buttonImage" );
19727
19728 if ( this._get( inst, "buttonImageOnly" ) ) {
19729 inst.trigger = $( "<img>" )
19730 .addClass( this._triggerClass )
19731 .attr( {
19732 src: buttonImage,
19733 alt: buttonText,
19734 title: buttonText
19735 } );
19736 } else {
19737 inst.trigger = $( "<button type='button'>" )
19738 .addClass( this._triggerClass );
19739 if ( buttonImage ) {
19740 inst.trigger.html(
19741 $( "<img>" )
19742 .attr( {
19743 src: buttonImage,
19744 alt: buttonText,
19745 title: buttonText
19746 } )
19747 );
19748 } else {
19749 inst.trigger.text( buttonText );
19750 }
19751 }
19752
19753 input[ isRTL ? "before" : "after" ]( inst.trigger );
19754 inst.trigger.on( "click", function() {
19755 if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
19756 $.datepicker._hideDatepicker();
19757 } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
19758 $.datepicker._hideDatepicker();
19759 $.datepicker._showDatepicker( input[ 0 ] );
19760 } else {
19761 $.datepicker._showDatepicker( input[ 0 ] );
19762 }
19763 return false;
19764 } );
19765 }
19766 },
19767
19768 /* Apply the maximum length for the date format. */
19769 _autoSize: function( inst ) {
19770 if ( this._get( inst, "autoSize" ) && !inst.inline ) {
19771 var findMax, max, maxI, i,
19772 date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
19773 dateFormat = this._get( inst, "dateFormat" );
19774
19775 if ( dateFormat.match( /[DM]/ ) ) {
19776 findMax = function( names ) {
19777 max = 0;
19778 maxI = 0;
19779 for ( i = 0; i < names.length; i++ ) {
19780 if ( names[ i ].length > max ) {
19781 max = names[ i ].length;
19782 maxI = i;
19783 }
19784 }
19785 return maxI;
19786 };
19787 date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
19788 "monthNames" : "monthNamesShort" ) ) ) );
19789 date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
19790 "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
19791 }
19792 inst.input.attr( "size", this._formatDate( inst, date ).length );
19793 }
19794 },
19795
19796 /* Attach an inline date picker to a div. */
19797 _inlineDatepicker: function( target, inst ) {
19798 var divSpan = $( target );
19799 if ( divSpan.hasClass( this.markerClassName ) ) {
19800 return;
19801 }
19802 divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
19803 $.data( target, "datepicker", inst );
19804 this._setDate( inst, this._getDefaultDate( inst ), true );
19805 this._updateDatepicker( inst );
19806 this._updateAlternate( inst );
19807
19808 //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
19809 if ( inst.settings.disabled ) {
19810 this._disableDatepicker( target );
19811 }
19812
19813 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
19814 // https://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
19815 inst.dpDiv.css( "display", "block" );
19816 },
19817
19818 /* Pop-up the date picker in a "dialog" box.
19819 * @param input element - ignored
19820 * @param date string or Date - the initial date to display
19821 * @param onSelect function - the function to call when a date is selected
19822 * @param settings object - update the dialog date picker instance's settings (anonymous object)
19823 * @param pos int[2] - coordinates for the dialog's position within the screen or
19824 * event - with x/y coordinates or
19825 * leave empty for default (screen centre)
19826 * @return the manager object
19827 */
19828 _dialogDatepicker: function( input, date, onSelect, settings, pos ) {
19829 var id, browserWidth, browserHeight, scrollX, scrollY,
19830 inst = this._dialogInst; // internal instance
19831
19832 if ( !inst ) {
19833 this.uuid += 1;
19834 id = "dp" + this.uuid;
19835 this._dialogInput = $( "<input type='text' id='" + id +
19836 "' style='position: absolute; top: -100px; width: 0px;'/>" );
19837 this._dialogInput.on( "keydown", this._doKeyDown );
19838 $( "body" ).append( this._dialogInput );
19839 inst = this._dialogInst = this._newInst( this._dialogInput, false );
19840 inst.settings = {};
19841 $.data( this._dialogInput[ 0 ], "datepicker", inst );
19842 }
19843 datepicker_extendRemove( inst.settings, settings || {} );
19844 date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
19845 this._dialogInput.val( date );
19846
19847 this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
19848 if ( !this._pos ) {
19849 browserWidth = document.documentElement.clientWidth;
19850 browserHeight = document.documentElement.clientHeight;
19851 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
19852 scrollY = document.documentElement.scrollTop || document.body.scrollTop;
19853 this._pos = // should use actual width/height below
19854 [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
19855 }
19856
19857 // Move input on screen for focus, but hidden behind dialog
19858 this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
19859 inst.settings.onSelect = onSelect;
19860 this._inDialog = true;
19861 this.dpDiv.addClass( this._dialogClass );
19862 this._showDatepicker( this._dialogInput[ 0 ] );
19863 if ( $.blockUI ) {
19864 $.blockUI( this.dpDiv );
19865 }
19866 $.data( this._dialogInput[ 0 ], "datepicker", inst );
19867 return this;
19868 },
19869
19870 /* Detach a datepicker from its control.
19871 * @param target element - the target input field or division or span
19872 */
19873 _destroyDatepicker: function( target ) {
19874 var nodeName,
19875 $target = $( target ),
19876 inst = $.data( target, "datepicker" );
19877
19878 if ( !$target.hasClass( this.markerClassName ) ) {
19879 return;
19880 }
19881
19882 nodeName = target.nodeName.toLowerCase();
19883 $.removeData( target, "datepicker" );
19884 if ( nodeName === "input" ) {
19885 inst.append.remove();
19886 inst.trigger.remove();
19887 $target.removeClass( this.markerClassName ).
19888 off( "focus", this._showDatepicker ).
19889 off( "keydown", this._doKeyDown ).
19890 off( "keypress", this._doKeyPress ).
19891 off( "keyup", this._doKeyUp );
19892 } else if ( nodeName === "div" || nodeName === "span" ) {
19893 $target.removeClass( this.markerClassName ).empty();
19894 }
19895
19896 $.datepicker._hideDatepicker();
19897 if ( datepicker_instActive === inst ) {
19898 datepicker_instActive = null;
19899 this._curInst = null;
19900 }
19901 },
19902
19903 /* Enable the date picker to a jQuery selection.
19904 * @param target element - the target input field or division or span
19905 */
19906 _enableDatepicker: function( target ) {
19907 var nodeName, inline,
19908 $target = $( target ),
19909 inst = $.data( target, "datepicker" );
19910
19911 if ( !$target.hasClass( this.markerClassName ) ) {
19912 return;
19913 }
19914
19915 nodeName = target.nodeName.toLowerCase();
19916 if ( nodeName === "input" ) {
19917 target.disabled = false;
19918 inst.trigger.filter( "button" ).
19919 each( function() {
19920 this.disabled = false;
19921 } ).end().
19922 filter( "img" ).css( { opacity: "1.0", cursor: "" } );
19923 } else if ( nodeName === "div" || nodeName === "span" ) {
19924 inline = $target.children( "." + this._inlineClass );
19925 inline.children().removeClass( "ui-state-disabled" );
19926 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
19927 prop( "disabled", false );
19928 }
19929 this._disabledInputs = $.map( this._disabledInputs,
19930
19931 // Delete entry
19932 function( value ) {
19933 return ( value === target ? null : value );
19934 } );
19935 },
19936
19937 /* Disable the date picker to a jQuery selection.
19938 * @param target element - the target input field or division or span
19939 */
19940 _disableDatepicker: function( target ) {
19941 var nodeName, inline,
19942 $target = $( target ),
19943 inst = $.data( target, "datepicker" );
19944
19945 if ( !$target.hasClass( this.markerClassName ) ) {
19946 return;
19947 }
19948
19949 nodeName = target.nodeName.toLowerCase();
19950 if ( nodeName === "input" ) {
19951 target.disabled = true;
19952 inst.trigger.filter( "button" ).
19953 each( function() {
19954 this.disabled = true;
19955 } ).end().
19956 filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
19957 } else if ( nodeName === "div" || nodeName === "span" ) {
19958 inline = $target.children( "." + this._inlineClass );
19959 inline.children().addClass( "ui-state-disabled" );
19960 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
19961 prop( "disabled", true );
19962 }
19963 this._disabledInputs = $.map( this._disabledInputs,
19964
19965 // Delete entry
19966 function( value ) {
19967 return ( value === target ? null : value );
19968 } );
19969 this._disabledInputs[ this._disabledInputs.length ] = target;
19970 },
19971
19972 /* Is the first field in a jQuery collection disabled as a datepicker?
19973 * @param target element - the target input field or division or span
19974 * @return boolean - true if disabled, false if enabled
19975 */
19976 _isDisabledDatepicker: function( target ) {
19977 if ( !target ) {
19978 return false;
19979 }
19980 for ( var i = 0; i < this._disabledInputs.length; i++ ) {
19981 if ( this._disabledInputs[ i ] === target ) {
19982 return true;
19983 }
19984 }
19985 return false;
19986 },
19987
19988 /* Retrieve the instance data for the target control.
19989 * @param target element - the target input field or division or span
19990 * @return object - the associated instance data
19991 * @throws error if a jQuery problem getting data
19992 */
19993 _getInst: function( target ) {
19994 try {
19995 return $.data( target, "datepicker" );
19996 } catch ( err ) {
19997 throw "Missing instance data for this datepicker";
19998 }
19999 },
20000
20001 /* Update or retrieve the settings for a date picker attached to an input field or division.
20002 * @param target element - the target input field or division or span
20003 * @param name object - the new settings to update or
20004 * string - the name of the setting to change or retrieve,
20005 * when retrieving also "all" for all instance settings or
20006 * "defaults" for all global defaults
20007 * @param value any - the new value for the setting
20008 * (omit if above is an object or to retrieve a value)
20009 */
20010 _optionDatepicker: function( target, name, value ) {
20011 var settings, date, minDate, maxDate,
20012 inst = this._getInst( target );
20013
20014 if ( arguments.length === 2 && typeof name === "string" ) {
20015 return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
20016 ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
20017 this._get( inst, name ) ) : null ) );
20018 }
20019
20020 settings = name || {};
20021 if ( typeof name === "string" ) {
20022 settings = {};
20023 settings[ name ] = value;
20024 }
20025
20026 if ( inst ) {
20027 if ( this._curInst === inst ) {
20028 this._hideDatepicker();
20029 }
20030
20031 date = this._getDateDatepicker( target, true );
20032 minDate = this._getMinMaxDate( inst, "min" );
20033 maxDate = this._getMinMaxDate( inst, "max" );
20034 datepicker_extendRemove( inst.settings, settings );
20035
20036 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
20037 if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
20038 inst.settings.minDate = this._formatDate( inst, minDate );
20039 }
20040 if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
20041 inst.settings.maxDate = this._formatDate( inst, maxDate );
20042 }
20043 if ( "disabled" in settings ) {
20044 if ( settings.disabled ) {
20045 this._disableDatepicker( target );
20046 } else {
20047 this._enableDatepicker( target );
20048 }
20049 }
20050 this._attachments( $( target ), inst );
20051 this._autoSize( inst );
20052 this._setDate( inst, date );
20053 this._updateAlternate( inst );
20054 this._updateDatepicker( inst );
20055 }
20056 },
20057
20058 // Change method deprecated
20059 _changeDatepicker: function( target, name, value ) {
20060 this._optionDatepicker( target, name, value );
20061 },
20062
20063 /* Redraw the date picker attached to an input field or division.
20064 * @param target element - the target input field or division or span
20065 */
20066 _refreshDatepicker: function( target ) {
20067 var inst = this._getInst( target );
20068 if ( inst ) {
20069 this._updateDatepicker( inst );
20070 }
20071 },
20072
20073 /* Set the dates for a jQuery selection.
20074 * @param target element - the target input field or division or span
20075 * @param date Date - the new date
20076 */
20077 _setDateDatepicker: function( target, date ) {
20078 var inst = this._getInst( target );
20079 if ( inst ) {
20080 this._setDate( inst, date );
20081 this._updateDatepicker( inst );
20082 this._updateAlternate( inst );
20083 }
20084 },
20085
20086 /* Get the date(s) for the first entry in a jQuery selection.
20087 * @param target element - the target input field or division or span
20088 * @param noDefault boolean - true if no default date is to be used
20089 * @return Date - the current date
20090 */
20091 _getDateDatepicker: function( target, noDefault ) {
20092 var inst = this._getInst( target );
20093 if ( inst && !inst.inline ) {
20094 this._setDateFromField( inst, noDefault );
20095 }
20096 return ( inst ? this._getDate( inst ) : null );
20097 },
20098
20099 /* Handle keystrokes. */
20100 _doKeyDown: function( event ) {
20101 var onSelect, dateStr, sel,
20102 inst = $.datepicker._getInst( event.target ),
20103 handled = true,
20104 isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
20105
20106 inst._keyEvent = true;
20107 if ( $.datepicker._datepickerShowing ) {
20108 switch ( event.keyCode ) {
20109 case 9: $.datepicker._hideDatepicker();
20110 handled = false;
20111 break; // hide on tab out
20112 case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
20113 $.datepicker._currentClass + ")", inst.dpDiv );
20114 if ( sel[ 0 ] ) {
20115 $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
20116 }
20117
20118 onSelect = $.datepicker._get( inst, "onSelect" );
20119 if ( onSelect ) {
20120 dateStr = $.datepicker._formatDate( inst );
20121
20122 // Trigger custom callback
20123 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
20124 } else {
20125 $.datepicker._hideDatepicker();
20126 }
20127
20128 return false; // don't submit the form
20129 case 27: $.datepicker._hideDatepicker();
20130 break; // hide on escape
20131 case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
20132 -$.datepicker._get( inst, "stepBigMonths" ) :
20133 -$.datepicker._get( inst, "stepMonths" ) ), "M" );
20134 break; // previous month/year on page up/+ ctrl
20135 case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
20136 +$.datepicker._get( inst, "stepBigMonths" ) :
20137 +$.datepicker._get( inst, "stepMonths" ) ), "M" );
20138 break; // next month/year on page down/+ ctrl
20139 case 35: if ( event.ctrlKey || event.metaKey ) {
20140 $.datepicker._clearDate( event.target );
20141 }
20142 handled = event.ctrlKey || event.metaKey;
20143 break; // clear on ctrl or command +end
20144 case 36: if ( event.ctrlKey || event.metaKey ) {
20145 $.datepicker._gotoToday( event.target );
20146 }
20147 handled = event.ctrlKey || event.metaKey;
20148 break; // current on ctrl or command +home
20149 case 37: if ( event.ctrlKey || event.metaKey ) {
20150 $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
20151 }
20152 handled = event.ctrlKey || event.metaKey;
20153
20154 // -1 day on ctrl or command +left
20155 if ( event.originalEvent.altKey ) {
20156 $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
20157 -$.datepicker._get( inst, "stepBigMonths" ) :
20158 -$.datepicker._get( inst, "stepMonths" ) ), "M" );
20159 }
20160
20161 // next month/year on alt +left on Mac
20162 break;
20163 case 38: if ( event.ctrlKey || event.metaKey ) {
20164 $.datepicker._adjustDate( event.target, -7, "D" );
20165 }
20166 handled = event.ctrlKey || event.metaKey;
20167 break; // -1 week on ctrl or command +up
20168 case 39: if ( event.ctrlKey || event.metaKey ) {
20169 $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
20170 }
20171 handled = event.ctrlKey || event.metaKey;
20172
20173 // +1 day on ctrl or command +right
20174 if ( event.originalEvent.altKey ) {
20175 $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
20176 +$.datepicker._get( inst, "stepBigMonths" ) :
20177 +$.datepicker._get( inst, "stepMonths" ) ), "M" );
20178 }
20179
20180 // next month/year on alt +right
20181 break;
20182 case 40: if ( event.ctrlKey || event.metaKey ) {
20183 $.datepicker._adjustDate( event.target, +7, "D" );
20184 }
20185 handled = event.ctrlKey || event.metaKey;
20186 break; // +1 week on ctrl or command +down
20187 default: handled = false;
20188 }
20189 } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
20190 $.datepicker._showDatepicker( this );
20191 } else {
20192 handled = false;
20193 }
20194
20195 if ( handled ) {
20196 event.preventDefault();
20197 event.stopPropagation();
20198 }
20199 },
20200
20201 /* Filter entered characters - based on date format. */
20202 _doKeyPress: function( event ) {
20203 var chars, chr,
20204 inst = $.datepicker._getInst( event.target );
20205
20206 if ( $.datepicker._get( inst, "constrainInput" ) ) {
20207 chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
20208 chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
20209 return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
20210 }
20211 },
20212
20213 /* Synchronise manual entry and field/alternate field. */
20214 _doKeyUp: function( event ) {
20215 var date,
20216 inst = $.datepicker._getInst( event.target );
20217
20218 if ( inst.input.val() !== inst.lastVal ) {
20219 try {
20220 date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
20221 ( inst.input ? inst.input.val() : null ),
20222 $.datepicker._getFormatConfig( inst ) );
20223
20224 if ( date ) { // only if valid
20225 $.datepicker._setDateFromField( inst );
20226 $.datepicker._updateAlternate( inst );
20227 $.datepicker._updateDatepicker( inst );
20228 }
20229 } catch ( err ) {
20230 }
20231 }
20232 return true;
20233 },
20234
20235 /* Pop-up the date picker for a given input field.
20236 * If false returned from beforeShow event handler do not show.
20237 * @param input element - the input field attached to the date picker or
20238 * event - if triggered by focus
20239 */
20240 _showDatepicker: function( input ) {
20241 input = input.target || input;
20242 if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
20243 input = $( "input", input.parentNode )[ 0 ];
20244 }
20245
20246 if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
20247 return;
20248 }
20249
20250 var inst, beforeShow, beforeShowSettings, isFixed,
20251 offset, showAnim, duration;
20252
20253 inst = $.datepicker._getInst( input );
20254 if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
20255 $.datepicker._curInst.dpDiv.stop( true, true );
20256 if ( inst && $.datepicker._datepickerShowing ) {
20257 $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
20258 }
20259 }
20260
20261 beforeShow = $.datepicker._get( inst, "beforeShow" );
20262 beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
20263 if ( beforeShowSettings === false ) {
20264 return;
20265 }
20266 datepicker_extendRemove( inst.settings, beforeShowSettings );
20267
20268 inst.lastVal = null;
20269 $.datepicker._lastInput = input;
20270 $.datepicker._setDateFromField( inst );
20271
20272 if ( $.datepicker._inDialog ) { // hide cursor
20273 input.value = "";
20274 }
20275 if ( !$.datepicker._pos ) { // position below input
20276 $.datepicker._pos = $.datepicker._findPos( input );
20277 $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
20278 }
20279
20280 isFixed = false;
20281 $( input ).parents().each( function() {
20282 isFixed |= $( this ).css( "position" ) === "fixed";
20283 return !isFixed;
20284 } );
20285
20286 offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
20287 $.datepicker._pos = null;
20288
20289 //to avoid flashes on Firefox
20290 inst.dpDiv.empty();
20291
20292 // determine sizing offscreen
20293 inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
20294 $.datepicker._updateDatepicker( inst );
20295
20296 // fix width for dynamic number of date pickers
20297 // and adjust position before showing
20298 offset = $.datepicker._checkOffset( inst, offset, isFixed );
20299 inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
20300 "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
20301 left: offset.left + "px", top: offset.top + "px" } );
20302
20303 if ( !inst.inline ) {
20304 showAnim = $.datepicker._get( inst, "showAnim" );
20305 duration = $.datepicker._get( inst, "duration" );
20306 inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
20307 $.datepicker._datepickerShowing = true;
20308
20309 if ( $.effects && $.effects.effect[ showAnim ] ) {
20310 inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
20311 } else {
20312 inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
20313 }
20314
20315 if ( $.datepicker._shouldFocusInput( inst ) ) {
20316 inst.input.trigger( "focus" );
20317 }
20318
20319 $.datepicker._curInst = inst;
20320 }
20321 },
20322
20323 /* Generate the date picker content. */
20324 _updateDatepicker: function( inst ) {
20325 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
20326 datepicker_instActive = inst; // for delegate hover events
20327 inst.dpDiv.empty().append( this._generateHTML( inst ) );
20328 this._attachHandlers( inst );
20329
20330 var origyearshtml,
20331 numMonths = this._getNumberOfMonths( inst ),
20332 cols = numMonths[ 1 ],
20333 width = 17,
20334 activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ),
20335 onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" );
20336
20337 if ( activeCell.length > 0 ) {
20338 datepicker_handleMouseover.apply( activeCell.get( 0 ) );
20339 }
20340
20341 inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
20342 if ( cols > 1 ) {
20343 inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
20344 }
20345 inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
20346 "Class" ]( "ui-datepicker-multi" );
20347 inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
20348 "Class" ]( "ui-datepicker-rtl" );
20349
20350 if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
20351 inst.input.trigger( "focus" );
20352 }
20353
20354 // Deffered render of the years select (to avoid flashes on Firefox)
20355 if ( inst.yearshtml ) {
20356 origyearshtml = inst.yearshtml;
20357 setTimeout( function() {
20358
20359 //assure that inst.yearshtml didn't change.
20360 if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
20361 inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml );
20362 }
20363 origyearshtml = inst.yearshtml = null;
20364 }, 0 );
20365 }
20366
20367 if ( onUpdateDatepicker ) {
20368 onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] );
20369 }
20370 },
20371
20372 _shouldFocusInput: function( inst ) {
20373 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" );
20374 },
20375
20376 /* Check positioning to remain on screen. */
20377 _checkOffset: function( inst, offset, isFixed ) {
20378 var dpWidth = inst.dpDiv.outerWidth(),
20379 dpHeight = inst.dpDiv.outerHeight(),
20380 inputWidth = inst.input ? inst.input.outerWidth() : 0,
20381 inputHeight = inst.input ? inst.input.outerHeight() : 0,
20382 viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
20383 viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
20384
20385 offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
20386 offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
20387 offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
20388
20389 // Now check if datepicker is showing outside window viewport - move to a better place if so.
20390 offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
20391 Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
20392 offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
20393 Math.abs( dpHeight + inputHeight ) : 0 );
20394
20395 return offset;
20396 },
20397
20398 /* Find an object's position on the screen. */
20399 _findPos: function( obj ) {
20400 var position,
20401 inst = this._getInst( obj ),
20402 isRTL = this._get( inst, "isRTL" );
20403
20404 while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) {
20405 obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
20406 }
20407
20408 position = $( obj ).offset();
20409 return [ position.left, position.top ];
20410 },
20411
20412 /* Hide the date picker from view.
20413 * @param input element - the input field attached to the date picker
20414 */
20415 _hideDatepicker: function( input ) {
20416 var showAnim, duration, postProcess, onClose,
20417 inst = this._curInst;
20418
20419 if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
20420 return;
20421 }
20422
20423 if ( this._datepickerShowing ) {
20424 showAnim = this._get( inst, "showAnim" );
20425 duration = this._get( inst, "duration" );
20426 postProcess = function() {
20427 $.datepicker._tidyDialog( inst );
20428 };
20429
20430 if ( $.effects && ( $.effects.effect[ showAnim ] ) ) {
20431 inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
20432 } else {
20433 inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
20434 ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
20435 }
20436
20437 if ( !showAnim ) {
20438 postProcess();
20439 }
20440 this._datepickerShowing = false;
20441
20442 onClose = this._get( inst, "onClose" );
20443 if ( onClose ) {
20444 onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
20445 }
20446
20447 this._lastInput = null;
20448 if ( this._inDialog ) {
20449 this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
20450 if ( $.blockUI ) {
20451 $.unblockUI();
20452 $( "body" ).append( this.dpDiv );
20453 }
20454 }
20455 this._inDialog = false;
20456 }
20457 },
20458
20459 /* Tidy up after a dialog display. */
20460 _tidyDialog: function( inst ) {
20461 inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
20462 },
20463
20464 /* Close date picker if clicked elsewhere. */
20465 _checkExternalClick: function( event ) {
20466 if ( !$.datepicker._curInst ) {
20467 return;
20468 }
20469
20470 var $target = $( event.target ),
20471 inst = $.datepicker._getInst( $target[ 0 ] );
20472
20473 if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
20474 $target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
20475 !$target.hasClass( $.datepicker.markerClassName ) &&
20476 !$target.closest( "." + $.datepicker._triggerClass ).length &&
20477 $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
20478 ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
20479 $.datepicker._hideDatepicker();
20480 }
20481 },
20482
20483 /* Adjust one of the date sub-fields. */
20484 _adjustDate: function( id, offset, period ) {
20485 var target = $( id ),
20486 inst = this._getInst( target[ 0 ] );
20487
20488 if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
20489 return;
20490 }
20491 this._adjustInstDate( inst, offset, period );
20492 this._updateDatepicker( inst );
20493 },
20494
20495 /* Action for current link. */
20496 _gotoToday: function( id ) {
20497 var date,
20498 target = $( id ),
20499 inst = this._getInst( target[ 0 ] );
20500
20501 if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
20502 inst.selectedDay = inst.currentDay;
20503 inst.drawMonth = inst.selectedMonth = inst.currentMonth;
20504 inst.drawYear = inst.selectedYear = inst.currentYear;
20505 } else {
20506 date = new Date();
20507 inst.selectedDay = date.getDate();
20508 inst.drawMonth = inst.selectedMonth = date.getMonth();
20509 inst.drawYear = inst.selectedYear = date.getFullYear();
20510 }
20511 this._notifyChange( inst );
20512 this._adjustDate( target );
20513 },
20514
20515 /* Action for selecting a new month/year. */
20516 _selectMonthYear: function( id, select, period ) {
20517 var target = $( id ),
20518 inst = this._getInst( target[ 0 ] );
20519
20520 inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
20521 inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
20522 parseInt( select.options[ select.selectedIndex ].value, 10 );
20523
20524 this._notifyChange( inst );
20525 this._adjustDate( target );
20526 },
20527
20528 /* Action for selecting a day. */
20529 _selectDay: function( id, month, year, td ) {
20530 var inst,
20531 target = $( id );
20532
20533 if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
20534 return;
20535 }
20536
20537 inst = this._getInst( target[ 0 ] );
20538 inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) );
20539 inst.selectedMonth = inst.currentMonth = month;
20540 inst.selectedYear = inst.currentYear = year;
20541 this._selectDate( id, this._formatDate( inst,
20542 inst.currentDay, inst.currentMonth, inst.currentYear ) );
20543 },
20544
20545 /* Erase the input field and hide the date picker. */
20546 _clearDate: function( id ) {
20547 var target = $( id );
20548 this._selectDate( target, "" );
20549 },
20550
20551 /* Update the input field with the selected date. */
20552 _selectDate: function( id, dateStr ) {
20553 var onSelect,
20554 target = $( id ),
20555 inst = this._getInst( target[ 0 ] );
20556
20557 dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
20558 if ( inst.input ) {
20559 inst.input.val( dateStr );
20560 }
20561 this._updateAlternate( inst );
20562
20563 onSelect = this._get( inst, "onSelect" );
20564 if ( onSelect ) {
20565 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback
20566 } else if ( inst.input ) {
20567 inst.input.trigger( "change" ); // fire the change event
20568 }
20569
20570 if ( inst.inline ) {
20571 this._updateDatepicker( inst );
20572 } else {
20573 this._hideDatepicker();
20574 this._lastInput = inst.input[ 0 ];
20575 if ( typeof( inst.input[ 0 ] ) !== "object" ) {
20576 inst.input.trigger( "focus" ); // restore focus
20577 }
20578 this._lastInput = null;
20579 }
20580 },
20581
20582 /* Update any alternate field to synchronise with the main field. */
20583 _updateAlternate: function( inst ) {
20584 var altFormat, date, dateStr,
20585 altField = this._get( inst, "altField" );
20586
20587 if ( altField ) { // update alternate field too
20588 altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
20589 date = this._getDate( inst );
20590 dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
20591 $( document ).find( altField ).val( dateStr );
20592 }
20593 },
20594
20595 /* Set as beforeShowDay function to prevent selection of weekends.
20596 * @param date Date - the date to customise
20597 * @return [boolean, string] - is this date selectable?, what is its CSS class?
20598 */
20599 noWeekends: function( date ) {
20600 var day = date.getDay();
20601 return [ ( day > 0 && day < 6 ), "" ];
20602 },
20603
20604 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
20605 * @param date Date - the date to get the week for
20606 * @return number - the number of the week within the year that contains this date
20607 */
20608 iso8601Week: function( date ) {
20609 var time,
20610 checkDate = new Date( date.getTime() );
20611
20612 // Find Thursday of this week starting on Monday
20613 checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
20614
20615 time = checkDate.getTime();
20616 checkDate.setMonth( 0 ); // Compare with Jan 1
20617 checkDate.setDate( 1 );
20618 return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
20619 },
20620
20621 /* Parse a string value into a date object.
20622 * See formatDate below for the possible formats.
20623 *
20624 * @param format string - the expected format of the date
20625 * @param value string - the date in the above format
20626 * @param settings Object - attributes include:
20627 * shortYearCutoff number - the cutoff year for determining the century (optional)
20628 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
20629 * dayNames string[7] - names of the days from Sunday (optional)
20630 * monthNamesShort string[12] - abbreviated names of the months (optional)
20631 * monthNames string[12] - names of the months (optional)
20632 * @return Date - the extracted date value or null if value is blank
20633 */
20634 parseDate: function( format, value, settings ) {
20635 if ( format == null || value == null ) {
20636 throw "Invalid arguments";
20637 }
20638
20639 value = ( typeof value === "object" ? value.toString() : value + "" );
20640 if ( value === "" ) {
20641 return null;
20642 }
20643
20644 var iFormat, dim, extra,
20645 iValue = 0,
20646 shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
20647 shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
20648 new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
20649 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
20650 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
20651 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
20652 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
20653 year = -1,
20654 month = -1,
20655 day = -1,
20656 doy = -1,
20657 literal = false,
20658 date,
20659
20660 // Check whether a format character is doubled
20661 lookAhead = function( match ) {
20662 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
20663 if ( matches ) {
20664 iFormat++;
20665 }
20666 return matches;
20667 },
20668
20669 // Extract a number from the string value
20670 getNumber = function( match ) {
20671 var isDoubled = lookAhead( match ),
20672 size = ( match === "@" ? 14 : ( match === "!" ? 20 :
20673 ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
20674 minSize = ( match === "y" ? size : 1 ),
20675 digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
20676 num = value.substring( iValue ).match( digits );
20677 if ( !num ) {
20678 throw "Missing number at position " + iValue;
20679 }
20680 iValue += num[ 0 ].length;
20681 return parseInt( num[ 0 ], 10 );
20682 },
20683
20684 // Extract a name from the string value and convert to an index
20685 getName = function( match, shortNames, longNames ) {
20686 var index = -1,
20687 names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
20688 return [ [ k, v ] ];
20689 } ).sort( function( a, b ) {
20690 return -( a[ 1 ].length - b[ 1 ].length );
20691 } );
20692
20693 $.each( names, function( i, pair ) {
20694 var name = pair[ 1 ];
20695 if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
20696 index = pair[ 0 ];
20697 iValue += name.length;
20698 return false;
20699 }
20700 } );
20701 if ( index !== -1 ) {
20702 return index + 1;
20703 } else {
20704 throw "Unknown name at position " + iValue;
20705 }
20706 },
20707
20708 // Confirm that a literal character matches the string value
20709 checkLiteral = function() {
20710 if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
20711 throw "Unexpected literal at position " + iValue;
20712 }
20713 iValue++;
20714 };
20715
20716 for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
20717 if ( literal ) {
20718 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
20719 literal = false;
20720 } else {
20721 checkLiteral();
20722 }
20723 } else {
20724 switch ( format.charAt( iFormat ) ) {
20725 case "d":
20726 day = getNumber( "d" );
20727 break;
20728 case "D":
20729 getName( "D", dayNamesShort, dayNames );
20730 break;
20731 case "o":
20732 doy = getNumber( "o" );
20733 break;
20734 case "m":
20735 month = getNumber( "m" );
20736 break;
20737 case "M":
20738 month = getName( "M", monthNamesShort, monthNames );
20739 break;
20740 case "y":
20741 year = getNumber( "y" );
20742 break;
20743 case "@":
20744 date = new Date( getNumber( "@" ) );
20745 year = date.getFullYear();
20746 month = date.getMonth() + 1;
20747 day = date.getDate();
20748 break;
20749 case "!":
20750 date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
20751 year = date.getFullYear();
20752 month = date.getMonth() + 1;
20753 day = date.getDate();
20754 break;
20755 case "'":
20756 if ( lookAhead( "'" ) ) {
20757 checkLiteral();
20758 } else {
20759 literal = true;
20760 }
20761 break;
20762 default:
20763 checkLiteral();
20764 }
20765 }
20766 }
20767
20768 if ( iValue < value.length ) {
20769 extra = value.substr( iValue );
20770 if ( !/^\s+/.test( extra ) ) {
20771 throw "Extra/unparsed characters found in date: " + extra;
20772 }
20773 }
20774
20775 if ( year === -1 ) {
20776 year = new Date().getFullYear();
20777 } else if ( year < 100 ) {
20778 year += new Date().getFullYear() - new Date().getFullYear() % 100 +
20779 ( year <= shortYearCutoff ? 0 : -100 );
20780 }
20781
20782 if ( doy > -1 ) {
20783 month = 1;
20784 day = doy;
20785 do {
20786 dim = this._getDaysInMonth( year, month - 1 );
20787 if ( day <= dim ) {
20788 break;
20789 }
20790 month++;
20791 day -= dim;
20792 } while ( true );
20793 }
20794
20795 date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
20796 if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
20797 throw "Invalid date"; // E.g. 31/02/00
20798 }
20799 return date;
20800 },
20801
20802 /* Standard date formats. */
20803 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
20804 COOKIE: "D, dd M yy",
20805 ISO_8601: "yy-mm-dd",
20806 RFC_822: "D, d M y",
20807 RFC_850: "DD, dd-M-y",
20808 RFC_1036: "D, d M y",
20809 RFC_1123: "D, d M yy",
20810 RFC_2822: "D, d M yy",
20811 RSS: "D, d M y", // RFC 822
20812 TICKS: "!",
20813 TIMESTAMP: "@",
20814 W3C: "yy-mm-dd", // ISO 8601
20815
20816 _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
20817 Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
20818
20819 /* Format a date object into a string value.
20820 * The format can be combinations of the following:
20821 * d - day of month (no leading zero)
20822 * dd - day of month (two digit)
20823 * o - day of year (no leading zeros)
20824 * oo - day of year (three digit)
20825 * D - day name short
20826 * DD - day name long
20827 * m - month of year (no leading zero)
20828 * mm - month of year (two digit)
20829 * M - month name short
20830 * MM - month name long
20831 * y - year (two digit)
20832 * yy - year (four digit)
20833 * @ - Unix timestamp (ms since 01/01/1970)
20834 * ! - Windows ticks (100ns since 01/01/0001)
20835 * "..." - literal text
20836 * '' - single quote
20837 *
20838 * @param format string - the desired format of the date
20839 * @param date Date - the date value to format
20840 * @param settings Object - attributes include:
20841 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
20842 * dayNames string[7] - names of the days from Sunday (optional)
20843 * monthNamesShort string[12] - abbreviated names of the months (optional)
20844 * monthNames string[12] - names of the months (optional)
20845 * @return string - the date in the above format
20846 */
20847 formatDate: function( format, date, settings ) {
20848 if ( !date ) {
20849 return "";
20850 }
20851
20852 var iFormat,
20853 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
20854 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
20855 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
20856 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
20857
20858 // Check whether a format character is doubled
20859 lookAhead = function( match ) {
20860 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
20861 if ( matches ) {
20862 iFormat++;
20863 }
20864 return matches;
20865 },
20866
20867 // Format a number, with leading zero if necessary
20868 formatNumber = function( match, value, len ) {
20869 var num = "" + value;
20870 if ( lookAhead( match ) ) {
20871 while ( num.length < len ) {
20872 num = "0" + num;
20873 }
20874 }
20875 return num;
20876 },
20877
20878 // Format a name, short or long as requested
20879 formatName = function( match, value, shortNames, longNames ) {
20880 return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
20881 },
20882 output = "",
20883 literal = false;
20884
20885 if ( date ) {
20886 for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
20887 if ( literal ) {
20888 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
20889 literal = false;
20890 } else {
20891 output += format.charAt( iFormat );
20892 }
20893 } else {
20894 switch ( format.charAt( iFormat ) ) {
20895 case "d":
20896 output += formatNumber( "d", date.getDate(), 2 );
20897 break;
20898 case "D":
20899 output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
20900 break;
20901 case "o":
20902 output += formatNumber( "o",
20903 Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
20904 break;
20905 case "m":
20906 output += formatNumber( "m", date.getMonth() + 1, 2 );
20907 break;
20908 case "M":
20909 output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
20910 break;
20911 case "y":
20912 output += ( lookAhead( "y" ) ? date.getFullYear() :
20913 ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
20914 break;
20915 case "@":
20916 output += date.getTime();
20917 break;
20918 case "!":
20919 output += date.getTime() * 10000 + this._ticksTo1970;
20920 break;
20921 case "'":
20922 if ( lookAhead( "'" ) ) {
20923 output += "'";
20924 } else {
20925 literal = true;
20926 }
20927 break;
20928 default:
20929 output += format.charAt( iFormat );
20930 }
20931 }
20932 }
20933 }
20934 return output;
20935 },
20936
20937 /* Extract all possible characters from the date format. */
20938 _possibleChars: function( format ) {
20939 var iFormat,
20940 chars = "",
20941 literal = false,
20942
20943 // Check whether a format character is doubled
20944 lookAhead = function( match ) {
20945 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
20946 if ( matches ) {
20947 iFormat++;
20948 }
20949 return matches;
20950 };
20951
20952 for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
20953 if ( literal ) {
20954 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
20955 literal = false;
20956 } else {
20957 chars += format.charAt( iFormat );
20958 }
20959 } else {
20960 switch ( format.charAt( iFormat ) ) {
20961 case "d": case "m": case "y": case "@":
20962 chars += "0123456789";
20963 break;
20964 case "D": case "M":
20965 return null; // Accept anything
20966 case "'":
20967 if ( lookAhead( "'" ) ) {
20968 chars += "'";
20969 } else {
20970 literal = true;
20971 }
20972 break;
20973 default:
20974 chars += format.charAt( iFormat );
20975 }
20976 }
20977 }
20978 return chars;
20979 },
20980
20981 /* Get a setting value, defaulting if necessary. */
20982 _get: function( inst, name ) {
20983 return inst.settings[ name ] !== undefined ?
20984 inst.settings[ name ] : this._defaults[ name ];
20985 },
20986
20987 /* Parse existing date and initialise date picker. */
20988 _setDateFromField: function( inst, noDefault ) {
20989 if ( inst.input.val() === inst.lastVal ) {
20990 return;
20991 }
20992
20993 var dateFormat = this._get( inst, "dateFormat" ),
20994 dates = inst.lastVal = inst.input ? inst.input.val() : null,
20995 defaultDate = this._getDefaultDate( inst ),
20996 date = defaultDate,
20997 settings = this._getFormatConfig( inst );
20998
20999 try {
21000 date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
21001 } catch ( event ) {
21002 dates = ( noDefault ? "" : dates );
21003 }
21004 inst.selectedDay = date.getDate();
21005 inst.drawMonth = inst.selectedMonth = date.getMonth();
21006 inst.drawYear = inst.selectedYear = date.getFullYear();
21007 inst.currentDay = ( dates ? date.getDate() : 0 );
21008 inst.currentMonth = ( dates ? date.getMonth() : 0 );
21009 inst.currentYear = ( dates ? date.getFullYear() : 0 );
21010 this._adjustInstDate( inst );
21011 },
21012
21013 /* Retrieve the default date shown on opening. */
21014 _getDefaultDate: function( inst ) {
21015 return this._restrictMinMax( inst,
21016 this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
21017 },
21018
21019 /* A date may be specified as an exact value or a relative one. */
21020 _determineDate: function( inst, date, defaultDate ) {
21021 var offsetNumeric = function( offset ) {
21022 var date = new Date();
21023 date.setDate( date.getDate() + offset );
21024 return date;
21025 },
21026 offsetString = function( offset ) {
21027 try {
21028 return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
21029 offset, $.datepicker._getFormatConfig( inst ) );
21030 } catch ( e ) {
21031
21032 // Ignore
21033 }
21034
21035 var date = ( offset.toLowerCase().match( /^c/ ) ?
21036 $.datepicker._getDate( inst ) : null ) || new Date(),
21037 year = date.getFullYear(),
21038 month = date.getMonth(),
21039 day = date.getDate(),
21040 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
21041 matches = pattern.exec( offset );
21042
21043 while ( matches ) {
21044 switch ( matches[ 2 ] || "d" ) {
21045 case "d" : case "D" :
21046 day += parseInt( matches[ 1 ], 10 ); break;
21047 case "w" : case "W" :
21048 day += parseInt( matches[ 1 ], 10 ) * 7; break;
21049 case "m" : case "M" :
21050 month += parseInt( matches[ 1 ], 10 );
21051 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
21052 break;
21053 case "y": case "Y" :
21054 year += parseInt( matches[ 1 ], 10 );
21055 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
21056 break;
21057 }
21058 matches = pattern.exec( offset );
21059 }
21060 return new Date( year, month, day );
21061 },
21062 newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
21063 ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
21064
21065 newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
21066 if ( newDate ) {
21067 newDate.setHours( 0 );
21068 newDate.setMinutes( 0 );
21069 newDate.setSeconds( 0 );
21070 newDate.setMilliseconds( 0 );
21071 }
21072 return this._daylightSavingAdjust( newDate );
21073 },
21074
21075 /* Handle switch to/from daylight saving.
21076 * Hours may be non-zero on daylight saving cut-over:
21077 * > 12 when midnight changeover, but then cannot generate
21078 * midnight datetime, so jump to 1AM, otherwise reset.
21079 * @param date (Date) the date to check
21080 * @return (Date) the corrected date
21081 */
21082 _daylightSavingAdjust: function( date ) {
21083 if ( !date ) {
21084 return null;
21085 }
21086 date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
21087 return date;
21088 },
21089
21090 /* Set the date(s) directly. */
21091 _setDate: function( inst, date, noChange ) {
21092 var clear = !date,
21093 origMonth = inst.selectedMonth,
21094 origYear = inst.selectedYear,
21095 newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
21096
21097 inst.selectedDay = inst.currentDay = newDate.getDate();
21098 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
21099 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
21100 if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
21101 this._notifyChange( inst );
21102 }
21103 this._adjustInstDate( inst );
21104 if ( inst.input ) {
21105 inst.input.val( clear ? "" : this._formatDate( inst ) );
21106 }
21107 },
21108
21109 /* Retrieve the date(s) directly. */
21110 _getDate: function( inst ) {
21111 var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
21112 this._daylightSavingAdjust( new Date(
21113 inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
21114 return startDate;
21115 },
21116
21117 /* Attach the onxxx handlers. These are declared statically so
21118 * they work with static code transformers like Caja.
21119 */
21120 _attachHandlers: function( inst ) {
21121 var stepMonths = this._get( inst, "stepMonths" ),
21122 id = "#" + inst.id.replace( /\\\\/g, "\\" );
21123 inst.dpDiv.find( "[data-handler]" ).map( function() {
21124 var handler = {
21125 prev: function() {
21126 $.datepicker._adjustDate( id, -stepMonths, "M" );
21127 },
21128 next: function() {
21129 $.datepicker._adjustDate( id, +stepMonths, "M" );
21130 },
21131 hide: function() {
21132 $.datepicker._hideDatepicker();
21133 },
21134 today: function() {
21135 $.datepicker._gotoToday( id );
21136 },
21137 selectDay: function() {
21138 $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
21139 return false;
21140 },
21141 selectMonth: function() {
21142 $.datepicker._selectMonthYear( id, this, "M" );
21143 return false;
21144 },
21145 selectYear: function() {
21146 $.datepicker._selectMonthYear( id, this, "Y" );
21147 return false;
21148 }
21149 };
21150 $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
21151 } );
21152 },
21153
21154 /* Generate the HTML for the current state of the date picker. */
21155 _generateHTML: function( inst ) {
21156 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
21157 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
21158 monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
21159 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
21160 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
21161 printDate, dRow, tbody, daySettings, otherMonth, unselectable,
21162 tempDate = new Date(),
21163 today = this._daylightSavingAdjust(
21164 new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
21165 isRTL = this._get( inst, "isRTL" ),
21166 showButtonPanel = this._get( inst, "showButtonPanel" ),
21167 hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
21168 navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
21169 numMonths = this._getNumberOfMonths( inst ),
21170 showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
21171 stepMonths = this._get( inst, "stepMonths" ),
21172 isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
21173 currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
21174 new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
21175 minDate = this._getMinMaxDate( inst, "min" ),
21176 maxDate = this._getMinMaxDate( inst, "max" ),
21177 drawMonth = inst.drawMonth - showCurrentAtPos,
21178 drawYear = inst.drawYear;
21179
21180 if ( drawMonth < 0 ) {
21181 drawMonth += 12;
21182 drawYear--;
21183 }
21184 if ( maxDate ) {
21185 maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
21186 maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
21187 maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
21188 while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
21189 drawMonth--;
21190 if ( drawMonth < 0 ) {
21191 drawMonth = 11;
21192 drawYear--;
21193 }
21194 }
21195 }
21196 inst.drawMonth = drawMonth;
21197 inst.drawYear = drawYear;
21198
21199 prevText = this._get( inst, "prevText" );
21200 prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
21201 this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
21202 this._getFormatConfig( inst ) ) );
21203
21204 if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) {
21205 prev = $( "<a>" )
21206 .attr( {
21207 "class": "ui-datepicker-prev ui-corner-all",
21208 "data-handler": "prev",
21209 "data-event": "click",
21210 title: prevText
21211 } )
21212 .append(
21213 $( "<span>" )
21214 .addClass( "ui-icon ui-icon-circle-triangle-" +
21215 ( isRTL ? "e" : "w" ) )
21216 .text( prevText )
21217 )[ 0 ].outerHTML;
21218 } else if ( hideIfNoPrevNext ) {
21219 prev = "";
21220 } else {
21221 prev = $( "<a>" )
21222 .attr( {
21223 "class": "ui-datepicker-prev ui-corner-all ui-state-disabled",
21224 title: prevText
21225 } )
21226 .append(
21227 $( "<span>" )
21228 .addClass( "ui-icon ui-icon-circle-triangle-" +
21229 ( isRTL ? "e" : "w" ) )
21230 .text( prevText )
21231 )[ 0 ].outerHTML;
21232 }
21233
21234 nextText = this._get( inst, "nextText" );
21235 nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
21236 this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
21237 this._getFormatConfig( inst ) ) );
21238
21239 if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) {
21240 next = $( "<a>" )
21241 .attr( {
21242 "class": "ui-datepicker-next ui-corner-all",
21243 "data-handler": "next",
21244 "data-event": "click",
21245 title: nextText
21246 } )
21247 .append(
21248 $( "<span>" )
21249 .addClass( "ui-icon ui-icon-circle-triangle-" +
21250 ( isRTL ? "w" : "e" ) )
21251 .text( nextText )
21252 )[ 0 ].outerHTML;
21253 } else if ( hideIfNoPrevNext ) {
21254 next = "";
21255 } else {
21256 next = $( "<a>" )
21257 .attr( {
21258 "class": "ui-datepicker-next ui-corner-all ui-state-disabled",
21259 title: nextText
21260 } )
21261 .append(
21262 $( "<span>" )
21263 .attr( "class", "ui-icon ui-icon-circle-triangle-" +
21264 ( isRTL ? "w" : "e" ) )
21265 .text( nextText )
21266 )[ 0 ].outerHTML;
21267 }
21268
21269 currentText = this._get( inst, "currentText" );
21270 gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
21271 currentText = ( !navigationAsDateFormat ? currentText :
21272 this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
21273
21274 controls = "";
21275 if ( !inst.inline ) {
21276 controls = $( "<button>" )
21277 .attr( {
21278 type: "button",
21279 "class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all",
21280 "data-handler": "hide",
21281 "data-event": "click"
21282 } )
21283 .text( this._get( inst, "closeText" ) )[ 0 ].outerHTML;
21284 }
21285
21286 buttonPanel = "";
21287 if ( showButtonPanel ) {
21288 buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" )
21289 .append( isRTL ? controls : "" )
21290 .append( this._isInRange( inst, gotoDate ) ?
21291 $( "<button>" )
21292 .attr( {
21293 type: "button",
21294 "class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all",
21295 "data-handler": "today",
21296 "data-event": "click"
21297 } )
21298 .text( currentText ) :
21299 "" )
21300 .append( isRTL ? "" : controls )[ 0 ].outerHTML;
21301 }
21302
21303 firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
21304 firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
21305
21306 showWeek = this._get( inst, "showWeek" );
21307 dayNames = this._get( inst, "dayNames" );
21308 dayNamesMin = this._get( inst, "dayNamesMin" );
21309 monthNames = this._get( inst, "monthNames" );
21310 monthNamesShort = this._get( inst, "monthNamesShort" );
21311 beforeShowDay = this._get( inst, "beforeShowDay" );
21312 showOtherMonths = this._get( inst, "showOtherMonths" );
21313 selectOtherMonths = this._get( inst, "selectOtherMonths" );
21314 defaultDate = this._getDefaultDate( inst );
21315 html = "";
21316
21317 for ( row = 0; row < numMonths[ 0 ]; row++ ) {
21318 group = "";
21319 this.maxRows = 4;
21320 for ( col = 0; col < numMonths[ 1 ]; col++ ) {
21321 selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
21322 cornerClass = " ui-corner-all";
21323 calender = "";
21324 if ( isMultiMonth ) {
21325 calender += "<div class='ui-datepicker-group";
21326 if ( numMonths[ 1 ] > 1 ) {
21327 switch ( col ) {
21328 case 0: calender += " ui-datepicker-group-first";
21329 cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
21330 case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
21331 cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
21332 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
21333 }
21334 }
21335 calender += "'>";
21336 }
21337 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
21338 ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
21339 ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
21340 this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
21341 row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
21342 "</div><table class='ui-datepicker-calendar'><thead>" +
21343 "<tr>";
21344 thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
21345 for ( dow = 0; dow < 7; dow++ ) { // days of the week
21346 day = ( dow + firstDay ) % 7;
21347 thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
21348 "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
21349 }
21350 calender += thead + "</tr></thead><tbody>";
21351 daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
21352 if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
21353 inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
21354 }
21355 leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
21356 curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
21357 numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
21358 this.maxRows = numRows;
21359 printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
21360 for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
21361 calender += "<tr>";
21362 tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
21363 this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
21364 for ( dow = 0; dow < 7; dow++ ) { // create date picker days
21365 daySettings = ( beforeShowDay ?
21366 beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
21367 otherMonth = ( printDate.getMonth() !== drawMonth );
21368 unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
21369 ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
21370 tbody += "<td class='" +
21371 ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
21372 ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
21373 ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
21374 ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
21375
21376 // or defaultDate is current printedDate and defaultDate is selectedDate
21377 " " + this._dayOverClass : "" ) + // highlight selected day
21378 ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days
21379 ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
21380 ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
21381 ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
21382 ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
21383 ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
21384 ( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
21385 ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
21386 ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
21387 ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
21388 ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
21389 "' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader
21390 "' data-date='" + printDate.getDate() + // store date as data
21391 "'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
21392 printDate.setDate( printDate.getDate() + 1 );
21393 printDate = this._daylightSavingAdjust( printDate );
21394 }
21395 calender += tbody + "</tr>";
21396 }
21397 drawMonth++;
21398 if ( drawMonth > 11 ) {
21399 drawMonth = 0;
21400 drawYear++;
21401 }
21402 calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
21403 ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
21404 group += calender;
21405 }
21406 html += group;
21407 }
21408 html += buttonPanel;
21409 inst._keyEvent = false;
21410 return html;
21411 },
21412
21413 /* Generate the month and year header. */
21414 _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
21415 secondary, monthNames, monthNamesShort ) {
21416
21417 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
21418 changeMonth = this._get( inst, "changeMonth" ),
21419 changeYear = this._get( inst, "changeYear" ),
21420 showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
21421 selectMonthLabel = this._get( inst, "selectMonthLabel" ),
21422 selectYearLabel = this._get( inst, "selectYearLabel" ),
21423 html = "<div class='ui-datepicker-title'>",
21424 monthHtml = "";
21425
21426 // Month selection
21427 if ( secondary || !changeMonth ) {
21428 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
21429 } else {
21430 inMinYear = ( minDate && minDate.getFullYear() === drawYear );
21431 inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
21432 monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>";
21433 for ( month = 0; month < 12; month++ ) {
21434 if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
21435 monthHtml += "<option value='" + month + "'" +
21436 ( month === drawMonth ? " selected='selected'" : "" ) +
21437 ">" + monthNamesShort[ month ] + "</option>";
21438 }
21439 }
21440 monthHtml += "</select>";
21441 }
21442
21443 if ( !showMonthAfterYear ) {
21444 html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
21445 }
21446
21447 // Year selection
21448 if ( !inst.yearshtml ) {
21449 inst.yearshtml = "";
21450 if ( secondary || !changeYear ) {
21451 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
21452 } else {
21453
21454 // determine range of years to display
21455 years = this._get( inst, "yearRange" ).split( ":" );
21456 thisYear = new Date().getFullYear();
21457 determineYear = function( value ) {
21458 var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
21459 ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
21460 parseInt( value, 10 ) ) );
21461 return ( isNaN( year ) ? thisYear : year );
21462 };
21463 year = determineYear( years[ 0 ] );
21464 endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
21465 year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
21466 endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
21467 inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>";
21468 for ( ; year <= endYear; year++ ) {
21469 inst.yearshtml += "<option value='" + year + "'" +
21470 ( year === drawYear ? " selected='selected'" : "" ) +
21471 ">" + year + "</option>";
21472 }
21473 inst.yearshtml += "</select>";
21474
21475 html += inst.yearshtml;
21476 inst.yearshtml = null;
21477 }
21478 }
21479
21480 html += this._get( inst, "yearSuffix" );
21481 if ( showMonthAfterYear ) {
21482 html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
21483 }
21484 html += "</div>"; // Close datepicker_header
21485 return html;
21486 },
21487
21488 /* Adjust one of the date sub-fields. */
21489 _adjustInstDate: function( inst, offset, period ) {
21490 var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
21491 month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
21492 day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
21493 date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
21494
21495 inst.selectedDay = date.getDate();
21496 inst.drawMonth = inst.selectedMonth = date.getMonth();
21497 inst.drawYear = inst.selectedYear = date.getFullYear();
21498 if ( period === "M" || period === "Y" ) {
21499 this._notifyChange( inst );
21500 }
21501 },
21502
21503 /* Ensure a date is within any min/max bounds. */
21504 _restrictMinMax: function( inst, date ) {
21505 var minDate = this._getMinMaxDate( inst, "min" ),
21506 maxDate = this._getMinMaxDate( inst, "max" ),
21507 newDate = ( minDate && date < minDate ? minDate : date );
21508 return ( maxDate && newDate > maxDate ? maxDate : newDate );
21509 },
21510
21511 /* Notify change of month/year. */
21512 _notifyChange: function( inst ) {
21513 var onChange = this._get( inst, "onChangeMonthYear" );
21514 if ( onChange ) {
21515 onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
21516 [ inst.selectedYear, inst.selectedMonth + 1, inst ] );
21517 }
21518 },
21519
21520 /* Determine the number of months to show. */
21521 _getNumberOfMonths: function( inst ) {
21522 var numMonths = this._get( inst, "numberOfMonths" );
21523 return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
21524 },
21525
21526 /* Determine the current maximum date - ensure no time components are set. */
21527 _getMinMaxDate: function( inst, minMax ) {
21528 return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
21529 },
21530
21531 /* Find the number of days in a given month. */
21532 _getDaysInMonth: function( year, month ) {
21533 return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
21534 },
21535
21536 /* Find the day of the week of the first of a month. */
21537 _getFirstDayOfMonth: function( year, month ) {
21538 return new Date( year, month, 1 ).getDay();
21539 },
21540
21541 /* Determines if we should allow a "next/prev" month display change. */
21542 _canAdjustMonth: function( inst, offset, curYear, curMonth ) {
21543 var numMonths = this._getNumberOfMonths( inst ),
21544 date = this._daylightSavingAdjust( new Date( curYear,
21545 curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
21546
21547 if ( offset < 0 ) {
21548 date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
21549 }
21550 return this._isInRange( inst, date );
21551 },
21552
21553 /* Is the given date in the accepted range? */
21554 _isInRange: function( inst, date ) {
21555 var yearSplit, currentYear,
21556 minDate = this._getMinMaxDate( inst, "min" ),
21557 maxDate = this._getMinMaxDate( inst, "max" ),
21558 minYear = null,
21559 maxYear = null,
21560 years = this._get( inst, "yearRange" );
21561 if ( years ) {
21562 yearSplit = years.split( ":" );
21563 currentYear = new Date().getFullYear();
21564 minYear = parseInt( yearSplit[ 0 ], 10 );
21565 maxYear = parseInt( yearSplit[ 1 ], 10 );
21566 if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
21567 minYear += currentYear;
21568 }
21569 if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
21570 maxYear += currentYear;
21571 }
21572 }
21573
21574 return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
21575 ( !maxDate || date.getTime() <= maxDate.getTime() ) &&
21576 ( !minYear || date.getFullYear() >= minYear ) &&
21577 ( !maxYear || date.getFullYear() <= maxYear ) );
21578 },
21579
21580 /* Provide the configuration settings for formatting/parsing. */
21581 _getFormatConfig: function( inst ) {
21582 var shortYearCutoff = this._get( inst, "shortYearCutoff" );
21583 shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
21584 new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
21585 return { shortYearCutoff: shortYearCutoff,
21586 dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
21587 monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
21588 },
21589
21590 /* Format the given date for display. */
21591 _formatDate: function( inst, day, month, year ) {
21592 if ( !day ) {
21593 inst.currentDay = inst.selectedDay;
21594 inst.currentMonth = inst.selectedMonth;
21595 inst.currentYear = inst.selectedYear;
21596 }
21597 var date = ( day ? ( typeof day === "object" ? day :
21598 this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
21599 this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
21600 return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
21601 }
21602} );
21603
21604/*
21605 * Bind hover events for datepicker elements.
21606 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
21607 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
21608 */
21609function datepicker_bindHover( dpDiv ) {
21610 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
21611 return dpDiv.on( "mouseout", selector, function() {
21612 $( this ).removeClass( "ui-state-hover" );
21613 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
21614 $( this ).removeClass( "ui-datepicker-prev-hover" );
21615 }
21616 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
21617 $( this ).removeClass( "ui-datepicker-next-hover" );
21618 }
21619 } )
21620 .on( "mouseover", selector, datepicker_handleMouseover );
21621}
21622
21623function datepicker_handleMouseover() {
21624 if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
21625 $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
21626 $( this ).addClass( "ui-state-hover" );
21627 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
21628 $( this ).addClass( "ui-datepicker-prev-hover" );
21629 }
21630 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
21631 $( this ).addClass( "ui-datepicker-next-hover" );
21632 }
21633 }
21634}
21635
21636/* jQuery extend now ignores nulls! */
21637function datepicker_extendRemove( target, props ) {
21638 $.extend( target, props );
21639 for ( var name in props ) {
21640 if ( props[ name ] == null ) {
21641 target[ name ] = props[ name ];
21642 }
21643 }
21644 return target;
21645}
21646
21647/* Invoke the datepicker functionality.
21648 @param options string - a command, optionally followed by additional parameters or
21649 Object - settings for attaching new datepicker functionality
21650 @return jQuery object */
21651$.fn.datepicker = function( options ) {
21652
21653 /* Verify an empty collection wasn't passed - Fixes #6976 */
21654 if ( !this.length ) {
21655 return this;
21656 }
21657
21658 /* Initialise the date picker. */
21659 if ( !$.datepicker.initialized ) {
21660 $( document ).on( "mousedown", $.datepicker._checkExternalClick );
21661 $.datepicker.initialized = true;
21662 }
21663
21664 /* Append datepicker main container to body if not exist. */
21665 if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
21666 $( "body" ).append( $.datepicker.dpDiv );
21667 }
21668
21669 var otherArgs = Array.prototype.slice.call( arguments, 1 );
21670 if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
21671 return $.datepicker[ "_" + options + "Datepicker" ].
21672 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
21673 }
21674 if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
21675 return $.datepicker[ "_" + options + "Datepicker" ].
21676 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
21677 }
21678 return this.each( function() {
21679 if ( typeof options === "string" ) {
21680 $.datepicker[ "_" + options + "Datepicker" ]
21681 .apply( $.datepicker, [ this ].concat( otherArgs ) );
21682 } else {
21683 $.datepicker._attachDatepicker( this, options );
21684 }
21685 } );
21686};
21687
21688$.datepicker = new Datepicker(); // singleton instance
21689$.datepicker.initialized = false;
21690$.datepicker.uuid = new Date().getTime();
21691$.datepicker.version = "1.14.1";
21692
21693return $.datepicker;
21694
21695} );
21696
21697
21698
21699/*!
21700 * jQuery UI Mouse 1.14.1
21701 * https://jqueryui.com
21702 *
21703 * Copyright OpenJS Foundation and other contributors
21704 * Released under the MIT license.
21705 * https://jquery.org/license
21706 */
21707
21708//>>label: Mouse
21709//>>group: Widgets
21710//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
21711//>>docs: https://api.jqueryui.com/mouse/
21712
21713( function( factory ) {
21714 "use strict";
21715
21716 if ( typeof define === "function" && define.amd ) {
21717
21718 // AMD. Register as an anonymous module.
21719 define( [
21720 "jquery",
21721 "../version",
21722 "../widget"
21723 ], factory );
21724 } else {
21725
21726 // Browser globals
21727 factory( jQuery );
21728 }
21729} )( function( $ ) {
21730"use strict";
21731
21732var mouseHandled = false;
21733$( document ).on( "mouseup", function() {
21734 mouseHandled = false;
21735} );
21736
21737return $.widget( "ui.mouse", {
21738 version: "1.14.1",
21739 options: {
21740 cancel: "input, textarea, button, select, option",
21741 distance: 1,
21742 delay: 0
21743 },
21744 _mouseInit: function() {
21745 var that = this;
21746
21747 this.element
21748 .on( "mousedown." + this.widgetName, function( event ) {
21749 return that._mouseDown( event );
21750 } )
21751 .on( "click." + this.widgetName, function( event ) {
21752 if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
21753 $.removeData( event.target, that.widgetName + ".preventClickEvent" );
21754 event.stopImmediatePropagation();
21755 return false;
21756 }
21757 } );
21758
21759 this.started = false;
21760 },
21761
21762 // TODO: make sure destroying one instance of mouse doesn't mess with
21763 // other instances of mouse
21764 _mouseDestroy: function() {
21765 this.element.off( "." + this.widgetName );
21766 if ( this._mouseMoveDelegate ) {
21767 this.document
21768 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
21769 .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
21770 }
21771 },
21772
21773 _mouseDown: function( event ) {
21774
21775 // don't let more than one widget handle mouseStart
21776 if ( mouseHandled ) {
21777 return;
21778 }
21779
21780 this._mouseMoved = false;
21781
21782 // We may have missed mouseup (out of window)
21783 if ( this._mouseStarted ) {
21784 this._mouseUp( event );
21785 }
21786
21787 this._mouseDownEvent = event;
21788
21789 var that = this,
21790 btnIsLeft = event.which === 1,
21791 elIsCancel = typeof this.options.cancel === "string" ?
21792 $( event.target ).closest( this.options.cancel ).length :
21793 false;
21794 if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
21795 return true;
21796 }
21797
21798 this.mouseDelayMet = !this.options.delay;
21799 if ( !this.mouseDelayMet ) {
21800 this._mouseDelayTimer = setTimeout( function() {
21801 that.mouseDelayMet = true;
21802 }, this.options.delay );
21803 }
21804
21805 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
21806 this._mouseStarted = ( this._mouseStart( event ) !== false );
21807 if ( !this._mouseStarted ) {
21808 event.preventDefault();
21809 return true;
21810 }
21811 }
21812
21813 // Click event may never have fired (Gecko & Opera)
21814 if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
21815 $.removeData( event.target, this.widgetName + ".preventClickEvent" );
21816 }
21817
21818 // These delegates are required to keep context
21819 this._mouseMoveDelegate = function( event ) {
21820 return that._mouseMove( event );
21821 };
21822 this._mouseUpDelegate = function( event ) {
21823 return that._mouseUp( event );
21824 };
21825
21826 this.document
21827 .on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
21828 .on( "mouseup." + this.widgetName, this._mouseUpDelegate );
21829
21830 event.preventDefault();
21831
21832 mouseHandled = true;
21833 return true;
21834 },
21835
21836 _mouseMove: function( event ) {
21837
21838 // Only check for mouseups outside the document if you've moved inside the document
21839 // at least once.
21840 if ( this._mouseMoved && !event.which ) {
21841
21842 // Support: Safari <=8 - 9
21843 // Safari sets which to 0 if you press any of the following keys
21844 // during a drag (#14461)
21845 if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
21846 event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
21847 this.ignoreMissingWhich = true;
21848 } else if ( !this.ignoreMissingWhich ) {
21849 return this._mouseUp( event );
21850 }
21851 }
21852
21853 if ( event.which || event.button ) {
21854 this._mouseMoved = true;
21855 }
21856
21857 if ( this._mouseStarted ) {
21858 this._mouseDrag( event );
21859 return event.preventDefault();
21860 }
21861
21862 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
21863 this._mouseStarted =
21864 ( this._mouseStart( this._mouseDownEvent, event ) !== false );
21865 if ( this._mouseStarted ) {
21866 this._mouseDrag( event );
21867 } else {
21868 this._mouseUp( event );
21869 }
21870 }
21871
21872 return !this._mouseStarted;
21873 },
21874
21875 _mouseUp: function( event ) {
21876 this.document
21877 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
21878 .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
21879
21880 if ( this._mouseStarted ) {
21881 this._mouseStarted = false;
21882
21883 if ( event.target === this._mouseDownEvent.target ) {
21884 $.data( event.target, this.widgetName + ".preventClickEvent", true );
21885 }
21886
21887 this._mouseStop( event );
21888 }
21889
21890 if ( this._mouseDelayTimer ) {
21891 clearTimeout( this._mouseDelayTimer );
21892 delete this._mouseDelayTimer;
21893 }
21894
21895 this.ignoreMissingWhich = false;
21896 mouseHandled = false;
21897 event.preventDefault();
21898 },
21899
21900 _mouseDistanceMet: function( event ) {
21901 return ( Math.max(
21902 Math.abs( this._mouseDownEvent.pageX - event.pageX ),
21903 Math.abs( this._mouseDownEvent.pageY - event.pageY )
21904 ) >= this.options.distance
21905 );
21906 },
21907
21908 _mouseDelayMet: function( /* event */ ) {
21909 return this.mouseDelayMet;
21910 },
21911
21912 // These are placeholder methods, to be overriden by extending plugin
21913 _mouseStart: function( /* event */ ) {},
21914 _mouseDrag: function( /* event */ ) {},
21915 _mouseStop: function( /* event */ ) {},
21916 _mouseCapture: function( /* event */ ) {
21917 return true;
21918 }
21919} );
21920
21921} );
21922
21923
21924
21925
21926
21927
21928
21929/*!
21930 * jQuery UI Draggable 1.14.1
21931 * https://jqueryui.com
21932 *
21933 * Copyright OpenJS Foundation and other contributors
21934 * Released under the MIT license.
21935 * https://jquery.org/license
21936 */
21937
21938//>>label: Draggable
21939//>>group: Interactions
21940//>>description: Enables dragging functionality for any element.
21941//>>docs: https://api.jqueryui.com/draggable/
21942//>>demos: https://jqueryui.com/draggable/
21943//>>css.structure: ../../themes/base/draggable.css
21944
21945( function( factory ) {
21946 "use strict";
21947
21948 if ( typeof define === "function" && define.amd ) {
21949
21950 // AMD. Register as an anonymous module.
21951 define( [
21952 "jquery",
21953 "./mouse",
21954 "../data",
21955 "../plugin",
21956 "../scroll-parent",
21957 "../version",
21958 "../widget"
21959 ], factory );
21960 } else {
21961
21962 // Browser globals
21963 factory( jQuery );
21964 }
21965} )( function( $ ) {
21966"use strict";
21967
21968$.widget( "ui.draggable", $.ui.mouse, {
21969 version: "1.14.1",
21970 widgetEventPrefix: "drag",
21971 options: {
21972 addClasses: true,
21973 appendTo: "parent",
21974 axis: false,
21975 connectToSortable: false,
21976 containment: false,
21977 cursor: "auto",
21978 cursorAt: false,
21979 grid: false,
21980 handle: false,
21981 helper: "original",
21982 iframeFix: false,
21983 opacity: false,
21984 refreshPositions: false,
21985 revert: false,
21986 revertDuration: 500,
21987 scope: "default",
21988 scroll: true,
21989 scrollSensitivity: 20,
21990 scrollSpeed: 20,
21991 snap: false,
21992 snapMode: "both",
21993 snapTolerance: 20,
21994 stack: false,
21995 zIndex: false,
21996
21997 // Callbacks
21998 drag: null,
21999 start: null,
22000 stop: null
22001 },
22002 _create: function() {
22003
22004 if ( this.options.helper === "original" ) {
22005 this._setPositionRelative();
22006 }
22007 if ( this.options.addClasses ) {
22008 this._addClass( "ui-draggable" );
22009 }
22010 this._setHandleClassName();
22011
22012 this._mouseInit();
22013 },
22014
22015 _setOption: function( key, value ) {
22016 this._super( key, value );
22017 if ( key === "handle" ) {
22018 this._removeHandleClassName();
22019 this._setHandleClassName();
22020 }
22021 },
22022
22023 _destroy: function() {
22024 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
22025 this.destroyOnClear = true;
22026 return;
22027 }
22028 this._removeHandleClassName();
22029 this._mouseDestroy();
22030 },
22031
22032 _mouseCapture: function( event ) {
22033 var o = this.options;
22034
22035 // Among others, prevent a drag on a resizable-handle
22036 if ( this.helper || o.disabled ||
22037 $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
22038 return false;
22039 }
22040
22041 //Quit if we're not on a valid handle
22042 this.handle = this._getHandle( event );
22043 if ( !this.handle ) {
22044 return false;
22045 }
22046
22047 this._blurActiveElement( event );
22048
22049 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
22050
22051 return true;
22052
22053 },
22054
22055 _blockFrames: function( selector ) {
22056 this.iframeBlocks = this.document.find( selector ).map( function() {
22057 var iframe = $( this );
22058
22059 return $( "<div>" )
22060 .css( "position", "absolute" )
22061 .appendTo( iframe.parent() )
22062 .outerWidth( iframe.outerWidth() )
22063 .outerHeight( iframe.outerHeight() )
22064 .offset( iframe.offset() )[ 0 ];
22065 } );
22066 },
22067
22068 _unblockFrames: function() {
22069 if ( this.iframeBlocks ) {
22070 this.iframeBlocks.remove();
22071 delete this.iframeBlocks;
22072 }
22073 },
22074
22075 _blurActiveElement: function( event ) {
22076 var activeElement = this.document[ 0 ].activeElement,
22077 target = $( event.target );
22078
22079 // Don't blur if the event occurred on an element that is within
22080 // the currently focused element
22081 // See #10527, #12472
22082 if ( target.closest( activeElement ).length ) {
22083 return;
22084 }
22085
22086 // Blur any element that currently has focus, see #4261
22087 $( activeElement ).trigger( "blur" );
22088 },
22089
22090 _mouseStart: function( event ) {
22091
22092 var o = this.options;
22093
22094 //Create and append the visible helper
22095 this.helper = this._createHelper( event );
22096
22097 this._addClass( this.helper, "ui-draggable-dragging" );
22098
22099 //Cache the helper size
22100 this._cacheHelperProportions();
22101
22102 //If ddmanager is used for droppables, set the global draggable
22103 if ( $.ui.ddmanager ) {
22104 $.ui.ddmanager.current = this;
22105 }
22106
22107 /*
22108 * - Position generation -
22109 * This block generates everything position related - it's the core of draggables.
22110 */
22111
22112 //Cache the margins of the original element
22113 this._cacheMargins();
22114
22115 //Store the helper's css position
22116 this.cssPosition = this.helper.css( "position" );
22117 this.scrollParent = this.helper.scrollParent( true );
22118 this.offsetParent = this.helper.offsetParent();
22119 this.hasFixedAncestor = this.helper.parents().filter( function() {
22120 return $( this ).css( "position" ) === "fixed";
22121 } ).length > 0;
22122
22123 //The element's absolute position on the page minus margins
22124 this.positionAbs = this.element.offset();
22125 this._refreshOffsets( event );
22126
22127 //Generate the original position
22128 this.originalPosition = this.position = this._generatePosition( event, false );
22129 this.originalPageX = event.pageX;
22130 this.originalPageY = event.pageY;
22131
22132 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
22133 if ( o.cursorAt ) {
22134 this._adjustOffsetFromHelper( o.cursorAt );
22135 }
22136
22137 //Set a containment if given in the options
22138 this._setContainment();
22139
22140 //Trigger event + callbacks
22141 if ( this._trigger( "start", event ) === false ) {
22142 this._clear();
22143 return false;
22144 }
22145
22146 //Recache the helper size
22147 this._cacheHelperProportions();
22148
22149 //Prepare the droppable offsets
22150 if ( $.ui.ddmanager && !o.dropBehaviour ) {
22151 $.ui.ddmanager.prepareOffsets( this, event );
22152 }
22153
22154 // Execute the drag once - this causes the helper not to be visible before getting its
22155 // correct position
22156 this._mouseDrag( event, true );
22157
22158 // If the ddmanager is used for droppables, inform the manager that dragging has started
22159 // (see #5003)
22160 if ( $.ui.ddmanager ) {
22161 $.ui.ddmanager.dragStart( this, event );
22162 }
22163
22164 return true;
22165 },
22166
22167 _refreshOffsets: function( event ) {
22168 this.offset = {
22169 top: this.positionAbs.top - this.margins.top,
22170 left: this.positionAbs.left - this.margins.left,
22171 scroll: false,
22172 parent: this._getParentOffset(),
22173 relative: this._getRelativeOffset()
22174 };
22175
22176 this.offset.click = {
22177 left: event.pageX - this.offset.left,
22178 top: event.pageY - this.offset.top
22179 };
22180 },
22181
22182 _mouseDrag: function( event, noPropagation ) {
22183
22184 // reset any necessary cached properties (see #5009)
22185 if ( this.hasFixedAncestor ) {
22186 this.offset.parent = this._getParentOffset();
22187 }
22188
22189 //Compute the helpers position
22190 this.position = this._generatePosition( event, true );
22191 this.positionAbs = this._convertPositionTo( "absolute" );
22192
22193 //Call plugins and callbacks and use the resulting position if something is returned
22194 if ( !noPropagation ) {
22195 var ui = this._uiHash();
22196 if ( this._trigger( "drag", event, ui ) === false ) {
22197 this._mouseUp( new $.Event( "mouseup", event ) );
22198 return false;
22199 }
22200 this.position = ui.position;
22201 }
22202
22203 this.helper[ 0 ].style.left = this.position.left + "px";
22204 this.helper[ 0 ].style.top = this.position.top + "px";
22205
22206 if ( $.ui.ddmanager ) {
22207 $.ui.ddmanager.drag( this, event );
22208 }
22209
22210 return false;
22211 },
22212
22213 _mouseStop: function( event ) {
22214
22215 //If we are using droppables, inform the manager about the drop
22216 var that = this,
22217 dropped = false;
22218 if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
22219 dropped = $.ui.ddmanager.drop( this, event );
22220 }
22221
22222 //if a drop comes from outside (a sortable)
22223 if ( this.dropped ) {
22224 dropped = this.dropped;
22225 this.dropped = false;
22226 }
22227
22228 if ( ( this.options.revert === "invalid" && !dropped ) ||
22229 ( this.options.revert === "valid" && dropped ) ||
22230 this.options.revert === true || ( typeof this.options.revert === "function" &&
22231 this.options.revert.call( this.element, dropped ) )
22232 ) {
22233 $( this.helper ).animate(
22234 this.originalPosition,
22235 parseInt( this.options.revertDuration, 10 ),
22236 function() {
22237 if ( that._trigger( "stop", event ) !== false ) {
22238 that._clear();
22239 }
22240 }
22241 );
22242 } else {
22243 if ( this._trigger( "stop", event ) !== false ) {
22244 this._clear();
22245 }
22246 }
22247
22248 return false;
22249 },
22250
22251 _mouseUp: function( event ) {
22252 this._unblockFrames();
22253
22254 // If the ddmanager is used for droppables, inform the manager that dragging has stopped
22255 // (see #5003)
22256 if ( $.ui.ddmanager ) {
22257 $.ui.ddmanager.dragStop( this, event );
22258 }
22259
22260 // Only need to focus if the event occurred on the draggable itself, see #10527
22261 if ( this.handleElement.is( event.target ) ) {
22262
22263 // The interaction is over; whether or not the click resulted in a drag,
22264 // focus the element
22265 this.element.trigger( "focus" );
22266 }
22267
22268 return $.ui.mouse.prototype._mouseUp.call( this, event );
22269 },
22270
22271 cancel: function() {
22272
22273 if ( this.helper.is( ".ui-draggable-dragging" ) ) {
22274 this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
22275 } else {
22276 this._clear();
22277 }
22278
22279 return this;
22280
22281 },
22282
22283 _getHandle: function( event ) {
22284 return this.options.handle ?
22285 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
22286 true;
22287 },
22288
22289 _setHandleClassName: function() {
22290 this.handleElement = this.options.handle ?
22291 this.element.find( this.options.handle ) : this.element;
22292 this._addClass( this.handleElement, "ui-draggable-handle" );
22293 },
22294
22295 _removeHandleClassName: function() {
22296 this._removeClass( this.handleElement, "ui-draggable-handle" );
22297 },
22298
22299 _createHelper: function( event ) {
22300
22301 var o = this.options,
22302 helperIsFunction = typeof o.helper === "function",
22303 helper = helperIsFunction ?
22304 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
22305 ( o.helper === "clone" ?
22306 this.element.clone().removeAttr( "id" ) :
22307 this.element );
22308
22309 if ( !helper.parents( "body" ).length ) {
22310 helper.appendTo( ( o.appendTo === "parent" ?
22311 this.element[ 0 ].parentNode :
22312 o.appendTo ) );
22313 }
22314
22315 // https://bugs.jqueryui.com/ticket/9446
22316 // a helper function can return the original element
22317 // which wouldn't have been set to relative in _create
22318 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
22319 this._setPositionRelative();
22320 }
22321
22322 if ( helper[ 0 ] !== this.element[ 0 ] &&
22323 !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
22324 helper.css( "position", "absolute" );
22325 }
22326
22327 return helper;
22328
22329 },
22330
22331 _setPositionRelative: function() {
22332 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
22333 this.element[ 0 ].style.position = "relative";
22334 }
22335 },
22336
22337 _adjustOffsetFromHelper: function( obj ) {
22338 if ( typeof obj === "string" ) {
22339 obj = obj.split( " " );
22340 }
22341 if ( Array.isArray( obj ) ) {
22342 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
22343 }
22344 if ( "left" in obj ) {
22345 this.offset.click.left = obj.left + this.margins.left;
22346 }
22347 if ( "right" in obj ) {
22348 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
22349 }
22350 if ( "top" in obj ) {
22351 this.offset.click.top = obj.top + this.margins.top;
22352 }
22353 if ( "bottom" in obj ) {
22354 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
22355 }
22356 },
22357
22358 _isRootNode: function( element ) {
22359 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
22360 },
22361
22362 _getParentOffset: function() {
22363
22364 //Get the offsetParent and cache its position
22365 var po = this.offsetParent.offset(),
22366 document = this.document[ 0 ];
22367
22368 // This is a special case where we need to modify a offset calculated on start, since the
22369 // following happened:
22370 // 1. The position of the helper is absolute, so it's position is calculated based on the
22371 // next positioned parent
22372 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
22373 // the document, which means that the scroll is included in the initial calculation of the
22374 // offset of the parent, and never recalculated upon drag
22375 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
22376 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
22377 po.left += this.scrollParent.scrollLeft();
22378 po.top += this.scrollParent.scrollTop();
22379 }
22380
22381 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
22382 po = { top: 0, left: 0 };
22383 }
22384
22385 return {
22386 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
22387 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
22388 };
22389
22390 },
22391
22392 _getRelativeOffset: function() {
22393 if ( this.cssPosition !== "relative" ) {
22394 return { top: 0, left: 0 };
22395 }
22396
22397 var p = this.element.position(),
22398 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
22399
22400 return {
22401 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
22402 ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
22403 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
22404 ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
22405 };
22406
22407 },
22408
22409 _cacheMargins: function() {
22410 this.margins = {
22411 left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
22412 top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
22413 right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
22414 bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
22415 };
22416 },
22417
22418 _cacheHelperProportions: function() {
22419 this.helperProportions = {
22420 width: this.helper.outerWidth(),
22421 height: this.helper.outerHeight()
22422 };
22423 },
22424
22425 _setContainment: function() {
22426
22427 var isUserScrollable, c, ce,
22428 o = this.options,
22429 document = this.document[ 0 ];
22430
22431 this.relativeContainer = null;
22432
22433 if ( !o.containment ) {
22434 this.containment = null;
22435 return;
22436 }
22437
22438 if ( o.containment === "window" ) {
22439 this.containment = [
22440 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
22441 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
22442 $( window ).scrollLeft() + $( window ).width() -
22443 this.helperProportions.width - this.margins.left,
22444 $( window ).scrollTop() +
22445 ( $( window ).height() || document.body.parentNode.scrollHeight ) -
22446 this.helperProportions.height - this.margins.top
22447 ];
22448 return;
22449 }
22450
22451 if ( o.containment === "document" ) {
22452 this.containment = [
22453 0,
22454 0,
22455 $( document ).width() - this.helperProportions.width - this.margins.left,
22456 ( $( document ).height() || document.body.parentNode.scrollHeight ) -
22457 this.helperProportions.height - this.margins.top
22458 ];
22459 return;
22460 }
22461
22462 if ( o.containment.constructor === Array ) {
22463 this.containment = o.containment;
22464 return;
22465 }
22466
22467 if ( o.containment === "parent" ) {
22468 o.containment = this.helper[ 0 ].parentNode;
22469 }
22470
22471 c = $( o.containment );
22472 ce = c[ 0 ];
22473
22474 if ( !ce ) {
22475 return;
22476 }
22477
22478 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
22479
22480 this.containment = [
22481 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
22482 ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
22483 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
22484 ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
22485 ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
22486 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
22487 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
22488 this.helperProportions.width -
22489 this.margins.left -
22490 this.margins.right,
22491 ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
22492 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
22493 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
22494 this.helperProportions.height -
22495 this.margins.top -
22496 this.margins.bottom
22497 ];
22498 this.relativeContainer = c;
22499 },
22500
22501 _convertPositionTo: function( d, pos ) {
22502
22503 if ( !pos ) {
22504 pos = this.position;
22505 }
22506
22507 var mod = d === "absolute" ? 1 : -1,
22508 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
22509
22510 return {
22511 top: (
22512
22513 // The absolute mouse position
22514 pos.top +
22515
22516 // Only for relative positioned nodes: Relative offset from element to offset parent
22517 this.offset.relative.top * mod +
22518
22519 // The offsetParent's offset without borders (offset + border)
22520 this.offset.parent.top * mod -
22521 ( ( this.cssPosition === "fixed" ?
22522 -this.offset.scroll.top :
22523 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
22524 ),
22525 left: (
22526
22527 // The absolute mouse position
22528 pos.left +
22529
22530 // Only for relative positioned nodes: Relative offset from element to offset parent
22531 this.offset.relative.left * mod +
22532
22533 // The offsetParent's offset without borders (offset + border)
22534 this.offset.parent.left * mod -
22535 ( ( this.cssPosition === "fixed" ?
22536 -this.offset.scroll.left :
22537 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
22538 )
22539 };
22540
22541 },
22542
22543 _generatePosition: function( event, constrainPosition ) {
22544
22545 var containment, co, top, left,
22546 o = this.options,
22547 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
22548 pageX = event.pageX,
22549 pageY = event.pageY;
22550
22551 // Cache the scroll
22552 if ( !scrollIsRootNode || !this.offset.scroll ) {
22553 this.offset.scroll = {
22554 top: this.scrollParent.scrollTop(),
22555 left: this.scrollParent.scrollLeft()
22556 };
22557 }
22558
22559 /*
22560 * - Position constraining -
22561 * Constrain the position to a mix of grid, containment.
22562 */
22563
22564 // If we are not dragging yet, we won't check for options
22565 if ( constrainPosition ) {
22566 if ( this.containment ) {
22567 if ( this.relativeContainer ) {
22568 co = this.relativeContainer.offset();
22569 containment = [
22570 this.containment[ 0 ] + co.left,
22571 this.containment[ 1 ] + co.top,
22572 this.containment[ 2 ] + co.left,
22573 this.containment[ 3 ] + co.top
22574 ];
22575 } else {
22576 containment = this.containment;
22577 }
22578
22579 if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
22580 pageX = containment[ 0 ] + this.offset.click.left;
22581 }
22582 if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
22583 pageY = containment[ 1 ] + this.offset.click.top;
22584 }
22585 if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
22586 pageX = containment[ 2 ] + this.offset.click.left;
22587 }
22588 if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
22589 pageY = containment[ 3 ] + this.offset.click.top;
22590 }
22591 }
22592
22593 if ( o.grid ) {
22594
22595 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid
22596 // argument errors in IE (see ticket #6950)
22597 top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
22598 this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
22599 pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
22600 top - this.offset.click.top > containment[ 3 ] ) ?
22601 top :
22602 ( ( top - this.offset.click.top >= containment[ 1 ] ) ?
22603 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
22604
22605 left = o.grid[ 0 ] ? this.originalPageX +
22606 Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
22607 this.originalPageX;
22608 pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
22609 left - this.offset.click.left > containment[ 2 ] ) ?
22610 left :
22611 ( ( left - this.offset.click.left >= containment[ 0 ] ) ?
22612 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
22613 }
22614
22615 if ( o.axis === "y" ) {
22616 pageX = this.originalPageX;
22617 }
22618
22619 if ( o.axis === "x" ) {
22620 pageY = this.originalPageY;
22621 }
22622 }
22623
22624 return {
22625 top: (
22626
22627 // The absolute mouse position
22628 pageY -
22629
22630 // Click offset (relative to the element)
22631 this.offset.click.top -
22632
22633 // Only for relative positioned nodes: Relative offset from element to offset parent
22634 this.offset.relative.top -
22635
22636 // The offsetParent's offset without borders (offset + border)
22637 this.offset.parent.top +
22638 ( this.cssPosition === "fixed" ?
22639 -this.offset.scroll.top :
22640 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
22641 ),
22642 left: (
22643
22644 // The absolute mouse position
22645 pageX -
22646
22647 // Click offset (relative to the element)
22648 this.offset.click.left -
22649
22650 // Only for relative positioned nodes: Relative offset from element to offset parent
22651 this.offset.relative.left -
22652
22653 // The offsetParent's offset without borders (offset + border)
22654 this.offset.parent.left +
22655 ( this.cssPosition === "fixed" ?
22656 -this.offset.scroll.left :
22657 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
22658 )
22659 };
22660
22661 },
22662
22663 _clear: function() {
22664 this._removeClass( this.helper, "ui-draggable-dragging" );
22665 if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
22666 this.helper.remove();
22667 }
22668 this.helper = null;
22669 this.cancelHelperRemoval = false;
22670 if ( this.destroyOnClear ) {
22671 this.destroy();
22672 }
22673 },
22674
22675 // From now on bulk stuff - mainly helpers
22676
22677 _trigger: function( type, event, ui ) {
22678 ui = ui || this._uiHash();
22679 $.ui.plugin.call( this, type, [ event, ui, this ], true );
22680
22681 // Absolute position and offset (see #6884 ) have to be recalculated after plugins
22682 if ( /^(drag|start|stop)/.test( type ) ) {
22683 this.positionAbs = this._convertPositionTo( "absolute" );
22684 ui.offset = this.positionAbs;
22685 }
22686 return $.Widget.prototype._trigger.call( this, type, event, ui );
22687 },
22688
22689 plugins: {},
22690
22691 _uiHash: function() {
22692 return {
22693 helper: this.helper,
22694 position: this.position,
22695 originalPosition: this.originalPosition,
22696 offset: this.positionAbs
22697 };
22698 }
22699
22700} );
22701
22702$.ui.plugin.add( "draggable", "connectToSortable", {
22703 start: function( event, ui, draggable ) {
22704 var uiSortable = $.extend( {}, ui, {
22705 item: draggable.element
22706 } );
22707
22708 draggable.sortables = [];
22709 $( draggable.options.connectToSortable ).each( function() {
22710 var sortable = $( this ).sortable( "instance" );
22711
22712 if ( sortable && !sortable.options.disabled ) {
22713 draggable.sortables.push( sortable );
22714
22715 // RefreshPositions is called at drag start to refresh the containerCache
22716 // which is used in drag. This ensures it's initialized and synchronized
22717 // with any changes that might have happened on the page since initialization.
22718 sortable.refreshPositions();
22719 sortable._trigger( "activate", event, uiSortable );
22720 }
22721 } );
22722 },
22723 stop: function( event, ui, draggable ) {
22724 var uiSortable = $.extend( {}, ui, {
22725 item: draggable.element
22726 } );
22727
22728 draggable.cancelHelperRemoval = false;
22729
22730 $.each( draggable.sortables, function() {
22731 var sortable = this;
22732
22733 if ( sortable.isOver ) {
22734 sortable.isOver = 0;
22735
22736 // Allow this sortable to handle removing the helper
22737 draggable.cancelHelperRemoval = true;
22738 sortable.cancelHelperRemoval = false;
22739
22740 // Use _storedCSS To restore properties in the sortable,
22741 // as this also handles revert (#9675) since the draggable
22742 // may have modified them in unexpected ways (#8809)
22743 sortable._storedCSS = {
22744 position: sortable.placeholder.css( "position" ),
22745 top: sortable.placeholder.css( "top" ),
22746 left: sortable.placeholder.css( "left" )
22747 };
22748
22749 sortable._mouseStop( event );
22750
22751 // Once drag has ended, the sortable should return to using
22752 // its original helper, not the shared helper from draggable
22753 sortable.options.helper = sortable.options._helper;
22754 } else {
22755
22756 // Prevent this Sortable from removing the helper.
22757 // However, don't set the draggable to remove the helper
22758 // either as another connected Sortable may yet handle the removal.
22759 sortable.cancelHelperRemoval = true;
22760
22761 sortable._trigger( "deactivate", event, uiSortable );
22762 }
22763 } );
22764 },
22765 drag: function( event, ui, draggable ) {
22766 $.each( draggable.sortables, function() {
22767 var innermostIntersecting = false,
22768 sortable = this;
22769
22770 // Copy over variables that sortable's _intersectsWith uses
22771 sortable.positionAbs = draggable.positionAbs;
22772 sortable.helperProportions = draggable.helperProportions;
22773 sortable.offset.click = draggable.offset.click;
22774
22775 if ( sortable._intersectsWith( sortable.containerCache ) ) {
22776 innermostIntersecting = true;
22777
22778 $.each( draggable.sortables, function() {
22779
22780 // Copy over variables that sortable's _intersectsWith uses
22781 this.positionAbs = draggable.positionAbs;
22782 this.helperProportions = draggable.helperProportions;
22783 this.offset.click = draggable.offset.click;
22784
22785 if ( this !== sortable &&
22786 this._intersectsWith( this.containerCache ) &&
22787 $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
22788 innermostIntersecting = false;
22789 }
22790
22791 return innermostIntersecting;
22792 } );
22793 }
22794
22795 if ( innermostIntersecting ) {
22796
22797 // If it intersects, we use a little isOver variable and set it once,
22798 // so that the move-in stuff gets fired only once.
22799 if ( !sortable.isOver ) {
22800 sortable.isOver = 1;
22801
22802 // Store draggable's parent in case we need to reappend to it later.
22803 draggable._parent = ui.helper.parent();
22804
22805 sortable.currentItem = ui.helper
22806 .appendTo( sortable.element )
22807 .data( "ui-sortable-item", true );
22808
22809 // Store helper option to later restore it
22810 sortable.options._helper = sortable.options.helper;
22811
22812 sortable.options.helper = function() {
22813 return ui.helper[ 0 ];
22814 };
22815
22816 // Fire the start events of the sortable with our passed browser event,
22817 // and our own helper (so it doesn't create a new one)
22818 event.target = sortable.currentItem[ 0 ];
22819 sortable._mouseCapture( event, true );
22820 sortable._mouseStart( event, true, true );
22821
22822 // Because the browser event is way off the new appended portlet,
22823 // modify necessary variables to reflect the changes
22824 sortable.offset.click.top = draggable.offset.click.top;
22825 sortable.offset.click.left = draggable.offset.click.left;
22826 sortable.offset.parent.left -= draggable.offset.parent.left -
22827 sortable.offset.parent.left;
22828 sortable.offset.parent.top -= draggable.offset.parent.top -
22829 sortable.offset.parent.top;
22830
22831 draggable._trigger( "toSortable", event );
22832
22833 // Inform draggable that the helper is in a valid drop zone,
22834 // used solely in the revert option to handle "valid/invalid".
22835 draggable.dropped = sortable.element;
22836
22837 // Need to refreshPositions of all sortables in the case that
22838 // adding to one sortable changes the location of the other sortables (#9675)
22839 $.each( draggable.sortables, function() {
22840 this.refreshPositions();
22841 } );
22842
22843 // Hack so receive/update callbacks work (mostly)
22844 draggable.currentItem = draggable.element;
22845 sortable.fromOutside = draggable;
22846 }
22847
22848 if ( sortable.currentItem ) {
22849 sortable._mouseDrag( event );
22850
22851 // Copy the sortable's position because the draggable's can potentially reflect
22852 // a relative position, while sortable is always absolute, which the dragged
22853 // element has now become. (#8809)
22854 ui.position = sortable.position;
22855 }
22856 } else {
22857
22858 // If it doesn't intersect with the sortable, and it intersected before,
22859 // we fake the drag stop of the sortable, but make sure it doesn't remove
22860 // the helper by using cancelHelperRemoval.
22861 if ( sortable.isOver ) {
22862
22863 sortable.isOver = 0;
22864 sortable.cancelHelperRemoval = true;
22865
22866 // Calling sortable's mouseStop would trigger a revert,
22867 // so revert must be temporarily false until after mouseStop is called.
22868 sortable.options._revert = sortable.options.revert;
22869 sortable.options.revert = false;
22870
22871 sortable._trigger( "out", event, sortable._uiHash( sortable ) );
22872 sortable._mouseStop( event, true );
22873
22874 // Restore sortable behaviors that were modfied
22875 // when the draggable entered the sortable area (#9481)
22876 sortable.options.revert = sortable.options._revert;
22877 sortable.options.helper = sortable.options._helper;
22878
22879 if ( sortable.placeholder ) {
22880 sortable.placeholder.remove();
22881 }
22882
22883 // Restore and recalculate the draggable's offset considering the sortable
22884 // may have modified them in unexpected ways. (#8809, #10669)
22885 ui.helper.appendTo( draggable._parent );
22886 draggable._refreshOffsets( event );
22887 ui.position = draggable._generatePosition( event, true );
22888
22889 draggable._trigger( "fromSortable", event );
22890
22891 // Inform draggable that the helper is no longer in a valid drop zone
22892 draggable.dropped = false;
22893
22894 // Need to refreshPositions of all sortables just in case removing
22895 // from one sortable changes the location of other sortables (#9675)
22896 $.each( draggable.sortables, function() {
22897 this.refreshPositions();
22898 } );
22899 }
22900 }
22901 } );
22902 }
22903} );
22904
22905$.ui.plugin.add( "draggable", "cursor", {
22906 start: function( event, ui, instance ) {
22907 var t = $( "body" ),
22908 o = instance.options;
22909
22910 if ( t.css( "cursor" ) ) {
22911 o._cursor = t.css( "cursor" );
22912 }
22913 t.css( "cursor", o.cursor );
22914 },
22915 stop: function( event, ui, instance ) {
22916 var o = instance.options;
22917 if ( o._cursor ) {
22918 $( "body" ).css( "cursor", o._cursor );
22919 }
22920 }
22921} );
22922
22923$.ui.plugin.add( "draggable", "opacity", {
22924 start: function( event, ui, instance ) {
22925 var t = $( ui.helper ),
22926 o = instance.options;
22927 if ( t.css( "opacity" ) ) {
22928 o._opacity = t.css( "opacity" );
22929 }
22930 t.css( "opacity", o.opacity );
22931 },
22932 stop: function( event, ui, instance ) {
22933 var o = instance.options;
22934 if ( o._opacity ) {
22935 $( ui.helper ).css( "opacity", o._opacity );
22936 }
22937 }
22938} );
22939
22940$.ui.plugin.add( "draggable", "scroll", {
22941 start: function( event, ui, i ) {
22942 if ( !i.scrollParentNotHidden ) {
22943 i.scrollParentNotHidden = i.helper.scrollParent( false );
22944 }
22945
22946 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
22947 i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
22948 i.overflowOffset = i.scrollParentNotHidden.offset();
22949 }
22950 },
22951 drag: function( event, ui, i ) {
22952
22953 var o = i.options,
22954 scrolled = false,
22955 scrollParent = i.scrollParentNotHidden[ 0 ],
22956 document = i.document[ 0 ];
22957
22958 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
22959 if ( !o.axis || o.axis !== "x" ) {
22960 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
22961 o.scrollSensitivity ) {
22962 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
22963 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
22964 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
22965 }
22966 }
22967
22968 if ( !o.axis || o.axis !== "y" ) {
22969 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
22970 o.scrollSensitivity ) {
22971 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
22972 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
22973 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
22974 }
22975 }
22976
22977 } else {
22978
22979 if ( !o.axis || o.axis !== "x" ) {
22980 if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
22981 scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
22982 } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
22983 o.scrollSensitivity ) {
22984 scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
22985 }
22986 }
22987
22988 if ( !o.axis || o.axis !== "y" ) {
22989 if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
22990 scrolled = $( document ).scrollLeft(
22991 $( document ).scrollLeft() - o.scrollSpeed
22992 );
22993 } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
22994 o.scrollSensitivity ) {
22995 scrolled = $( document ).scrollLeft(
22996 $( document ).scrollLeft() + o.scrollSpeed
22997 );
22998 }
22999 }
23000
23001 }
23002
23003 if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
23004 $.ui.ddmanager.prepareOffsets( i, event );
23005 }
23006
23007 }
23008} );
23009
23010$.ui.plugin.add( "draggable", "snap", {
23011 start: function( event, ui, i ) {
23012
23013 var o = i.options;
23014
23015 i.snapElements = [];
23016
23017 $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
23018 .each( function() {
23019 var $t = $( this ),
23020 $o = $t.offset();
23021 if ( this !== i.element[ 0 ] ) {
23022 i.snapElements.push( {
23023 item: this,
23024 width: $t.outerWidth(), height: $t.outerHeight(),
23025 top: $o.top, left: $o.left
23026 } );
23027 }
23028 } );
23029
23030 },
23031 drag: function( event, ui, inst ) {
23032
23033 var ts, bs, ls, rs, l, r, t, b, i, first,
23034 o = inst.options,
23035 d = o.snapTolerance,
23036 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
23037 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
23038
23039 for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
23040
23041 l = inst.snapElements[ i ].left - inst.margins.left;
23042 r = l + inst.snapElements[ i ].width;
23043 t = inst.snapElements[ i ].top - inst.margins.top;
23044 b = t + inst.snapElements[ i ].height;
23045
23046 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
23047 !$.contains( inst.snapElements[ i ].item.ownerDocument,
23048 inst.snapElements[ i ].item ) ) {
23049 if ( inst.snapElements[ i ].snapping ) {
23050 if ( inst.options.snap.release ) {
23051 inst.options.snap.release.call(
23052 inst.element,
23053 event,
23054 $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
23055 );
23056 }
23057 }
23058 inst.snapElements[ i ].snapping = false;
23059 continue;
23060 }
23061
23062 if ( o.snapMode !== "inner" ) {
23063 ts = Math.abs( t - y2 ) <= d;
23064 bs = Math.abs( b - y1 ) <= d;
23065 ls = Math.abs( l - x2 ) <= d;
23066 rs = Math.abs( r - x1 ) <= d;
23067 if ( ts ) {
23068 ui.position.top = inst._convertPositionTo( "relative", {
23069 top: t - inst.helperProportions.height,
23070 left: 0
23071 } ).top;
23072 }
23073 if ( bs ) {
23074 ui.position.top = inst._convertPositionTo( "relative", {
23075 top: b,
23076 left: 0
23077 } ).top;
23078 }
23079 if ( ls ) {
23080 ui.position.left = inst._convertPositionTo( "relative", {
23081 top: 0,
23082 left: l - inst.helperProportions.width
23083 } ).left;
23084 }
23085 if ( rs ) {
23086 ui.position.left = inst._convertPositionTo( "relative", {
23087 top: 0,
23088 left: r
23089 } ).left;
23090 }
23091 }
23092
23093 first = ( ts || bs || ls || rs );
23094
23095 if ( o.snapMode !== "outer" ) {
23096 ts = Math.abs( t - y1 ) <= d;
23097 bs = Math.abs( b - y2 ) <= d;
23098 ls = Math.abs( l - x1 ) <= d;
23099 rs = Math.abs( r - x2 ) <= d;
23100 if ( ts ) {
23101 ui.position.top = inst._convertPositionTo( "relative", {
23102 top: t,
23103 left: 0
23104 } ).top;
23105 }
23106 if ( bs ) {
23107 ui.position.top = inst._convertPositionTo( "relative", {
23108 top: b - inst.helperProportions.height,
23109 left: 0
23110 } ).top;
23111 }
23112 if ( ls ) {
23113 ui.position.left = inst._convertPositionTo( "relative", {
23114 top: 0,
23115 left: l
23116 } ).left;
23117 }
23118 if ( rs ) {
23119 ui.position.left = inst._convertPositionTo( "relative", {
23120 top: 0,
23121 left: r - inst.helperProportions.width
23122 } ).left;
23123 }
23124 }
23125
23126 if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
23127 if ( inst.options.snap.snap ) {
23128 inst.options.snap.snap.call(
23129 inst.element,
23130 event,
23131 $.extend( inst._uiHash(), {
23132 snapItem: inst.snapElements[ i ].item
23133 } ) );
23134 }
23135 }
23136 inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
23137
23138 }
23139
23140 }
23141} );
23142
23143$.ui.plugin.add( "draggable", "stack", {
23144 start: function( event, ui, instance ) {
23145 var min,
23146 o = instance.options,
23147 group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
23148 return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
23149 ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
23150 } );
23151
23152 if ( !group.length ) {
23153 return;
23154 }
23155
23156 min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
23157 $( group ).each( function( i ) {
23158 $( this ).css( "zIndex", min + i );
23159 } );
23160 this.css( "zIndex", ( min + group.length ) );
23161 }
23162} );
23163
23164$.ui.plugin.add( "draggable", "zIndex", {
23165 start: function( event, ui, instance ) {
23166 var t = $( ui.helper ),
23167 o = instance.options;
23168
23169 if ( t.css( "zIndex" ) ) {
23170 o._zIndex = t.css( "zIndex" );
23171 }
23172 t.css( "zIndex", o.zIndex );
23173 },
23174 stop: function( event, ui, instance ) {
23175 var o = instance.options;
23176
23177 if ( o._zIndex ) {
23178 $( ui.helper ).css( "zIndex", o._zIndex );
23179 }
23180 }
23181} );
23182
23183return $.ui.draggable;
23184
23185} );
23186
23187
23188
23189
23190
23191
23192/*!
23193 * jQuery UI Resizable 1.14.1
23194 * https://jqueryui.com
23195 *
23196 * Copyright OpenJS Foundation and other contributors
23197 * Released under the MIT license.
23198 * https://jquery.org/license
23199 */
23200
23201//>>label: Resizable
23202//>>group: Interactions
23203//>>description: Enables resize functionality for any element.
23204//>>docs: https://api.jqueryui.com/resizable/
23205//>>demos: https://jqueryui.com/resizable/
23206//>>css.structure: ../../themes/base/core.css
23207//>>css.structure: ../../themes/base/resizable.css
23208//>>css.theme: ../../themes/base/theme.css
23209
23210( function( factory ) {
23211 "use strict";
23212
23213 if ( typeof define === "function" && define.amd ) {
23214
23215 // AMD. Register as an anonymous module.
23216 define( [
23217 "jquery",
23218 "./mouse",
23219 "../disable-selection",
23220 "../plugin",
23221 "../version",
23222 "../widget"
23223 ], factory );
23224 } else {
23225
23226 // Browser globals
23227 factory( jQuery );
23228 }
23229} )( function( $ ) {
23230"use strict";
23231
23232$.widget( "ui.resizable", $.ui.mouse, {
23233 version: "1.14.1",
23234 widgetEventPrefix: "resize",
23235 options: {
23236 alsoResize: false,
23237 animate: false,
23238 animateDuration: "slow",
23239 animateEasing: "swing",
23240 aspectRatio: false,
23241 autoHide: false,
23242 classes: {
23243 "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
23244 },
23245 containment: false,
23246 ghost: false,
23247 grid: false,
23248 handles: "e,s,se",
23249 helper: false,
23250 maxHeight: null,
23251 maxWidth: null,
23252 minHeight: 10,
23253 minWidth: 10,
23254
23255 // See #7960
23256 zIndex: 90,
23257
23258 // Callbacks
23259 resize: null,
23260 start: null,
23261 stop: null
23262 },
23263
23264 _num: function( value ) {
23265 return parseFloat( value ) || 0;
23266 },
23267
23268 _isNumber: function( value ) {
23269 return !isNaN( parseFloat( value ) );
23270 },
23271
23272 _hasScroll: function( el, a ) {
23273
23274 var scroll,
23275 has = false,
23276 overflow = $( el ).css( "overflow" );
23277
23278 if ( overflow === "hidden" ) {
23279 return false;
23280 }
23281 if ( overflow === "scroll" ) {
23282 return true;
23283 }
23284
23285 scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop";
23286
23287 if ( el[ scroll ] > 0 ) {
23288 return true;
23289 }
23290
23291 // TODO: determine which cases actually cause this to happen
23292 // if the element doesn't have the scroll set, see if it's possible to
23293 // set the scroll
23294 try {
23295 el[ scroll ] = 1;
23296 has = ( el[ scroll ] > 0 );
23297 el[ scroll ] = 0;
23298 } catch ( e ) {
23299
23300 // `el` might be a string, then setting `scroll` will throw
23301 // an error in strict mode; ignore it.
23302 }
23303 return has;
23304 },
23305
23306 _create: function() {
23307
23308 var margins,
23309 o = this.options,
23310 that = this;
23311 this._addClass( "ui-resizable" );
23312
23313 $.extend( this, {
23314 _aspectRatio: !!( o.aspectRatio ),
23315 aspectRatio: o.aspectRatio,
23316 originalElement: this.element,
23317 _proportionallyResizeElements: [],
23318 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
23319 } );
23320
23321 // Wrap the element if it cannot hold child nodes
23322 if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
23323
23324 this.element.wrap(
23325 $( "<div class='ui-wrapper'></div>" ).css( {
23326 overflow: "hidden",
23327 position: this.element.css( "position" ),
23328 width: this.element.outerWidth(),
23329 height: this.element.outerHeight(),
23330 top: this.element.css( "top" ),
23331 left: this.element.css( "left" )
23332 } )
23333 );
23334
23335 this.element = this.element.parent().data(
23336 "ui-resizable", this.element.resizable( "instance" )
23337 );
23338
23339 this.elementIsWrapper = true;
23340
23341 margins = {
23342 marginTop: this.originalElement.css( "marginTop" ),
23343 marginRight: this.originalElement.css( "marginRight" ),
23344 marginBottom: this.originalElement.css( "marginBottom" ),
23345 marginLeft: this.originalElement.css( "marginLeft" )
23346 };
23347
23348 this.element.css( margins );
23349
23350 // Support: Safari
23351 // Prevent Safari textarea resize
23352 this.originalResizeStyle = this.originalElement.css( "resize" );
23353 this.originalElement.css( "resize", "none" );
23354
23355 this._proportionallyResizeElements.push( this.originalElement.css( {
23356 position: "static",
23357 zoom: 1,
23358 display: "block"
23359 } ) );
23360
23361 this._proportionallyResize();
23362 }
23363
23364 this._setupHandles();
23365
23366 if ( o.autoHide ) {
23367 $( this.element )
23368 .on( "mouseenter", function() {
23369 if ( o.disabled ) {
23370 return;
23371 }
23372 that._removeClass( "ui-resizable-autohide" );
23373 that._handles.show();
23374 } )
23375 .on( "mouseleave", function() {
23376 if ( o.disabled ) {
23377 return;
23378 }
23379 if ( !that.resizing ) {
23380 that._addClass( "ui-resizable-autohide" );
23381 that._handles.hide();
23382 }
23383 } );
23384 }
23385
23386 this._mouseInit();
23387 },
23388
23389 _destroy: function() {
23390
23391 this._mouseDestroy();
23392 this._addedHandles.remove();
23393
23394 var wrapper,
23395 _destroy = function( exp ) {
23396 $( exp )
23397 .removeData( "resizable" )
23398 .removeData( "ui-resizable" )
23399 .off( ".resizable" );
23400 };
23401
23402 // TODO: Unwrap at same DOM position
23403 if ( this.elementIsWrapper ) {
23404 _destroy( this.element );
23405 wrapper = this.element;
23406 this.originalElement.css( {
23407 position: wrapper.css( "position" ),
23408 width: wrapper.outerWidth(),
23409 height: wrapper.outerHeight(),
23410 top: wrapper.css( "top" ),
23411 left: wrapper.css( "left" )
23412 } ).insertAfter( wrapper );
23413 wrapper.remove();
23414 }
23415
23416 this.originalElement.css( "resize", this.originalResizeStyle );
23417 _destroy( this.originalElement );
23418
23419 return this;
23420 },
23421
23422 _setOption: function( key, value ) {
23423 this._super( key, value );
23424
23425 switch ( key ) {
23426 case "handles":
23427 this._removeHandles();
23428 this._setupHandles();
23429 break;
23430 case "aspectRatio":
23431 this._aspectRatio = !!value;
23432 break;
23433 default:
23434 break;
23435 }
23436 },
23437
23438 _setupHandles: function() {
23439 var o = this.options, handle, i, n, hname, axis, that = this;
23440 this.handles = o.handles ||
23441 ( !$( ".ui-resizable-handle", this.element ).length ?
23442 "e,s,se" : {
23443 n: ".ui-resizable-n",
23444 e: ".ui-resizable-e",
23445 s: ".ui-resizable-s",
23446 w: ".ui-resizable-w",
23447 se: ".ui-resizable-se",
23448 sw: ".ui-resizable-sw",
23449 ne: ".ui-resizable-ne",
23450 nw: ".ui-resizable-nw"
23451 } );
23452
23453 this._handles = $();
23454 this._addedHandles = $();
23455 if ( this.handles.constructor === String ) {
23456
23457 if ( this.handles === "all" ) {
23458 this.handles = "n,e,s,w,se,sw,ne,nw";
23459 }
23460
23461 n = this.handles.split( "," );
23462 this.handles = {};
23463
23464 for ( i = 0; i < n.length; i++ ) {
23465
23466 handle = String.prototype.trim.call( n[ i ] );
23467 hname = "ui-resizable-" + handle;
23468 axis = $( "<div>" );
23469 this._addClass( axis, "ui-resizable-handle " + hname );
23470
23471 axis.css( { zIndex: o.zIndex } );
23472
23473 this.handles[ handle ] = ".ui-resizable-" + handle;
23474 if ( !this.element.children( this.handles[ handle ] ).length ) {
23475 this.element.append( axis );
23476 this._addedHandles = this._addedHandles.add( axis );
23477 }
23478 }
23479
23480 }
23481
23482 this._renderAxis = function( target ) {
23483
23484 var i, axis, padPos, padWrapper;
23485
23486 target = target || this.element;
23487
23488 for ( i in this.handles ) {
23489
23490 if ( this.handles[ i ].constructor === String ) {
23491 this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
23492 } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
23493 this.handles[ i ] = $( this.handles[ i ] );
23494 this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
23495 }
23496
23497 if ( this.elementIsWrapper &&
23498 this.originalElement[ 0 ]
23499 .nodeName
23500 .match( /^(textarea|input|select|button)$/i ) ) {
23501 axis = $( this.handles[ i ], this.element );
23502
23503 padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
23504 axis.outerHeight() :
23505 axis.outerWidth();
23506
23507 padPos = [ "padding",
23508 /ne|nw|n/.test( i ) ? "Top" :
23509 /se|sw|s/.test( i ) ? "Bottom" :
23510 /^e$/.test( i ) ? "Right" : "Left" ].join( "" );
23511
23512 target.css( padPos, padWrapper );
23513
23514 this._proportionallyResize();
23515 }
23516
23517 this._handles = this._handles.add( this.handles[ i ] );
23518 }
23519 };
23520
23521 // TODO: make renderAxis a prototype function
23522 this._renderAxis( this.element );
23523
23524 this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
23525 this._handles.disableSelection();
23526
23527 this._handles.on( "mouseover", function() {
23528 if ( !that.resizing ) {
23529 if ( this.className ) {
23530 axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
23531 }
23532 that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
23533 }
23534 } );
23535
23536 if ( o.autoHide ) {
23537 this._handles.hide();
23538 this._addClass( "ui-resizable-autohide" );
23539 }
23540 },
23541
23542 _removeHandles: function() {
23543 this._addedHandles.remove();
23544 },
23545
23546 _mouseCapture: function( event ) {
23547 var i, handle,
23548 capture = false;
23549
23550 for ( i in this.handles ) {
23551 handle = $( this.handles[ i ] )[ 0 ];
23552 if ( handle === event.target || $.contains( handle, event.target ) ) {
23553 capture = true;
23554 }
23555 }
23556
23557 return !this.options.disabled && capture;
23558 },
23559
23560 _mouseStart: function( event ) {
23561
23562 var curleft, curtop, cursor, calculatedSize,
23563 o = this.options,
23564 el = this.element;
23565
23566 this.resizing = true;
23567
23568 this._renderProxy();
23569
23570 curleft = this._num( this.helper.css( "left" ) );
23571 curtop = this._num( this.helper.css( "top" ) );
23572
23573 if ( o.containment ) {
23574 curleft += $( o.containment ).scrollLeft() || 0;
23575 curtop += $( o.containment ).scrollTop() || 0;
23576 }
23577
23578 this.offset = this.helper.offset();
23579 this.position = { left: curleft, top: curtop };
23580
23581 if ( !this._helper ) {
23582 calculatedSize = this._calculateAdjustedElementDimensions( el );
23583 }
23584
23585 this.size = this._helper ? {
23586 width: this.helper.width(),
23587 height: this.helper.height()
23588 } : {
23589 width: calculatedSize.width,
23590 height: calculatedSize.height
23591 };
23592
23593 this.originalSize = this._helper ? {
23594 width: el.outerWidth(),
23595 height: el.outerHeight()
23596 } : {
23597 width: calculatedSize.width,
23598 height: calculatedSize.height
23599 };
23600
23601 this.sizeDiff = {
23602 width: el.outerWidth() - el.width(),
23603 height: el.outerHeight() - el.height()
23604 };
23605
23606 this.originalPosition = { left: curleft, top: curtop };
23607 this.originalMousePosition = { left: event.pageX, top: event.pageY };
23608
23609 this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
23610 o.aspectRatio :
23611 ( ( this.originalSize.width / this.originalSize.height ) || 1 );
23612
23613 cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
23614 $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
23615
23616 this._addClass( "ui-resizable-resizing" );
23617 this._propagate( "start", event );
23618 return true;
23619 },
23620
23621 _mouseDrag: function( event ) {
23622
23623 var data, props,
23624 smp = this.originalMousePosition,
23625 a = this.axis,
23626 dx = ( event.pageX - smp.left ) || 0,
23627 dy = ( event.pageY - smp.top ) || 0,
23628 trigger = this._change[ a ];
23629
23630 this._updatePrevProperties();
23631
23632 if ( !trigger ) {
23633 return false;
23634 }
23635
23636 data = trigger.apply( this, [ event, dx, dy ] );
23637
23638 this._updateVirtualBoundaries( event.shiftKey );
23639 if ( this._aspectRatio || event.shiftKey ) {
23640 data = this._updateRatio( data, event );
23641 }
23642
23643 data = this._respectSize( data, event );
23644
23645 this._updateCache( data );
23646
23647 this._propagate( "resize", event );
23648
23649 props = this._applyChanges();
23650
23651 if ( !this._helper && this._proportionallyResizeElements.length ) {
23652 this._proportionallyResize();
23653 }
23654
23655 if ( !$.isEmptyObject( props ) ) {
23656 this._updatePrevProperties();
23657 this._trigger( "resize", event, this.ui() );
23658 this._applyChanges();
23659 }
23660
23661 return false;
23662 },
23663
23664 _mouseStop: function( event ) {
23665
23666 this.resizing = false;
23667 var pr, ista, soffseth, soffsetw, s, left, top,
23668 o = this.options, that = this;
23669
23670 if ( this._helper ) {
23671
23672 pr = this._proportionallyResizeElements;
23673 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
23674 soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
23675 soffsetw = ista ? 0 : that.sizeDiff.width;
23676
23677 s = {
23678 width: ( that.helper.width() - soffsetw ),
23679 height: ( that.helper.height() - soffseth )
23680 };
23681 left = ( parseFloat( that.element.css( "left" ) ) +
23682 ( that.position.left - that.originalPosition.left ) ) || null;
23683 top = ( parseFloat( that.element.css( "top" ) ) +
23684 ( that.position.top - that.originalPosition.top ) ) || null;
23685
23686 if ( !o.animate ) {
23687 this.element.css( $.extend( s, { top: top, left: left } ) );
23688 }
23689
23690 that.helper.height( that.size.height );
23691 that.helper.width( that.size.width );
23692
23693 if ( this._helper && !o.animate ) {
23694 this._proportionallyResize();
23695 }
23696 }
23697
23698 $( "body" ).css( "cursor", "auto" );
23699
23700 this._removeClass( "ui-resizable-resizing" );
23701
23702 this._propagate( "stop", event );
23703
23704 if ( this._helper ) {
23705 this.helper.remove();
23706 }
23707
23708 return false;
23709
23710 },
23711
23712 _updatePrevProperties: function() {
23713 this.prevPosition = {
23714 top: this.position.top,
23715 left: this.position.left
23716 };
23717 this.prevSize = {
23718 width: this.size.width,
23719 height: this.size.height
23720 };
23721 },
23722
23723 _applyChanges: function() {
23724 var props = {};
23725
23726 if ( this.position.top !== this.prevPosition.top ) {
23727 props.top = this.position.top + "px";
23728 }
23729 if ( this.position.left !== this.prevPosition.left ) {
23730 props.left = this.position.left + "px";
23731 }
23732
23733 this.helper.css( props );
23734
23735 if ( this.size.width !== this.prevSize.width ) {
23736 props.width = this.size.width + "px";
23737 this.helper.width( props.width );
23738 }
23739 if ( this.size.height !== this.prevSize.height ) {
23740 props.height = this.size.height + "px";
23741 this.helper.height( props.height );
23742 }
23743
23744 return props;
23745 },
23746
23747 _updateVirtualBoundaries: function( forceAspectRatio ) {
23748 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
23749 o = this.options;
23750
23751 b = {
23752 minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
23753 maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
23754 minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
23755 maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
23756 };
23757
23758 if ( this._aspectRatio || forceAspectRatio ) {
23759 pMinWidth = b.minHeight * this.aspectRatio;
23760 pMinHeight = b.minWidth / this.aspectRatio;
23761 pMaxWidth = b.maxHeight * this.aspectRatio;
23762 pMaxHeight = b.maxWidth / this.aspectRatio;
23763
23764 if ( pMinWidth > b.minWidth ) {
23765 b.minWidth = pMinWidth;
23766 }
23767 if ( pMinHeight > b.minHeight ) {
23768 b.minHeight = pMinHeight;
23769 }
23770 if ( pMaxWidth < b.maxWidth ) {
23771 b.maxWidth = pMaxWidth;
23772 }
23773 if ( pMaxHeight < b.maxHeight ) {
23774 b.maxHeight = pMaxHeight;
23775 }
23776 }
23777 this._vBoundaries = b;
23778 },
23779
23780 _updateCache: function( data ) {
23781 this.offset = this.helper.offset();
23782 if ( this._isNumber( data.left ) ) {
23783 this.position.left = data.left;
23784 }
23785 if ( this._isNumber( data.top ) ) {
23786 this.position.top = data.top;
23787 }
23788 if ( this._isNumber( data.height ) ) {
23789 this.size.height = data.height;
23790 }
23791 if ( this._isNumber( data.width ) ) {
23792 this.size.width = data.width;
23793 }
23794 },
23795
23796 _updateRatio: function( data ) {
23797
23798 var cpos = this.position,
23799 csize = this.size,
23800 a = this.axis;
23801
23802 if ( this._isNumber( data.height ) ) {
23803 data.width = ( data.height * this.aspectRatio );
23804 } else if ( this._isNumber( data.width ) ) {
23805 data.height = ( data.width / this.aspectRatio );
23806 }
23807
23808 if ( a === "sw" ) {
23809 data.left = cpos.left + ( csize.width - data.width );
23810 data.top = null;
23811 }
23812 if ( a === "nw" ) {
23813 data.top = cpos.top + ( csize.height - data.height );
23814 data.left = cpos.left + ( csize.width - data.width );
23815 }
23816
23817 return data;
23818 },
23819
23820 _respectSize: function( data ) {
23821
23822 var o = this._vBoundaries,
23823 a = this.axis,
23824 ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
23825 ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
23826 isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
23827 isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
23828 dw = this.originalPosition.left + this.originalSize.width,
23829 dh = this.originalPosition.top + this.originalSize.height,
23830 cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
23831 if ( isminw ) {
23832 data.width = o.minWidth;
23833 }
23834 if ( isminh ) {
23835 data.height = o.minHeight;
23836 }
23837 if ( ismaxw ) {
23838 data.width = o.maxWidth;
23839 }
23840 if ( ismaxh ) {
23841 data.height = o.maxHeight;
23842 }
23843
23844 if ( isminw && cw ) {
23845 data.left = dw - o.minWidth;
23846 }
23847 if ( ismaxw && cw ) {
23848 data.left = dw - o.maxWidth;
23849 }
23850 if ( isminh && ch ) {
23851 data.top = dh - o.minHeight;
23852 }
23853 if ( ismaxh && ch ) {
23854 data.top = dh - o.maxHeight;
23855 }
23856
23857 // Fixing jump error on top/left - bug #2330
23858 if ( !data.width && !data.height && !data.left && data.top ) {
23859 data.top = null;
23860 } else if ( !data.width && !data.height && !data.top && data.left ) {
23861 data.left = null;
23862 }
23863
23864 return data;
23865 },
23866
23867 _getPaddingPlusBorderDimensions: function( element ) {
23868 var i = 0,
23869 widths = [],
23870 borders = [
23871 element.css( "borderTopWidth" ),
23872 element.css( "borderRightWidth" ),
23873 element.css( "borderBottomWidth" ),
23874 element.css( "borderLeftWidth" )
23875 ],
23876 paddings = [
23877 element.css( "paddingTop" ),
23878 element.css( "paddingRight" ),
23879 element.css( "paddingBottom" ),
23880 element.css( "paddingLeft" )
23881 ];
23882
23883 for ( ; i < 4; i++ ) {
23884 widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
23885 widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
23886 }
23887
23888 return {
23889 height: widths[ 0 ] + widths[ 2 ],
23890 width: widths[ 1 ] + widths[ 3 ]
23891 };
23892 },
23893
23894 _calculateAdjustedElementDimensions: function( element ) {
23895 var elWidth, elHeight, paddingBorder,
23896 ce = element.get( 0 );
23897
23898 if ( element.css( "box-sizing" ) !== "content-box" ||
23899 ( !this._hasScroll( ce ) && !this._hasScroll( ce, "left" ) ) ) {
23900 return {
23901 height: parseFloat( element.css( "height" ) ),
23902 width: parseFloat( element.css( "width" ) )
23903 };
23904 }
23905
23906 // Check if CSS inline styles are set and use those (usually from previous resizes)
23907 elWidth = parseFloat( ce.style.width );
23908 elHeight = parseFloat( ce.style.height );
23909
23910 paddingBorder = this._getPaddingPlusBorderDimensions( element );
23911 elWidth = isNaN( elWidth ) ?
23912 this._getElementTheoreticalSize( element, paddingBorder, "width" ) :
23913 elWidth;
23914 elHeight = isNaN( elHeight ) ?
23915 this._getElementTheoreticalSize( element, paddingBorder, "height" ) :
23916 elHeight;
23917
23918 return {
23919 height: elHeight,
23920 width: elWidth
23921 };
23922 },
23923
23924 _getElementTheoreticalSize: function( element, extraSize, dimension ) {
23925
23926 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
23927 var size = Math.max( 0, Math.ceil(
23928 element.get( 0 )[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
23929 extraSize[ dimension ] -
23930 0.5
23931
23932 // If offsetWidth/offsetHeight is unknown, then we can't determine theoretical size.
23933 // Use an explicit zero to avoid NaN.
23934 // See https://github.com/jquery/jquery/issues/3964
23935 ) ) || 0;
23936
23937 return size;
23938 },
23939
23940 _proportionallyResize: function() {
23941
23942 if ( !this._proportionallyResizeElements.length ) {
23943 return;
23944 }
23945
23946 var prel,
23947 i = 0,
23948 element = this.helper || this.element;
23949
23950 for ( ; i < this._proportionallyResizeElements.length; i++ ) {
23951
23952 prel = this._proportionallyResizeElements[ i ];
23953
23954 // TODO: Seems like a bug to cache this.outerDimensions
23955 // considering that we are in a loop.
23956 if ( !this.outerDimensions ) {
23957 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
23958 }
23959
23960 prel.css( {
23961 height: ( element.height() - this.outerDimensions.height ) || 0,
23962 width: ( element.width() - this.outerDimensions.width ) || 0
23963 } );
23964
23965 }
23966
23967 },
23968
23969 _renderProxy: function() {
23970
23971 var el = this.element, o = this.options;
23972 this.elementOffset = el.offset();
23973
23974 if ( this._helper ) {
23975
23976 this.helper = this.helper || $( "<div></div>" ).css( { overflow: "hidden" } );
23977
23978 this._addClass( this.helper, this._helper );
23979 this.helper.css( {
23980 width: this.element.outerWidth(),
23981 height: this.element.outerHeight(),
23982 position: "absolute",
23983 left: this.elementOffset.left + "px",
23984 top: this.elementOffset.top + "px",
23985 zIndex: ++o.zIndex //TODO: Don't modify option
23986 } );
23987
23988 this.helper
23989 .appendTo( "body" )
23990 .disableSelection();
23991
23992 } else {
23993 this.helper = this.element;
23994 }
23995
23996 },
23997
23998 _change: {
23999 e: function( event, dx ) {
24000 return { width: this.originalSize.width + dx };
24001 },
24002 w: function( event, dx ) {
24003 var cs = this.originalSize, sp = this.originalPosition;
24004 return { left: sp.left + dx, width: cs.width - dx };
24005 },
24006 n: function( event, dx, dy ) {
24007 var cs = this.originalSize, sp = this.originalPosition;
24008 return { top: sp.top + dy, height: cs.height - dy };
24009 },
24010 s: function( event, dx, dy ) {
24011 return { height: this.originalSize.height + dy };
24012 },
24013 se: function( event, dx, dy ) {
24014 return $.extend( this._change.s.apply( this, arguments ),
24015 this._change.e.apply( this, [ event, dx, dy ] ) );
24016 },
24017 sw: function( event, dx, dy ) {
24018 return $.extend( this._change.s.apply( this, arguments ),
24019 this._change.w.apply( this, [ event, dx, dy ] ) );
24020 },
24021 ne: function( event, dx, dy ) {
24022 return $.extend( this._change.n.apply( this, arguments ),
24023 this._change.e.apply( this, [ event, dx, dy ] ) );
24024 },
24025 nw: function( event, dx, dy ) {
24026 return $.extend( this._change.n.apply( this, arguments ),
24027 this._change.w.apply( this, [ event, dx, dy ] ) );
24028 }
24029 },
24030
24031 _propagate: function( n, event ) {
24032 $.ui.plugin.call( this, n, [ event, this.ui() ] );
24033 if ( n !== "resize" ) {
24034 this._trigger( n, event, this.ui() );
24035 }
24036 },
24037
24038 plugins: {},
24039
24040 ui: function() {
24041 return {
24042 originalElement: this.originalElement,
24043 element: this.element,
24044 helper: this.helper,
24045 position: this.position,
24046 size: this.size,
24047 originalSize: this.originalSize,
24048 originalPosition: this.originalPosition
24049 };
24050 }
24051
24052} );
24053
24054/*
24055 * Resizable Extensions
24056 */
24057
24058$.ui.plugin.add( "resizable", "animate", {
24059
24060 stop: function( event ) {
24061 var that = $( this ).resizable( "instance" ),
24062 o = that.options,
24063 pr = that._proportionallyResizeElements,
24064 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
24065 soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
24066 soffsetw = ista ? 0 : that.sizeDiff.width,
24067 style = {
24068 width: ( that.size.width - soffsetw ),
24069 height: ( that.size.height - soffseth )
24070 },
24071 left = ( parseFloat( that.element.css( "left" ) ) +
24072 ( that.position.left - that.originalPosition.left ) ) || null,
24073 top = ( parseFloat( that.element.css( "top" ) ) +
24074 ( that.position.top - that.originalPosition.top ) ) || null;
24075
24076 that.element.animate(
24077 $.extend( style, top && left ? { top: top, left: left } : {} ), {
24078 duration: o.animateDuration,
24079 easing: o.animateEasing,
24080 step: function() {
24081
24082 var data = {
24083 width: parseFloat( that.element.css( "width" ) ),
24084 height: parseFloat( that.element.css( "height" ) ),
24085 top: parseFloat( that.element.css( "top" ) ),
24086 left: parseFloat( that.element.css( "left" ) )
24087 };
24088
24089 if ( pr && pr.length ) {
24090 $( pr[ 0 ] ).css( { width: data.width, height: data.height } );
24091 }
24092
24093 // Propagating resize, and updating values for each animation step
24094 that._updateCache( data );
24095 that._propagate( "resize", event );
24096
24097 }
24098 }
24099 );
24100 }
24101
24102} );
24103
24104$.ui.plugin.add( "resizable", "containment", {
24105
24106 start: function() {
24107 var element, p, co, ch, cw, width, height,
24108 that = $( this ).resizable( "instance" ),
24109 o = that.options,
24110 el = that.element,
24111 oc = o.containment,
24112 ce = ( oc instanceof $ ) ?
24113 oc.get( 0 ) :
24114 ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
24115
24116 if ( !ce ) {
24117 return;
24118 }
24119
24120 that.containerElement = $( ce );
24121
24122 if ( /document/.test( oc ) || oc === document ) {
24123 that.containerOffset = {
24124 left: 0,
24125 top: 0
24126 };
24127 that.containerPosition = {
24128 left: 0,
24129 top: 0
24130 };
24131
24132 that.parentData = {
24133 element: $( document ),
24134 left: 0,
24135 top: 0,
24136 width: $( document ).width(),
24137 height: $( document ).height() || document.body.parentNode.scrollHeight
24138 };
24139 } else {
24140 element = $( ce );
24141 p = [];
24142 $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
24143 p[ i ] = that._num( element.css( "padding" + name ) );
24144 } );
24145
24146 that.containerOffset = element.offset();
24147 that.containerPosition = element.position();
24148 that.containerSize = {
24149 height: ( element.innerHeight() - p[ 3 ] ),
24150 width: ( element.innerWidth() - p[ 1 ] )
24151 };
24152
24153 co = that.containerOffset;
24154 ch = that.containerSize.height;
24155 cw = that.containerSize.width;
24156 width = ( that._hasScroll( ce, "left" ) ? ce.scrollWidth : cw );
24157 height = ( that._hasScroll( ce ) ? ce.scrollHeight : ch );
24158
24159 that.parentData = {
24160 element: ce,
24161 left: co.left,
24162 top: co.top,
24163 width: width,
24164 height: height
24165 };
24166 }
24167 },
24168
24169 resize: function( event ) {
24170 var woset, hoset, isParent, isOffsetRelative,
24171 that = $( this ).resizable( "instance" ),
24172 o = that.options,
24173 co = that.containerOffset,
24174 cp = that.position,
24175 pRatio = that._aspectRatio || event.shiftKey,
24176 cop = {
24177 top: 0,
24178 left: 0
24179 },
24180 ce = that.containerElement,
24181 continueResize = true;
24182
24183 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
24184 cop = co;
24185 }
24186
24187 if ( cp.left < ( that._helper ? co.left : 0 ) ) {
24188 that.size.width = that.size.width +
24189 ( that._helper ?
24190 ( that.position.left - co.left ) :
24191 ( that.position.left - cop.left ) );
24192
24193 if ( pRatio ) {
24194 that.size.height = that.size.width / that.aspectRatio;
24195 continueResize = false;
24196 }
24197 that.position.left = o.helper ? co.left : 0;
24198 }
24199
24200 if ( cp.top < ( that._helper ? co.top : 0 ) ) {
24201 that.size.height = that.size.height +
24202 ( that._helper ?
24203 ( that.position.top - co.top ) :
24204 that.position.top );
24205
24206 if ( pRatio ) {
24207 that.size.width = that.size.height * that.aspectRatio;
24208 continueResize = false;
24209 }
24210 that.position.top = that._helper ? co.top : 0;
24211 }
24212
24213 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
24214 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
24215
24216 if ( isParent && isOffsetRelative ) {
24217 that.offset.left = that.parentData.left + that.position.left;
24218 that.offset.top = that.parentData.top + that.position.top;
24219 } else {
24220 that.offset.left = that.element.offset().left;
24221 that.offset.top = that.element.offset().top;
24222 }
24223
24224 woset = Math.abs( that.sizeDiff.width +
24225 ( that._helper ?
24226 that.offset.left - cop.left :
24227 ( that.offset.left - co.left ) ) );
24228
24229 hoset = Math.abs( that.sizeDiff.height +
24230 ( that._helper ?
24231 that.offset.top - cop.top :
24232 ( that.offset.top - co.top ) ) );
24233
24234 if ( woset + that.size.width >= that.parentData.width ) {
24235 that.size.width = that.parentData.width - woset;
24236 if ( pRatio ) {
24237 that.size.height = that.size.width / that.aspectRatio;
24238 continueResize = false;
24239 }
24240 }
24241
24242 if ( hoset + that.size.height >= that.parentData.height ) {
24243 that.size.height = that.parentData.height - hoset;
24244 if ( pRatio ) {
24245 that.size.width = that.size.height * that.aspectRatio;
24246 continueResize = false;
24247 }
24248 }
24249
24250 if ( !continueResize ) {
24251 that.position.left = that.prevPosition.left;
24252 that.position.top = that.prevPosition.top;
24253 that.size.width = that.prevSize.width;
24254 that.size.height = that.prevSize.height;
24255 }
24256 },
24257
24258 stop: function() {
24259 var that = $( this ).resizable( "instance" ),
24260 o = that.options,
24261 co = that.containerOffset,
24262 cop = that.containerPosition,
24263 ce = that.containerElement,
24264 helper = $( that.helper ),
24265 ho = helper.offset(),
24266 w = helper.outerWidth() - that.sizeDiff.width,
24267 h = helper.outerHeight() - that.sizeDiff.height;
24268
24269 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
24270 $( this ).css( {
24271 left: ho.left - cop.left - co.left,
24272 width: w,
24273 height: h
24274 } );
24275 }
24276
24277 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
24278 $( this ).css( {
24279 left: ho.left - cop.left - co.left,
24280 width: w,
24281 height: h
24282 } );
24283 }
24284 }
24285} );
24286
24287$.ui.plugin.add( "resizable", "alsoResize", {
24288
24289 start: function() {
24290 var that = $( this ).resizable( "instance" ),
24291 o = that.options;
24292
24293 $( o.alsoResize ).each( function() {
24294 var el = $( this ),
24295 elSize = that._calculateAdjustedElementDimensions( el );
24296
24297 el.data( "ui-resizable-alsoresize", {
24298 width: elSize.width, height: elSize.height,
24299 left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
24300 } );
24301 } );
24302 },
24303
24304 resize: function( event, ui ) {
24305 var that = $( this ).resizable( "instance" ),
24306 o = that.options,
24307 os = that.originalSize,
24308 op = that.originalPosition,
24309 delta = {
24310 height: ( that.size.height - os.height ) || 0,
24311 width: ( that.size.width - os.width ) || 0,
24312 top: ( that.position.top - op.top ) || 0,
24313 left: ( that.position.left - op.left ) || 0
24314 };
24315
24316 $( o.alsoResize ).each( function() {
24317 var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
24318 css = el.parents( ui.originalElement[ 0 ] ).length ?
24319 [ "width", "height" ] :
24320 [ "width", "height", "top", "left" ];
24321
24322 $.each( css, function( i, prop ) {
24323 var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
24324 if ( sum && sum >= 0 ) {
24325 style[ prop ] = sum || null;
24326 }
24327 } );
24328
24329 el.css( style );
24330 } );
24331 },
24332
24333 stop: function() {
24334 $( this ).removeData( "ui-resizable-alsoresize" );
24335 }
24336} );
24337
24338$.ui.plugin.add( "resizable", "ghost", {
24339
24340 start: function() {
24341
24342 var that = $( this ).resizable( "instance" ), cs = that.size;
24343
24344 that.ghost = that.originalElement.clone();
24345 that.ghost.css( {
24346 opacity: 0.25,
24347 display: "block",
24348 position: "relative",
24349 height: cs.height,
24350 width: cs.width,
24351 margin: 0,
24352 left: 0,
24353 top: 0
24354 } );
24355
24356 that._addClass( that.ghost, "ui-resizable-ghost" );
24357
24358 // DEPRECATED
24359 // TODO: remove after 1.12
24360 if ( $.uiBackCompat === true && typeof that.options.ghost === "string" ) {
24361
24362 // Ghost option
24363 that.ghost.addClass( this.options.ghost );
24364 }
24365
24366 that.ghost.appendTo( that.helper );
24367
24368 },
24369
24370 resize: function() {
24371 var that = $( this ).resizable( "instance" );
24372 if ( that.ghost ) {
24373 that.ghost.css( {
24374 position: "relative",
24375 height: that.size.height,
24376 width: that.size.width
24377 } );
24378 }
24379 },
24380
24381 stop: function() {
24382 var that = $( this ).resizable( "instance" );
24383 if ( that.ghost && that.helper ) {
24384 that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
24385 }
24386 }
24387
24388} );
24389
24390$.ui.plugin.add( "resizable", "grid", {
24391
24392 resize: function() {
24393 var outerDimensions,
24394 that = $( this ).resizable( "instance" ),
24395 o = that.options,
24396 cs = that.size,
24397 os = that.originalSize,
24398 op = that.originalPosition,
24399 a = that.axis,
24400 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
24401 gridX = ( grid[ 0 ] || 1 ),
24402 gridY = ( grid[ 1 ] || 1 ),
24403 ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
24404 oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
24405 newWidth = os.width + ox,
24406 newHeight = os.height + oy,
24407 isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
24408 isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
24409 isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
24410 isMinHeight = o.minHeight && ( o.minHeight > newHeight );
24411
24412 o.grid = grid;
24413
24414 if ( isMinWidth ) {
24415 newWidth += gridX;
24416 }
24417 if ( isMinHeight ) {
24418 newHeight += gridY;
24419 }
24420 if ( isMaxWidth ) {
24421 newWidth -= gridX;
24422 }
24423 if ( isMaxHeight ) {
24424 newHeight -= gridY;
24425 }
24426
24427 if ( /^(se|s|e)$/.test( a ) ) {
24428 that.size.width = newWidth;
24429 that.size.height = newHeight;
24430 } else if ( /^(ne)$/.test( a ) ) {
24431 that.size.width = newWidth;
24432 that.size.height = newHeight;
24433 that.position.top = op.top - oy;
24434 } else if ( /^(sw)$/.test( a ) ) {
24435 that.size.width = newWidth;
24436 that.size.height = newHeight;
24437 that.position.left = op.left - ox;
24438 } else {
24439 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
24440 outerDimensions = that._getPaddingPlusBorderDimensions( this );
24441 }
24442
24443 if ( newHeight - gridY > 0 ) {
24444 that.size.height = newHeight;
24445 that.position.top = op.top - oy;
24446 } else {
24447 newHeight = gridY - outerDimensions.height;
24448 that.size.height = newHeight;
24449 that.position.top = op.top + os.height - newHeight;
24450 }
24451 if ( newWidth - gridX > 0 ) {
24452 that.size.width = newWidth;
24453 that.position.left = op.left - ox;
24454 } else {
24455 newWidth = gridX - outerDimensions.width;
24456 that.size.width = newWidth;
24457 that.position.left = op.left + os.width - newWidth;
24458 }
24459 }
24460 }
24461
24462} );
24463
24464return $.ui.resizable;
24465
24466} );
24467
24468
24469
24470
24471
24472
24473
24474
24475
24476
24477
24478
24479/*!
24480 * jQuery UI Dialog 1.14.1
24481 * https://jqueryui.com
24482 *
24483 * Copyright OpenJS Foundation and other contributors
24484 * Released under the MIT license.
24485 * https://jquery.org/license
24486 */
24487
24488//>>label: Dialog
24489//>>group: Widgets
24490//>>description: Displays customizable dialog windows.
24491//>>docs: https://api.jqueryui.com/dialog/
24492//>>demos: https://jqueryui.com/dialog/
24493//>>css.structure: ../../themes/base/core.css
24494//>>css.structure: ../../themes/base/dialog.css
24495//>>css.theme: ../../themes/base/theme.css
24496
24497( function( factory ) {
24498 "use strict";
24499
24500 if ( typeof define === "function" && define.amd ) {
24501
24502 // AMD. Register as an anonymous module.
24503 define( [
24504 "jquery",
24505 "./button",
24506 "./draggable",
24507 "./mouse",
24508 "./resizable",
24509 "../focusable",
24510 "../keycode",
24511 "../position",
24512 "../tabbable",
24513 "../unique-id",
24514 "../version",
24515 "../widget"
24516 ], factory );
24517 } else {
24518
24519 // Browser globals
24520 factory( jQuery );
24521 }
24522} )( function( $ ) {
24523"use strict";
24524
24525$.widget( "ui.dialog", {
24526 version: "1.14.1",
24527 options: {
24528 appendTo: "body",
24529 autoOpen: true,
24530 buttons: [],
24531 classes: {
24532 "ui-dialog": "ui-corner-all",
24533 "ui-dialog-titlebar": "ui-corner-all"
24534 },
24535 closeOnEscape: true,
24536 closeText: "Close",
24537 draggable: true,
24538 hide: null,
24539 height: "auto",
24540 maxHeight: null,
24541 maxWidth: null,
24542 minHeight: 150,
24543 minWidth: 150,
24544 modal: false,
24545 position: {
24546 my: "center",
24547 at: "center",
24548 of: window,
24549 collision: "fit",
24550
24551 // Ensure the titlebar is always visible
24552 using: function( pos ) {
24553 var topOffset = $( this ).css( pos ).offset().top;
24554 if ( topOffset < 0 ) {
24555 $( this ).css( "top", pos.top - topOffset );
24556 }
24557 }
24558 },
24559 resizable: true,
24560 show: null,
24561 title: null,
24562 uiDialogTitleHeadingLevel: 0,
24563 width: 300,
24564
24565 // Callbacks
24566 beforeClose: null,
24567 close: null,
24568 drag: null,
24569 dragStart: null,
24570 dragStop: null,
24571 focus: null,
24572 open: null,
24573 resize: null,
24574 resizeStart: null,
24575 resizeStop: null
24576 },
24577
24578 sizeRelatedOptions: {
24579 buttons: true,
24580 height: true,
24581 maxHeight: true,
24582 maxWidth: true,
24583 minHeight: true,
24584 minWidth: true,
24585 width: true
24586 },
24587
24588 resizableRelatedOptions: {
24589 maxHeight: true,
24590 maxWidth: true,
24591 minHeight: true,
24592 minWidth: true
24593 },
24594
24595 _create: function() {
24596 this.originalCss = {
24597 display: this.element[ 0 ].style.display,
24598 width: this.element[ 0 ].style.width,
24599 minHeight: this.element[ 0 ].style.minHeight,
24600 maxHeight: this.element[ 0 ].style.maxHeight,
24601 height: this.element[ 0 ].style.height
24602 };
24603 this.originalPosition = {
24604 parent: this.element.parent(),
24605 index: this.element.parent().children().index( this.element )
24606 };
24607 this.originalTitle = this.element.attr( "title" );
24608 if ( this.options.title == null && this.originalTitle != null ) {
24609 this.options.title = this.originalTitle;
24610 }
24611
24612 // Dialogs can't be disabled
24613 if ( this.options.disabled ) {
24614 this.options.disabled = false;
24615 }
24616
24617 this._createWrapper();
24618
24619 this.element
24620 .show()
24621 .removeAttr( "title" )
24622 .appendTo( this.uiDialog );
24623
24624 this._addClass( "ui-dialog-content", "ui-widget-content" );
24625
24626 this._createTitlebar();
24627 this._createButtonPane();
24628
24629 if ( this.options.draggable && $.fn.draggable ) {
24630 this._makeDraggable();
24631 }
24632 if ( this.options.resizable && $.fn.resizable ) {
24633 this._makeResizable();
24634 }
24635
24636 this._isOpen = false;
24637
24638 this._trackFocus();
24639 },
24640
24641 _init: function() {
24642 if ( this.options.autoOpen ) {
24643 this.open();
24644 }
24645 },
24646
24647 _appendTo: function() {
24648 var element = this.options.appendTo;
24649 if ( element && ( element.jquery || element.nodeType ) ) {
24650 return $( element );
24651 }
24652 return this.document.find( element || "body" ).eq( 0 );
24653 },
24654
24655 _destroy: function() {
24656 var next,
24657 originalPosition = this.originalPosition;
24658
24659 this._untrackInstance();
24660 this._destroyOverlay();
24661
24662 this.element
24663 .removeUniqueId()
24664 .css( this.originalCss )
24665
24666 // Without detaching first, the following becomes really slow
24667 .detach();
24668
24669 this.uiDialog.remove();
24670
24671 if ( this.originalTitle ) {
24672 this.element.attr( "title", this.originalTitle );
24673 }
24674
24675 next = originalPosition.parent.children().eq( originalPosition.index );
24676
24677 // Don't try to place the dialog next to itself (#8613)
24678 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
24679 next.before( this.element );
24680 } else {
24681 originalPosition.parent.append( this.element );
24682 }
24683 },
24684
24685 widget: function() {
24686 return this.uiDialog;
24687 },
24688
24689 disable: $.noop,
24690 enable: $.noop,
24691
24692 close: function( event ) {
24693 var that = this;
24694
24695 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
24696 return;
24697 }
24698
24699 this._isOpen = false;
24700 this._focusedElement = null;
24701 this._destroyOverlay();
24702 this._untrackInstance();
24703
24704 if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
24705
24706 // Hiding a focused element doesn't trigger blur in WebKit
24707 // so in case we have nothing to focus on, explicitly blur the active element
24708 // https://bugs.webkit.org/show_bug.cgi?id=47182
24709 $( this.document[ 0 ].activeElement ).trigger( "blur" );
24710 }
24711
24712 this._hide( this.uiDialog, this.options.hide, function() {
24713 that._trigger( "close", event );
24714 } );
24715 },
24716
24717 isOpen: function() {
24718 return this._isOpen;
24719 },
24720
24721 moveToTop: function() {
24722 this._moveToTop();
24723 },
24724
24725 _moveToTop: function( event, silent ) {
24726 var moved = false,
24727 zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
24728 return +$( this ).css( "z-index" );
24729 } ).get(),
24730 zIndexMax = Math.max.apply( null, zIndices );
24731
24732 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
24733 this.uiDialog.css( "z-index", zIndexMax + 1 );
24734 moved = true;
24735 }
24736
24737 if ( moved && !silent ) {
24738 this._trigger( "focus", event );
24739 }
24740 return moved;
24741 },
24742
24743 open: function() {
24744 var that = this;
24745 if ( this._isOpen ) {
24746 if ( this._moveToTop() ) {
24747 this._focusTabbable();
24748 }
24749 return;
24750 }
24751
24752 this._isOpen = true;
24753 this.opener = $( this.document[ 0 ].activeElement );
24754
24755 this._size();
24756 this._position();
24757 this._createOverlay();
24758 this._moveToTop( null, true );
24759
24760 // Ensure the overlay is moved to the top with the dialog, but only when
24761 // opening. The overlay shouldn't move after the dialog is open so that
24762 // modeless dialogs opened after the modal dialog stack properly.
24763 if ( this.overlay ) {
24764 this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
24765 }
24766
24767 this._show( this.uiDialog, this.options.show, function() {
24768 that._focusTabbable();
24769 that._trigger( "focus" );
24770 } );
24771
24772 // Track the dialog immediately upon opening in case a focus event
24773 // somehow occurs outside of the dialog before an element inside the
24774 // dialog is focused (#10152)
24775 this._makeFocusTarget();
24776
24777 this._trigger( "open" );
24778 },
24779
24780 _focusTabbable: function() {
24781
24782 // Set focus to the first match:
24783 // 1. An element that was focused previously
24784 // 2. First element inside the dialog matching [autofocus]
24785 // 3. Tabbable element inside the content element
24786 // 4. Tabbable element inside the buttonpane
24787 // 5. The close button
24788 // 6. The dialog itself
24789 var hasFocus = this._focusedElement;
24790 if ( !hasFocus ) {
24791 hasFocus = this.element.find( "[autofocus]" );
24792 }
24793 if ( !hasFocus.length ) {
24794 hasFocus = this.element.find( ":tabbable" );
24795 }
24796 if ( !hasFocus.length ) {
24797 hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
24798 }
24799 if ( !hasFocus.length ) {
24800 hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
24801 }
24802 if ( !hasFocus.length ) {
24803 hasFocus = this.uiDialog;
24804 }
24805 hasFocus.eq( 0 ).trigger( "focus" );
24806 },
24807
24808 _restoreTabbableFocus: function() {
24809 var activeElement = this.document[ 0 ].activeElement,
24810 isActive = this.uiDialog[ 0 ] === activeElement ||
24811 $.contains( this.uiDialog[ 0 ], activeElement );
24812 if ( !isActive ) {
24813 this._focusTabbable();
24814 }
24815 },
24816
24817 _keepFocus: function( event ) {
24818 event.preventDefault();
24819 this._restoreTabbableFocus();
24820 },
24821
24822 _createWrapper: function() {
24823 this.uiDialog = $( "<div>" )
24824 .hide()
24825 .attr( {
24826
24827 // Setting tabIndex makes the div focusable
24828 tabIndex: -1,
24829 role: "dialog",
24830 "aria-modal": this.options.modal ? "true" : null
24831 } )
24832 .appendTo( this._appendTo() );
24833
24834 this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
24835 this._on( this.uiDialog, {
24836 keydown: function( event ) {
24837 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
24838 event.keyCode === $.ui.keyCode.ESCAPE ) {
24839 event.preventDefault();
24840 this.close( event );
24841 return;
24842 }
24843
24844 // Prevent tabbing out of dialogs
24845 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
24846 return;
24847 }
24848 var tabbables = this.uiDialog.find( ":tabbable" ),
24849 first = tabbables.first(),
24850 last = tabbables.last();
24851
24852 if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
24853 !event.shiftKey ) {
24854 this._delay( function() {
24855 first.trigger( "focus" );
24856 } );
24857 event.preventDefault();
24858 } else if ( ( event.target === first[ 0 ] ||
24859 event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
24860 this._delay( function() {
24861 last.trigger( "focus" );
24862 } );
24863 event.preventDefault();
24864 }
24865 },
24866 mousedown: function( event ) {
24867 if ( this._moveToTop( event ) ) {
24868 this._focusTabbable();
24869 }
24870 }
24871 } );
24872
24873 // We assume that any existing aria-describedby attribute means
24874 // that the dialog content is marked up properly
24875 // otherwise we brute force the content as the description
24876 if ( !this.element.find( "[aria-describedby]" ).length ) {
24877 this.uiDialog.attr( {
24878 "aria-describedby": this.element.uniqueId().attr( "id" )
24879 } );
24880 }
24881 },
24882
24883 _createTitlebar: function() {
24884 var uiDialogTitle;
24885
24886 this.uiDialogTitlebar = $( "<div>" );
24887 this._addClass( this.uiDialogTitlebar,
24888 "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
24889 this._on( this.uiDialogTitlebar, {
24890 mousedown: function( event ) {
24891
24892 // Don't prevent click on close button (#8838)
24893 // Focusing a dialog that is partially scrolled out of view
24894 // causes the browser to scroll it into view, preventing the click event
24895 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
24896
24897 // Dialog isn't getting focus when dragging (#8063)
24898 this.uiDialog.trigger( "focus" );
24899 }
24900 }
24901 } );
24902
24903 this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
24904 .button( {
24905 label: $( "<a>" ).text( this.options.closeText ).html(),
24906 icon: "ui-icon-closethick",
24907 showLabel: false
24908 } )
24909 .appendTo( this.uiDialogTitlebar );
24910
24911 this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
24912 this._on( this.uiDialogTitlebarClose, {
24913 click: function( event ) {
24914 event.preventDefault();
24915 this.close( event );
24916 }
24917 } );
24918
24919 var uiDialogHeadingLevel = Number.isInteger( this.options.uiDialogTitleHeadingLevel ) &&
24920 this.options.uiDialogTitleHeadingLevel > 0 &&
24921 this.options.uiDialogTitleHeadingLevel <= 6 ?
24922 "h" + this.options.uiDialogTitleHeadingLevel : "span";
24923
24924 uiDialogTitle = $( "<" + uiDialogHeadingLevel + ">" )
24925 .uniqueId().prependTo( this.uiDialogTitlebar );
24926 this._addClass( uiDialogTitle, "ui-dialog-title" );
24927 this._title( uiDialogTitle );
24928
24929 this.uiDialogTitlebar.prependTo( this.uiDialog );
24930
24931 this.uiDialog.attr( {
24932 "aria-labelledby": uiDialogTitle.attr( "id" )
24933 } );
24934 },
24935
24936 _title: function( title ) {
24937 if ( this.options.title ) {
24938 title.text( this.options.title );
24939 } else {
24940 title.html( "&#160;" );
24941 }
24942 },
24943
24944 _createButtonPane: function() {
24945 this.uiDialogButtonPane = $( "<div>" );
24946 this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
24947 "ui-widget-content ui-helper-clearfix" );
24948
24949 this.uiButtonSet = $( "<div>" )
24950 .appendTo( this.uiDialogButtonPane );
24951 this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
24952
24953 this._createButtons();
24954 },
24955
24956 _createButtons: function() {
24957 var that = this,
24958 buttons = this.options.buttons;
24959
24960 // If we already have a button pane, remove it
24961 this.uiDialogButtonPane.remove();
24962 this.uiButtonSet.empty();
24963
24964 if ( $.isEmptyObject( buttons ) || ( Array.isArray( buttons ) && !buttons.length ) ) {
24965 this._removeClass( this.uiDialog, "ui-dialog-buttons" );
24966 return;
24967 }
24968
24969 $.each( buttons, function( name, props ) {
24970 var click, buttonOptions;
24971 props = typeof props === "function" ?
24972 { click: props, text: name } :
24973 props;
24974
24975 // Default to a non-submitting button
24976 props = $.extend( { type: "button" }, props );
24977
24978 // Change the context for the click callback to be the main element
24979 click = props.click;
24980 buttonOptions = {
24981 icon: props.icon,
24982 iconPosition: props.iconPosition,
24983 showLabel: props.showLabel,
24984
24985 // Deprecated options
24986 icons: props.icons,
24987 text: props.text
24988 };
24989
24990 delete props.click;
24991 delete props.icon;
24992 delete props.iconPosition;
24993 delete props.showLabel;
24994
24995 // Deprecated options
24996 delete props.icons;
24997 if ( typeof props.text === "boolean" ) {
24998 delete props.text;
24999 }
25000
25001 $( "<button></button>", props )
25002 .button( buttonOptions )
25003 .appendTo( that.uiButtonSet )
25004 .on( "click", function() {
25005 click.apply( that.element[ 0 ], arguments );
25006 } );
25007 } );
25008 this._addClass( this.uiDialog, "ui-dialog-buttons" );
25009 this.uiDialogButtonPane.appendTo( this.uiDialog );
25010 },
25011
25012 _makeDraggable: function() {
25013 var that = this,
25014 options = this.options;
25015
25016 function filteredUi( ui ) {
25017 return {
25018 position: ui.position,
25019 offset: ui.offset
25020 };
25021 }
25022
25023 this.uiDialog.draggable( {
25024 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
25025 handle: ".ui-dialog-titlebar",
25026 containment: "document",
25027 start: function( event, ui ) {
25028 that._addClass( $( this ), "ui-dialog-dragging" );
25029 that._blockFrames();
25030 that._trigger( "dragStart", event, filteredUi( ui ) );
25031 },
25032 drag: function( event, ui ) {
25033 that._trigger( "drag", event, filteredUi( ui ) );
25034 },
25035 stop: function( event, ui ) {
25036 var left = ui.offset.left - that.document.scrollLeft(),
25037 top = ui.offset.top - that.document.scrollTop();
25038
25039 options.position = {
25040 my: "left top",
25041 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
25042 "top" + ( top >= 0 ? "+" : "" ) + top,
25043 of: that.window
25044 };
25045 that._removeClass( $( this ), "ui-dialog-dragging" );
25046 that._unblockFrames();
25047 that._trigger( "dragStop", event, filteredUi( ui ) );
25048 }
25049 } );
25050 },
25051
25052 _makeResizable: function() {
25053 var that = this,
25054 options = this.options,
25055 handles = options.resizable,
25056
25057 // .ui-resizable has position: relative defined in the stylesheet
25058 // but dialogs have to use absolute or fixed positioning
25059 position = this.uiDialog.css( "position" ),
25060 resizeHandles = typeof handles === "string" ?
25061 handles :
25062 "n,e,s,w,se,sw,ne,nw";
25063
25064 function filteredUi( ui ) {
25065 return {
25066 originalPosition: ui.originalPosition,
25067 originalSize: ui.originalSize,
25068 position: ui.position,
25069 size: ui.size
25070 };
25071 }
25072
25073 this.uiDialog.resizable( {
25074 cancel: ".ui-dialog-content",
25075 containment: "document",
25076 alsoResize: this.element,
25077 maxWidth: options.maxWidth,
25078 maxHeight: options.maxHeight,
25079 minWidth: options.minWidth,
25080 minHeight: this._minHeight(),
25081 handles: resizeHandles,
25082 start: function( event, ui ) {
25083 that._addClass( $( this ), "ui-dialog-resizing" );
25084 that._blockFrames();
25085 that._trigger( "resizeStart", event, filteredUi( ui ) );
25086 },
25087 resize: function( event, ui ) {
25088 that._trigger( "resize", event, filteredUi( ui ) );
25089 },
25090 stop: function( event, ui ) {
25091 var offset = that.uiDialog.offset(),
25092 left = offset.left - that.document.scrollLeft(),
25093 top = offset.top - that.document.scrollTop();
25094
25095 options.height = that.uiDialog.height();
25096 options.width = that.uiDialog.width();
25097 options.position = {
25098 my: "left top",
25099 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
25100 "top" + ( top >= 0 ? "+" : "" ) + top,
25101 of: that.window
25102 };
25103 that._removeClass( $( this ), "ui-dialog-resizing" );
25104 that._unblockFrames();
25105 that._trigger( "resizeStop", event, filteredUi( ui ) );
25106 }
25107 } )
25108 .css( "position", position );
25109 },
25110
25111 _trackFocus: function() {
25112 this._on( this.widget(), {
25113 focusin: function( event ) {
25114 this._makeFocusTarget();
25115 this._focusedElement = $( event.target );
25116 }
25117 } );
25118 },
25119
25120 _makeFocusTarget: function() {
25121 this._untrackInstance();
25122 this._trackingInstances().unshift( this );
25123 },
25124
25125 _untrackInstance: function() {
25126 var instances = this._trackingInstances(),
25127 exists = $.inArray( this, instances );
25128 if ( exists !== -1 ) {
25129 instances.splice( exists, 1 );
25130 }
25131 },
25132
25133 _trackingInstances: function() {
25134 var instances = this.document.data( "ui-dialog-instances" );
25135 if ( !instances ) {
25136 instances = [];
25137 this.document.data( "ui-dialog-instances", instances );
25138 }
25139 return instances;
25140 },
25141
25142 _minHeight: function() {
25143 var options = this.options;
25144
25145 return options.height === "auto" ?
25146 options.minHeight :
25147 Math.min( options.minHeight, options.height );
25148 },
25149
25150 _position: function() {
25151
25152 // Need to show the dialog to get the actual offset in the position plugin
25153 var isVisible = this.uiDialog.is( ":visible" );
25154 if ( !isVisible ) {
25155 this.uiDialog.show();
25156 }
25157 this.uiDialog.position( this.options.position );
25158 if ( !isVisible ) {
25159 this.uiDialog.hide();
25160 }
25161 },
25162
25163 _setOptions: function( options ) {
25164 var that = this,
25165 resize = false,
25166 resizableOptions = {};
25167
25168 $.each( options, function( key, value ) {
25169 that._setOption( key, value );
25170
25171 if ( key in that.sizeRelatedOptions ) {
25172 resize = true;
25173 }
25174 if ( key in that.resizableRelatedOptions ) {
25175 resizableOptions[ key ] = value;
25176 }
25177 } );
25178
25179 if ( resize ) {
25180 this._size();
25181 this._position();
25182 }
25183 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
25184 this.uiDialog.resizable( "option", resizableOptions );
25185 }
25186 },
25187
25188 _setOption: function( key, value ) {
25189 var isDraggable, isResizable,
25190 uiDialog = this.uiDialog;
25191
25192 if ( key === "disabled" ) {
25193 return;
25194 }
25195
25196 this._super( key, value );
25197
25198 if ( key === "appendTo" ) {
25199 this.uiDialog.appendTo( this._appendTo() );
25200 }
25201
25202 if ( key === "buttons" ) {
25203 this._createButtons();
25204 }
25205
25206 if ( key === "closeText" ) {
25207 this.uiDialogTitlebarClose.button( {
25208
25209 // Ensure that we always pass a string
25210 label: $( "<a>" ).text( "" + this.options.closeText ).html()
25211 } );
25212 }
25213
25214 if ( key === "draggable" ) {
25215 isDraggable = uiDialog.is( ":data(ui-draggable)" );
25216 if ( isDraggable && !value ) {
25217 uiDialog.draggable( "destroy" );
25218 }
25219
25220 if ( !isDraggable && value ) {
25221 this._makeDraggable();
25222 }
25223 }
25224
25225 if ( key === "position" ) {
25226 this._position();
25227 }
25228
25229 if ( key === "resizable" ) {
25230
25231 // currently resizable, becoming non-resizable
25232 isResizable = uiDialog.is( ":data(ui-resizable)" );
25233 if ( isResizable && !value ) {
25234 uiDialog.resizable( "destroy" );
25235 }
25236
25237 // Currently resizable, changing handles
25238 if ( isResizable && typeof value === "string" ) {
25239 uiDialog.resizable( "option", "handles", value );
25240 }
25241
25242 // Currently non-resizable, becoming resizable
25243 if ( !isResizable && value !== false ) {
25244 this._makeResizable();
25245 }
25246 }
25247
25248 if ( key === "title" ) {
25249 this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
25250 }
25251
25252 if ( key === "modal" ) {
25253 uiDialog.attr( "aria-modal", value ? "true" : null );
25254 }
25255 },
25256
25257 _size: function() {
25258
25259 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
25260 // divs will both have width and height set, so we need to reset them
25261 var nonContentHeight, minContentHeight, maxContentHeight,
25262 options = this.options;
25263
25264 // Reset content sizing
25265 this.element.show().css( {
25266 width: "auto",
25267 minHeight: 0,
25268 maxHeight: "none",
25269 height: 0
25270 } );
25271
25272 if ( options.minWidth > options.width ) {
25273 options.width = options.minWidth;
25274 }
25275
25276 // Reset wrapper sizing
25277 // determine the height of all the non-content elements
25278 nonContentHeight = this.uiDialog.css( {
25279 height: "auto",
25280 width: options.width
25281 } )
25282 .outerHeight();
25283 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
25284 maxContentHeight = typeof options.maxHeight === "number" ?
25285 Math.max( 0, options.maxHeight - nonContentHeight ) :
25286 "none";
25287
25288 if ( options.height === "auto" ) {
25289 this.element.css( {
25290 minHeight: minContentHeight,
25291 maxHeight: maxContentHeight,
25292 height: "auto"
25293 } );
25294 } else {
25295 this.element.height( Math.max( 0, options.height - nonContentHeight ) );
25296 }
25297
25298 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
25299 this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
25300 }
25301 },
25302
25303 _blockFrames: function() {
25304 this.iframeBlocks = this.document.find( "iframe" ).map( function() {
25305 var iframe = $( this );
25306
25307 return $( "<div>" )
25308 .css( {
25309 position: "absolute",
25310 width: iframe.outerWidth(),
25311 height: iframe.outerHeight()
25312 } )
25313 .appendTo( iframe.parent() )
25314 .offset( iframe.offset() )[ 0 ];
25315 } );
25316 },
25317
25318 _unblockFrames: function() {
25319 if ( this.iframeBlocks ) {
25320 this.iframeBlocks.remove();
25321 delete this.iframeBlocks;
25322 }
25323 },
25324
25325 _allowInteraction: function( event ) {
25326 if ( $( event.target ).closest( ".ui-dialog" ).length ) {
25327 return true;
25328 }
25329
25330 // TODO: Remove hack when datepicker implements
25331 // the .ui-front logic (#8989)
25332 return !!$( event.target ).closest( ".ui-datepicker" ).length;
25333 },
25334
25335 _createOverlay: function() {
25336 if ( !this.options.modal ) {
25337 return;
25338 }
25339
25340 // We use a delay in case the overlay is created from an
25341 // event that we're going to be cancelling (#2804)
25342 var isOpening = true;
25343 this._delay( function() {
25344 isOpening = false;
25345 } );
25346
25347 if ( !this.document.data( "ui-dialog-overlays" ) ) {
25348
25349 // Prevent use of anchors and inputs
25350 // This doesn't use `_on()` because it is a shared event handler
25351 // across all open modal dialogs.
25352 this.document.on( "focusin.ui-dialog", function( event ) {
25353 if ( isOpening ) {
25354 return;
25355 }
25356
25357 var instance = this._trackingInstances()[ 0 ];
25358 if ( !instance._allowInteraction( event ) ) {
25359 event.preventDefault();
25360 instance._focusTabbable();
25361 }
25362 }.bind( this ) );
25363 }
25364
25365 this.overlay = $( "<div>" )
25366 .appendTo( this._appendTo() );
25367
25368 this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
25369 this._on( this.overlay, {
25370 mousedown: "_keepFocus"
25371 } );
25372 this.document.data( "ui-dialog-overlays",
25373 ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
25374 },
25375
25376 _destroyOverlay: function() {
25377 if ( !this.options.modal ) {
25378 return;
25379 }
25380
25381 if ( this.overlay ) {
25382 var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
25383
25384 if ( !overlays ) {
25385 this.document.off( "focusin.ui-dialog" );
25386 this.document.removeData( "ui-dialog-overlays" );
25387 } else {
25388 this.document.data( "ui-dialog-overlays", overlays );
25389 }
25390
25391 this.overlay.remove();
25392 this.overlay = null;
25393 }
25394 }
25395} );
25396
25397// DEPRECATED
25398// TODO: switch return back to widget declaration at top of file when this is removed
25399if ( $.uiBackCompat === true ) {
25400
25401 // Backcompat for dialogClass option
25402 $.widget( "ui.dialog", $.ui.dialog, {
25403 options: {
25404 dialogClass: ""
25405 },
25406 _createWrapper: function() {
25407 this._super();
25408 this.uiDialog.addClass( this.options.dialogClass );
25409 },
25410 _setOption: function( key, value ) {
25411 if ( key === "dialogClass" ) {
25412 this.uiDialog
25413 .removeClass( this.options.dialogClass )
25414 .addClass( value );
25415 }
25416 this._superApply( arguments );
25417 }
25418 } );
25419}
25420
25421return $.ui.dialog;
25422
25423} );
25424
25425
25426
25427
25428
25429/*!
25430 * jQuery UI Droppable 1.14.1
25431 * https://jqueryui.com
25432 *
25433 * Copyright OpenJS Foundation and other contributors
25434 * Released under the MIT license.
25435 * https://jquery.org/license
25436 */
25437
25438//>>label: Droppable
25439//>>group: Interactions
25440//>>description: Enables drop targets for draggable elements.
25441//>>docs: https://api.jqueryui.com/droppable/
25442//>>demos: https://jqueryui.com/droppable/
25443
25444( function( factory ) {
25445 "use strict";
25446
25447 if ( typeof define === "function" && define.amd ) {
25448
25449 // AMD. Register as an anonymous module.
25450 define( [
25451 "jquery",
25452 "./draggable",
25453 "./mouse",
25454 "../version",
25455 "../widget"
25456 ], factory );
25457 } else {
25458
25459 // Browser globals
25460 factory( jQuery );
25461 }
25462} )( function( $ ) {
25463"use strict";
25464
25465$.widget( "ui.droppable", {
25466 version: "1.14.1",
25467 widgetEventPrefix: "drop",
25468 options: {
25469 accept: "*",
25470 addClasses: true,
25471 greedy: false,
25472 scope: "default",
25473 tolerance: "intersect",
25474
25475 // Callbacks
25476 activate: null,
25477 deactivate: null,
25478 drop: null,
25479 out: null,
25480 over: null
25481 },
25482 _create: function() {
25483
25484 var proportions,
25485 o = this.options,
25486 accept = o.accept;
25487
25488 this.isover = false;
25489 this.isout = true;
25490
25491 this.accept = typeof accept === "function" ? accept : function( d ) {
25492 return d.is( accept );
25493 };
25494
25495 this.proportions = function( /* valueToWrite */ ) {
25496 if ( arguments.length ) {
25497
25498 // Store the droppable's proportions
25499 proportions = arguments[ 0 ];
25500 } else {
25501
25502 // Retrieve or derive the droppable's proportions
25503 return proportions ?
25504 proportions :
25505 proportions = {
25506 width: this.element[ 0 ].offsetWidth,
25507 height: this.element[ 0 ].offsetHeight
25508 };
25509 }
25510 };
25511
25512 this._addToManager( o.scope );
25513
25514 if ( o.addClasses ) {
25515 this._addClass( "ui-droppable" );
25516 }
25517
25518 },
25519
25520 _addToManager: function( scope ) {
25521
25522 // Add the reference and positions to the manager
25523 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
25524 $.ui.ddmanager.droppables[ scope ].push( this );
25525 },
25526
25527 _splice: function( drop ) {
25528 var i = 0;
25529 for ( ; i < drop.length; i++ ) {
25530 if ( drop[ i ] === this ) {
25531 drop.splice( i, 1 );
25532 }
25533 }
25534 },
25535
25536 _destroy: function() {
25537 var drop = $.ui.ddmanager.droppables[ this.options.scope ];
25538
25539 this._splice( drop );
25540 },
25541
25542 _setOption: function( key, value ) {
25543
25544 if ( key === "accept" ) {
25545 this.accept = typeof value === "function" ? value : function( d ) {
25546 return d.is( value );
25547 };
25548 } else if ( key === "scope" ) {
25549 var drop = $.ui.ddmanager.droppables[ this.options.scope ];
25550
25551 this._splice( drop );
25552 this._addToManager( value );
25553 }
25554
25555 this._super( key, value );
25556 },
25557
25558 _activate: function( event ) {
25559 var draggable = $.ui.ddmanager.current;
25560
25561 this._addActiveClass();
25562 if ( draggable ) {
25563 this._trigger( "activate", event, this.ui( draggable ) );
25564 }
25565 },
25566
25567 _deactivate: function( event ) {
25568 var draggable = $.ui.ddmanager.current;
25569
25570 this._removeActiveClass();
25571 if ( draggable ) {
25572 this._trigger( "deactivate", event, this.ui( draggable ) );
25573 }
25574 },
25575
25576 _over: function( event ) {
25577
25578 var draggable = $.ui.ddmanager.current;
25579
25580 // Bail if draggable and droppable are same element
25581 if ( !draggable || ( draggable.currentItem ||
25582 draggable.element )[ 0 ] === this.element[ 0 ] ) {
25583 return;
25584 }
25585
25586 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
25587 draggable.element ) ) ) {
25588 this._addHoverClass();
25589 this._trigger( "over", event, this.ui( draggable ) );
25590 }
25591
25592 },
25593
25594 _out: function( event ) {
25595
25596 var draggable = $.ui.ddmanager.current;
25597
25598 // Bail if draggable and droppable are same element
25599 if ( !draggable || ( draggable.currentItem ||
25600 draggable.element )[ 0 ] === this.element[ 0 ] ) {
25601 return;
25602 }
25603
25604 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
25605 draggable.element ) ) ) {
25606 this._removeHoverClass();
25607 this._trigger( "out", event, this.ui( draggable ) );
25608 }
25609
25610 },
25611
25612 _drop: function( event, custom ) {
25613
25614 var draggable = custom || $.ui.ddmanager.current,
25615 childrenIntersection = false;
25616
25617 // Bail if draggable and droppable are same element
25618 if ( !draggable || ( draggable.currentItem ||
25619 draggable.element )[ 0 ] === this.element[ 0 ] ) {
25620 return false;
25621 }
25622
25623 this.element
25624 .find( ":data(ui-droppable)" )
25625 .not( ".ui-draggable-dragging" )
25626 .each( function() {
25627 var inst = $( this ).droppable( "instance" );
25628 if (
25629 inst.options.greedy &&
25630 !inst.options.disabled &&
25631 inst.options.scope === draggable.options.scope &&
25632 inst.accept.call(
25633 inst.element[ 0 ], ( draggable.currentItem || draggable.element )
25634 ) &&
25635 $.ui.intersect(
25636 draggable,
25637 $.extend( inst, { offset: inst.element.offset() } ),
25638 inst.options.tolerance, event
25639 )
25640 ) {
25641 childrenIntersection = true;
25642 return false;
25643 }
25644 } );
25645 if ( childrenIntersection ) {
25646 return false;
25647 }
25648
25649 if ( this.accept.call( this.element[ 0 ],
25650 ( draggable.currentItem || draggable.element ) ) ) {
25651 this._removeActiveClass();
25652 this._removeHoverClass();
25653
25654 this._trigger( "drop", event, this.ui( draggable ) );
25655 return this.element;
25656 }
25657
25658 return false;
25659
25660 },
25661
25662 ui: function( c ) {
25663 return {
25664 draggable: ( c.currentItem || c.element ),
25665 helper: c.helper,
25666 position: c.position,
25667 offset: c.positionAbs
25668 };
25669 },
25670
25671 // Extension points just to make backcompat sane and avoid duplicating logic
25672 // TODO: Remove in 1.14 along with call to it below
25673 _addHoverClass: function() {
25674 this._addClass( "ui-droppable-hover" );
25675 },
25676
25677 _removeHoverClass: function() {
25678 this._removeClass( "ui-droppable-hover" );
25679 },
25680
25681 _addActiveClass: function() {
25682 this._addClass( "ui-droppable-active" );
25683 },
25684
25685 _removeActiveClass: function() {
25686 this._removeClass( "ui-droppable-active" );
25687 }
25688} );
25689
25690$.ui.intersect = ( function() {
25691 function isOverAxis( x, reference, size ) {
25692 return ( x >= reference ) && ( x < ( reference + size ) );
25693 }
25694
25695 return function( draggable, droppable, toleranceMode, event ) {
25696
25697 if ( !droppable.offset ) {
25698 return false;
25699 }
25700
25701 var x1 = ( draggable.positionAbs ||
25702 draggable.position.absolute ).left + draggable.margins.left,
25703 y1 = ( draggable.positionAbs ||
25704 draggable.position.absolute ).top + draggable.margins.top,
25705 x2 = x1 + draggable.helperProportions.width,
25706 y2 = y1 + draggable.helperProportions.height,
25707 l = droppable.offset.left,
25708 t = droppable.offset.top,
25709 r = l + droppable.proportions().width,
25710 b = t + droppable.proportions().height;
25711
25712 switch ( toleranceMode ) {
25713 case "fit":
25714 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
25715 case "intersect":
25716 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
25717 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
25718 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
25719 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
25720 case "pointer":
25721 return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
25722 isOverAxis( event.pageX, l, droppable.proportions().width );
25723 case "touch":
25724 return (
25725 ( y1 >= t && y1 <= b ) || // Top edge touching
25726 ( y2 >= t && y2 <= b ) || // Bottom edge touching
25727 ( y1 < t && y2 > b ) // Surrounded vertically
25728 ) && (
25729 ( x1 >= l && x1 <= r ) || // Left edge touching
25730 ( x2 >= l && x2 <= r ) || // Right edge touching
25731 ( x1 < l && x2 > r ) // Surrounded horizontally
25732 );
25733 default:
25734 return false;
25735 }
25736 };
25737} )();
25738
25739/*
25740 This manager tracks offsets of draggables and droppables
25741*/
25742$.ui.ddmanager = {
25743 current: null,
25744 droppables: { "default": [] },
25745 prepareOffsets: function( t, event ) {
25746
25747 var i, j,
25748 m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
25749 type = event ? event.type : null, // workaround for #2317
25750 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
25751
25752 droppablesLoop: for ( i = 0; i < m.length; i++ ) {
25753
25754 // No disabled and non-accepted
25755 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
25756 ( t.currentItem || t.element ) ) ) ) {
25757 continue;
25758 }
25759
25760 // Filter out elements in the current dragged item
25761 for ( j = 0; j < list.length; j++ ) {
25762 if ( list[ j ] === m[ i ].element[ 0 ] ) {
25763 m[ i ].proportions().height = 0;
25764 continue droppablesLoop;
25765 }
25766 }
25767
25768 m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
25769 if ( !m[ i ].visible ) {
25770 continue;
25771 }
25772
25773 // Activate the droppable if used directly from draggables
25774 if ( type === "mousedown" ) {
25775 m[ i ]._activate.call( m[ i ], event );
25776 }
25777
25778 m[ i ].offset = m[ i ].element.offset();
25779 m[ i ].proportions( {
25780 width: m[ i ].element[ 0 ].offsetWidth,
25781 height: m[ i ].element[ 0 ].offsetHeight
25782 } );
25783
25784 }
25785
25786 },
25787 drop: function( draggable, event ) {
25788
25789 var dropped = false;
25790
25791 // Create a copy of the droppables in case the list changes during the drop (#9116)
25792 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
25793
25794 if ( !this.options ) {
25795 return;
25796 }
25797 if ( !this.options.disabled && this.visible &&
25798 $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
25799 dropped = this._drop.call( this, event ) || dropped;
25800 }
25801
25802 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
25803 ( draggable.currentItem || draggable.element ) ) ) {
25804 this.isout = true;
25805 this.isover = false;
25806 this._deactivate.call( this, event );
25807 }
25808
25809 } );
25810 return dropped;
25811
25812 },
25813 dragStart: function( draggable, event ) {
25814
25815 // Listen for scrolling so that if the dragging causes scrolling the position of the
25816 // droppables can be recalculated (see #5003)
25817 draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
25818 if ( !draggable.options.refreshPositions ) {
25819 $.ui.ddmanager.prepareOffsets( draggable, event );
25820 }
25821 } );
25822 },
25823 drag: function( draggable, event ) {
25824
25825 // If you have a highly dynamic page, you might try this option. It renders positions
25826 // every time you move the mouse.
25827 if ( draggable.options.refreshPositions ) {
25828 $.ui.ddmanager.prepareOffsets( draggable, event );
25829 }
25830
25831 // Run through all droppables and check their positions based on specific tolerance options
25832 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
25833
25834 if ( this.options.disabled || this.greedyChild || !this.visible ) {
25835 return;
25836 }
25837
25838 var parentInstance, scope, parent,
25839 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
25840 c = !intersects && this.isover ?
25841 "isout" :
25842 ( intersects && !this.isover ? "isover" : null );
25843 if ( !c ) {
25844 return;
25845 }
25846
25847 if ( this.options.greedy ) {
25848
25849 // find droppable parents with same scope
25850 scope = this.options.scope;
25851 parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
25852 return $( this ).droppable( "instance" ).options.scope === scope;
25853 } );
25854
25855 if ( parent.length ) {
25856 parentInstance = $( parent[ 0 ] ).droppable( "instance" );
25857 parentInstance.greedyChild = ( c === "isover" );
25858 }
25859 }
25860
25861 // We just moved into a greedy child
25862 if ( parentInstance && c === "isover" ) {
25863 parentInstance.isover = false;
25864 parentInstance.isout = true;
25865 parentInstance._out.call( parentInstance, event );
25866 }
25867
25868 this[ c ] = true;
25869 this[ c === "isout" ? "isover" : "isout" ] = false;
25870 this[ c === "isover" ? "_over" : "_out" ].call( this, event );
25871
25872 // We just moved out of a greedy child
25873 if ( parentInstance && c === "isout" ) {
25874 parentInstance.isout = false;
25875 parentInstance.isover = true;
25876 parentInstance._over.call( parentInstance, event );
25877 }
25878 } );
25879
25880 },
25881 dragStop: function( draggable, event ) {
25882 draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
25883
25884 // Call prepareOffsets one final time since IE does not fire return scroll events when
25885 // overflow was caused by drag (see #5003)
25886 if ( !draggable.options.refreshPositions ) {
25887 $.ui.ddmanager.prepareOffsets( draggable, event );
25888 }
25889 }
25890};
25891
25892// DEPRECATED
25893// TODO: switch return back to widget declaration at top of file when this is removed
25894if ( $.uiBackCompat === true ) {
25895
25896 // Backcompat for activeClass and hoverClass options
25897 $.widget( "ui.droppable", $.ui.droppable, {
25898 options: {
25899 hoverClass: false,
25900 activeClass: false
25901 },
25902 _addActiveClass: function() {
25903 this._super();
25904 if ( this.options.activeClass ) {
25905 this.element.addClass( this.options.activeClass );
25906 }
25907 },
25908 _removeActiveClass: function() {
25909 this._super();
25910 if ( this.options.activeClass ) {
25911 this.element.removeClass( this.options.activeClass );
25912 }
25913 },
25914 _addHoverClass: function() {
25915 this._super();
25916 if ( this.options.hoverClass ) {
25917 this.element.addClass( this.options.hoverClass );
25918 }
25919 },
25920 _removeHoverClass: function() {
25921 this._super();
25922 if ( this.options.hoverClass ) {
25923 this.element.removeClass( this.options.hoverClass );
25924 }
25925 }
25926 } );
25927}
25928
25929return $.ui.droppable;
25930
25931} );
25932
25933
25934
25935/*!
25936 * jQuery UI Progressbar 1.14.1
25937 * https://jqueryui.com
25938 *
25939 * Copyright OpenJS Foundation and other contributors
25940 * Released under the MIT license.
25941 * https://jquery.org/license
25942 */
25943
25944//>>label: Progressbar
25945//>>group: Widgets
25946/* eslint-disable max-len */
25947//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
25948/* eslint-enable max-len */
25949//>>docs: https://api.jqueryui.com/progressbar/
25950//>>demos: https://jqueryui.com/progressbar/
25951//>>css.structure: ../../themes/base/core.css
25952//>>css.structure: ../../themes/base/progressbar.css
25953//>>css.theme: ../../themes/base/theme.css
25954
25955( function( factory ) {
25956 "use strict";
25957
25958 if ( typeof define === "function" && define.amd ) {
25959
25960 // AMD. Register as an anonymous module.
25961 define( [
25962 "jquery",
25963 "../version",
25964 "../widget"
25965 ], factory );
25966 } else {
25967
25968 // Browser globals
25969 factory( jQuery );
25970 }
25971} )( function( $ ) {
25972"use strict";
25973
25974return $.widget( "ui.progressbar", {
25975 version: "1.14.1",
25976 options: {
25977 classes: {
25978 "ui-progressbar": "ui-corner-all",
25979 "ui-progressbar-value": "ui-corner-left",
25980 "ui-progressbar-complete": "ui-corner-right"
25981 },
25982 max: 100,
25983 value: 0,
25984
25985 change: null,
25986 complete: null
25987 },
25988
25989 min: 0,
25990
25991 _create: function() {
25992
25993 // Constrain initial value
25994 this.oldValue = this.options.value = this._constrainedValue();
25995
25996 this.element.attr( {
25997
25998 // Only set static values; aria-valuenow and aria-valuemax are
25999 // set inside _refreshValue()
26000 role: "progressbar",
26001 "aria-valuemin": this.min
26002 } );
26003 this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
26004
26005 this.valueDiv = $( "<div>" ).appendTo( this.element );
26006 this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
26007 this._refreshValue();
26008 },
26009
26010 _destroy: function() {
26011 this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
26012
26013 this.valueDiv.remove();
26014 },
26015
26016 value: function( newValue ) {
26017 if ( newValue === undefined ) {
26018 return this.options.value;
26019 }
26020
26021 this.options.value = this._constrainedValue( newValue );
26022 this._refreshValue();
26023 },
26024
26025 _constrainedValue: function( newValue ) {
26026 if ( newValue === undefined ) {
26027 newValue = this.options.value;
26028 }
26029
26030 this.indeterminate = newValue === false;
26031
26032 // Sanitize value
26033 if ( typeof newValue !== "number" ) {
26034 newValue = 0;
26035 }
26036
26037 return this.indeterminate ? false :
26038 Math.min( this.options.max, Math.max( this.min, newValue ) );
26039 },
26040
26041 _setOptions: function( options ) {
26042
26043 // Ensure "value" option is set after other values (like max)
26044 var value = options.value;
26045 delete options.value;
26046
26047 this._super( options );
26048
26049 this.options.value = this._constrainedValue( value );
26050 this._refreshValue();
26051 },
26052
26053 _setOption: function( key, value ) {
26054 if ( key === "max" ) {
26055
26056 // Don't allow a max less than min
26057 value = Math.max( this.min, value );
26058 }
26059 this._super( key, value );
26060 },
26061
26062 _setOptionDisabled: function( value ) {
26063 this._super( value );
26064
26065 this.element.attr( "aria-disabled", value );
26066 this._toggleClass( null, "ui-state-disabled", !!value );
26067 },
26068
26069 _percentage: function() {
26070 return this.indeterminate ?
26071 100 :
26072 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
26073 },
26074
26075 _refreshValue: function() {
26076 var value = this.options.value,
26077 percentage = this._percentage();
26078
26079 this.valueDiv
26080 .toggle( this.indeterminate || value > this.min )
26081 .width( percentage.toFixed( 0 ) + "%" );
26082
26083 this
26084 ._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
26085 value === this.options.max )
26086 ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
26087
26088 if ( this.indeterminate ) {
26089 this.element.removeAttr( "aria-valuenow" );
26090 if ( !this.overlayDiv ) {
26091 this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
26092 this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
26093 }
26094 } else {
26095 this.element.attr( {
26096 "aria-valuemax": this.options.max,
26097 "aria-valuenow": value
26098 } );
26099 if ( this.overlayDiv ) {
26100 this.overlayDiv.remove();
26101 this.overlayDiv = null;
26102 }
26103 }
26104
26105 if ( this.oldValue !== value ) {
26106 this.oldValue = value;
26107 this._trigger( "change" );
26108 }
26109 if ( value === this.options.max ) {
26110 this._trigger( "complete" );
26111 }
26112 }
26113} );
26114
26115} );
26116
26117
26118
26119
26120/*!
26121 * jQuery UI Selectable 1.14.1
26122 * https://jqueryui.com
26123 *
26124 * Copyright OpenJS Foundation and other contributors
26125 * Released under the MIT license.
26126 * https://jquery.org/license
26127 */
26128
26129//>>label: Selectable
26130//>>group: Interactions
26131//>>description: Allows groups of elements to be selected with the mouse.
26132//>>docs: https://api.jqueryui.com/selectable/
26133//>>demos: https://jqueryui.com/selectable/
26134//>>css.structure: ../../themes/base/selectable.css
26135
26136( function( factory ) {
26137 "use strict";
26138
26139 if ( typeof define === "function" && define.amd ) {
26140
26141 // AMD. Register as an anonymous module.
26142 define( [
26143 "jquery",
26144 "./mouse",
26145 "../version",
26146 "../widget"
26147 ], factory );
26148 } else {
26149
26150 // Browser globals
26151 factory( jQuery );
26152 }
26153} )( function( $ ) {
26154"use strict";
26155
26156return $.widget( "ui.selectable", $.ui.mouse, {
26157 version: "1.14.1",
26158 options: {
26159 appendTo: "body",
26160 autoRefresh: true,
26161 distance: 0,
26162 filter: "*",
26163 tolerance: "touch",
26164
26165 // Callbacks
26166 selected: null,
26167 selecting: null,
26168 start: null,
26169 stop: null,
26170 unselected: null,
26171 unselecting: null
26172 },
26173 _create: function() {
26174 var that = this;
26175
26176 this._addClass( "ui-selectable" );
26177
26178 this.dragged = false;
26179
26180 // Cache selectee children based on filter
26181 this.refresh = function() {
26182 that.elementPos = $( that.element[ 0 ] ).offset();
26183 that.selectees = $( that.options.filter, that.element[ 0 ] );
26184 that._addClass( that.selectees, "ui-selectee" );
26185 that.selectees.each( function() {
26186 var $this = $( this ),
26187 selecteeOffset = $this.offset(),
26188 pos = {
26189 left: selecteeOffset.left - that.elementPos.left,
26190 top: selecteeOffset.top - that.elementPos.top
26191 };
26192 $.data( this, "selectable-item", {
26193 element: this,
26194 $element: $this,
26195 left: pos.left,
26196 top: pos.top,
26197 right: pos.left + $this.outerWidth(),
26198 bottom: pos.top + $this.outerHeight(),
26199 startselected: false,
26200 selected: $this.hasClass( "ui-selected" ),
26201 selecting: $this.hasClass( "ui-selecting" ),
26202 unselecting: $this.hasClass( "ui-unselecting" )
26203 } );
26204 } );
26205 };
26206 this.refresh();
26207
26208 this._mouseInit();
26209
26210 this.helper = $( "<div>" );
26211 this._addClass( this.helper, "ui-selectable-helper" );
26212 },
26213
26214 _destroy: function() {
26215 this.selectees.removeData( "selectable-item" );
26216 this._mouseDestroy();
26217 },
26218
26219 _mouseStart: function( event ) {
26220 var that = this,
26221 options = this.options;
26222
26223 this.opos = [ event.pageX, event.pageY ];
26224 this.elementPos = $( this.element[ 0 ] ).offset();
26225
26226 if ( this.options.disabled ) {
26227 return;
26228 }
26229
26230 this.selectees = $( options.filter, this.element[ 0 ] );
26231
26232 this._trigger( "start", event );
26233
26234 $( options.appendTo ).append( this.helper );
26235
26236 // position helper (lasso)
26237 this.helper.css( {
26238 "left": event.pageX,
26239 "top": event.pageY,
26240 "width": 0,
26241 "height": 0
26242 } );
26243
26244 if ( options.autoRefresh ) {
26245 this.refresh();
26246 }
26247
26248 this.selectees.filter( ".ui-selected" ).each( function() {
26249 var selectee = $.data( this, "selectable-item" );
26250 selectee.startselected = true;
26251 if ( !event.metaKey && !event.ctrlKey ) {
26252 that._removeClass( selectee.$element, "ui-selected" );
26253 selectee.selected = false;
26254 that._addClass( selectee.$element, "ui-unselecting" );
26255 selectee.unselecting = true;
26256
26257 // selectable UNSELECTING callback
26258 that._trigger( "unselecting", event, {
26259 unselecting: selectee.element
26260 } );
26261 }
26262 } );
26263
26264 $( event.target ).parents().addBack().each( function() {
26265 var doSelect,
26266 selectee = $.data( this, "selectable-item" );
26267 if ( selectee ) {
26268 doSelect = ( !event.metaKey && !event.ctrlKey ) ||
26269 !selectee.$element.hasClass( "ui-selected" );
26270 that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
26271 ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
26272 selectee.unselecting = !doSelect;
26273 selectee.selecting = doSelect;
26274 selectee.selected = doSelect;
26275
26276 // selectable (UN)SELECTING callback
26277 if ( doSelect ) {
26278 that._trigger( "selecting", event, {
26279 selecting: selectee.element
26280 } );
26281 } else {
26282 that._trigger( "unselecting", event, {
26283 unselecting: selectee.element
26284 } );
26285 }
26286 return false;
26287 }
26288 } );
26289
26290 },
26291
26292 _mouseDrag: function( event ) {
26293
26294 this.dragged = true;
26295
26296 if ( this.options.disabled ) {
26297 return;
26298 }
26299
26300 var tmp,
26301 that = this,
26302 options = this.options,
26303 x1 = this.opos[ 0 ],
26304 y1 = this.opos[ 1 ],
26305 x2 = event.pageX,
26306 y2 = event.pageY;
26307
26308 if ( x1 > x2 ) {
26309 tmp = x2; x2 = x1; x1 = tmp;
26310 }
26311 if ( y1 > y2 ) {
26312 tmp = y2; y2 = y1; y1 = tmp;
26313 }
26314 this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
26315
26316 this.selectees.each( function() {
26317 var selectee = $.data( this, "selectable-item" ),
26318 hit = false,
26319 offset = {};
26320
26321 //prevent helper from being selected if appendTo: selectable
26322 if ( !selectee || selectee.element === that.element[ 0 ] ) {
26323 return;
26324 }
26325
26326 offset.left = selectee.left + that.elementPos.left;
26327 offset.right = selectee.right + that.elementPos.left;
26328 offset.top = selectee.top + that.elementPos.top;
26329 offset.bottom = selectee.bottom + that.elementPos.top;
26330
26331 if ( options.tolerance === "touch" ) {
26332 hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
26333 offset.bottom < y1 ) );
26334 } else if ( options.tolerance === "fit" ) {
26335 hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
26336 offset.bottom < y2 );
26337 }
26338
26339 if ( hit ) {
26340
26341 // SELECT
26342 if ( selectee.selected ) {
26343 that._removeClass( selectee.$element, "ui-selected" );
26344 selectee.selected = false;
26345 }
26346 if ( selectee.unselecting ) {
26347 that._removeClass( selectee.$element, "ui-unselecting" );
26348 selectee.unselecting = false;
26349 }
26350 if ( !selectee.selecting ) {
26351 that._addClass( selectee.$element, "ui-selecting" );
26352 selectee.selecting = true;
26353
26354 // selectable SELECTING callback
26355 that._trigger( "selecting", event, {
26356 selecting: selectee.element
26357 } );
26358 }
26359 } else {
26360
26361 // UNSELECT
26362 if ( selectee.selecting ) {
26363 if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
26364 that._removeClass( selectee.$element, "ui-selecting" );
26365 selectee.selecting = false;
26366 that._addClass( selectee.$element, "ui-selected" );
26367 selectee.selected = true;
26368 } else {
26369 that._removeClass( selectee.$element, "ui-selecting" );
26370 selectee.selecting = false;
26371 if ( selectee.startselected ) {
26372 that._addClass( selectee.$element, "ui-unselecting" );
26373 selectee.unselecting = true;
26374 }
26375
26376 // selectable UNSELECTING callback
26377 that._trigger( "unselecting", event, {
26378 unselecting: selectee.element
26379 } );
26380 }
26381 }
26382 if ( selectee.selected ) {
26383 if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
26384 that._removeClass( selectee.$element, "ui-selected" );
26385 selectee.selected = false;
26386
26387 that._addClass( selectee.$element, "ui-unselecting" );
26388 selectee.unselecting = true;
26389
26390 // selectable UNSELECTING callback
26391 that._trigger( "unselecting", event, {
26392 unselecting: selectee.element
26393 } );
26394 }
26395 }
26396 }
26397 } );
26398
26399 return false;
26400 },
26401
26402 _mouseStop: function( event ) {
26403 var that = this;
26404
26405 this.dragged = false;
26406
26407 $( ".ui-unselecting", this.element[ 0 ] ).each( function() {
26408 var selectee = $.data( this, "selectable-item" );
26409 that._removeClass( selectee.$element, "ui-unselecting" );
26410 selectee.unselecting = false;
26411 selectee.startselected = false;
26412 that._trigger( "unselected", event, {
26413 unselected: selectee.element
26414 } );
26415 } );
26416 $( ".ui-selecting", this.element[ 0 ] ).each( function() {
26417 var selectee = $.data( this, "selectable-item" );
26418 that._removeClass( selectee.$element, "ui-selecting" )
26419 ._addClass( selectee.$element, "ui-selected" );
26420 selectee.selecting = false;
26421 selectee.selected = true;
26422 selectee.startselected = true;
26423 that._trigger( "selected", event, {
26424 selected: selectee.element
26425 } );
26426 } );
26427 this._trigger( "stop", event );
26428
26429 this.helper.remove();
26430
26431 return false;
26432 }
26433
26434} );
26435
26436} );
26437
26438
26439
26440
26441
26442
26443
26444
26445
26446/*!
26447 * jQuery UI Selectmenu 1.14.1
26448 * https://jqueryui.com
26449 *
26450 * Copyright OpenJS Foundation and other contributors
26451 * Released under the MIT license.
26452 * https://jquery.org/license
26453 */
26454
26455//>>label: Selectmenu
26456//>>group: Widgets
26457/* eslint-disable max-len */
26458//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select.
26459/* eslint-enable max-len */
26460//>>docs: https://api.jqueryui.com/selectmenu/
26461//>>demos: https://jqueryui.com/selectmenu/
26462//>>css.structure: ../../themes/base/core.css
26463//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
26464//>>css.theme: ../../themes/base/theme.css
26465
26466( function( factory ) {
26467 "use strict";
26468
26469 if ( typeof define === "function" && define.amd ) {
26470
26471 // AMD. Register as an anonymous module.
26472 define( [
26473 "jquery",
26474 "./menu",
26475 "../form-reset-mixin",
26476 "../keycode",
26477 "../labels",
26478 "../position",
26479 "../unique-id",
26480 "../version",
26481 "../widget"
26482 ], factory );
26483 } else {
26484
26485 // Browser globals
26486 factory( jQuery );
26487 }
26488} )( function( $ ) {
26489"use strict";
26490
26491return $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
26492 version: "1.14.1",
26493 defaultElement: "<select>",
26494 options: {
26495 appendTo: null,
26496 classes: {
26497 "ui-selectmenu-button-open": "ui-corner-top",
26498 "ui-selectmenu-button-closed": "ui-corner-all"
26499 },
26500 disabled: null,
26501 icons: {
26502 button: "ui-icon-triangle-1-s"
26503 },
26504 position: {
26505 my: "left top",
26506 at: "left bottom",
26507 collision: "none"
26508 },
26509 width: false,
26510
26511 // Callbacks
26512 change: null,
26513 close: null,
26514 focus: null,
26515 open: null,
26516 select: null
26517 },
26518
26519 _create: function() {
26520 var selectmenuId = this.element.uniqueId().attr( "id" );
26521 this.ids = {
26522 element: selectmenuId,
26523 button: selectmenuId + "-button",
26524 menu: selectmenuId + "-menu"
26525 };
26526
26527 this._drawButton();
26528 this._drawMenu();
26529 this._bindFormResetHandler();
26530
26531 this._rendered = false;
26532 this.menuItems = $();
26533 },
26534
26535 _drawButton: function() {
26536 var icon,
26537 that = this,
26538 item = this._parseOption(
26539 this.element.find( "option:selected" ),
26540 this.element[ 0 ].selectedIndex
26541 );
26542
26543 // Associate existing label with the new button
26544 this.labels = this.element.labels().attr( "for", this.ids.button );
26545 this._on( this.labels, {
26546 click: function( event ) {
26547 this.button.trigger( "focus" );
26548 event.preventDefault();
26549 }
26550 } );
26551
26552 // Hide original select element
26553 this.element.hide();
26554
26555 // Create button
26556 this.button = $( "<span>", {
26557 tabindex: this.options.disabled ? -1 : 0,
26558 id: this.ids.button,
26559 role: "combobox",
26560 "aria-expanded": "false",
26561 "aria-autocomplete": "list",
26562 "aria-owns": this.ids.menu,
26563 "aria-haspopup": "true",
26564 title: this.element.attr( "title" )
26565 } )
26566 .insertAfter( this.element );
26567
26568 this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
26569 "ui-button ui-widget" );
26570
26571 icon = $( "<span>" ).appendTo( this.button );
26572 this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
26573 this.buttonItem = this._renderButtonItem( item )
26574 .appendTo( this.button );
26575
26576 if ( this.options.width !== false ) {
26577 this._resizeButton();
26578 }
26579
26580 this._on( this.button, this._buttonEvents );
26581 this.button.one( "focusin", function() {
26582
26583 // Delay rendering the menu items until the button receives focus.
26584 // The menu may have already been rendered via a programmatic open.
26585 if ( !that._rendered ) {
26586 that._refreshMenu();
26587 }
26588 } );
26589 },
26590
26591 _drawMenu: function() {
26592 var that = this;
26593
26594 // Create menu
26595 this.menu = $( "<ul>", {
26596 "aria-hidden": "true",
26597 "aria-labelledby": this.ids.button,
26598 id: this.ids.menu
26599 } );
26600
26601 // Wrap menu
26602 this.menuWrap = $( "<div>" ).append( this.menu );
26603 this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
26604 this.menuWrap.appendTo( this._appendTo() );
26605
26606 // Initialize menu widget
26607 this.menuInstance = this.menu
26608 .menu( {
26609 classes: {
26610 "ui-menu": "ui-corner-bottom"
26611 },
26612 role: "listbox",
26613 select: function( event, ui ) {
26614 event.preventDefault();
26615 that._select( ui.item.data( "ui-selectmenu-item" ), event );
26616 },
26617 focus: function( event, ui ) {
26618 var item = ui.item.data( "ui-selectmenu-item" );
26619
26620 // Prevent inital focus from firing and check if its a newly focused item
26621 if ( that.focusIndex != null && item.index !== that.focusIndex ) {
26622 that._trigger( "focus", event, { item: item } );
26623 if ( !that.isOpen ) {
26624 that._select( item, event );
26625 }
26626 }
26627 that.focusIndex = item.index;
26628
26629 that.button.attr( "aria-activedescendant",
26630 that.menuItems.eq( item.index ).attr( "id" ) );
26631 }
26632 } )
26633 .menu( "instance" );
26634
26635 // Don't close the menu on mouseleave
26636 this.menuInstance._off( this.menu, "mouseleave" );
26637
26638 // Cancel the menu's collapseAll on document click
26639 this.menuInstance._closeOnDocumentClick = function() {
26640 return false;
26641 };
26642
26643 // Selects often contain empty items, but never contain dividers
26644 this.menuInstance._isDivider = function() {
26645 return false;
26646 };
26647 },
26648
26649 refresh: function() {
26650 this._refreshMenu();
26651 this.buttonItem.replaceWith(
26652 this.buttonItem = this._renderButtonItem(
26653
26654 // Fall back to an empty object in case there are no options
26655 this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
26656 )
26657 );
26658 if ( this.options.width === null ) {
26659 this._resizeButton();
26660 }
26661 },
26662
26663 _refreshMenu: function() {
26664 var item,
26665 options = this.element.find( "option" );
26666
26667 this.menu.empty();
26668
26669 this._parseOptions( options );
26670 this._renderMenu( this.menu, this.items );
26671
26672 this.menuInstance.refresh();
26673 this.menuItems = this.menu.find( "li" )
26674 .not( ".ui-selectmenu-optgroup" )
26675 .find( ".ui-menu-item-wrapper" );
26676
26677 this._rendered = true;
26678
26679 if ( !options.length ) {
26680 return;
26681 }
26682
26683 item = this._getSelectedItem();
26684
26685 // Update the menu to have the correct item focused
26686 this.menuInstance.focus( null, item );
26687 this._setAria( item.data( "ui-selectmenu-item" ) );
26688
26689 // Set disabled state
26690 this._setOption( "disabled", this.element.prop( "disabled" ) );
26691 },
26692
26693 open: function( event ) {
26694 if ( this.options.disabled ) {
26695 return;
26696 }
26697
26698 // If this is the first time the menu is being opened, render the items
26699 if ( !this._rendered ) {
26700 this._refreshMenu();
26701 } else {
26702
26703 // Menu clears focus on close, reset focus to selected item
26704 this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
26705 this.menuInstance.focus( null, this._getSelectedItem() );
26706 }
26707
26708 // If there are no options, don't open the menu
26709 if ( !this.menuItems.length ) {
26710 return;
26711 }
26712
26713 this.isOpen = true;
26714 this._toggleAttr();
26715 this._resizeMenu();
26716 this._position();
26717
26718 this._on( this.document, this._documentClick );
26719
26720 this._trigger( "open", event );
26721 },
26722
26723 _position: function() {
26724 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
26725 },
26726
26727 close: function( event ) {
26728 if ( !this.isOpen ) {
26729 return;
26730 }
26731
26732 this.isOpen = false;
26733 this._toggleAttr();
26734
26735 this.range = null;
26736 this._off( this.document );
26737
26738 this._trigger( "close", event );
26739 },
26740
26741 widget: function() {
26742 return this.button;
26743 },
26744
26745 menuWidget: function() {
26746 return this.menu;
26747 },
26748
26749 _renderButtonItem: function( item ) {
26750 var buttonItem = $( "<span>" );
26751
26752 this._setText( buttonItem, item.label );
26753 this._addClass( buttonItem, "ui-selectmenu-text" );
26754
26755 return buttonItem;
26756 },
26757
26758 _renderMenu: function( ul, items ) {
26759 var that = this,
26760 currentOptgroup = "";
26761
26762 $.each( items, function( index, item ) {
26763 var li;
26764
26765 if ( item.optgroup !== currentOptgroup ) {
26766 li = $( "<li>", {
26767 text: item.optgroup
26768 } );
26769 that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
26770 ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
26771 " ui-state-disabled" :
26772 "" ) );
26773
26774 li.appendTo( ul );
26775
26776 currentOptgroup = item.optgroup;
26777 }
26778
26779 that._renderItemData( ul, item );
26780 } );
26781 },
26782
26783 _renderItemData: function( ul, item ) {
26784 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
26785 },
26786
26787 _renderItem: function( ul, item ) {
26788 var li = $( "<li>" ),
26789 wrapper = $( "<div>", {
26790 title: item.element.attr( "title" )
26791 } );
26792
26793 if ( item.disabled ) {
26794 this._addClass( li, null, "ui-state-disabled" );
26795 }
26796
26797 if ( item.hidden ) {
26798 li.prop( "hidden", true );
26799 } else {
26800 this._setText( wrapper, item.label );
26801 }
26802
26803 return li.append( wrapper ).appendTo( ul );
26804 },
26805
26806 _setText: function( element, value ) {
26807 if ( value ) {
26808 element.text( value );
26809 } else {
26810 element.html( "&#160;" );
26811 }
26812 },
26813
26814 _move: function( direction, event ) {
26815 var item, next,
26816 filter = ".ui-menu-item";
26817
26818 if ( this.isOpen ) {
26819 item = this.menuItems.eq( this.focusIndex ).parent( "li" );
26820 } else {
26821 item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
26822 filter += ":not(.ui-state-disabled)";
26823 }
26824
26825 if ( direction === "first" || direction === "last" ) {
26826 next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
26827 } else {
26828 next = item[ direction + "All" ]( filter ).eq( 0 );
26829 }
26830
26831 if ( next.length ) {
26832 this.menuInstance.focus( event, next );
26833 }
26834 },
26835
26836 _getSelectedItem: function() {
26837 return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
26838 },
26839
26840 _toggle: function( event ) {
26841 this[ this.isOpen ? "close" : "open" ]( event );
26842 },
26843
26844 _setSelection: function() {
26845 var selection;
26846
26847 if ( !this.range ) {
26848 return;
26849 }
26850
26851 selection = window.getSelection();
26852 selection.removeAllRanges();
26853 selection.addRange( this.range );
26854 },
26855
26856 _documentClick: {
26857 mousedown: function( event ) {
26858 if ( !this.isOpen ) {
26859 return;
26860 }
26861
26862 if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
26863 CSS.escape( this.ids.button ) ).length ) {
26864 this.close( event );
26865 }
26866 }
26867 },
26868
26869 _buttonEvents: {
26870
26871 // Prevent text selection from being reset when interacting with the selectmenu (#10144)
26872 mousedown: function() {
26873 var selection = window.getSelection();
26874 if ( selection.rangeCount ) {
26875 this.range = selection.getRangeAt( 0 );
26876 }
26877 },
26878
26879 click: function( event ) {
26880 this._setSelection();
26881 this._toggle( event );
26882 },
26883
26884 keydown: function( event ) {
26885 var preventDefault = true;
26886 switch ( event.keyCode ) {
26887 case $.ui.keyCode.TAB:
26888 case $.ui.keyCode.ESCAPE:
26889 this.close( event );
26890 preventDefault = false;
26891 break;
26892 case $.ui.keyCode.ENTER:
26893 if ( this.isOpen ) {
26894 this._selectFocusedItem( event );
26895 }
26896 break;
26897 case $.ui.keyCode.UP:
26898 if ( event.altKey ) {
26899 this._toggle( event );
26900 } else {
26901 this._move( "prev", event );
26902 }
26903 break;
26904 case $.ui.keyCode.DOWN:
26905 if ( event.altKey ) {
26906 this._toggle( event );
26907 } else {
26908 this._move( "next", event );
26909 }
26910 break;
26911 case $.ui.keyCode.SPACE:
26912 if ( this.isOpen ) {
26913 this._selectFocusedItem( event );
26914 } else {
26915 this._toggle( event );
26916 }
26917 break;
26918 case $.ui.keyCode.LEFT:
26919 this._move( "prev", event );
26920 break;
26921 case $.ui.keyCode.RIGHT:
26922 this._move( "next", event );
26923 break;
26924 case $.ui.keyCode.HOME:
26925 case $.ui.keyCode.PAGE_UP:
26926 this._move( "first", event );
26927 break;
26928 case $.ui.keyCode.END:
26929 case $.ui.keyCode.PAGE_DOWN:
26930 this._move( "last", event );
26931 break;
26932 default:
26933 this.menu.trigger( event );
26934 preventDefault = false;
26935 }
26936
26937 if ( preventDefault ) {
26938 event.preventDefault();
26939 }
26940 }
26941 },
26942
26943 _selectFocusedItem: function( event ) {
26944 var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
26945 if ( !item.hasClass( "ui-state-disabled" ) ) {
26946 this._select( item.data( "ui-selectmenu-item" ), event );
26947 }
26948 },
26949
26950 _select: function( item, event ) {
26951 var oldIndex = this.element[ 0 ].selectedIndex;
26952
26953 // Change native select element
26954 this.element[ 0 ].selectedIndex = item.index;
26955 this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
26956 this._setAria( item );
26957 this._trigger( "select", event, { item: item } );
26958
26959 if ( item.index !== oldIndex ) {
26960 this._trigger( "change", event, { item: item } );
26961 }
26962
26963 this.close( event );
26964 },
26965
26966 _setAria: function( item ) {
26967 var id = this.menuItems.eq( item.index ).attr( "id" );
26968
26969 this.button.attr( {
26970 "aria-labelledby": id,
26971 "aria-activedescendant": id
26972 } );
26973 this.menu.attr( "aria-activedescendant", id );
26974 },
26975
26976 _setOption: function( key, value ) {
26977 if ( key === "icons" ) {
26978 var icon = this.button.find( "span.ui-icon" );
26979 this._removeClass( icon, null, this.options.icons.button )
26980 ._addClass( icon, null, value.button );
26981 }
26982
26983 this._super( key, value );
26984
26985 if ( key === "appendTo" ) {
26986 this.menuWrap.appendTo( this._appendTo() );
26987 }
26988
26989 if ( key === "width" ) {
26990 this._resizeButton();
26991 }
26992 },
26993
26994 _setOptionDisabled: function( value ) {
26995 this._super( value );
26996
26997 this.menuInstance.option( "disabled", value );
26998 this.button.attr( "aria-disabled", value );
26999 this._toggleClass( this.button, null, "ui-state-disabled", value );
27000
27001 this.element.prop( "disabled", value );
27002 if ( value ) {
27003 this.button.attr( "tabindex", -1 );
27004 this.close();
27005 } else {
27006 this.button.attr( "tabindex", 0 );
27007 }
27008 },
27009
27010 _appendTo: function() {
27011 var element = this.options.appendTo;
27012
27013 if ( element ) {
27014 element = element.jquery || element.nodeType ?
27015 $( element ) :
27016 this.document.find( element ).eq( 0 );
27017 }
27018
27019 if ( !element || !element[ 0 ] ) {
27020 element = this.element.closest( ".ui-front, dialog" );
27021 }
27022
27023 if ( !element.length ) {
27024 element = this.document[ 0 ].body;
27025 }
27026
27027 return element;
27028 },
27029
27030 _toggleAttr: function() {
27031 this.button.attr( "aria-expanded", this.isOpen );
27032
27033 // We can't use two _toggleClass() calls here, because we need to make sure
27034 // we always remove classes first and add them second, otherwise if both classes have the
27035 // same theme class, it will be removed after we add it.
27036 this._removeClass( this.button, "ui-selectmenu-button-" +
27037 ( this.isOpen ? "closed" : "open" ) )
27038 ._addClass( this.button, "ui-selectmenu-button-" +
27039 ( this.isOpen ? "open" : "closed" ) )
27040 ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
27041
27042 this.menu.attr( "aria-hidden", !this.isOpen );
27043 },
27044
27045 _resizeButton: function() {
27046 var width = this.options.width;
27047
27048 // For `width: false`, just remove inline style and stop
27049 if ( width === false ) {
27050 this.button.css( "width", "" );
27051 return;
27052 }
27053
27054 // For `width: null`, match the width of the original element
27055 if ( width === null ) {
27056 width = this.element.show().outerWidth();
27057 this.element.hide();
27058 }
27059
27060 this.button.outerWidth( width );
27061 },
27062
27063 _resizeMenu: function() {
27064 this.menu.outerWidth( Math.max(
27065 this.button.outerWidth(),
27066 this.menu.width( "" ).outerWidth()
27067 ) );
27068 },
27069
27070 _getCreateOptions: function() {
27071 var options = this._super();
27072
27073 options.disabled = this.element.prop( "disabled" );
27074
27075 return options;
27076 },
27077
27078 _parseOptions: function( options ) {
27079 var that = this,
27080 data = [];
27081 options.each( function( index, item ) {
27082 data.push( that._parseOption( $( item ), index ) );
27083 } );
27084 this.items = data;
27085 },
27086
27087 _parseOption: function( option, index ) {
27088 var optgroup = option.parent( "optgroup" );
27089
27090 return {
27091 element: option,
27092 index: index,
27093 value: option.val(),
27094 label: option.text(),
27095 hidden: optgroup.prop( "hidden" ) || option.prop( "hidden" ),
27096 optgroup: optgroup.attr( "label" ) || "",
27097 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
27098 };
27099 },
27100
27101 _destroy: function() {
27102 this._unbindFormResetHandler();
27103 this.menuWrap.remove();
27104 this.button.remove();
27105 this.element.show();
27106 this.element.removeUniqueId();
27107 this.labels.attr( "for", this.ids.element );
27108 }
27109} ] );
27110
27111} );
27112
27113
27114
27115
27116
27117/*!
27118 * jQuery UI Slider 1.14.1
27119 * https://jqueryui.com
27120 *
27121 * Copyright OpenJS Foundation and other contributors
27122 * Released under the MIT license.
27123 * https://jquery.org/license
27124 */
27125
27126//>>label: Slider
27127//>>group: Widgets
27128//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
27129//>>docs: https://api.jqueryui.com/slider/
27130//>>demos: https://jqueryui.com/slider/
27131//>>css.structure: ../../themes/base/core.css
27132//>>css.structure: ../../themes/base/slider.css
27133//>>css.theme: ../../themes/base/theme.css
27134
27135( function( factory ) {
27136 "use strict";
27137
27138 if ( typeof define === "function" && define.amd ) {
27139
27140 // AMD. Register as an anonymous module.
27141 define( [
27142 "jquery",
27143 "./mouse",
27144 "../keycode",
27145 "../version",
27146 "../widget"
27147 ], factory );
27148 } else {
27149
27150 // Browser globals
27151 factory( jQuery );
27152 }
27153} )( function( $ ) {
27154"use strict";
27155
27156return $.widget( "ui.slider", $.ui.mouse, {
27157 version: "1.14.1",
27158 widgetEventPrefix: "slide",
27159
27160 options: {
27161 animate: false,
27162 classes: {
27163 "ui-slider": "ui-corner-all",
27164 "ui-slider-handle": "ui-corner-all",
27165
27166 // Note: ui-widget-header isn't the most fittingly semantic framework class for this
27167 // element, but worked best visually with a variety of themes
27168 "ui-slider-range": "ui-corner-all ui-widget-header"
27169 },
27170 distance: 0,
27171 max: 100,
27172 min: 0,
27173 orientation: "horizontal",
27174 range: false,
27175 step: 1,
27176 value: 0,
27177 values: null,
27178
27179 // Callbacks
27180 change: null,
27181 slide: null,
27182 start: null,
27183 stop: null
27184 },
27185
27186 // Number of pages in a slider
27187 // (how many times can you page up/down to go through the whole range)
27188 numPages: 5,
27189
27190 _create: function() {
27191 this._keySliding = false;
27192 this._mouseSliding = false;
27193 this._animateOff = true;
27194 this._handleIndex = null;
27195 this._detectOrientation();
27196 this._mouseInit();
27197 this._calculateNewMax();
27198
27199 this._addClass( "ui-slider ui-slider-" + this.orientation,
27200 "ui-widget ui-widget-content" );
27201
27202 this._refresh();
27203
27204 this._animateOff = false;
27205 },
27206
27207 _refresh: function() {
27208 this._createRange();
27209 this._createHandles();
27210 this._setupEvents();
27211 this._refreshValue();
27212 },
27213
27214 _createHandles: function() {
27215 var i, handleCount,
27216 options = this.options,
27217 existingHandles = this.element.find( ".ui-slider-handle" ),
27218 handle = "<span tabindex='0'></span>",
27219 handles = [];
27220
27221 handleCount = ( options.values && options.values.length ) || 1;
27222
27223 if ( existingHandles.length > handleCount ) {
27224 existingHandles.slice( handleCount ).remove();
27225 existingHandles = existingHandles.slice( 0, handleCount );
27226 }
27227
27228 for ( i = existingHandles.length; i < handleCount; i++ ) {
27229 handles.push( handle );
27230 }
27231
27232 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
27233
27234 this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
27235
27236 this.handle = this.handles.eq( 0 );
27237
27238 this.handles.each( function( i ) {
27239 $( this )
27240 .data( "ui-slider-handle-index", i )
27241 .attr( "tabIndex", 0 );
27242 } );
27243 },
27244
27245 _createRange: function() {
27246 var options = this.options;
27247
27248 if ( options.range ) {
27249 if ( options.range === true ) {
27250 if ( !options.values ) {
27251 options.values = [ this._valueMin(), this._valueMin() ];
27252 } else if ( options.values.length && options.values.length !== 2 ) {
27253 options.values = [ options.values[ 0 ], options.values[ 0 ] ];
27254 } else if ( Array.isArray( options.values ) ) {
27255 options.values = options.values.slice( 0 );
27256 }
27257 }
27258
27259 if ( !this.range || !this.range.length ) {
27260 this.range = $( "<div>" )
27261 .appendTo( this.element );
27262
27263 this._addClass( this.range, "ui-slider-range" );
27264 } else {
27265 this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
27266
27267 // Handle range switching from true to min/max
27268 this.range.css( {
27269 "left": "",
27270 "bottom": ""
27271 } );
27272 }
27273 if ( options.range === "min" || options.range === "max" ) {
27274 this._addClass( this.range, "ui-slider-range-" + options.range );
27275 }
27276 } else {
27277 if ( this.range ) {
27278 this.range.remove();
27279 }
27280 this.range = null;
27281 }
27282 },
27283
27284 _setupEvents: function() {
27285 this._off( this.handles );
27286 this._on( this.handles, this._handleEvents );
27287 this._hoverable( this.handles );
27288 this._focusable( this.handles );
27289 },
27290
27291 _destroy: function() {
27292 this.handles.remove();
27293 if ( this.range ) {
27294 this.range.remove();
27295 }
27296
27297 this._mouseDestroy();
27298 },
27299
27300 _mouseCapture: function( event ) {
27301 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
27302 that = this,
27303 o = this.options;
27304
27305 if ( o.disabled ) {
27306 return false;
27307 }
27308
27309 this.elementSize = {
27310 width: this.element.outerWidth(),
27311 height: this.element.outerHeight()
27312 };
27313 this.elementOffset = this.element.offset();
27314
27315 position = { x: event.pageX, y: event.pageY };
27316 normValue = this._normValueFromMouse( position );
27317 distance = this._valueMax() - this._valueMin() + 1;
27318 this.handles.each( function( i ) {
27319 var thisDistance = Math.abs( normValue - that.values( i ) );
27320 if ( ( distance > thisDistance ) ||
27321 ( distance === thisDistance &&
27322 ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
27323 distance = thisDistance;
27324 closestHandle = $( this );
27325 index = i;
27326 }
27327 } );
27328
27329 allowed = this._start( event, index );
27330 if ( allowed === false ) {
27331 return false;
27332 }
27333 this._mouseSliding = true;
27334
27335 this._handleIndex = index;
27336
27337 this._addClass( closestHandle, null, "ui-state-active" );
27338 closestHandle.trigger( "focus" );
27339
27340 offset = closestHandle.offset();
27341 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
27342 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
27343 left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
27344 top: event.pageY - offset.top -
27345 ( closestHandle.height() / 2 ) -
27346 ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
27347 ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
27348 ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
27349 };
27350
27351 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
27352 this._slide( event, index, normValue );
27353 }
27354 this._animateOff = true;
27355 return true;
27356 },
27357
27358 _mouseStart: function() {
27359 return true;
27360 },
27361
27362 _mouseDrag: function( event ) {
27363 var position = { x: event.pageX, y: event.pageY },
27364 normValue = this._normValueFromMouse( position );
27365
27366 this._slide( event, this._handleIndex, normValue );
27367
27368 return false;
27369 },
27370
27371 _mouseStop: function( event ) {
27372 this._removeClass( this.handles, null, "ui-state-active" );
27373 this._mouseSliding = false;
27374
27375 this._stop( event, this._handleIndex );
27376 this._change( event, this._handleIndex );
27377
27378 this._handleIndex = null;
27379 this._clickOffset = null;
27380 this._animateOff = false;
27381
27382 return false;
27383 },
27384
27385 _detectOrientation: function() {
27386 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
27387 },
27388
27389 _normValueFromMouse: function( position ) {
27390 var pixelTotal,
27391 pixelMouse,
27392 percentMouse,
27393 valueTotal,
27394 valueMouse;
27395
27396 if ( this.orientation === "horizontal" ) {
27397 pixelTotal = this.elementSize.width;
27398 pixelMouse = position.x - this.elementOffset.left -
27399 ( this._clickOffset ? this._clickOffset.left : 0 );
27400 } else {
27401 pixelTotal = this.elementSize.height;
27402 pixelMouse = position.y - this.elementOffset.top -
27403 ( this._clickOffset ? this._clickOffset.top : 0 );
27404 }
27405
27406 percentMouse = ( pixelMouse / pixelTotal );
27407 if ( percentMouse > 1 ) {
27408 percentMouse = 1;
27409 }
27410 if ( percentMouse < 0 ) {
27411 percentMouse = 0;
27412 }
27413 if ( this.orientation === "vertical" ) {
27414 percentMouse = 1 - percentMouse;
27415 }
27416
27417 valueTotal = this._valueMax() - this._valueMin();
27418 valueMouse = this._valueMin() + percentMouse * valueTotal;
27419
27420 return this._trimAlignValue( valueMouse );
27421 },
27422
27423 _uiHash: function( index, value, values ) {
27424 var uiHash = {
27425 handle: this.handles[ index ],
27426 handleIndex: index,
27427 value: value !== undefined ? value : this.value()
27428 };
27429
27430 if ( this._hasMultipleValues() ) {
27431 uiHash.value = value !== undefined ? value : this.values( index );
27432 uiHash.values = values || this.values();
27433 }
27434
27435 return uiHash;
27436 },
27437
27438 _hasMultipleValues: function() {
27439 return this.options.values && this.options.values.length;
27440 },
27441
27442 _start: function( event, index ) {
27443 return this._trigger( "start", event, this._uiHash( index ) );
27444 },
27445
27446 _slide: function( event, index, newVal ) {
27447 var allowed, otherVal,
27448 currentValue = this.value(),
27449 newValues = this.values();
27450
27451 if ( this._hasMultipleValues() ) {
27452 otherVal = this.values( index ? 0 : 1 );
27453 currentValue = this.values( index );
27454
27455 if ( this.options.values.length === 2 && this.options.range === true ) {
27456 newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
27457 }
27458
27459 newValues[ index ] = newVal;
27460 }
27461
27462 if ( newVal === currentValue ) {
27463 return;
27464 }
27465
27466 allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
27467
27468 // A slide can be canceled by returning false from the slide callback
27469 if ( allowed === false ) {
27470 return;
27471 }
27472
27473 if ( this._hasMultipleValues() ) {
27474 this.values( index, newVal );
27475 } else {
27476 this.value( newVal );
27477 }
27478 },
27479
27480 _stop: function( event, index ) {
27481 this._trigger( "stop", event, this._uiHash( index ) );
27482 },
27483
27484 _change: function( event, index ) {
27485 if ( !this._keySliding && !this._mouseSliding ) {
27486
27487 //store the last changed value index for reference when handles overlap
27488 this._lastChangedValue = index;
27489 this._trigger( "change", event, this._uiHash( index ) );
27490 }
27491 },
27492
27493 value: function( newValue ) {
27494 if ( arguments.length ) {
27495 this.options.value = this._trimAlignValue( newValue );
27496 this._refreshValue();
27497 this._change( null, 0 );
27498 return;
27499 }
27500
27501 return this._value();
27502 },
27503
27504 values: function( index, newValue ) {
27505 var vals,
27506 newValues,
27507 i;
27508
27509 if ( arguments.length > 1 ) {
27510 this.options.values[ index ] = this._trimAlignValue( newValue );
27511 this._refreshValue();
27512 this._change( null, index );
27513 return;
27514 }
27515
27516 if ( arguments.length ) {
27517 if ( Array.isArray( arguments[ 0 ] ) ) {
27518 vals = this.options.values;
27519 newValues = arguments[ 0 ];
27520 for ( i = 0; i < vals.length; i += 1 ) {
27521 vals[ i ] = this._trimAlignValue( newValues[ i ] );
27522 this._change( null, i );
27523 }
27524 this._refreshValue();
27525 } else {
27526 if ( this._hasMultipleValues() ) {
27527 return this._values( index );
27528 } else {
27529 return this.value();
27530 }
27531 }
27532 } else {
27533 return this._values();
27534 }
27535 },
27536
27537 _setOption: function( key, value ) {
27538 var i,
27539 valsLength = 0;
27540
27541 if ( key === "range" && this.options.range === true ) {
27542 if ( value === "min" ) {
27543 this.options.value = this._values( 0 );
27544 this.options.values = null;
27545 } else if ( value === "max" ) {
27546 this.options.value = this._values( this.options.values.length - 1 );
27547 this.options.values = null;
27548 }
27549 }
27550
27551 if ( Array.isArray( this.options.values ) ) {
27552 valsLength = this.options.values.length;
27553 }
27554
27555 this._super( key, value );
27556
27557 switch ( key ) {
27558 case "orientation":
27559 this._detectOrientation();
27560 this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
27561 ._addClass( "ui-slider-" + this.orientation );
27562 this._refreshValue();
27563 if ( this.options.range ) {
27564 this._refreshRange( value );
27565 }
27566
27567 // Reset positioning from previous orientation
27568 this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
27569 break;
27570 case "value":
27571 this._animateOff = true;
27572 this._refreshValue();
27573 this._change( null, 0 );
27574 this._animateOff = false;
27575 break;
27576 case "values":
27577 this._animateOff = true;
27578 this._refreshValue();
27579
27580 // Start from the last handle to prevent unreachable handles (#9046)
27581 for ( i = valsLength - 1; i >= 0; i-- ) {
27582 this._change( null, i );
27583 }
27584 this._animateOff = false;
27585 break;
27586 case "step":
27587 case "min":
27588 case "max":
27589 this._animateOff = true;
27590 this._calculateNewMax();
27591 this._refreshValue();
27592 this._animateOff = false;
27593 break;
27594 case "range":
27595 this._animateOff = true;
27596 this._refresh();
27597 this._animateOff = false;
27598 break;
27599 }
27600 },
27601
27602 _setOptionDisabled: function( value ) {
27603 this._super( value );
27604
27605 this._toggleClass( null, "ui-state-disabled", !!value );
27606 },
27607
27608 //internal value getter
27609 // _value() returns value trimmed by min and max, aligned by step
27610 _value: function() {
27611 var val = this.options.value;
27612 val = this._trimAlignValue( val );
27613
27614 return val;
27615 },
27616
27617 //internal values getter
27618 // _values() returns array of values trimmed by min and max, aligned by step
27619 // _values( index ) returns single value trimmed by min and max, aligned by step
27620 _values: function( index ) {
27621 var val,
27622 vals,
27623 i;
27624
27625 if ( arguments.length ) {
27626 val = this.options.values[ index ];
27627 val = this._trimAlignValue( val );
27628
27629 return val;
27630 } else if ( this._hasMultipleValues() ) {
27631
27632 // .slice() creates a copy of the array
27633 // this copy gets trimmed by min and max and then returned
27634 vals = this.options.values.slice();
27635 for ( i = 0; i < vals.length; i += 1 ) {
27636 vals[ i ] = this._trimAlignValue( vals[ i ] );
27637 }
27638
27639 return vals;
27640 } else {
27641 return [];
27642 }
27643 },
27644
27645 // Returns the step-aligned value that val is closest to, between (inclusive) min and max
27646 _trimAlignValue: function( val ) {
27647 if ( val <= this._valueMin() ) {
27648 return this._valueMin();
27649 }
27650 if ( val >= this._valueMax() ) {
27651 return this._valueMax();
27652 }
27653 var step = ( this.options.step > 0 ) ? this.options.step : 1,
27654 valModStep = ( val - this._valueMin() ) % step,
27655 alignValue = val - valModStep;
27656
27657 if ( Math.abs( valModStep ) * 2 >= step ) {
27658 alignValue += ( valModStep > 0 ) ? step : ( -step );
27659 }
27660
27661 // Since JavaScript has problems with large floats, round
27662 // the final value to 5 digits after the decimal point (see #4124)
27663 return parseFloat( alignValue.toFixed( 5 ) );
27664 },
27665
27666 _calculateNewMax: function() {
27667 var max = this.options.max,
27668 min = this._valueMin(),
27669 step = this.options.step,
27670 aboveMin = Math.round( ( max - min ) / step ) * step;
27671 max = aboveMin + min;
27672 if ( max > this.options.max ) {
27673
27674 //If max is not divisible by step, rounding off may increase its value
27675 max -= step;
27676 }
27677 this.max = parseFloat( max.toFixed( this._precision() ) );
27678 },
27679
27680 _precision: function() {
27681 var precision = this._precisionOf( this.options.step );
27682 if ( this.options.min !== null ) {
27683 precision = Math.max( precision, this._precisionOf( this.options.min ) );
27684 }
27685 return precision;
27686 },
27687
27688 _precisionOf: function( num ) {
27689 var str = num.toString(),
27690 decimal = str.indexOf( "." );
27691 return decimal === -1 ? 0 : str.length - decimal - 1;
27692 },
27693
27694 _valueMin: function() {
27695 return this.options.min;
27696 },
27697
27698 _valueMax: function() {
27699 return this.max;
27700 },
27701
27702 _refreshRange: function( orientation ) {
27703 if ( orientation === "vertical" ) {
27704 this.range.css( { "width": "", "left": "" } );
27705 }
27706 if ( orientation === "horizontal" ) {
27707 this.range.css( { "height": "", "bottom": "" } );
27708 }
27709 },
27710
27711 _refreshValue: function() {
27712 var lastValPercent, valPercent, value, valueMin, valueMax,
27713 oRange = this.options.range,
27714 o = this.options,
27715 that = this,
27716 animate = ( !this._animateOff ) ? o.animate : false,
27717 _set = {};
27718
27719 if ( this._hasMultipleValues() ) {
27720 this.handles.each( function( i ) {
27721 valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
27722 that._valueMin() ) * 100;
27723 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
27724 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
27725 if ( that.options.range === true ) {
27726 if ( that.orientation === "horizontal" ) {
27727 if ( i === 0 ) {
27728 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
27729 left: valPercent + "%"
27730 }, o.animate );
27731 }
27732 if ( i === 1 ) {
27733 that.range[ animate ? "animate" : "css" ]( {
27734 width: ( valPercent - lastValPercent ) + "%"
27735 }, {
27736 queue: false,
27737 duration: o.animate
27738 } );
27739 }
27740 } else {
27741 if ( i === 0 ) {
27742 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
27743 bottom: ( valPercent ) + "%"
27744 }, o.animate );
27745 }
27746 if ( i === 1 ) {
27747 that.range[ animate ? "animate" : "css" ]( {
27748 height: ( valPercent - lastValPercent ) + "%"
27749 }, {
27750 queue: false,
27751 duration: o.animate
27752 } );
27753 }
27754 }
27755 }
27756 lastValPercent = valPercent;
27757 } );
27758 } else {
27759 value = this.value();
27760 valueMin = this._valueMin();
27761 valueMax = this._valueMax();
27762 valPercent = ( valueMax !== valueMin ) ?
27763 ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
27764 0;
27765 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
27766 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
27767
27768 if ( oRange === "min" && this.orientation === "horizontal" ) {
27769 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
27770 width: valPercent + "%"
27771 }, o.animate );
27772 }
27773 if ( oRange === "max" && this.orientation === "horizontal" ) {
27774 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
27775 width: ( 100 - valPercent ) + "%"
27776 }, o.animate );
27777 }
27778 if ( oRange === "min" && this.orientation === "vertical" ) {
27779 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
27780 height: valPercent + "%"
27781 }, o.animate );
27782 }
27783 if ( oRange === "max" && this.orientation === "vertical" ) {
27784 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
27785 height: ( 100 - valPercent ) + "%"
27786 }, o.animate );
27787 }
27788 }
27789 },
27790
27791 _handleEvents: {
27792 keydown: function( event ) {
27793 var allowed, curVal, newVal, step,
27794 index = $( event.target ).data( "ui-slider-handle-index" );
27795
27796 switch ( event.keyCode ) {
27797 case $.ui.keyCode.HOME:
27798 case $.ui.keyCode.END:
27799 case $.ui.keyCode.PAGE_UP:
27800 case $.ui.keyCode.PAGE_DOWN:
27801 case $.ui.keyCode.UP:
27802 case $.ui.keyCode.RIGHT:
27803 case $.ui.keyCode.DOWN:
27804 case $.ui.keyCode.LEFT:
27805 event.preventDefault();
27806 if ( !this._keySliding ) {
27807 this._keySliding = true;
27808 this._addClass( $( event.target ), null, "ui-state-active" );
27809 allowed = this._start( event, index );
27810 if ( allowed === false ) {
27811 return;
27812 }
27813 }
27814 break;
27815 }
27816
27817 step = this.options.step;
27818 if ( this._hasMultipleValues() ) {
27819 curVal = newVal = this.values( index );
27820 } else {
27821 curVal = newVal = this.value();
27822 }
27823
27824 switch ( event.keyCode ) {
27825 case $.ui.keyCode.HOME:
27826 newVal = this._valueMin();
27827 break;
27828 case $.ui.keyCode.END:
27829 newVal = this._valueMax();
27830 break;
27831 case $.ui.keyCode.PAGE_UP:
27832 newVal = this._trimAlignValue(
27833 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
27834 );
27835 break;
27836 case $.ui.keyCode.PAGE_DOWN:
27837 newVal = this._trimAlignValue(
27838 curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
27839 break;
27840 case $.ui.keyCode.UP:
27841 case $.ui.keyCode.RIGHT:
27842 if ( curVal === this._valueMax() ) {
27843 return;
27844 }
27845 newVal = this._trimAlignValue( curVal + step );
27846 break;
27847 case $.ui.keyCode.DOWN:
27848 case $.ui.keyCode.LEFT:
27849 if ( curVal === this._valueMin() ) {
27850 return;
27851 }
27852 newVal = this._trimAlignValue( curVal - step );
27853 break;
27854 }
27855
27856 this._slide( event, index, newVal );
27857 },
27858 keyup: function( event ) {
27859 var index = $( event.target ).data( "ui-slider-handle-index" );
27860
27861 if ( this._keySliding ) {
27862 this._keySliding = false;
27863 this._stop( event, index );
27864 this._change( event, index );
27865 this._removeClass( $( event.target ), null, "ui-state-active" );
27866 }
27867 }
27868 }
27869} );
27870
27871} );
27872
27873
27874
27875
27876
27877
27878/*!
27879 * jQuery UI Sortable 1.14.1
27880 * https://jqueryui.com
27881 *
27882 * Copyright OpenJS Foundation and other contributors
27883 * Released under the MIT license.
27884 * https://jquery.org/license
27885 */
27886
27887//>>label: Sortable
27888//>>group: Interactions
27889//>>description: Enables items in a list to be sorted using the mouse.
27890//>>docs: https://api.jqueryui.com/sortable/
27891//>>demos: https://jqueryui.com/sortable/
27892//>>css.structure: ../../themes/base/sortable.css
27893
27894( function( factory ) {
27895 "use strict";
27896
27897 if ( typeof define === "function" && define.amd ) {
27898
27899 // AMD. Register as an anonymous module.
27900 define( [
27901 "jquery",
27902 "./mouse",
27903 "../data",
27904 "../scroll-parent",
27905 "../version",
27906 "../widget"
27907 ], factory );
27908 } else {
27909
27910 // Browser globals
27911 factory( jQuery );
27912 }
27913} )( function( $ ) {
27914"use strict";
27915
27916return $.widget( "ui.sortable", $.ui.mouse, {
27917 version: "1.14.1",
27918 widgetEventPrefix: "sort",
27919 ready: false,
27920 options: {
27921 appendTo: "parent",
27922 axis: false,
27923 connectWith: false,
27924 containment: false,
27925 cursor: "auto",
27926 cursorAt: false,
27927 dropOnEmpty: true,
27928 forcePlaceholderSize: false,
27929 forceHelperSize: false,
27930 grid: false,
27931 handle: false,
27932 helper: "original",
27933 items: "> *",
27934 opacity: false,
27935 placeholder: false,
27936 revert: false,
27937 scroll: true,
27938 scrollSensitivity: 20,
27939 scrollSpeed: 20,
27940 scope: "default",
27941 tolerance: "intersect",
27942 zIndex: 1000,
27943
27944 // Callbacks
27945 activate: null,
27946 beforeStop: null,
27947 change: null,
27948 deactivate: null,
27949 out: null,
27950 over: null,
27951 receive: null,
27952 remove: null,
27953 sort: null,
27954 start: null,
27955 stop: null,
27956 update: null
27957 },
27958
27959 _isOverAxis: function( x, reference, size ) {
27960 return ( x >= reference ) && ( x < ( reference + size ) );
27961 },
27962
27963 _isFloating: function( item ) {
27964 return ( /left|right/ ).test( item.css( "float" ) ) ||
27965 ( /inline|table-cell/ ).test( item.css( "display" ) );
27966 },
27967
27968 _create: function() {
27969 this.containerCache = {};
27970 this._addClass( "ui-sortable" );
27971
27972 //Get the items
27973 this.refresh();
27974
27975 //Let's determine the parent's offset
27976 this.offset = this.element.offset();
27977
27978 //Initialize mouse events for interaction
27979 this._mouseInit();
27980
27981 this._setHandleClassName();
27982
27983 //We're ready to go
27984 this.ready = true;
27985
27986 },
27987
27988 _setOption: function( key, value ) {
27989 this._super( key, value );
27990
27991 if ( key === "handle" ) {
27992 this._setHandleClassName();
27993 }
27994 },
27995
27996 _setHandleClassName: function() {
27997 var that = this;
27998 this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
27999 $.each( this.items, function() {
28000 that._addClass(
28001 this.instance.options.handle ?
28002 this.item.find( this.instance.options.handle ) :
28003 this.item,
28004 "ui-sortable-handle"
28005 );
28006 } );
28007 },
28008
28009 _destroy: function() {
28010 this._mouseDestroy();
28011
28012 for ( var i = this.items.length - 1; i >= 0; i-- ) {
28013 this.items[ i ].item.removeData( this.widgetName + "-item" );
28014 }
28015
28016 return this;
28017 },
28018
28019 _mouseCapture: function( event, overrideHandle ) {
28020 var currentItem = null,
28021 validHandle = false,
28022 that = this;
28023
28024 if ( this.reverting ) {
28025 return false;
28026 }
28027
28028 if ( this.options.disabled || this.options.type === "static" ) {
28029 return false;
28030 }
28031
28032 //We have to refresh the items data once first
28033 this._refreshItems( event );
28034
28035 //Find out if the clicked node (or one of its parents) is a actual item in this.items
28036 $( event.target ).parents().each( function() {
28037 if ( $.data( this, that.widgetName + "-item" ) === that ) {
28038 currentItem = $( this );
28039 return false;
28040 }
28041 } );
28042 if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
28043 currentItem = $( event.target );
28044 }
28045
28046 if ( !currentItem ) {
28047 return false;
28048 }
28049 if ( this.options.handle && !overrideHandle ) {
28050 $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
28051 if ( this === event.target ) {
28052 validHandle = true;
28053 }
28054 } );
28055 if ( !validHandle ) {
28056 return false;
28057 }
28058 }
28059
28060 this.currentItem = currentItem;
28061 this._removeCurrentsFromItems();
28062 return true;
28063
28064 },
28065
28066 _mouseStart: function( event, overrideHandle, noActivation ) {
28067
28068 var i, body,
28069 o = this.options;
28070
28071 this.currentContainer = this;
28072
28073 //We only need to call refreshPositions, because the refreshItems call has been moved to
28074 // mouseCapture
28075 this.refreshPositions();
28076
28077 //Prepare the dragged items parent
28078 this.appendTo = $( o.appendTo !== "parent" ?
28079 o.appendTo :
28080 this.currentItem.parent() );
28081
28082 //Create and append the visible helper
28083 this.helper = this._createHelper( event );
28084
28085 //Cache the helper size
28086 this._cacheHelperProportions();
28087
28088 /*
28089 * - Position generation -
28090 * This block generates everything position related - it's the core of draggables.
28091 */
28092
28093 //Cache the margins of the original element
28094 this._cacheMargins();
28095
28096 //The element's absolute position on the page minus margins
28097 this.offset = this.currentItem.offset();
28098 this.offset = {
28099 top: this.offset.top - this.margins.top,
28100 left: this.offset.left - this.margins.left
28101 };
28102
28103 $.extend( this.offset, {
28104 click: { //Where the click happened, relative to the element
28105 left: event.pageX - this.offset.left,
28106 top: event.pageY - this.offset.top
28107 },
28108
28109 // This is a relative to absolute position minus the actual position calculation -
28110 // only used for relative positioned helper
28111 relative: this._getRelativeOffset()
28112 } );
28113
28114 // After we get the helper offset, but before we get the parent offset we can
28115 // change the helper's position to absolute
28116 // TODO: Still need to figure out a way to make relative sorting possible
28117 this.helper.css( "position", "absolute" );
28118 this.cssPosition = this.helper.css( "position" );
28119
28120 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
28121 if ( o.cursorAt ) {
28122 this._adjustOffsetFromHelper( o.cursorAt );
28123 }
28124
28125 //Cache the former DOM position
28126 this.domPosition = {
28127 prev: this.currentItem.prev()[ 0 ],
28128 parent: this.currentItem.parent()[ 0 ]
28129 };
28130
28131 // If the helper is not the original, hide the original so it's not playing any role during
28132 // the drag, won't cause anything bad this way
28133 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
28134 this.currentItem.hide();
28135 }
28136
28137 //Create the placeholder
28138 this._createPlaceholder();
28139
28140 //Get the next scrolling parent
28141 this.scrollParent = this.placeholder.scrollParent();
28142
28143 $.extend( this.offset, {
28144 parent: this._getParentOffset()
28145 } );
28146
28147 //Set a containment if given in the options
28148 if ( o.containment ) {
28149 this._setContainment();
28150 }
28151
28152 if ( o.cursor && o.cursor !== "auto" ) { // cursor option
28153 body = this.document.find( "body" );
28154
28155 this._storedStylesheet =
28156 $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
28157 }
28158
28159 // We need to make sure to grab the zIndex before setting the
28160 // opacity, because setting the opacity to anything lower than 1
28161 // causes the zIndex to change from "auto" to 0.
28162 if ( o.zIndex ) { // zIndex option
28163 if ( this.helper.css( "zIndex" ) ) {
28164 this._storedZIndex = this.helper.css( "zIndex" );
28165 }
28166 this.helper.css( "zIndex", o.zIndex );
28167 }
28168
28169 if ( o.opacity ) { // opacity option
28170 if ( this.helper.css( "opacity" ) ) {
28171 this._storedOpacity = this.helper.css( "opacity" );
28172 }
28173 this.helper.css( "opacity", o.opacity );
28174 }
28175
28176 //Prepare scrolling
28177 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
28178 this.scrollParent[ 0 ].tagName !== "HTML" ) {
28179 this.overflowOffset = this.scrollParent.offset();
28180 }
28181
28182 //Call callbacks
28183 this._trigger( "start", event, this._uiHash() );
28184
28185 //Recache the helper size
28186 if ( !this._preserveHelperProportions ) {
28187 this._cacheHelperProportions();
28188 }
28189
28190 //Post "activate" events to possible containers
28191 if ( !noActivation ) {
28192 for ( i = this.containers.length - 1; i >= 0; i-- ) {
28193 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
28194 }
28195 }
28196
28197 //Prepare possible droppables
28198 if ( $.ui.ddmanager ) {
28199 $.ui.ddmanager.current = this;
28200 }
28201
28202 if ( $.ui.ddmanager && !o.dropBehaviour ) {
28203 $.ui.ddmanager.prepareOffsets( this, event );
28204 }
28205
28206 this.dragging = true;
28207
28208 this._addClass( this.helper, "ui-sortable-helper" );
28209
28210 //Move the helper, if needed
28211 if ( !this.helper.parent().is( this.appendTo ) ) {
28212 this.helper.detach().appendTo( this.appendTo );
28213
28214 //Update position
28215 this.offset.parent = this._getParentOffset();
28216 }
28217
28218 //Generate the original position
28219 this.position = this.originalPosition = this._generatePosition( event );
28220 this.originalPageX = event.pageX;
28221 this.originalPageY = event.pageY;
28222 this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" );
28223
28224 this._mouseDrag( event );
28225
28226 return true;
28227
28228 },
28229
28230 _scroll: function( event ) {
28231 var o = this.options,
28232 scrolled = false;
28233
28234 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
28235 this.scrollParent[ 0 ].tagName !== "HTML" ) {
28236
28237 if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
28238 event.pageY < o.scrollSensitivity ) {
28239 this.scrollParent[ 0 ].scrollTop =
28240 scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
28241 } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
28242 this.scrollParent[ 0 ].scrollTop =
28243 scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
28244 }
28245
28246 if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
28247 event.pageX < o.scrollSensitivity ) {
28248 this.scrollParent[ 0 ].scrollLeft = scrolled =
28249 this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
28250 } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
28251 this.scrollParent[ 0 ].scrollLeft = scrolled =
28252 this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
28253 }
28254
28255 } else {
28256
28257 if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
28258 scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
28259 } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
28260 o.scrollSensitivity ) {
28261 scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
28262 }
28263
28264 if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
28265 scrolled = this.document.scrollLeft(
28266 this.document.scrollLeft() - o.scrollSpeed
28267 );
28268 } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
28269 o.scrollSensitivity ) {
28270 scrolled = this.document.scrollLeft(
28271 this.document.scrollLeft() + o.scrollSpeed
28272 );
28273 }
28274
28275 }
28276
28277 return scrolled;
28278 },
28279
28280 _mouseDrag: function( event ) {
28281 var i, item, itemElement, intersection,
28282 o = this.options;
28283
28284 //Compute the helpers position
28285 this.position = this._generatePosition( event );
28286 this.positionAbs = this._convertPositionTo( "absolute" );
28287
28288 //Set the helper position
28289 if ( !this.options.axis || this.options.axis !== "y" ) {
28290 this.helper[ 0 ].style.left = this.position.left + "px";
28291 }
28292 if ( !this.options.axis || this.options.axis !== "x" ) {
28293 this.helper[ 0 ].style.top = this.position.top + "px";
28294 }
28295
28296 //Do scrolling
28297 if ( o.scroll ) {
28298 if ( this._scroll( event ) !== false ) {
28299
28300 //Update item positions used in position checks
28301 this._refreshItemPositions( true );
28302
28303 if ( $.ui.ddmanager && !o.dropBehaviour ) {
28304 $.ui.ddmanager.prepareOffsets( this, event );
28305 }
28306 }
28307 }
28308
28309 this.dragDirection = {
28310 vertical: this._getDragVerticalDirection(),
28311 horizontal: this._getDragHorizontalDirection()
28312 };
28313
28314 //Rearrange
28315 for ( i = this.items.length - 1; i >= 0; i-- ) {
28316
28317 //Cache variables and intersection, continue if no intersection
28318 item = this.items[ i ];
28319 itemElement = item.item[ 0 ];
28320 intersection = this._intersectsWithPointer( item );
28321 if ( !intersection ) {
28322 continue;
28323 }
28324
28325 // Only put the placeholder inside the current Container, skip all
28326 // items from other containers. This works because when moving
28327 // an item from one container to another the
28328 // currentContainer is switched before the placeholder is moved.
28329 //
28330 // Without this, moving items in "sub-sortables" can cause
28331 // the placeholder to jitter between the outer and inner container.
28332 if ( item.instance !== this.currentContainer ) {
28333 continue;
28334 }
28335
28336 // Cannot intersect with itself
28337 // no useless actions that have been done before
28338 // no action if the item moved is the parent of the item checked
28339 if ( itemElement !== this.currentItem[ 0 ] &&
28340 this.placeholder[ intersection === 1 ?
28341 "next" : "prev" ]()[ 0 ] !== itemElement &&
28342 !$.contains( this.placeholder[ 0 ], itemElement ) &&
28343 ( this.options.type === "semi-dynamic" ?
28344 !$.contains( this.element[ 0 ], itemElement ) :
28345 true
28346 )
28347 ) {
28348
28349 this.direction = intersection === 1 ? "down" : "up";
28350
28351 if ( this.options.tolerance === "pointer" ||
28352 this._intersectsWithSides( item ) ) {
28353 this._rearrange( event, item );
28354 } else {
28355 break;
28356 }
28357
28358 this._trigger( "change", event, this._uiHash() );
28359 break;
28360 }
28361 }
28362
28363 //Post events to containers
28364 this._contactContainers( event );
28365
28366 //Interconnect with droppables
28367 if ( $.ui.ddmanager ) {
28368 $.ui.ddmanager.drag( this, event );
28369 }
28370
28371 //Call callbacks
28372 this._trigger( "sort", event, this._uiHash() );
28373
28374 this.lastPositionAbs = this.positionAbs;
28375 return false;
28376
28377 },
28378
28379 _mouseStop: function( event, noPropagation ) {
28380
28381 if ( !event ) {
28382 return;
28383 }
28384
28385 //If we are using droppables, inform the manager about the drop
28386 if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
28387 $.ui.ddmanager.drop( this, event );
28388 }
28389
28390 if ( this.options.revert ) {
28391 var that = this,
28392 cur = this.placeholder.offset(),
28393 axis = this.options.axis,
28394 animation = {};
28395
28396 if ( !axis || axis === "x" ) {
28397 animation.left = cur.left - this.offset.parent.left - this.margins.left +
28398 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
28399 0 :
28400 this.offsetParent[ 0 ].scrollLeft
28401 );
28402 }
28403 if ( !axis || axis === "y" ) {
28404 animation.top = cur.top - this.offset.parent.top - this.margins.top +
28405 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
28406 0 :
28407 this.offsetParent[ 0 ].scrollTop
28408 );
28409 }
28410 this.reverting = true;
28411 $( this.helper ).animate(
28412 animation,
28413 parseInt( this.options.revert, 10 ) || 500,
28414 function() {
28415 that._clear( event );
28416 }
28417 );
28418 } else {
28419 this._clear( event, noPropagation );
28420 }
28421
28422 return false;
28423
28424 },
28425
28426 cancel: function() {
28427
28428 if ( this.dragging ) {
28429
28430 this._mouseUp( new $.Event( "mouseup", { target: null } ) );
28431
28432 if ( this.options.helper === "original" ) {
28433 this.currentItem.css( this._storedCSS );
28434 this._removeClass( this.currentItem, "ui-sortable-helper" );
28435 } else {
28436 this.currentItem.show();
28437 }
28438
28439 //Post deactivating events to containers
28440 for ( var i = this.containers.length - 1; i >= 0; i-- ) {
28441 this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
28442 if ( this.containers[ i ].containerCache.over ) {
28443 this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
28444 this.containers[ i ].containerCache.over = 0;
28445 }
28446 }
28447
28448 }
28449
28450 if ( this.placeholder ) {
28451
28452 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
28453 // it unbinds ALL events from the original node!
28454 if ( this.placeholder[ 0 ].parentNode ) {
28455 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
28456 }
28457 if ( this.options.helper !== "original" && this.helper &&
28458 this.helper[ 0 ].parentNode ) {
28459 this.helper.remove();
28460 }
28461
28462 $.extend( this, {
28463 helper: null,
28464 dragging: false,
28465 reverting: false,
28466 _noFinalSort: null
28467 } );
28468
28469 if ( this.domPosition.prev ) {
28470 $( this.domPosition.prev ).after( this.currentItem );
28471 } else {
28472 $( this.domPosition.parent ).prepend( this.currentItem );
28473 }
28474 }
28475
28476 return this;
28477
28478 },
28479
28480 serialize: function( o ) {
28481
28482 var items = this._getItemsAsjQuery( o && o.connected ),
28483 str = [];
28484 o = o || {};
28485
28486 $( items ).each( function() {
28487 var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
28488 .match( o.expression || ( /(.+)[\-=_](.+)/ ) );
28489 if ( res ) {
28490 str.push(
28491 ( o.key || res[ 1 ] + "[]" ) +
28492 "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
28493 }
28494 } );
28495
28496 if ( !str.length && o.key ) {
28497 str.push( o.key + "=" );
28498 }
28499
28500 return str.join( "&" );
28501
28502 },
28503
28504 toArray: function( o ) {
28505
28506 var items = this._getItemsAsjQuery( o && o.connected ),
28507 ret = [];
28508
28509 o = o || {};
28510
28511 items.each( function() {
28512 ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
28513 } );
28514 return ret;
28515
28516 },
28517
28518 /* Be careful with the following core functions */
28519 _intersectsWith: function( item ) {
28520
28521 var x1 = this.positionAbs.left,
28522 x2 = x1 + this.helperProportions.width,
28523 y1 = this.positionAbs.top,
28524 y2 = y1 + this.helperProportions.height,
28525 l = item.left,
28526 r = l + item.width,
28527 t = item.top,
28528 b = t + item.height,
28529 dyClick = this.offset.click.top,
28530 dxClick = this.offset.click.left,
28531 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
28532 ( y1 + dyClick ) < b ),
28533 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
28534 ( x1 + dxClick ) < r ),
28535 isOverElement = isOverElementHeight && isOverElementWidth;
28536
28537 if ( this.options.tolerance === "pointer" ||
28538 this.options.forcePointerForContainers ||
28539 ( this.options.tolerance !== "pointer" &&
28540 this.helperProportions[ this.floating ? "width" : "height" ] >
28541 item[ this.floating ? "width" : "height" ] )
28542 ) {
28543 return isOverElement;
28544 } else {
28545
28546 return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
28547 x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
28548 t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
28549 y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
28550
28551 }
28552 },
28553
28554 _intersectsWithPointer: function( item ) {
28555 var verticalDirection, horizontalDirection,
28556 isOverElementHeight = ( this.options.axis === "x" ) ||
28557 this._isOverAxis(
28558 this.positionAbs.top + this.offset.click.top, item.top, item.height ),
28559 isOverElementWidth = ( this.options.axis === "y" ) ||
28560 this._isOverAxis(
28561 this.positionAbs.left + this.offset.click.left, item.left, item.width ),
28562 isOverElement = isOverElementHeight && isOverElementWidth;
28563
28564 if ( !isOverElement ) {
28565 return false;
28566 }
28567
28568 verticalDirection = this.dragDirection.vertical;
28569 horizontalDirection = this.dragDirection.horizontal;
28570
28571 return this.floating ?
28572 ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) :
28573 ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
28574
28575 },
28576
28577 _intersectsWithSides: function( item ) {
28578
28579 var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
28580 this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
28581 isOverRightHalf = this._isOverAxis( this.positionAbs.left +
28582 this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
28583 verticalDirection = this.dragDirection.vertical,
28584 horizontalDirection = this.dragDirection.horizontal;
28585
28586 if ( this.floating && horizontalDirection ) {
28587 return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
28588 ( horizontalDirection === "left" && !isOverRightHalf ) );
28589 } else {
28590 return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
28591 ( verticalDirection === "up" && !isOverBottomHalf ) );
28592 }
28593
28594 },
28595
28596 _getDragVerticalDirection: function() {
28597 var delta = this.positionAbs.top - this.lastPositionAbs.top;
28598 return delta !== 0 && ( delta > 0 ? "down" : "up" );
28599 },
28600
28601 _getDragHorizontalDirection: function() {
28602 var delta = this.positionAbs.left - this.lastPositionAbs.left;
28603 return delta !== 0 && ( delta > 0 ? "right" : "left" );
28604 },
28605
28606 refresh: function( event ) {
28607 this._refreshItems( event );
28608 this._setHandleClassName();
28609 this.refreshPositions();
28610 return this;
28611 },
28612
28613 _connectWith: function() {
28614 var options = this.options;
28615 return options.connectWith.constructor === String ?
28616 [ options.connectWith ] :
28617 options.connectWith;
28618 },
28619
28620 _getItemsAsjQuery: function( connected ) {
28621
28622 var i, j, cur, inst,
28623 items = [],
28624 queries = [],
28625 connectWith = this._connectWith();
28626
28627 if ( connectWith && connected ) {
28628 for ( i = connectWith.length - 1; i >= 0; i-- ) {
28629 cur = $( connectWith[ i ], this.document[ 0 ] );
28630 for ( j = cur.length - 1; j >= 0; j-- ) {
28631 inst = $.data( cur[ j ], this.widgetFullName );
28632 if ( inst && inst !== this && !inst.options.disabled ) {
28633 queries.push( [ typeof inst.options.items === "function" ?
28634 inst.options.items.call( inst.element ) :
28635 $( inst.options.items, inst.element )
28636 .not( ".ui-sortable-helper" )
28637 .not( ".ui-sortable-placeholder" ), inst ] );
28638 }
28639 }
28640 }
28641 }
28642
28643 queries.push( [ typeof this.options.items === "function" ?
28644 this.options.items
28645 .call( this.element, null, { options: this.options, item: this.currentItem } ) :
28646 $( this.options.items, this.element )
28647 .not( ".ui-sortable-helper" )
28648 .not( ".ui-sortable-placeholder" ), this ] );
28649
28650 function addItems() {
28651 items.push( this );
28652 }
28653 for ( i = queries.length - 1; i >= 0; i-- ) {
28654 queries[ i ][ 0 ].each( addItems );
28655 }
28656
28657 return $( items );
28658
28659 },
28660
28661 _removeCurrentsFromItems: function() {
28662
28663 var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
28664
28665 this.items = $.grep( this.items, function( item ) {
28666 for ( var j = 0; j < list.length; j++ ) {
28667 if ( list[ j ] === item.item[ 0 ] ) {
28668 return false;
28669 }
28670 }
28671 return true;
28672 } );
28673
28674 },
28675
28676 _refreshItems: function( event ) {
28677
28678 this.items = [];
28679 this.containers = [ this ];
28680
28681 var i, j, cur, inst, targetData, _queries, item, queriesLength,
28682 items = this.items,
28683 queries = [ [ typeof this.options.items === "function" ?
28684 this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
28685 $( this.options.items, this.element ), this ] ],
28686 connectWith = this._connectWith();
28687
28688 //Shouldn't be run the first time through due to massive slow-down
28689 if ( connectWith && this.ready ) {
28690 for ( i = connectWith.length - 1; i >= 0; i-- ) {
28691 cur = $( connectWith[ i ], this.document[ 0 ] );
28692 for ( j = cur.length - 1; j >= 0; j-- ) {
28693 inst = $.data( cur[ j ], this.widgetFullName );
28694 if ( inst && inst !== this && !inst.options.disabled ) {
28695 queries.push( [ typeof inst.options.items === "function" ?
28696 inst.options.items
28697 .call( inst.element[ 0 ], event, { item: this.currentItem } ) :
28698 $( inst.options.items, inst.element ), inst ] );
28699 this.containers.push( inst );
28700 }
28701 }
28702 }
28703 }
28704
28705 for ( i = queries.length - 1; i >= 0; i-- ) {
28706 targetData = queries[ i ][ 1 ];
28707 _queries = queries[ i ][ 0 ];
28708
28709 for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
28710 item = $( _queries[ j ] );
28711
28712 // Data for target checking (mouse manager)
28713 item.data( this.widgetName + "-item", targetData );
28714
28715 items.push( {
28716 item: item,
28717 instance: targetData,
28718 width: 0, height: 0,
28719 left: 0, top: 0
28720 } );
28721 }
28722 }
28723
28724 },
28725
28726 _refreshItemPositions: function( fast ) {
28727 var i, item, t, p;
28728
28729 for ( i = this.items.length - 1; i >= 0; i-- ) {
28730 item = this.items[ i ];
28731
28732 //We ignore calculating positions of all connected containers when we're not over them
28733 if ( this.currentContainer && item.instance !== this.currentContainer &&
28734 item.item[ 0 ] !== this.currentItem[ 0 ] ) {
28735 continue;
28736 }
28737
28738 t = this.options.toleranceElement ?
28739 $( this.options.toleranceElement, item.item ) :
28740 item.item;
28741
28742 if ( !fast ) {
28743 item.width = t.outerWidth();
28744 item.height = t.outerHeight();
28745 }
28746
28747 p = t.offset();
28748 item.left = p.left;
28749 item.top = p.top;
28750 }
28751 },
28752
28753 refreshPositions: function( fast ) {
28754
28755 // Determine whether items are being displayed horizontally
28756 this.floating = this.items.length ?
28757 this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
28758 false;
28759
28760 // This has to be redone because due to the item being moved out/into the offsetParent,
28761 // the offsetParent's position will change
28762 if ( this.offsetParent && this.helper ) {
28763 this.offset.parent = this._getParentOffset();
28764 }
28765
28766 this._refreshItemPositions( fast );
28767
28768 var i, p;
28769
28770 if ( this.options.custom && this.options.custom.refreshContainers ) {
28771 this.options.custom.refreshContainers.call( this );
28772 } else {
28773 for ( i = this.containers.length - 1; i >= 0; i-- ) {
28774 p = this.containers[ i ].element.offset();
28775 this.containers[ i ].containerCache.left = p.left;
28776 this.containers[ i ].containerCache.top = p.top;
28777 this.containers[ i ].containerCache.width =
28778 this.containers[ i ].element.outerWidth();
28779 this.containers[ i ].containerCache.height =
28780 this.containers[ i ].element.outerHeight();
28781 }
28782 }
28783
28784 return this;
28785 },
28786
28787 _createPlaceholder: function( that ) {
28788 that = that || this;
28789 var className, nodeName,
28790 o = that.options;
28791
28792 if ( !o.placeholder || o.placeholder.constructor === String ) {
28793 className = o.placeholder;
28794 nodeName = that.currentItem[ 0 ].nodeName.toLowerCase();
28795 o.placeholder = {
28796 element: function() {
28797
28798 var element = $( "<" + nodeName + ">", that.document[ 0 ] );
28799
28800 that._addClass( element, "ui-sortable-placeholder",
28801 className || that.currentItem[ 0 ].className )
28802 ._removeClass( element, "ui-sortable-helper" );
28803
28804 if ( nodeName === "tbody" ) {
28805 that._createTrPlaceholder(
28806 that.currentItem.find( "tr" ).eq( 0 ),
28807 $( "<tr>", that.document[ 0 ] ).appendTo( element )
28808 );
28809 } else if ( nodeName === "tr" ) {
28810 that._createTrPlaceholder( that.currentItem, element );
28811 } else if ( nodeName === "img" ) {
28812 element.attr( "src", that.currentItem.attr( "src" ) );
28813 }
28814
28815 if ( !className ) {
28816 element.css( "visibility", "hidden" );
28817 }
28818
28819 return element;
28820 },
28821 update: function( container, p ) {
28822
28823 // 1. If a className is set as 'placeholder option, we don't force sizes -
28824 // the class is responsible for that
28825 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a
28826 // class name is specified
28827 if ( className && !o.forcePlaceholderSize ) {
28828 return;
28829 }
28830
28831 // If the element doesn't have a actual height or width by itself (without
28832 // styles coming from a stylesheet), it receives the inline height and width
28833 // from the dragged item. Or, if it's a tbody or tr, it's going to have a height
28834 // anyway since we're populating them with <td>s above, but they're unlikely to
28835 // be the correct height on their own if the row heights are dynamic, so we'll
28836 // always assign the height of the dragged item given forcePlaceholderSize
28837 // is true.
28838 if ( !p.height() || ( o.forcePlaceholderSize &&
28839 ( nodeName === "tbody" || nodeName === "tr" ) ) ) {
28840 p.height(
28841 that.currentItem.innerHeight() -
28842 parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
28843 parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
28844 }
28845 if ( !p.width() ) {
28846 p.width(
28847 that.currentItem.innerWidth() -
28848 parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
28849 parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
28850 }
28851 }
28852 };
28853 }
28854
28855 //Create the placeholder
28856 that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
28857
28858 //Append it after the actual current item
28859 that.currentItem.after( that.placeholder );
28860
28861 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
28862 o.placeholder.update( that, that.placeholder );
28863
28864 },
28865
28866 _createTrPlaceholder: function( sourceTr, targetTr ) {
28867 var that = this;
28868
28869 sourceTr.children().each( function() {
28870 $( "<td>&#160;</td>", that.document[ 0 ] )
28871 .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
28872 .appendTo( targetTr );
28873 } );
28874 },
28875
28876 _contactContainers: function( event ) {
28877 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
28878 floating, axis,
28879 innermostContainer = null,
28880 innermostIndex = null;
28881
28882 // Get innermost container that intersects with item
28883 for ( i = this.containers.length - 1; i >= 0; i-- ) {
28884
28885 // Never consider a container that's located within the item itself
28886 if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
28887 continue;
28888 }
28889
28890 if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
28891
28892 // If we've already found a container and it's more "inner" than this, then continue
28893 if ( innermostContainer &&
28894 $.contains(
28895 this.containers[ i ].element[ 0 ],
28896 innermostContainer.element[ 0 ] ) ) {
28897 continue;
28898 }
28899
28900 innermostContainer = this.containers[ i ];
28901 innermostIndex = i;
28902
28903 } else {
28904
28905 // container doesn't intersect. trigger "out" event if necessary
28906 if ( this.containers[ i ].containerCache.over ) {
28907 this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
28908 this.containers[ i ].containerCache.over = 0;
28909 }
28910 }
28911
28912 }
28913
28914 // If no intersecting containers found, return
28915 if ( !innermostContainer ) {
28916 return;
28917 }
28918
28919 // Move the item into the container if it's not there already
28920 if ( this.containers.length === 1 ) {
28921 if ( !this.containers[ innermostIndex ].containerCache.over ) {
28922 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
28923 this.containers[ innermostIndex ].containerCache.over = 1;
28924 }
28925 } else {
28926
28927 // When entering a new container, we will find the item with the least distance and
28928 // append our item near it
28929 dist = 10000;
28930 itemWithLeastDistance = null;
28931 floating = innermostContainer.floating || this._isFloating( this.currentItem );
28932 posProperty = floating ? "left" : "top";
28933 sizeProperty = floating ? "width" : "height";
28934 axis = floating ? "pageX" : "pageY";
28935
28936 for ( j = this.items.length - 1; j >= 0; j-- ) {
28937 if ( !$.contains(
28938 this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
28939 ) {
28940 continue;
28941 }
28942 if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
28943 continue;
28944 }
28945
28946 cur = this.items[ j ].item.offset()[ posProperty ];
28947 nearBottom = false;
28948 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
28949 nearBottom = true;
28950 }
28951
28952 if ( Math.abs( event[ axis ] - cur ) < dist ) {
28953 dist = Math.abs( event[ axis ] - cur );
28954 itemWithLeastDistance = this.items[ j ];
28955 this.direction = nearBottom ? "up" : "down";
28956 }
28957 }
28958
28959 //Check if dropOnEmpty is enabled
28960 if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
28961 return;
28962 }
28963
28964 if ( this.currentContainer === this.containers[ innermostIndex ] ) {
28965 if ( !this.currentContainer.containerCache.over ) {
28966 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
28967 this.currentContainer.containerCache.over = 1;
28968 }
28969 return;
28970 }
28971
28972 if ( itemWithLeastDistance ) {
28973 this._rearrange( event, itemWithLeastDistance, null, true );
28974 } else {
28975 this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
28976 }
28977 this._trigger( "change", event, this._uiHash() );
28978 this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
28979 this.currentContainer = this.containers[ innermostIndex ];
28980
28981 //Update the placeholder
28982 this.options.placeholder.update( this.currentContainer, this.placeholder );
28983
28984 //Update scrollParent
28985 this.scrollParent = this.placeholder.scrollParent();
28986
28987 //Update overflowOffset
28988 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
28989 this.scrollParent[ 0 ].tagName !== "HTML" ) {
28990 this.overflowOffset = this.scrollParent.offset();
28991 }
28992
28993 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
28994 this.containers[ innermostIndex ].containerCache.over = 1;
28995 }
28996
28997 },
28998
28999 _createHelper: function( event ) {
29000
29001 var o = this.options,
29002 helper = typeof o.helper === "function" ?
29003 $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
29004 ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
29005
29006 //Add the helper to the DOM if that didn't happen already
29007 if ( !helper.parents( "body" ).length ) {
29008 this.appendTo[ 0 ].appendChild( helper[ 0 ] );
29009 }
29010
29011 if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
29012 this._storedCSS = {
29013 width: this.currentItem[ 0 ].style.width,
29014 height: this.currentItem[ 0 ].style.height,
29015 position: this.currentItem.css( "position" ),
29016 top: this.currentItem.css( "top" ),
29017 left: this.currentItem.css( "left" )
29018 };
29019 }
29020
29021 if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
29022 helper.width( this.currentItem.width() );
29023 }
29024 if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
29025 helper.height( this.currentItem.height() );
29026 }
29027
29028 return helper;
29029
29030 },
29031
29032 _adjustOffsetFromHelper: function( obj ) {
29033 if ( typeof obj === "string" ) {
29034 obj = obj.split( " " );
29035 }
29036 if ( Array.isArray( obj ) ) {
29037 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
29038 }
29039 if ( "left" in obj ) {
29040 this.offset.click.left = obj.left + this.margins.left;
29041 }
29042 if ( "right" in obj ) {
29043 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
29044 }
29045 if ( "top" in obj ) {
29046 this.offset.click.top = obj.top + this.margins.top;
29047 }
29048 if ( "bottom" in obj ) {
29049 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
29050 }
29051 },
29052
29053 _getParentOffset: function() {
29054
29055 //Get the offsetParent and cache its position
29056 this.offsetParent = this.helper.offsetParent();
29057 var po = this.offsetParent.offset();
29058
29059 // This is a special case where we need to modify a offset calculated on start, since the
29060 // following happened:
29061 // 1. The position of the helper is absolute, so it's position is calculated based on the
29062 // next positioned parent
29063 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
29064 // the document, which means that the scroll is included in the initial calculation of the
29065 // offset of the parent, and never recalculated upon drag
29066 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
29067 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
29068 po.left += this.scrollParent.scrollLeft();
29069 po.top += this.scrollParent.scrollTop();
29070 }
29071
29072 // This needs to be actually done for all browsers, since pageX/pageY includes
29073 // this information.
29074 if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ) {
29075 po = { top: 0, left: 0 };
29076 }
29077
29078 return {
29079 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
29080 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
29081 };
29082
29083 },
29084
29085 _getRelativeOffset: function() {
29086
29087 if ( this.cssPosition === "relative" ) {
29088 var p = this.currentItem.position();
29089 return {
29090 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
29091 this.scrollParent.scrollTop(),
29092 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
29093 this.scrollParent.scrollLeft()
29094 };
29095 } else {
29096 return { top: 0, left: 0 };
29097 }
29098
29099 },
29100
29101 _cacheMargins: function() {
29102 this.margins = {
29103 left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
29104 top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
29105 };
29106 },
29107
29108 _cacheHelperProportions: function() {
29109 this.helperProportions = {
29110 width: this.helper.outerWidth(),
29111 height: this.helper.outerHeight()
29112 };
29113 },
29114
29115 _setContainment: function() {
29116
29117 var ce, co, over,
29118 o = this.options;
29119 if ( o.containment === "parent" ) {
29120 o.containment = this.helper[ 0 ].parentNode;
29121 }
29122 if ( o.containment === "document" || o.containment === "window" ) {
29123 this.containment = [
29124 0 - this.offset.relative.left - this.offset.parent.left,
29125 0 - this.offset.relative.top - this.offset.parent.top,
29126 o.containment === "document" ?
29127 this.document.width() :
29128 this.window.width() - this.helperProportions.width - this.margins.left,
29129 ( o.containment === "document" ?
29130 ( this.document.height() || document.body.parentNode.scrollHeight ) :
29131 this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
29132 ) - this.helperProportions.height - this.margins.top
29133 ];
29134 }
29135
29136 if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
29137 ce = $( o.containment )[ 0 ];
29138 co = $( o.containment ).offset();
29139 over = ( $( ce ).css( "overflow" ) !== "hidden" );
29140
29141 this.containment = [
29142 co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
29143 ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
29144 co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
29145 ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
29146 co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
29147 ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
29148 ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
29149 this.helperProportions.width - this.margins.left,
29150 co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
29151 ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
29152 ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
29153 this.helperProportions.height - this.margins.top
29154 ];
29155 }
29156
29157 },
29158
29159 _convertPositionTo: function( d, pos ) {
29160
29161 if ( !pos ) {
29162 pos = this.position;
29163 }
29164 var mod = d === "absolute" ? 1 : -1,
29165 scroll = this.cssPosition === "absolute" &&
29166 !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
29167 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
29168 this.offsetParent :
29169 this.scrollParent,
29170 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
29171
29172 return {
29173 top: (
29174
29175 // The absolute mouse position
29176 pos.top +
29177
29178 // Only for relative positioned nodes: Relative offset from element to offset parent
29179 this.offset.relative.top * mod +
29180
29181 // The offsetParent's offset without borders (offset + border)
29182 this.offset.parent.top * mod -
29183 ( ( this.cssPosition === "fixed" ?
29184 -this.scrollParent.scrollTop() :
29185 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
29186 ),
29187 left: (
29188
29189 // The absolute mouse position
29190 pos.left +
29191
29192 // Only for relative positioned nodes: Relative offset from element to offset parent
29193 this.offset.relative.left * mod +
29194
29195 // The offsetParent's offset without borders (offset + border)
29196 this.offset.parent.left * mod -
29197 ( ( this.cssPosition === "fixed" ?
29198 -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
29199 scroll.scrollLeft() ) * mod )
29200 )
29201 };
29202
29203 },
29204
29205 _generatePosition: function( event ) {
29206
29207 var top, left,
29208 o = this.options,
29209 pageX = event.pageX,
29210 pageY = event.pageY,
29211 scroll = this.cssPosition === "absolute" &&
29212 !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
29213 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
29214 this.offsetParent :
29215 this.scrollParent,
29216 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
29217
29218 // This is another very weird special case that only happens for relative elements:
29219 // 1. If the css position is relative
29220 // 2. and the scroll parent is the document or similar to the offset parent
29221 // we have to refresh the relative offset during the scroll so there are no jumps
29222 if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
29223 this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
29224 this.offset.relative = this._getRelativeOffset();
29225 }
29226
29227 /*
29228 * - Position constraining -
29229 * Constrain the position to a mix of grid, containment.
29230 */
29231
29232 if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
29233
29234 if ( this.containment ) {
29235 if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
29236 pageX = this.containment[ 0 ] + this.offset.click.left;
29237 }
29238 if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
29239 pageY = this.containment[ 1 ] + this.offset.click.top;
29240 }
29241 if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
29242 pageX = this.containment[ 2 ] + this.offset.click.left;
29243 }
29244 if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
29245 pageY = this.containment[ 3 ] + this.offset.click.top;
29246 }
29247 }
29248
29249 if ( o.grid ) {
29250 top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
29251 o.grid[ 1 ] ) * o.grid[ 1 ];
29252 pageY = this.containment ?
29253 ( ( top - this.offset.click.top >= this.containment[ 1 ] &&
29254 top - this.offset.click.top <= this.containment[ 3 ] ) ?
29255 top :
29256 ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
29257 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
29258 top;
29259
29260 left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
29261 o.grid[ 0 ] ) * o.grid[ 0 ];
29262 pageX = this.containment ?
29263 ( ( left - this.offset.click.left >= this.containment[ 0 ] &&
29264 left - this.offset.click.left <= this.containment[ 2 ] ) ?
29265 left :
29266 ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
29267 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
29268 left;
29269 }
29270
29271 }
29272
29273 return {
29274 top: (
29275
29276 // The absolute mouse position
29277 pageY -
29278
29279 // Click offset (relative to the element)
29280 this.offset.click.top -
29281
29282 // Only for relative positioned nodes: Relative offset from element to offset parent
29283 this.offset.relative.top -
29284
29285 // The offsetParent's offset without borders (offset + border)
29286 this.offset.parent.top +
29287 ( ( this.cssPosition === "fixed" ?
29288 -this.scrollParent.scrollTop() :
29289 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
29290 ),
29291 left: (
29292
29293 // The absolute mouse position
29294 pageX -
29295
29296 // Click offset (relative to the element)
29297 this.offset.click.left -
29298
29299 // Only for relative positioned nodes: Relative offset from element to offset parent
29300 this.offset.relative.left -
29301
29302 // The offsetParent's offset without borders (offset + border)
29303 this.offset.parent.left +
29304 ( ( this.cssPosition === "fixed" ?
29305 -this.scrollParent.scrollLeft() :
29306 scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
29307 )
29308 };
29309
29310 },
29311
29312 _rearrange: function( event, i, a, hardRefresh ) {
29313
29314 if ( a ) {
29315 a[ 0 ].appendChild( this.placeholder[ 0 ] );
29316 } else {
29317 i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
29318 ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
29319 }
29320
29321 //Various things done here to improve the performance:
29322 // 1. we create a setTimeout, that calls refreshPositions
29323 // 2. on the instance, we have a counter variable, that get's higher after every append
29324 // 3. on the local scope, we copy the counter variable, and check in the timeout,
29325 // if it's still the same
29326 // 4. this lets only the last addition to the timeout stack through
29327 this.counter = this.counter ? ++this.counter : 1;
29328 var counter = this.counter;
29329
29330 this._delay( function() {
29331 if ( counter === this.counter ) {
29332
29333 //Precompute after each DOM insertion, NOT on mousemove
29334 this.refreshPositions( !hardRefresh );
29335 }
29336 } );
29337
29338 },
29339
29340 _clear: function( event, noPropagation ) {
29341
29342 this.reverting = false;
29343
29344 // We delay all events that have to be triggered to after the point where the placeholder
29345 // has been removed and everything else normalized again
29346 var i,
29347 delayedTriggers = [];
29348
29349 // We first have to update the dom position of the actual currentItem
29350 // Note: don't do it if the current item is already removed (by a user), or it gets
29351 // reappended (see #4088)
29352 if ( !this._noFinalSort && this.currentItem.parent().length ) {
29353 this.placeholder.before( this.currentItem );
29354 }
29355 this._noFinalSort = null;
29356
29357 if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
29358 for ( i in this._storedCSS ) {
29359 if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
29360 this._storedCSS[ i ] = "";
29361 }
29362 }
29363 this.currentItem.css( this._storedCSS );
29364 this._removeClass( this.currentItem, "ui-sortable-helper" );
29365 } else {
29366 this.currentItem.show();
29367 }
29368
29369 if ( this.fromOutside && !noPropagation ) {
29370 delayedTriggers.push( function( event ) {
29371 this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
29372 } );
29373 }
29374 if ( ( this.fromOutside ||
29375 this.domPosition.prev !==
29376 this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
29377 this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
29378
29379 // Trigger update callback if the DOM position has changed
29380 delayedTriggers.push( function( event ) {
29381 this._trigger( "update", event, this._uiHash() );
29382 } );
29383 }
29384
29385 // Check if the items Container has Changed and trigger appropriate
29386 // events.
29387 if ( this !== this.currentContainer ) {
29388 if ( !noPropagation ) {
29389 delayedTriggers.push( function( event ) {
29390 this._trigger( "remove", event, this._uiHash() );
29391 } );
29392 delayedTriggers.push( ( function( c ) {
29393 return function( event ) {
29394 c._trigger( "receive", event, this._uiHash( this ) );
29395 };
29396 } ).call( this, this.currentContainer ) );
29397 delayedTriggers.push( ( function( c ) {
29398 return function( event ) {
29399 c._trigger( "update", event, this._uiHash( this ) );
29400 };
29401 } ).call( this, this.currentContainer ) );
29402 }
29403 }
29404
29405 //Post events to containers
29406 function delayEvent( type, instance, container ) {
29407 return function( event ) {
29408 container._trigger( type, event, instance._uiHash( instance ) );
29409 };
29410 }
29411 for ( i = this.containers.length - 1; i >= 0; i-- ) {
29412 if ( !noPropagation ) {
29413 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
29414 }
29415 if ( this.containers[ i ].containerCache.over ) {
29416 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
29417 this.containers[ i ].containerCache.over = 0;
29418 }
29419 }
29420
29421 //Do what was originally in plugins
29422 if ( this._storedStylesheet ) {
29423 this._storedStylesheet.remove();
29424 this._storedStylesheet = null;
29425 }
29426 if ( this._storedOpacity ) {
29427 this.helper.css( "opacity", this._storedOpacity );
29428 }
29429 if ( this._storedZIndex ) {
29430 this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
29431 }
29432
29433 this.dragging = false;
29434
29435 if ( !noPropagation ) {
29436 this._trigger( "beforeStop", event, this._uiHash() );
29437 }
29438
29439 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
29440 // it unbinds ALL events from the original node!
29441 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
29442
29443 if ( !this.cancelHelperRemoval ) {
29444 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
29445 this.helper.remove();
29446 }
29447 this.helper = null;
29448 }
29449
29450 if ( !noPropagation ) {
29451 for ( i = 0; i < delayedTriggers.length; i++ ) {
29452
29453 // Trigger all delayed events
29454 delayedTriggers[ i ].call( this, event );
29455 }
29456 this._trigger( "stop", event, this._uiHash() );
29457 }
29458
29459 this.fromOutside = false;
29460 return !this.cancelHelperRemoval;
29461
29462 },
29463
29464 _trigger: function() {
29465 if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
29466 this.cancel();
29467 }
29468 },
29469
29470 _uiHash: function( _inst ) {
29471 var inst = _inst || this;
29472 return {
29473 helper: inst.helper,
29474 placeholder: inst.placeholder || $( [] ),
29475 position: inst.position,
29476 originalPosition: inst.originalPosition,
29477 offset: inst.positionAbs,
29478 item: inst.currentItem,
29479 sender: _inst ? _inst.element : null
29480 };
29481 }
29482
29483} );
29484
29485} );
29486
29487
29488
29489
29490
29491/*!
29492 * jQuery UI Spinner 1.14.1
29493 * https://jqueryui.com
29494 *
29495 * Copyright OpenJS Foundation and other contributors
29496 * Released under the MIT license.
29497 * https://jquery.org/license
29498 */
29499
29500//>>label: Spinner
29501//>>group: Widgets
29502//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
29503//>>docs: https://api.jqueryui.com/spinner/
29504//>>demos: https://jqueryui.com/spinner/
29505//>>css.structure: ../../themes/base/core.css
29506//>>css.structure: ../../themes/base/spinner.css
29507//>>css.theme: ../../themes/base/theme.css
29508
29509( function( factory ) {
29510 "use strict";
29511
29512 if ( typeof define === "function" && define.amd ) {
29513
29514 // AMD. Register as an anonymous module.
29515 define( [
29516 "jquery",
29517 "./button",
29518 "../version",
29519 "../keycode",
29520 "../widget"
29521 ], factory );
29522 } else {
29523
29524 // Browser globals
29525 factory( jQuery );
29526 }
29527} )( function( $ ) {
29528"use strict";
29529
29530function spinnerModifier( fn ) {
29531 return function() {
29532 var previous = this.element.val();
29533 fn.apply( this, arguments );
29534 this._refresh();
29535 if ( previous !== this.element.val() ) {
29536 this._trigger( "change" );
29537 }
29538 };
29539}
29540
29541$.widget( "ui.spinner", {
29542 version: "1.14.1",
29543 defaultElement: "<input>",
29544 widgetEventPrefix: "spin",
29545 options: {
29546 classes: {
29547 "ui-spinner": "ui-corner-all",
29548 "ui-spinner-down": "ui-corner-br",
29549 "ui-spinner-up": "ui-corner-tr"
29550 },
29551 culture: null,
29552 icons: {
29553 down: "ui-icon-triangle-1-s",
29554 up: "ui-icon-triangle-1-n"
29555 },
29556 incremental: true,
29557 max: null,
29558 min: null,
29559 numberFormat: null,
29560 page: 10,
29561 step: 1,
29562
29563 change: null,
29564 spin: null,
29565 start: null,
29566 stop: null
29567 },
29568
29569 _create: function() {
29570
29571 // handle string values that need to be parsed
29572 this._setOption( "max", this.options.max );
29573 this._setOption( "min", this.options.min );
29574 this._setOption( "step", this.options.step );
29575
29576 // Only format if there is a value, prevents the field from being marked
29577 // as invalid in Firefox, see #9573.
29578 if ( this.value() !== "" ) {
29579
29580 // Format the value, but don't constrain.
29581 this._value( this.element.val(), true );
29582 }
29583
29584 this._draw();
29585 this._on( this._events );
29586 this._refresh();
29587
29588 // Turning off autocomplete prevents the browser from remembering the
29589 // value when navigating through history, so we re-enable autocomplete
29590 // if the page is unloaded before the widget is destroyed. #7790
29591 this._on( this.window, {
29592 beforeunload: function() {
29593 this.element.removeAttr( "autocomplete" );
29594 }
29595 } );
29596 },
29597
29598 _getCreateOptions: function() {
29599 var options = this._super();
29600 var element = this.element;
29601
29602 $.each( [ "min", "max", "step" ], function( i, option ) {
29603 var value = element.attr( option );
29604 if ( value != null && value.length ) {
29605 options[ option ] = value;
29606 }
29607 } );
29608
29609 return options;
29610 },
29611
29612 _events: {
29613 keydown: function( event ) {
29614 if ( this._start( event ) && this._keydown( event ) ) {
29615 event.preventDefault();
29616 }
29617 },
29618 keyup: "_stop",
29619 focus: function() {
29620 this.previous = this.element.val();
29621 },
29622 blur: function( event ) {
29623 this._stop();
29624 this._refresh();
29625 if ( this.previous !== this.element.val() ) {
29626 this._trigger( "change", event );
29627 }
29628 },
29629 mousewheel: function( event, delta ) {
29630 var activeElement = this.document[ 0 ].activeElement;
29631 var isActive = this.element[ 0 ] === activeElement;
29632
29633 if ( !isActive || !delta ) {
29634 return;
29635 }
29636
29637 if ( !this.spinning && !this._start( event ) ) {
29638 return false;
29639 }
29640
29641 this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
29642 clearTimeout( this.mousewheelTimer );
29643 this.mousewheelTimer = this._delay( function() {
29644 if ( this.spinning ) {
29645 this._stop( event );
29646 }
29647 }, 100 );
29648 event.preventDefault();
29649 },
29650 "mousedown .ui-spinner-button": function( event ) {
29651 var previous;
29652
29653 // We never want the buttons to have focus; whenever the user is
29654 // interacting with the spinner, the focus should be on the input.
29655 // If the input is focused then this.previous is properly set from
29656 // when the input first received focus. If the input is not focused
29657 // then we need to set this.previous based on the value before spinning.
29658 previous = this.element[ 0 ] === this.document[ 0 ].activeElement ?
29659 this.previous : this.element.val();
29660 function checkFocus() {
29661 var isActive = this.element[ 0 ] === this.document[ 0 ].activeElement;
29662 if ( !isActive ) {
29663 this.element.trigger( "focus" );
29664 this.previous = previous;
29665 }
29666 }
29667
29668 // Ensure focus is on (or stays on) the text field
29669 event.preventDefault();
29670 checkFocus.call( this );
29671
29672 if ( this._start( event ) === false ) {
29673 return;
29674 }
29675
29676 this._repeat( null, $( event.currentTarget )
29677 .hasClass( "ui-spinner-up" ) ? 1 : -1, event );
29678 },
29679 "mouseup .ui-spinner-button": "_stop",
29680 "mouseenter .ui-spinner-button": function( event ) {
29681
29682 // button will add ui-state-active if mouse was down while mouseleave and kept down
29683 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
29684 return;
29685 }
29686
29687 if ( this._start( event ) === false ) {
29688 return false;
29689 }
29690 this._repeat( null, $( event.currentTarget )
29691 .hasClass( "ui-spinner-up" ) ? 1 : -1, event );
29692 },
29693
29694 // TODO: do we really want to consider this a stop?
29695 // shouldn't we just stop the repeater and wait until mouseup before
29696 // we trigger the stop event?
29697 "mouseleave .ui-spinner-button": "_stop"
29698 },
29699
29700 // Support mobile enhanced option and make backcompat more sane
29701 _enhance: function() {
29702 this.uiSpinner = this.element
29703 .attr( "autocomplete", "off" )
29704 .wrap( "<span>" )
29705 .parent()
29706
29707 // Add buttons
29708 .append(
29709 "<a></a><a></a>"
29710 );
29711 },
29712
29713 _draw: function() {
29714 this._enhance();
29715
29716 this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
29717 this._addClass( "ui-spinner-input" );
29718
29719 this.element.attr( "role", "spinbutton" );
29720
29721 // Button bindings
29722 this.buttons = this.uiSpinner.children( "a" )
29723 .attr( "tabIndex", -1 )
29724 .attr( "aria-hidden", true )
29725 .button( {
29726 classes: {
29727 "ui-button": ""
29728 }
29729 } );
29730
29731 // TODO: Right now button does not support classes this is already updated in button PR
29732 this._removeClass( this.buttons, "ui-corner-all" );
29733
29734 this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
29735 this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
29736 this.buttons.first().button( {
29737 "icon": this.options.icons.up,
29738 "showLabel": false
29739 } );
29740 this.buttons.last().button( {
29741 "icon": this.options.icons.down,
29742 "showLabel": false
29743 } );
29744
29745 // IE 6 doesn't understand height: 50% for the buttons
29746 // unless the wrapper has an explicit height
29747 if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
29748 this.uiSpinner.height() > 0 ) {
29749 this.uiSpinner.height( this.uiSpinner.height() );
29750 }
29751 },
29752
29753 _keydown: function( event ) {
29754 var options = this.options,
29755 keyCode = $.ui.keyCode;
29756
29757 switch ( event.keyCode ) {
29758 case keyCode.UP:
29759 this._repeat( null, 1, event );
29760 return true;
29761 case keyCode.DOWN:
29762 this._repeat( null, -1, event );
29763 return true;
29764 case keyCode.PAGE_UP:
29765 this._repeat( null, options.page, event );
29766 return true;
29767 case keyCode.PAGE_DOWN:
29768 this._repeat( null, -options.page, event );
29769 return true;
29770 }
29771
29772 return false;
29773 },
29774
29775 _start: function( event ) {
29776 if ( !this.spinning && this._trigger( "start", event ) === false ) {
29777 return false;
29778 }
29779
29780 if ( !this.counter ) {
29781 this.counter = 1;
29782 }
29783 this.spinning = true;
29784 return true;
29785 },
29786
29787 _repeat: function( i, steps, event ) {
29788 i = i || 500;
29789
29790 clearTimeout( this.timer );
29791 this.timer = this._delay( function() {
29792 this._repeat( 40, steps, event );
29793 }, i );
29794
29795 this._spin( steps * this.options.step, event );
29796 },
29797
29798 _spin: function( step, event ) {
29799 var value = this.value() || 0;
29800
29801 if ( !this.counter ) {
29802 this.counter = 1;
29803 }
29804
29805 value = this._adjustValue( value + step * this._increment( this.counter ) );
29806
29807 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
29808 this._value( value );
29809 this.counter++;
29810 }
29811 },
29812
29813 _increment: function( i ) {
29814 var incremental = this.options.incremental;
29815
29816 if ( incremental ) {
29817 return typeof incremental === "function" ?
29818 incremental( i ) :
29819 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
29820 }
29821
29822 return 1;
29823 },
29824
29825 _precision: function() {
29826 var precision = this._precisionOf( this.options.step );
29827 if ( this.options.min !== null ) {
29828 precision = Math.max( precision, this._precisionOf( this.options.min ) );
29829 }
29830 return precision;
29831 },
29832
29833 _precisionOf: function( num ) {
29834 var str = num.toString(),
29835 decimal = str.indexOf( "." );
29836 return decimal === -1 ? 0 : str.length - decimal - 1;
29837 },
29838
29839 _adjustValue: function( value ) {
29840 var base, aboveMin,
29841 options = this.options;
29842
29843 // Make sure we're at a valid step
29844 // - find out where we are relative to the base (min or 0)
29845 base = options.min !== null ? options.min : 0;
29846 aboveMin = value - base;
29847
29848 // - round to the nearest step
29849 aboveMin = Math.round( aboveMin / options.step ) * options.step;
29850
29851 // - rounding is based on 0, so adjust back to our base
29852 value = base + aboveMin;
29853
29854 // Fix precision from bad JS floating point math
29855 value = parseFloat( value.toFixed( this._precision() ) );
29856
29857 // Clamp the value
29858 if ( options.max !== null && value > options.max ) {
29859 return options.max;
29860 }
29861 if ( options.min !== null && value < options.min ) {
29862 return options.min;
29863 }
29864
29865 return value;
29866 },
29867
29868 _stop: function( event ) {
29869 if ( !this.spinning ) {
29870 return;
29871 }
29872
29873 clearTimeout( this.timer );
29874 clearTimeout( this.mousewheelTimer );
29875 this.counter = 0;
29876 this.spinning = false;
29877 this._trigger( "stop", event );
29878 },
29879
29880 _setOption: function( key, value ) {
29881 var prevValue, first, last;
29882
29883 if ( key === "culture" || key === "numberFormat" ) {
29884 prevValue = this._parse( this.element.val() );
29885 this.options[ key ] = value;
29886 this.element.val( this._format( prevValue ) );
29887 return;
29888 }
29889
29890 if ( key === "max" || key === "min" || key === "step" ) {
29891 if ( typeof value === "string" ) {
29892 value = this._parse( value );
29893 }
29894 }
29895 if ( key === "icons" ) {
29896 first = this.buttons.first().find( ".ui-icon" );
29897 this._removeClass( first, null, this.options.icons.up );
29898 this._addClass( first, null, value.up );
29899 last = this.buttons.last().find( ".ui-icon" );
29900 this._removeClass( last, null, this.options.icons.down );
29901 this._addClass( last, null, value.down );
29902 }
29903
29904 this._super( key, value );
29905 },
29906
29907 _setOptionDisabled: function( value ) {
29908 this._super( value );
29909
29910 this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
29911 this.element.prop( "disabled", !!value );
29912 this.buttons.button( value ? "disable" : "enable" );
29913 },
29914
29915 _setOptions: spinnerModifier( function( options ) {
29916 this._super( options );
29917 } ),
29918
29919 _parse: function( val ) {
29920 if ( typeof val === "string" && val !== "" ) {
29921 val = window.Globalize && this.options.numberFormat ?
29922 Globalize.parseFloat( val, 10, this.options.culture ) : +val;
29923 }
29924 return val === "" || isNaN( val ) ? null : val;
29925 },
29926
29927 _format: function( value ) {
29928 if ( value === "" ) {
29929 return "";
29930 }
29931 return window.Globalize && this.options.numberFormat ?
29932 Globalize.format( value, this.options.numberFormat, this.options.culture ) :
29933 value;
29934 },
29935
29936 _refresh: function() {
29937 this.element.attr( {
29938 "aria-valuemin": this.options.min,
29939 "aria-valuemax": this.options.max,
29940
29941 // TODO: what should we do with values that can't be parsed?
29942 "aria-valuenow": this._parse( this.element.val() )
29943 } );
29944 },
29945
29946 isValid: function() {
29947 var value = this.value();
29948
29949 // Null is invalid
29950 if ( value === null ) {
29951 return false;
29952 }
29953
29954 // If value gets adjusted, it's invalid
29955 return value === this._adjustValue( value );
29956 },
29957
29958 // Update the value without triggering change
29959 _value: function( value, allowAny ) {
29960 var parsed;
29961 if ( value !== "" ) {
29962 parsed = this._parse( value );
29963 if ( parsed !== null ) {
29964 if ( !allowAny ) {
29965 parsed = this._adjustValue( parsed );
29966 }
29967 value = this._format( parsed );
29968 }
29969 }
29970 this.element.val( value );
29971 this._refresh();
29972 },
29973
29974 _destroy: function() {
29975 this.element
29976 .prop( "disabled", false )
29977 .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
29978
29979 this.uiSpinner.replaceWith( this.element );
29980 },
29981
29982 stepUp: spinnerModifier( function( steps ) {
29983 this._stepUp( steps );
29984 } ),
29985 _stepUp: function( steps ) {
29986 if ( this._start() ) {
29987 this._spin( ( steps || 1 ) * this.options.step );
29988 this._stop();
29989 }
29990 },
29991
29992 stepDown: spinnerModifier( function( steps ) {
29993 this._stepDown( steps );
29994 } ),
29995 _stepDown: function( steps ) {
29996 if ( this._start() ) {
29997 this._spin( ( steps || 1 ) * -this.options.step );
29998 this._stop();
29999 }
30000 },
30001
30002 pageUp: spinnerModifier( function( pages ) {
30003 this._stepUp( ( pages || 1 ) * this.options.page );
30004 } ),
30005
30006 pageDown: spinnerModifier( function( pages ) {
30007 this._stepDown( ( pages || 1 ) * this.options.page );
30008 } ),
30009
30010 value: function( newVal ) {
30011 if ( !arguments.length ) {
30012 return this._parse( this.element.val() );
30013 }
30014 spinnerModifier( this._value ).call( this, newVal );
30015 },
30016
30017 widget: function() {
30018 return this.uiSpinner;
30019 }
30020} );
30021
30022// DEPRECATED
30023// TODO: switch return back to widget declaration at top of file when this is removed
30024if ( $.uiBackCompat === true ) {
30025
30026 // Backcompat for spinner html extension points
30027 $.widget( "ui.spinner", $.ui.spinner, {
30028 _enhance: function() {
30029 this.uiSpinner = this.element
30030 .attr( "autocomplete", "off" )
30031 .wrap( this._uiSpinnerHtml() )
30032 .parent()
30033
30034 // Add buttons
30035 .append( this._buttonHtml() );
30036 },
30037 _uiSpinnerHtml: function() {
30038 return "<span>";
30039 },
30040
30041 _buttonHtml: function() {
30042 return "<a></a><a></a>";
30043 }
30044 } );
30045}
30046
30047return $.ui.spinner;
30048
30049} );
30050
30051
30052
30053
30054
30055/*!
30056 * jQuery UI Tabs 1.14.1
30057 * https://jqueryui.com
30058 *
30059 * Copyright OpenJS Foundation and other contributors
30060 * Released under the MIT license.
30061 * https://jquery.org/license
30062 */
30063
30064//>>label: Tabs
30065//>>group: Widgets
30066//>>description: Transforms a set of container elements into a tab structure.
30067//>>docs: https://api.jqueryui.com/tabs/
30068//>>demos: https://jqueryui.com/tabs/
30069//>>css.structure: ../../themes/base/core.css
30070//>>css.structure: ../../themes/base/tabs.css
30071//>>css.theme: ../../themes/base/theme.css
30072
30073( function( factory ) {
30074 "use strict";
30075
30076 if ( typeof define === "function" && define.amd ) {
30077
30078 // AMD. Register as an anonymous module.
30079 define( [
30080 "jquery",
30081 "../keycode",
30082 "../unique-id",
30083 "../version",
30084 "../widget"
30085 ], factory );
30086 } else {
30087
30088 // Browser globals
30089 factory( jQuery );
30090 }
30091} )( function( $ ) {
30092"use strict";
30093
30094$.widget( "ui.tabs", {
30095 version: "1.14.1",
30096 delay: 300,
30097 options: {
30098 active: null,
30099 classes: {
30100 "ui-tabs": "ui-corner-all",
30101 "ui-tabs-nav": "ui-corner-all",
30102 "ui-tabs-panel": "ui-corner-bottom",
30103 "ui-tabs-tab": "ui-corner-top"
30104 },
30105 collapsible: false,
30106 event: "click",
30107 heightStyle: "content",
30108 hide: null,
30109 show: null,
30110
30111 // Callbacks
30112 activate: null,
30113 beforeActivate: null,
30114 beforeLoad: null,
30115 load: null
30116 },
30117
30118 _isLocal: ( function() {
30119 var rhash = /#.*$/;
30120
30121 return function( anchor ) {
30122 var anchorUrl, locationUrl;
30123
30124 anchorUrl = anchor.href.replace( rhash, "" );
30125 locationUrl = location.href.replace( rhash, "" );
30126
30127 // Decoding may throw an error if the URL isn't UTF-8 (#9518)
30128 try {
30129 anchorUrl = decodeURIComponent( anchorUrl );
30130 } catch ( error ) {}
30131 try {
30132 locationUrl = decodeURIComponent( locationUrl );
30133 } catch ( error ) {}
30134
30135 return anchor.hash.length > 1 && anchorUrl === locationUrl;
30136 };
30137 } )(),
30138
30139 _create: function() {
30140 var that = this,
30141 options = this.options;
30142
30143 this.running = false;
30144
30145 this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
30146 this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
30147
30148 this._processTabs();
30149 options.active = this._initialActive();
30150
30151 // Take disabling tabs via class attribute from HTML
30152 // into account and update option properly.
30153 if ( Array.isArray( options.disabled ) ) {
30154 options.disabled = $.uniqueSort( options.disabled.concat(
30155 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
30156 return that.tabs.index( li );
30157 } )
30158 ) ).sort();
30159 }
30160
30161 // Check for length avoids error when initializing empty list
30162 if ( this.options.active !== false && this.anchors.length ) {
30163 this.active = this._findActive( options.active );
30164 } else {
30165 this.active = $();
30166 }
30167
30168 this._refresh();
30169
30170 if ( this.active.length ) {
30171 this.load( options.active );
30172 }
30173 },
30174
30175 _initialActive: function() {
30176 var active = this.options.active,
30177 collapsible = this.options.collapsible,
30178 locationHashDecoded = decodeURIComponent( location.hash.substring( 1 ) );
30179
30180 if ( active === null ) {
30181
30182 // check the fragment identifier in the URL
30183 if ( locationHashDecoded ) {
30184 this.tabs.each( function( i, tab ) {
30185 if ( $( tab ).attr( "aria-controls" ) === locationHashDecoded ) {
30186 active = i;
30187 return false;
30188 }
30189 } );
30190 }
30191
30192 // Check for a tab marked active via a class
30193 if ( active === null ) {
30194 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
30195 }
30196
30197 // No active tab, set to false
30198 if ( active === null || active === -1 ) {
30199 active = this.tabs.length ? 0 : false;
30200 }
30201 }
30202
30203 // Handle numbers: negative, out of range
30204 if ( active !== false ) {
30205 active = this.tabs.index( this.tabs.eq( active ) );
30206 if ( active === -1 ) {
30207 active = collapsible ? false : 0;
30208 }
30209 }
30210
30211 // Don't allow collapsible: false and active: false
30212 if ( !collapsible && active === false && this.anchors.length ) {
30213 active = 0;
30214 }
30215
30216 return active;
30217 },
30218
30219 _getCreateEventData: function() {
30220 return {
30221 tab: this.active,
30222 panel: !this.active.length ? $() : this._getPanelForTab( this.active )
30223 };
30224 },
30225
30226 _tabKeydown: function( event ) {
30227 var focusedTab = $( this.document[ 0 ].activeElement ).closest( "li" ),
30228 selectedIndex = this.tabs.index( focusedTab ),
30229 goingForward = true;
30230
30231 if ( this._handlePageNav( event ) ) {
30232 return;
30233 }
30234
30235 switch ( event.keyCode ) {
30236 case $.ui.keyCode.RIGHT:
30237 case $.ui.keyCode.DOWN:
30238 selectedIndex++;
30239 break;
30240 case $.ui.keyCode.UP:
30241 case $.ui.keyCode.LEFT:
30242 goingForward = false;
30243 selectedIndex--;
30244 break;
30245 case $.ui.keyCode.END:
30246 selectedIndex = this.anchors.length - 1;
30247 break;
30248 case $.ui.keyCode.HOME:
30249 selectedIndex = 0;
30250 break;
30251 case $.ui.keyCode.SPACE:
30252
30253 // Activate only, no collapsing
30254 event.preventDefault();
30255 clearTimeout( this.activating );
30256 this._activate( selectedIndex );
30257 return;
30258 case $.ui.keyCode.ENTER:
30259
30260 // Toggle (cancel delayed activation, allow collapsing)
30261 event.preventDefault();
30262 clearTimeout( this.activating );
30263
30264 // Determine if we should collapse or activate
30265 this._activate( selectedIndex === this.options.active ? false : selectedIndex );
30266 return;
30267 default:
30268 return;
30269 }
30270
30271 // Focus the appropriate tab, based on which key was pressed
30272 event.preventDefault();
30273 clearTimeout( this.activating );
30274 selectedIndex = this._focusNextTab( selectedIndex, goingForward );
30275
30276 // Navigating with control/command key will prevent automatic activation
30277 if ( !event.ctrlKey && !event.metaKey ) {
30278
30279 // Update aria-selected immediately so that AT think the tab is already selected.
30280 // Otherwise AT may confuse the user by stating that they need to activate the tab,
30281 // but the tab will already be activated by the time the announcement finishes.
30282 focusedTab.attr( "aria-selected", "false" );
30283 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
30284
30285 this.activating = this._delay( function() {
30286 this.option( "active", selectedIndex );
30287 }, this.delay );
30288 }
30289 },
30290
30291 _panelKeydown: function( event ) {
30292 if ( this._handlePageNav( event ) ) {
30293 return;
30294 }
30295
30296 // Ctrl+up moves focus to the current tab
30297 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
30298 event.preventDefault();
30299 this.active.trigger( "focus" );
30300 }
30301 },
30302
30303 // Alt+page up/down moves focus to the previous/next tab (and activates)
30304 _handlePageNav: function( event ) {
30305 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
30306 this._activate( this._focusNextTab( this.options.active - 1, false ) );
30307 return true;
30308 }
30309 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
30310 this._activate( this._focusNextTab( this.options.active + 1, true ) );
30311 return true;
30312 }
30313 },
30314
30315 _findNextTab: function( index, goingForward ) {
30316 var lastTabIndex = this.tabs.length - 1;
30317
30318 function constrain() {
30319 if ( index > lastTabIndex ) {
30320 index = 0;
30321 }
30322 if ( index < 0 ) {
30323 index = lastTabIndex;
30324 }
30325 return index;
30326 }
30327
30328 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
30329 index = goingForward ? index + 1 : index - 1;
30330 }
30331
30332 return index;
30333 },
30334
30335 _focusNextTab: function( index, goingForward ) {
30336 index = this._findNextTab( index, goingForward );
30337 this.tabs.eq( index ).trigger( "focus" );
30338 return index;
30339 },
30340
30341 _setOption: function( key, value ) {
30342 if ( key === "active" ) {
30343
30344 // _activate() will handle invalid values and update this.options
30345 this._activate( value );
30346 return;
30347 }
30348
30349 this._super( key, value );
30350
30351 if ( key === "collapsible" ) {
30352 this._toggleClass( "ui-tabs-collapsible", null, value );
30353
30354 // Setting collapsible: false while collapsed; open first panel
30355 if ( !value && this.options.active === false ) {
30356 this._activate( 0 );
30357 }
30358 }
30359
30360 if ( key === "event" ) {
30361 this._setupEvents( value );
30362 }
30363
30364 if ( key === "heightStyle" ) {
30365 this._setupHeightStyle( value );
30366 }
30367 },
30368
30369 refresh: function() {
30370 var options = this.options,
30371 lis = this.tablist.children( ":has(a[href])" );
30372
30373 // Get disabled tabs from class attribute from HTML
30374 // this will get converted to a boolean if needed in _refresh()
30375 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
30376 return lis.index( tab );
30377 } );
30378
30379 this._processTabs();
30380
30381 // Was collapsed or no tabs
30382 if ( options.active === false || !this.anchors.length ) {
30383 options.active = false;
30384 this.active = $();
30385
30386 // was active, but active tab is gone
30387 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
30388
30389 // all remaining tabs are disabled
30390 if ( this.tabs.length === options.disabled.length ) {
30391 options.active = false;
30392 this.active = $();
30393
30394 // activate previous tab
30395 } else {
30396 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
30397 }
30398
30399 // was active, active tab still exists
30400 } else {
30401
30402 // make sure active index is correct
30403 options.active = this.tabs.index( this.active );
30404 }
30405
30406 this._refresh();
30407 },
30408
30409 _refresh: function() {
30410 this._setOptionDisabled( this.options.disabled );
30411 this._setupEvents( this.options.event );
30412 this._setupHeightStyle( this.options.heightStyle );
30413
30414 this.tabs.not( this.active ).attr( {
30415 "aria-selected": "false",
30416 "aria-expanded": "false",
30417 tabIndex: -1
30418 } );
30419 this.panels.not( this._getPanelForTab( this.active ) )
30420 .hide()
30421 .attr( {
30422 "aria-hidden": "true"
30423 } );
30424
30425 // Make sure one tab is in the tab order
30426 if ( !this.active.length ) {
30427 this.tabs.eq( 0 ).attr( "tabIndex", 0 );
30428 } else {
30429 this.active
30430 .attr( {
30431 "aria-selected": "true",
30432 "aria-expanded": "true",
30433 tabIndex: 0
30434 } );
30435 this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
30436 this._getPanelForTab( this.active )
30437 .show()
30438 .attr( {
30439 "aria-hidden": "false"
30440 } );
30441 }
30442 },
30443
30444 _processTabs: function() {
30445 var that = this,
30446 prevTabs = this.tabs,
30447 prevAnchors = this.anchors,
30448 prevPanels = this.panels;
30449
30450 this.tablist = this._getList().attr( "role", "tablist" );
30451 this._addClass( this.tablist, "ui-tabs-nav",
30452 "ui-helper-reset ui-helper-clearfix ui-widget-header" );
30453
30454 // Prevent users from focusing disabled tabs via click
30455 this.tablist
30456 .on( "mousedown" + this.eventNamespace, "> li", function( event ) {
30457 if ( $( this ).is( ".ui-state-disabled" ) ) {
30458 event.preventDefault();
30459 }
30460 } );
30461
30462 this.tabs = this.tablist.find( "> li:has(a[href])" )
30463 .attr( {
30464 role: "tab",
30465 tabIndex: -1
30466 } );
30467 this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
30468
30469 this.anchors = this.tabs.map( function() {
30470 return $( "a", this )[ 0 ];
30471 } )
30472 .attr( {
30473 tabIndex: -1
30474 } );
30475 this._addClass( this.anchors, "ui-tabs-anchor" );
30476
30477 this.panels = $();
30478
30479 this.anchors.each( function( i, anchor ) {
30480 var selector, panel, panelId,
30481 anchorId = $( anchor ).uniqueId().attr( "id" ),
30482 tab = $( anchor ).closest( "li" ),
30483 originalAriaControls = tab.attr( "aria-controls" );
30484
30485 // Inline tab
30486 if ( that._isLocal( anchor ) ) {
30487 selector = decodeURIComponent( anchor.hash );
30488 panelId = selector.substring( 1 );
30489 panel = that.element.find( "#" + CSS.escape( panelId ) );
30490
30491 // remote tab
30492 } else {
30493
30494 // If the tab doesn't already have aria-controls,
30495 // generate an id by using a throw-away element
30496 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
30497 selector = "#" + panelId;
30498 panel = that.element.find( selector );
30499 if ( !panel.length ) {
30500 panel = that._createPanel( panelId );
30501 panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
30502 }
30503 panel.attr( "aria-live", "polite" );
30504 }
30505
30506 if ( panel.length ) {
30507 that.panels = that.panels.add( panel );
30508 }
30509 if ( originalAriaControls ) {
30510 tab.data( "ui-tabs-aria-controls", originalAriaControls );
30511 }
30512 tab.attr( {
30513 "aria-controls": panelId,
30514 "aria-labelledby": anchorId
30515 } );
30516 panel.attr( "aria-labelledby", anchorId );
30517 } );
30518
30519 this.panels.attr( "role", "tabpanel" );
30520 this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
30521
30522 // Avoid memory leaks (#10056)
30523 if ( prevTabs ) {
30524 this._off( prevTabs.not( this.tabs ) );
30525 this._off( prevAnchors.not( this.anchors ) );
30526 this._off( prevPanels.not( this.panels ) );
30527 }
30528 },
30529
30530 // Allow overriding how to find the list for rare usage scenarios (#7715)
30531 _getList: function() {
30532 return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
30533 },
30534
30535 _createPanel: function( id ) {
30536 return $( "<div>" )
30537 .attr( "id", id )
30538 .data( "ui-tabs-destroy", true );
30539 },
30540
30541 _setOptionDisabled: function( disabled ) {
30542 var currentItem, li, i;
30543
30544 if ( Array.isArray( disabled ) ) {
30545 if ( !disabled.length ) {
30546 disabled = false;
30547 } else if ( disabled.length === this.anchors.length ) {
30548 disabled = true;
30549 }
30550 }
30551
30552 // Disable tabs
30553 for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
30554 currentItem = $( li );
30555 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
30556 currentItem.attr( "aria-disabled", "true" );
30557 this._addClass( currentItem, null, "ui-state-disabled" );
30558 } else {
30559 currentItem.removeAttr( "aria-disabled" );
30560 this._removeClass( currentItem, null, "ui-state-disabled" );
30561 }
30562 }
30563
30564 this.options.disabled = disabled;
30565
30566 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
30567 disabled === true );
30568 },
30569
30570 _setupEvents: function( event ) {
30571 var events = {};
30572 if ( event ) {
30573 $.each( event.split( " " ), function( index, eventName ) {
30574 events[ eventName ] = "_eventHandler";
30575 } );
30576 }
30577
30578 this._off( this.anchors.add( this.tabs ).add( this.panels ) );
30579
30580 // Always prevent the default action, even when disabled
30581 this._on( true, this.anchors, {
30582 click: function( event ) {
30583 event.preventDefault();
30584 }
30585 } );
30586 this._on( this.anchors, events );
30587 this._on( this.tabs, { keydown: "_tabKeydown" } );
30588 this._on( this.panels, { keydown: "_panelKeydown" } );
30589
30590 this._focusable( this.tabs );
30591 this._hoverable( this.tabs );
30592 },
30593
30594 _setupHeightStyle: function( heightStyle ) {
30595 var maxHeight,
30596 parent = this.element.parent();
30597
30598 if ( heightStyle === "fill" ) {
30599 maxHeight = parent.height();
30600 maxHeight -= this.element.outerHeight() - this.element.height();
30601
30602 this.element.siblings( ":visible" ).each( function() {
30603 var elem = $( this ),
30604 position = elem.css( "position" );
30605
30606 if ( position === "absolute" || position === "fixed" ) {
30607 return;
30608 }
30609 maxHeight -= elem.outerHeight( true );
30610 } );
30611
30612 this.element.children().not( this.panels ).each( function() {
30613 maxHeight -= $( this ).outerHeight( true );
30614 } );
30615
30616 this.panels.each( function() {
30617 $( this ).height( Math.max( 0, maxHeight -
30618 $( this ).innerHeight() + $( this ).height() ) );
30619 } )
30620 .css( "overflow", "auto" );
30621 } else if ( heightStyle === "auto" ) {
30622 maxHeight = 0;
30623 this.panels.each( function() {
30624 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
30625 } ).height( maxHeight );
30626 }
30627 },
30628
30629 _eventHandler: function( event ) {
30630 var options = this.options,
30631 active = this.active,
30632 anchor = $( event.currentTarget ),
30633 tab = anchor.closest( "li" ),
30634 clickedIsActive = tab[ 0 ] === active[ 0 ],
30635 collapsing = clickedIsActive && options.collapsible,
30636 toShow = collapsing ? $() : this._getPanelForTab( tab ),
30637 toHide = !active.length ? $() : this._getPanelForTab( active ),
30638 eventData = {
30639 oldTab: active,
30640 oldPanel: toHide,
30641 newTab: collapsing ? $() : tab,
30642 newPanel: toShow
30643 };
30644
30645 event.preventDefault();
30646
30647 if ( tab.hasClass( "ui-state-disabled" ) ||
30648
30649 // tab is already loading
30650 tab.hasClass( "ui-tabs-loading" ) ||
30651
30652 // can't switch durning an animation
30653 this.running ||
30654
30655 // click on active header, but not collapsible
30656 ( clickedIsActive && !options.collapsible ) ||
30657
30658 // allow canceling activation
30659 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
30660 return;
30661 }
30662
30663 options.active = collapsing ? false : this.tabs.index( tab );
30664
30665 this.active = clickedIsActive ? $() : tab;
30666 if ( this.xhr ) {
30667 this.xhr.abort();
30668 }
30669
30670 if ( !toHide.length && !toShow.length ) {
30671 $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
30672 }
30673
30674 if ( toShow.length ) {
30675 this.load( this.tabs.index( tab ), event );
30676 }
30677 this._toggle( event, eventData );
30678 },
30679
30680 // Handles show/hide for selecting tabs
30681 _toggle: function( event, eventData ) {
30682 var that = this,
30683 toShow = eventData.newPanel,
30684 toHide = eventData.oldPanel;
30685
30686 this.running = true;
30687
30688 function complete() {
30689 that.running = false;
30690 that._trigger( "activate", event, eventData );
30691 }
30692
30693 function show() {
30694 that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
30695
30696 if ( toShow.length && that.options.show ) {
30697 that._show( toShow, that.options.show, complete );
30698 } else {
30699 toShow.show();
30700 complete();
30701 }
30702 }
30703
30704 // Start out by hiding, then showing, then completing
30705 if ( toHide.length && this.options.hide ) {
30706 this._hide( toHide, this.options.hide, function() {
30707 that._removeClass( eventData.oldTab.closest( "li" ),
30708 "ui-tabs-active", "ui-state-active" );
30709 show();
30710 } );
30711 } else {
30712 this._removeClass( eventData.oldTab.closest( "li" ),
30713 "ui-tabs-active", "ui-state-active" );
30714 toHide.hide();
30715 show();
30716 }
30717
30718 toHide.attr( "aria-hidden", "true" );
30719 eventData.oldTab.attr( {
30720 "aria-selected": "false",
30721 "aria-expanded": "false"
30722 } );
30723
30724 // If we're switching tabs, remove the old tab from the tab order.
30725 // If we're opening from collapsed state, remove the previous tab from the tab order.
30726 // If we're collapsing, then keep the collapsing tab in the tab order.
30727 if ( toShow.length && toHide.length ) {
30728 eventData.oldTab.attr( "tabIndex", -1 );
30729 } else if ( toShow.length ) {
30730 this.tabs.filter( function() {
30731 return $( this ).attr( "tabIndex" ) === 0;
30732 } )
30733 .attr( "tabIndex", -1 );
30734 }
30735
30736 toShow.attr( "aria-hidden", "false" );
30737 eventData.newTab.attr( {
30738 "aria-selected": "true",
30739 "aria-expanded": "true",
30740 tabIndex: 0
30741 } );
30742 },
30743
30744 _activate: function( index ) {
30745 var anchor,
30746 active = this._findActive( index );
30747
30748 // Trying to activate the already active panel
30749 if ( active[ 0 ] === this.active[ 0 ] ) {
30750 return;
30751 }
30752
30753 // Trying to collapse, simulate a click on the current active header
30754 if ( !active.length ) {
30755 active = this.active;
30756 }
30757
30758 anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
30759 this._eventHandler( {
30760 target: anchor,
30761 currentTarget: anchor,
30762 preventDefault: $.noop
30763 } );
30764 },
30765
30766 _findActive: function( index ) {
30767 return index === false ? $() : this.tabs.eq( index );
30768 },
30769
30770 _getIndex: function( index ) {
30771
30772 // meta-function to give users option to provide a href string instead of a numerical index.
30773 if ( typeof index === "string" ) {
30774 index = this.anchors.index( this.anchors.filter( "[href$='" +
30775 CSS.escape( index ) + "']" ) );
30776 }
30777
30778 return index;
30779 },
30780
30781 _destroy: function() {
30782 if ( this.xhr ) {
30783 this.xhr.abort();
30784 }
30785
30786 this.tablist
30787 .removeAttr( "role" )
30788 .off( this.eventNamespace );
30789
30790 this.anchors
30791 .removeAttr( "role tabIndex" )
30792 .removeUniqueId();
30793
30794 this.tabs.add( this.panels ).each( function() {
30795 if ( $.data( this, "ui-tabs-destroy" ) ) {
30796 $( this ).remove();
30797 } else {
30798 $( this ).removeAttr( "role tabIndex " +
30799 "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
30800 }
30801 } );
30802
30803 this.tabs.each( function() {
30804 var li = $( this ),
30805 prev = li.data( "ui-tabs-aria-controls" );
30806 if ( prev ) {
30807 li
30808 .attr( "aria-controls", prev )
30809 .removeData( "ui-tabs-aria-controls" );
30810 } else {
30811 li.removeAttr( "aria-controls" );
30812 }
30813 } );
30814
30815 this.panels.show();
30816
30817 if ( this.options.heightStyle !== "content" ) {
30818 this.panels.css( "height", "" );
30819 }
30820 },
30821
30822 enable: function( index ) {
30823 var disabled = this.options.disabled;
30824 if ( disabled === false ) {
30825 return;
30826 }
30827
30828 if ( index === undefined ) {
30829 disabled = false;
30830 } else {
30831 index = this._getIndex( index );
30832 if ( Array.isArray( disabled ) ) {
30833 disabled = $.map( disabled, function( num ) {
30834 return num !== index ? num : null;
30835 } );
30836 } else {
30837 disabled = $.map( this.tabs, function( li, num ) {
30838 return num !== index ? num : null;
30839 } );
30840 }
30841 }
30842 this._setOptionDisabled( disabled );
30843 },
30844
30845 disable: function( index ) {
30846 var disabled = this.options.disabled;
30847 if ( disabled === true ) {
30848 return;
30849 }
30850
30851 if ( index === undefined ) {
30852 disabled = true;
30853 } else {
30854 index = this._getIndex( index );
30855 if ( $.inArray( index, disabled ) !== -1 ) {
30856 return;
30857 }
30858 if ( Array.isArray( disabled ) ) {
30859 disabled = $.merge( [ index ], disabled ).sort();
30860 } else {
30861 disabled = [ index ];
30862 }
30863 }
30864 this._setOptionDisabled( disabled );
30865 },
30866
30867 load: function( index, event ) {
30868 index = this._getIndex( index );
30869 var that = this,
30870 tab = this.tabs.eq( index ),
30871 anchor = tab.find( ".ui-tabs-anchor" ),
30872 panel = this._getPanelForTab( tab ),
30873 eventData = {
30874 tab: tab,
30875 panel: panel
30876 },
30877 complete = function( jqXHR, status ) {
30878 if ( status === "abort" ) {
30879 that.panels.stop( false, true );
30880 }
30881
30882 that._removeClass( tab, "ui-tabs-loading" );
30883 panel.removeAttr( "aria-busy" );
30884
30885 if ( jqXHR === that.xhr ) {
30886 delete that.xhr;
30887 }
30888 };
30889
30890 // Not remote
30891 if ( this._isLocal( anchor[ 0 ] ) ) {
30892 return;
30893 }
30894
30895 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
30896
30897 if ( this.xhr.statusText !== "canceled" ) {
30898 this._addClass( tab, "ui-tabs-loading" );
30899 panel.attr( "aria-busy", "true" );
30900
30901 this.xhr
30902 .done( function( response, status, jqXHR ) {
30903 panel.html( response );
30904 that._trigger( "load", event, eventData );
30905
30906 complete( jqXHR, status );
30907 } )
30908 .fail( function( jqXHR, status ) {
30909 complete( jqXHR, status );
30910 } );
30911 }
30912 },
30913
30914 _ajaxSettings: function( anchor, event, eventData ) {
30915 var that = this;
30916 return {
30917 url: anchor.attr( "href" ),
30918 beforeSend: function( jqXHR, settings ) {
30919 return that._trigger( "beforeLoad", event,
30920 $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
30921 }
30922 };
30923 },
30924
30925 _getPanelForTab: function( tab ) {
30926 var id = $( tab ).attr( "aria-controls" );
30927 return this.element.find( "#" + CSS.escape( id ) );
30928 }
30929} );
30930
30931// DEPRECATED
30932// TODO: Switch return back to widget declaration at top of file when this is removed
30933if ( $.uiBackCompat === true ) {
30934
30935 // Backcompat for ui-tab class (now ui-tabs-tab)
30936 $.widget( "ui.tabs", $.ui.tabs, {
30937 _processTabs: function() {
30938 this._superApply( arguments );
30939 this._addClass( this.tabs, "ui-tab" );
30940 }
30941 } );
30942}
30943
30944return $.ui.tabs;
30945
30946} );
30947
30948
30949
30950
30951
30952
30953/*!
30954 * jQuery UI Tooltip 1.14.1
30955 * https://jqueryui.com
30956 *
30957 * Copyright OpenJS Foundation and other contributors
30958 * Released under the MIT license.
30959 * https://jquery.org/license
30960 */
30961
30962//>>label: Tooltip
30963//>>group: Widgets
30964//>>description: Shows additional information for any element on hover or focus.
30965//>>docs: https://api.jqueryui.com/tooltip/
30966//>>demos: https://jqueryui.com/tooltip/
30967//>>css.structure: ../../themes/base/core.css
30968//>>css.structure: ../../themes/base/tooltip.css
30969//>>css.theme: ../../themes/base/theme.css
30970
30971( function( factory ) {
30972 "use strict";
30973
30974 if ( typeof define === "function" && define.amd ) {
30975
30976 // AMD. Register as an anonymous module.
30977 define( [
30978 "jquery",
30979 "../keycode",
30980 "../position",
30981 "../unique-id",
30982 "../version",
30983 "../widget"
30984 ], factory );
30985 } else {
30986
30987 // Browser globals
30988 factory( jQuery );
30989 }
30990} )( function( $ ) {
30991"use strict";
30992
30993$.widget( "ui.tooltip", {
30994 version: "1.14.1",
30995 options: {
30996 classes: {
30997 "ui-tooltip": "ui-corner-all ui-widget-shadow"
30998 },
30999 content: function() {
31000 var title = $( this ).attr( "title" );
31001
31002 // Escape title, since we're going from an attribute to raw HTML
31003 return $( "<a>" ).text( title ).html();
31004 },
31005 hide: true,
31006
31007 // Disabled elements have inconsistent behavior across browsers (#8661)
31008 items: "[title]:not([disabled])",
31009 position: {
31010 my: "left top+15",
31011 at: "left bottom",
31012 collision: "flipfit flip"
31013 },
31014 show: true,
31015 track: false,
31016
31017 // Callbacks
31018 close: null,
31019 open: null
31020 },
31021
31022 _addDescribedBy: function( elem, id ) {
31023 var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
31024 describedby.push( id );
31025 elem
31026 .data( "ui-tooltip-id", id )
31027 .attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) );
31028 },
31029
31030 _removeDescribedBy: function( elem ) {
31031 var id = elem.data( "ui-tooltip-id" ),
31032 describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
31033 index = $.inArray( id, describedby );
31034
31035 if ( index !== -1 ) {
31036 describedby.splice( index, 1 );
31037 }
31038
31039 elem.removeData( "ui-tooltip-id" );
31040 describedby = String.prototype.trim.call( describedby.join( " " ) );
31041 if ( describedby ) {
31042 elem.attr( "aria-describedby", describedby );
31043 } else {
31044 elem.removeAttr( "aria-describedby" );
31045 }
31046 },
31047
31048 _create: function() {
31049 this._on( {
31050 mouseover: "open",
31051 focusin: "open"
31052 } );
31053
31054 // IDs of generated tooltips, needed for destroy
31055 this.tooltips = {};
31056
31057 // IDs of parent tooltips where we removed the title attribute
31058 this.parents = {};
31059
31060 // Append the aria-live region so tooltips announce correctly
31061 this.liveRegion = $( "<div>" )
31062 .attr( {
31063 role: "log",
31064 "aria-live": "assertive",
31065 "aria-relevant": "additions"
31066 } )
31067 .appendTo( this.document[ 0 ].body );
31068 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
31069
31070 this.disabledTitles = $( [] );
31071 },
31072
31073 _setOption: function( key, value ) {
31074 var that = this;
31075
31076 this._super( key, value );
31077
31078 if ( key === "content" ) {
31079 $.each( this.tooltips, function( id, tooltipData ) {
31080 that._updateContent( tooltipData.element );
31081 } );
31082 }
31083 },
31084
31085 _setOptionDisabled: function( value ) {
31086 this[ value ? "_disable" : "_enable" ]();
31087 },
31088
31089 _disable: function() {
31090 var that = this;
31091
31092 // Close open tooltips
31093 $.each( this.tooltips, function( id, tooltipData ) {
31094 var event = $.Event( "blur" );
31095 event.target = event.currentTarget = tooltipData.element[ 0 ];
31096 that.close( event, true );
31097 } );
31098
31099 // Remove title attributes to prevent native tooltips
31100 this.disabledTitles = this.disabledTitles.add(
31101 this.element.find( this.options.items ).addBack()
31102 .filter( function() {
31103 var element = $( this );
31104 if ( element.is( "[title]" ) ) {
31105 return element
31106 .data( "ui-tooltip-title", element.attr( "title" ) )
31107 .removeAttr( "title" );
31108 }
31109 } )
31110 );
31111 },
31112
31113 _enable: function() {
31114
31115 // restore title attributes
31116 this.disabledTitles.each( function() {
31117 var element = $( this );
31118 if ( element.data( "ui-tooltip-title" ) ) {
31119 element.attr( "title", element.data( "ui-tooltip-title" ) );
31120 }
31121 } );
31122 this.disabledTitles = $( [] );
31123 },
31124
31125 open: function( event ) {
31126 var that = this,
31127 target = $( event ? event.target : this.element )
31128
31129 // we need closest here due to mouseover bubbling,
31130 // but always pointing at the same event target
31131 .closest( this.options.items );
31132
31133 // No element to show a tooltip for or the tooltip is already open
31134 if ( !target.length || target.data( "ui-tooltip-id" ) ) {
31135 return;
31136 }
31137
31138 if ( target.attr( "title" ) ) {
31139 target.data( "ui-tooltip-title", target.attr( "title" ) );
31140 }
31141
31142 target.data( "ui-tooltip-open", true );
31143
31144 // Kill parent tooltips, custom or native, for hover
31145 if ( event && event.type === "mouseover" ) {
31146 target.parents().each( function() {
31147 var parent = $( this ),
31148 blurEvent;
31149 if ( parent.data( "ui-tooltip-open" ) ) {
31150 blurEvent = $.Event( "blur" );
31151 blurEvent.target = blurEvent.currentTarget = this;
31152 that.close( blurEvent, true );
31153 }
31154 if ( parent.attr( "title" ) ) {
31155 parent.uniqueId();
31156 that.parents[ this.id ] = {
31157 element: this,
31158 title: parent.attr( "title" )
31159 };
31160 parent.attr( "title", "" );
31161 }
31162 } );
31163 }
31164
31165 this._registerCloseHandlers( event, target );
31166 this._updateContent( target, event );
31167 },
31168
31169 _updateContent: function( target, event ) {
31170 var content,
31171 contentOption = this.options.content,
31172 that = this,
31173 eventType = event ? event.type : null;
31174
31175 if ( typeof contentOption === "string" || contentOption.nodeType ||
31176 contentOption.jquery ) {
31177 return this._open( event, target, contentOption );
31178 }
31179
31180 content = contentOption.call( target[ 0 ], function( response ) {
31181
31182 // Ignore async response if tooltip was closed already
31183 if ( !target.data( "ui-tooltip-open" ) ) {
31184 return;
31185 }
31186
31187 // JQuery creates a special event for focusin when it doesn't
31188 // exist natively. To improve performance, the native event
31189 // object is reused and the type is changed. Therefore, we can't
31190 // rely on the type being correct after the event finished
31191 // bubbling, so we set it back to the previous value. (#8740)
31192 if ( event ) {
31193 event.type = eventType;
31194 }
31195 that._open( event, target, response );
31196 } );
31197 if ( content ) {
31198 this._open( event, target, content );
31199 }
31200 },
31201
31202 _open: function( event, target, content ) {
31203 var tooltipData, tooltip, delayedShow, a11yContent,
31204 positionOption = $.extend( {}, this.options.position );
31205
31206 if ( !content ) {
31207 return;
31208 }
31209
31210 // Content can be updated multiple times. If the tooltip already
31211 // exists, then just update the content and bail.
31212 tooltipData = this._find( target );
31213 if ( tooltipData ) {
31214 tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
31215 return;
31216 }
31217
31218 // If we have a title, clear it to prevent the native tooltip
31219 // we have to check first to avoid defining a title if none exists
31220 // (we don't want to cause an element to start matching [title])
31221 //
31222 // We use removeAttr only for key events, to allow IE to export the correct
31223 // accessible attributes. For mouse events, set to empty string to avoid
31224 // native tooltip showing up (happens only when removing inside mouseover).
31225 if ( target.is( "[title]" ) ) {
31226 if ( event && event.type === "mouseover" ) {
31227 target.attr( "title", "" );
31228 } else {
31229 target.removeAttr( "title" );
31230 }
31231 }
31232
31233 tooltipData = this._tooltip( target );
31234 tooltip = tooltipData.tooltip;
31235 this._addDescribedBy( target, tooltip.attr( "id" ) );
31236 tooltip.find( ".ui-tooltip-content" ).html( content );
31237
31238 // Support: Voiceover on OS X, JAWS on IE <= 9
31239 // JAWS announces deletions even when aria-relevant="additions"
31240 // Voiceover will sometimes re-read the entire log region's contents from the beginning
31241 this.liveRegion.children().hide();
31242 a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
31243 a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
31244 a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
31245 a11yContent.appendTo( this.liveRegion );
31246
31247 function position( event ) {
31248 positionOption.of = event;
31249 if ( tooltip.is( ":hidden" ) ) {
31250 return;
31251 }
31252 tooltip.position( positionOption );
31253 }
31254 if ( this.options.track && event && /^mouse/.test( event.type ) ) {
31255 this._on( this.document, {
31256 mousemove: position
31257 } );
31258
31259 // trigger once to override element-relative positioning
31260 position( event );
31261 } else {
31262 tooltip.position( $.extend( {
31263 of: target
31264 }, this.options.position ) );
31265 }
31266
31267 tooltip.hide();
31268
31269 this._show( tooltip, this.options.show );
31270
31271 // Handle tracking tooltips that are shown with a delay (#8644). As soon
31272 // as the tooltip is visible, position the tooltip using the most recent
31273 // event.
31274 // Adds the check to add the timers only when both delay and track options are set (#14682)
31275 if ( this.options.track && this.options.show && this.options.show.delay ) {
31276 delayedShow = this.delayedShow = setInterval( function() {
31277 if ( tooltip.is( ":visible" ) ) {
31278 position( positionOption.of );
31279 clearInterval( delayedShow );
31280 }
31281 }, 13 );
31282 }
31283
31284 this._trigger( "open", event, { tooltip: tooltip } );
31285 },
31286
31287 _registerCloseHandlers: function( event, target ) {
31288 var events = {
31289 keyup: function( event ) {
31290 if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
31291 var fakeEvent = $.Event( event );
31292 fakeEvent.currentTarget = target[ 0 ];
31293 this.close( fakeEvent, true );
31294 }
31295 }
31296 };
31297
31298 // Only bind remove handler for delegated targets. Non-delegated
31299 // tooltips will handle this in destroy.
31300 if ( target[ 0 ] !== this.element[ 0 ] ) {
31301 events.remove = function() {
31302 var targetElement = this._find( target );
31303 if ( targetElement ) {
31304 this._removeTooltip( targetElement.tooltip );
31305 }
31306 };
31307 }
31308
31309 if ( !event || event.type === "mouseover" ) {
31310 events.mouseleave = "close";
31311 }
31312 if ( !event || event.type === "focusin" ) {
31313 events.focusout = "close";
31314 }
31315 this._on( true, target, events );
31316 },
31317
31318 close: function( event ) {
31319 var tooltip,
31320 that = this,
31321 target = $( event ? event.currentTarget : this.element ),
31322 tooltipData = this._find( target );
31323
31324 // The tooltip may already be closed
31325 if ( !tooltipData ) {
31326
31327 // We set ui-tooltip-open immediately upon open (in open()), but only set the
31328 // additional data once there's actually content to show (in _open()). So even if the
31329 // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
31330 // the period between open() and _open().
31331 target.removeData( "ui-tooltip-open" );
31332 return;
31333 }
31334
31335 tooltip = tooltipData.tooltip;
31336
31337 // Disabling closes the tooltip, so we need to track when we're closing
31338 // to avoid an infinite loop in case the tooltip becomes disabled on close
31339 if ( tooltipData.closing ) {
31340 return;
31341 }
31342
31343 // Clear the interval for delayed tracking tooltips
31344 clearInterval( this.delayedShow );
31345
31346 // Only set title if we had one before (see comment in _open())
31347 // If the title attribute has changed since open(), don't restore
31348 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
31349 target.attr( "title", target.data( "ui-tooltip-title" ) );
31350 }
31351
31352 this._removeDescribedBy( target );
31353
31354 tooltipData.hiding = true;
31355 tooltip.stop( true );
31356 this._hide( tooltip, this.options.hide, function() {
31357 that._removeTooltip( $( this ) );
31358 } );
31359
31360 target.removeData( "ui-tooltip-open" );
31361 this._off( target, "mouseleave focusout keyup" );
31362
31363 // Remove 'remove' binding only on delegated targets
31364 if ( target[ 0 ] !== this.element[ 0 ] ) {
31365 this._off( target, "remove" );
31366 }
31367 this._off( this.document, "mousemove" );
31368
31369 if ( event && event.type === "mouseleave" ) {
31370 $.each( this.parents, function( id, parent ) {
31371 $( parent.element ).attr( "title", parent.title );
31372 delete that.parents[ id ];
31373 } );
31374 }
31375
31376 tooltipData.closing = true;
31377 this._trigger( "close", event, { tooltip: tooltip } );
31378 if ( !tooltipData.hiding ) {
31379 tooltipData.closing = false;
31380 }
31381 },
31382
31383 _tooltip: function( element ) {
31384 var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
31385 content = $( "<div>" ).appendTo( tooltip ),
31386 id = tooltip.uniqueId().attr( "id" );
31387
31388 this._addClass( content, "ui-tooltip-content" );
31389 this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
31390
31391 tooltip.appendTo( this._appendTo( element ) );
31392
31393 return this.tooltips[ id ] = {
31394 element: element,
31395 tooltip: tooltip
31396 };
31397 },
31398
31399 _find: function( target ) {
31400 var id = target.data( "ui-tooltip-id" );
31401 return id ? this.tooltips[ id ] : null;
31402 },
31403
31404 _removeTooltip: function( tooltip ) {
31405
31406 // Clear the interval for delayed tracking tooltips
31407 clearInterval( this.delayedShow );
31408
31409 tooltip.remove();
31410 delete this.tooltips[ tooltip.attr( "id" ) ];
31411 },
31412
31413 _appendTo: function( target ) {
31414 var element = target.closest( ".ui-front, dialog" );
31415
31416 if ( !element.length ) {
31417 element = this.document[ 0 ].body;
31418 }
31419
31420 return element;
31421 },
31422
31423 _destroy: function() {
31424 var that = this;
31425
31426 // Close open tooltips
31427 $.each( this.tooltips, function( id, tooltipData ) {
31428
31429 // Delegate to close method to handle common cleanup
31430 var event = $.Event( "blur" ),
31431 element = tooltipData.element;
31432 event.target = event.currentTarget = element[ 0 ];
31433 that.close( event, true );
31434
31435 // Remove immediately; destroying an open tooltip doesn't use the
31436 // hide animation
31437 $( "#" + id ).remove();
31438
31439 // Restore the title
31440 if ( element.data( "ui-tooltip-title" ) ) {
31441
31442 // If the title attribute has changed since open(), don't restore
31443 if ( !element.attr( "title" ) ) {
31444 element.attr( "title", element.data( "ui-tooltip-title" ) );
31445 }
31446 element.removeData( "ui-tooltip-title" );
31447 }
31448 } );
31449 this.liveRegion.remove();
31450 }
31451} );
31452
31453// DEPRECATED
31454// TODO: Switch return back to widget declaration at top of file when this is removed
31455if ( $.uiBackCompat === true ) {
31456
31457 // Backcompat for tooltipClass option
31458 $.widget( "ui.tooltip", $.ui.tooltip, {
31459 options: {
31460 tooltipClass: null
31461 },
31462 _tooltip: function() {
31463 var tooltipData = this._superApply( arguments );
31464 if ( this.options.tooltipClass ) {
31465 tooltipData.tooltip.addClass( this.options.tooltipClass );
31466 }
31467 return tooltipData;
31468 }
31469 } );
31470}
31471
31472return $.ui.tooltip;
31473
31474} );
31475
31476
31477
31478
31479
31480
31481
31482
31483
31484
31485
31486
31487
31488
31489
31490
31491
31492
31493
31494
31495
31496
31497
31498
31499
31500
31501
31502
31503
31504
31505
31506
31507
31508
31509
31510
31511
31512
31513
31514
31515
31516
31517
31518
31519
31520
31521
31522
31523
31524
31525
31526
31527/*
31528(c) Copyrights 2007 - 2008
31529
31530Original idea by by Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/
31531
31532jQuery Plugin by Tzury Bar Yochay
31533tzury.by@gmail.com
31534http://evalinux.wordpress.com
31535http://facebook.com/profile.php?id=513676303
31536
31537Project's sites:
31538http://code.google.com/p/js-hotkeys/
31539http://github.com/tzuryby/hotkeys/tree/master
31540
31541License: same as jQuery license.
31542
31543USAGE:
31544 // simple usage
31545 $(document).bind('keydown', 'Ctrl+c', function(){ alert('copy anyone?');});
31546
31547 // special options such as disableInIput
31548 $(document).bind('keydown', {combi:'Ctrl+x', disableInInput: true} , function() {});
31549
31550Note:
31551 This plugin wraps the following jQuery methods: $.fn.find, $.fn.bind and $.fn.unbind
31552*/
31553
31554(function (jQuery){
31555 // keep reference to the original $.fn.bind, $.fn.unbind and $.fn.find
31556 jQuery.fn.__bind__ = jQuery.fn.bind;
31557 jQuery.fn.__unbind__ = jQuery.fn.unbind;
31558 jQuery.fn.__find__ = jQuery.fn.find;
31559
31560 var hotkeys = {
31561 version: '0.7.9',
31562 override: /keypress|keydown|keyup/g,
31563 triggersMap: {},
31564
31565 specialKeys: { 27: 'esc', 9: 'tab', 32:'space', 13: 'return', 8:'backspace', 145: 'scroll',
31566 20: 'capslock', 144: 'numlock', 19:'pause', 45:'insert', 36:'home', 46:'del',
31567 35:'end', 33: 'pageup', 34:'pagedown', 37:'left', 38:'up', 39:'right',40:'down',
31568 109: '-',
31569 112:'f1',113:'f2', 114:'f3', 115:'f4', 116:'f5', 117:'f6', 118:'f7', 119:'f8',
31570 120:'f9', 121:'f10', 122:'f11', 123:'f12', 191: '/'},
31571
31572 shiftNums: { "`":"~", "1":"!", "2":"@", "3":"#", "4":"$", "5":"%", "6":"^", "7":"&",
31573 "8":"*", "9":"(", "0":")", "-":"_", "=":"+", ";":":", "'":"\"", ",":"<",
31574 ".":">", "/":"?", "\\":"|" },
31575
31576 newTrigger: function (type, combi, callback) {
31577 // i.e. {'keyup': {'ctrl': {cb: callback, disableInInput: false}}}
31578 var result = {};
31579 result[type] = {};
31580 result[type][combi] = {cb: callback, disableInInput: false};
31581 return result;
31582 }
31583 };
31584 // add firefox num pad char codes
31585 //if (jQuery.browser.mozilla){
31586 // add num pad char codes
31587 hotkeys.specialKeys = jQuery.extend(hotkeys.specialKeys, { 96: '0', 97:'1', 98: '2', 99:
31588 '3', 100: '4', 101: '5', 102: '6', 103: '7', 104: '8', 105: '9', 106: '*',
31589 107: '+', 109: '-', 110: '.', 111 : '/'
31590 });
31591 //}
31592
31593 // a wrapper around of $.fn.find
31594 // see more at: http://groups.google.com/group/jquery-en/browse_thread/thread/18f9825e8d22f18d
31595 jQuery.fn.find = function( selector ) {
31596 this.query = selector;
31597 return jQuery.fn.__find__.apply(this, arguments);
31598 };
31599
31600 jQuery.fn.unbind = function (type, combi, fn){
31601 if (jQuery.isFunction(combi)){
31602 fn = combi;
31603 combi = null;
31604 }
31605 if (combi && typeof combi === 'string'){
31606 var selectorId = ((this.prevObject && this.prevObject.query) || (this[0].id && this[0].id) || this[0]).toString();
31607 var hkTypes = type.split(' ');
31608 for (var x=0; x<hkTypes.length; x++){
31609 delete hotkeys.triggersMap[selectorId][hkTypes[x]][combi];
31610 }
31611 }
31612 // call jQuery original unbind
31613 return this.__unbind__(type, fn);
31614 };
31615
31616 jQuery.fn.bind = function(type, data, fn){
31617 // grab keyup,keydown,keypress
31618 var handle = type.match(hotkeys.override);
31619
31620 if (jQuery.isFunction(data) || !handle){
31621 // call jQuery.bind only
31622 return this.__bind__(type, data, fn);
31623 }
31624 else{
31625 // split the job
31626 var result = null,
31627 // pass the rest to the original $.fn.bind
31628 pass2jq = jQuery.trim(type.replace(hotkeys.override, ''));
31629
31630 // see if there are other types, pass them to the original $.fn.bind
31631 if (pass2jq){
31632 result = this.__bind__(pass2jq, data, fn);
31633 }
31634
31635 if (typeof data === "string"){
31636 data = {'combi': data};
31637 }
31638 if(data.combi){
31639 for (var x=0; x < handle.length; x++){
31640 var eventType = handle[x];
31641 var combi = data.combi.toLowerCase(),
31642 trigger = hotkeys.newTrigger(eventType, combi, fn),
31643 selectorId = ((this.prevObject && this.prevObject.query) || (this[0].id && this[0].id) || this[0]).toString();
31644
31645 //trigger[eventType][combi].propagate = data.propagate;
31646 trigger[eventType][combi].disableInInput = data.disableInInput;
31647
31648 // first time selector is bounded
31649 if (!hotkeys.triggersMap[selectorId]) {
31650 hotkeys.triggersMap[selectorId] = trigger;
31651 }
31652 // first time selector is bounded with this type
31653 else if (!hotkeys.triggersMap[selectorId][eventType]) {
31654 hotkeys.triggersMap[selectorId][eventType] = trigger[eventType];
31655 }
31656 // make trigger point as array so more than one handler can be bound
31657 var mapPoint = hotkeys.triggersMap[selectorId][eventType][combi];
31658 if (!mapPoint){
31659 hotkeys.triggersMap[selectorId][eventType][combi] = [trigger[eventType][combi]];
31660 }
31661 else if (mapPoint.constructor !== Array){
31662 hotkeys.triggersMap[selectorId][eventType][combi] = [mapPoint];
31663 }
31664 else {
31665 hotkeys.triggersMap[selectorId][eventType][combi][mapPoint.length] = trigger[eventType][combi];
31666 }
31667
31668 // add attribute and call $.event.add per matched element
31669 this.each(function(){
31670 // jQuery wrapper for the current element
31671 var jqElem = jQuery(this);
31672
31673 // element already associated with another collection
31674 if (jqElem.attr('hkId') && jqElem.attr('hkId') !== selectorId){
31675 selectorId = jqElem.attr('hkId') + ";" + selectorId;
31676 }
31677 jqElem.attr('hkId', selectorId);
31678 });
31679 result = this.__bind__(handle.join(' '), data, hotkeys.handler)
31680 }
31681 }
31682 return result;
31683 }
31684 };
31685 // work-around for opera and safari where (sometimes) the target is the element which was last
31686 // clicked with the mouse and not the document event it would make sense to get the document
31687 hotkeys.findElement = function (elem){
31688 if (!jQuery(elem).attr('hkId')){
31689 if (jQuery.browser.opera || jQuery.browser.safari){
31690 while (!jQuery(elem).attr('hkId') && elem.parentNode){
31691 elem = elem.parentNode;
31692 }
31693 }
31694 }
31695 return elem;
31696 };
31697 // the event handler
31698 hotkeys.handler = function(event) {
31699 var target = hotkeys.findElement(event.currentTarget),
31700 jTarget = jQuery(target),
31701 ids = jTarget.attr('hkId');
31702
31703 if(ids){
31704 ids = ids.split(';');
31705 var code = event.which,
31706 type = event.type,
31707 special = hotkeys.specialKeys[code],
31708 // prevent f5 overlapping with 't' (or f4 with 's', etc.)
31709 character = !special && String.fromCharCode(code).toLowerCase(),
31710 shift = event.shiftKey,
31711 ctrl = event.ctrlKey,
31712 // patch for jquery 1.2.5 && 1.2.6 see more at:
31713 // http://groups.google.com/group/jquery-en/browse_thread/thread/83e10b3bb1f1c32b
31714 alt = event.altKey || event.originalEvent.altKey,
31715 mapPoint = null;
31716
31717 for (var x=0; x < ids.length; x++){
31718 if (hotkeys.triggersMap[ids[x]][type]){
31719 mapPoint = hotkeys.triggersMap[ids[x]][type];
31720 break;
31721 }
31722 }
31723
31724 //find by: id.type.combi.options
31725 if (mapPoint){
31726 var trigger;
31727 // event type is associated with the hkId
31728 if(!shift && !ctrl && !alt) { // No Modifiers
31729 trigger = mapPoint[special] || (character && mapPoint[character]);
31730 }
31731 else{
31732 // check combinations (alt|ctrl|shift+anything)
31733 var modif = '';
31734 if(alt) modif +='alt+';
31735 if(ctrl) modif+= 'ctrl+';
31736 if(shift) modif += 'shift+';
31737 // modifiers + special keys or modifiers + character or modifiers + shift character or just shift character
31738 trigger = mapPoint[modif+special];
31739 if (!trigger){
31740 if (character){
31741 trigger = mapPoint[modif+character]
31742 || mapPoint[modif+hotkeys.shiftNums[character]]
31743 // '$' can be triggered as 'Shift+4' or 'Shift+$' or just '$'
31744 || (modif === 'shift+' && mapPoint[hotkeys.shiftNums[character]]);
31745 }
31746 }
31747 }
31748 if (trigger){
31749 var result = false;
31750 for (var x=0; x < trigger.length; x++){
31751 if(trigger[x].disableInInput){
31752 // double check event.currentTarget and event.target
31753 var elem = jQuery(event.target);
31754 if (jTarget.is("input") || jTarget.is("textarea") || jTarget.is("select")
31755 || elem.is("input") || elem.is("textarea") || elem.is("select")) {
31756 return true;
31757 }
31758 }
31759 // call the registered callback function
31760 result = result || trigger[x].cb.apply(this, [event]);
31761 }
31762 return result;
31763 }
31764 }
31765 }
31766 };
31767 // place it under window so it can be extended and overridden by others
31768 window.hotkeys = hotkeys;
31769 return jQuery;
31770})(jQuery);
31771
31772
31773
31774
31775