1/*! 2 * jQuery JavaScript Library v2.2.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:23Z 13 */ 14// 15var jQuery_backup = jQuery; 16// 17
vendor: 257,288 bytes, lines 18-9820
18 19 20(function( global, factory ) { 21 22 if ( typeof module === "object" && typeof module.exports === "object" ) { 23 // For CommonJS and CommonJS-like environments where a proper `window` 24 // is present, execute the factory and get jQuery. 25 // For environments that do not have a `window` with a `document` 26 // (such as Node.js), expose a factory as module.exports. 27 // This accentuates the need for the creation of a real `window`. 28 // e.g. var jQuery = require("jquery")(window); 29 // See ticket #14549 for more info. 30 module.exports = global.document ? 31 factory( global, true ) : 32 function( w ) { 33 if ( !w.document ) { 34 throw new Error( "jQuery requires a window with a document" ); 35 } 36 return factory( w ); 37 }; 38 } else { 39 factory( global ); 40 } 41 42// Pass this if window is not defined yet 43}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { 44 45// Support: Firefox 18+ 46// Can't be in strict mode, several libs including ASP.NET trace 47// the stack via arguments.caller.callee and Firefox dies if 48// you try to trace through "use strict" call chains. (#13335) 49//"use strict"; 50var arr = []; 51 52var document = window.document; 53 54var slice = arr.slice; 55 56var concat = arr.concat; 57 58var push = arr.push; 59 60var indexOf = arr.indexOf; 61 62var class2type = {}; 63 64var toString = class2type.toString; 65 66var hasOwn = class2type.hasOwnProperty; 67 68var support = {}; 69 70 71 72var 73 version = "2.2.4", 74 75 // Define a local copy of jQuery 76 jQuery = function( selector, context ) { 77 78 // The jQuery object is actually just the init constructor 'enhanced' 79 // Need init if jQuery is called (just allow error to be thrown if not included) 80 return new jQuery.fn.init( selector, context ); 81 }, 82 83 // Support: Android<4.1 84 // Make sure we trim BOM and NBSP 85 rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, 86 87 // Matches dashed string for camelizing 88 rmsPrefix = /^-ms-/, 89 rdashAlpha = /-([\da-z])/gi, 90 91 // Used by jQuery.camelCase as callback to replace() 92 fcamelCase = function( all, letter ) { 93 return letter.toUpperCase(); 94 }; 95 96jQuery.fn = jQuery.prototype = { 97 98 // The current version of jQuery being used 99 jquery: version, 100 101 constructor: jQuery, 102 103 // Start with an empty selector 104 selector: "", 105 106 // The default length of a jQuery object is 0 107 length: 0, 108 109 toArray: function() { 110 return slice.call( this ); 111 }, 112 113 // Get the Nth element in the matched element set OR 114 // Get the whole matched element set as a clean array 115 get: function( num ) { 116 return num != null ? 117 118 // Return just the one element from the set 119 ( num < 0 ? this[ num + this.length ] : this[ num ] ) : 120 121 // Return all the elements in a clean array 122 slice.call( this ); 123 }, 124 125 // Take an array of elements and push it onto the stack 126 // (returning the new matched element set) 127 pushStack: function( elems ) { 128 129 // Build a new jQuery matched element set 130 var ret = jQuery.merge( this.constructor(), elems ); 131 132 // Add the old object onto the stack (as a reference) 133 ret.prevObject = this; 134 ret.context = this.context; 135 136 // Return the newly-formed element set 137 return ret; 138 }, 139 140 // Execute a callback for every element in the matched set. 141 each: function( callback ) { 142 return jQuery.each( this, callback ); 143 }, 144 145 map: function( callback ) { 146 return this.pushStack( jQuery.map( this, function( elem, i ) { 147 return callback.call( elem, i, elem ); 148 } ) ); 149 }, 150 151 slice: function() { 152 return this.pushStack( slice.apply( this, arguments ) ); 153 }, 154 155 first: function() { 156 return this.eq( 0 ); 157 }, 158 159 last: function() { 160 return this.eq( -1 ); 161 }, 162 163 eq: function( i ) { 164 var len = this.length, 165 j = +i + ( i < 0 ? len : 0 ); 166 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); 167 }, 168 169 end: function() { 170 return this.prevObject || this.constructor(); 171 }, 172 173 // For internal use only. 174 // Behaves like an Array's method, not like a jQuery method. 175 push: push, 176 sort: arr.sort, 177 splice: arr.splice 178}; 179 180jQuery.extend = jQuery.fn.extend = function() { 181 var options, name, src, copy, copyIsArray, clone, 182 target = arguments[ 0 ] || {}, 183 i = 1, 184 length = arguments.length, 185 deep = false; 186 187 // Handle a deep copy situation 188 if ( typeof target === "boolean" ) { 189 deep = target; 190 191 // Skip the boolean and the target 192 target = arguments[ i ] || {}; 193 i++; 194 } 195 196 // Handle case when target is a string or something (possible in deep copy) 197 if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { 198 target = {}; 199 } 200 201 // Extend jQuery itself if only one argument is passed 202 if ( i === length ) { 203 target = this; 204 i--; 205 } 206 207 for ( ; i < length; i++ ) { 208 209 // Only deal with non-null/undefined values 210 if ( ( options = arguments[ i ] ) != null ) { 211 212 // Extend the base object 213 for ( name in options ) { 214 src = target[ name ]; 215 copy = options[ name ]; 216 217 // Prevent never-ending loop 218 if ( target === copy ) { 219 continue; 220 } 221 222 // Recurse if we're merging plain objects or arrays 223 if ( deep && copy && ( jQuery.isPlainObject( copy ) || 224 ( copyIsArray = jQuery.isArray( copy ) ) ) ) { 225 226 if ( copyIsArray ) { 227 copyIsArray = false; 228 clone = src && jQuery.isArray( src ) ? src : []; 229 230 } else { 231 clone = src && jQuery.isPlainObject( src ) ? src : {}; 232 } 233 234 // Never move original objects, clone them 235 target[ name ] = jQuery.extend( deep, clone, copy ); 236 237 // Don't bring in undefined values 238 } else if ( copy !== undefined ) { 239 target[ name ] = copy; 240 } 241 } 242 } 243 } 244 245 // Return the modified object 246 return target; 247}; 248 249jQuery.extend( { 250 251 // Unique for each copy of jQuery on the page 252 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), 253 254 // Assume jQuery is ready without the ready module 255 isReady: true, 256 257 error: function( msg ) { 258 throw new Error( msg ); 259 }, 260 261 noop: function() {}, 262 263 isFunction: function( obj ) { 264 return jQuery.type( obj ) === "function"; 265 }, 266 267 isArray: Array.isArray, 268 269 isWindow: function( obj ) { 270 return obj != null && obj === obj.window; 271 }, 272 273 isNumeric: function( obj ) { 274 275 // parseFloat NaNs numeric-cast false positives (null|true|false|"") 276 // ...but misinterprets leading-number strings, particularly hex literals ("0x...") 277 // subtraction forces infinities to NaN 278 // adding 1 corrects loss of precision from parseFloat (#15100) 279 var realStringObj = obj && obj.toString(); 280 return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; 281 }, 282 283 isPlainObject: function( obj ) { 284 var key; 285 286 // Not plain objects: 287 // - Any object or value whose internal [[Class]] property is not "[object Object]" 288 // - DOM nodes 289 // - window 290 if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { 291 return false; 292 } 293 294 // Not own constructor property must be Object 295 if ( obj.constructor && 296 !hasOwn.call( obj, "constructor" ) && 297 !hasOwn.call( obj.constructor.prototype || {}, "isPrototypeOf" ) ) { 298 return false; 299 } 300 301 // Own properties are enumerated firstly, so to speed up, 302 // if last one is own, then all properties are own 303 for ( key in obj ) {} 304 305 return key === undefined || hasOwn.call( obj, key ); 306 }, 307 308 isEmptyObject: function( obj ) { 309 var name; 310 for ( name in obj ) { 311 return false; 312 } 313 return true; 314 }, 315 316 type: function( obj ) { 317 if ( obj == null ) { 318 return obj + ""; 319 } 320 321 // Support: Android<4.0, iOS<6 (functionish RegExp) 322 return typeof obj === "object" || typeof obj === "function" ? 323 class2type[ toString.call( obj ) ] || "object" : 324 typeof obj; 325 }, 326 327 // Evaluates a script in a global context 328 globalEval: function( code ) { 329 var script, 330 indirect = eval; 331 332 code = jQuery.trim( code ); 333 334 if ( code ) { 335 336 // If the code includes a valid, prologue position 337 // strict mode pragma, execute code by injecting a 338 // script tag into the document. 339 if ( code.indexOf( "use strict" ) === 1 ) { 340 script = document.createElement( "script" ); 341 script.text = code; 342 document.head.appendChild( script ).parentNode.removeChild( script ); 343 } else { 344 345 // Otherwise, avoid the DOM node creation, insertion 346 // and removal by using an indirect global eval 347 348 indirect( code ); 349 } 350 } 351 }, 352 353 // Convert dashed to camelCase; used by the css and data modules 354 // Support: IE9-11+ 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 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 return arr == null ? -1 : indexOf.call( arr, elem, i ); 412 }, 413 414 merge: function( first, second ) { 415 var len = +second.length, 416 j = 0, 417 i = first.length; 418 419 for ( ; j < len; j++ ) { 420 first[ i++ ] = second[ j ]; 421 } 422 423 first.length = i; 424 425 return first; 426 }, 427 428 grep: function( elems, callback, invert ) { 429 var callbackInverse, 430 matches = [], 431 i = 0, 432 length = elems.length, 433 callbackExpect = !invert; 434 435 // Go through the array, only saving the items 436 // that pass the validator function 437 for ( ; i < length; i++ ) { 438 callbackInverse = !callback( elems[ i ], i ); 439 if ( callbackInverse !== callbackExpect ) { 440 matches.push( elems[ i ] ); 441 } 442 } 443 444 return matches; 445 }, 446 447 // arg is for internal usage only 448 map: function( elems, callback, arg ) { 449 var length, value, 450 i = 0, 451 ret = []; 452 453 // Go through the array, translating each of the items to their new values 454 if ( isArrayLike( elems ) ) { 455 length = elems.length; 456 for ( ; i < length; i++ ) { 457 value = callback( elems[ i ], i, arg ); 458 459 if ( value != null ) { 460 ret.push( value ); 461 } 462 } 463 464 // Go through every key on the object, 465 } else { 466 for ( i in elems ) { 467 value = callback( elems[ i ], i, arg ); 468 469 if ( value != null ) { 470 ret.push( value ); 471 } 472 } 473 } 474 475 // Flatten any nested arrays 476 return concat.apply( [], ret ); 477 }, 478 479 // A global GUID counter for objects 480 guid: 1, 481 482 // Bind a function to a context, optionally partially applying any 483 // arguments. 484 proxy: function( fn, context ) { 485 var tmp, args, proxy; 486 487 if ( typeof context === "string" ) { 488 tmp = fn[ context ]; 489 context = fn; 490 fn = tmp; 491 } 492 493 // Quick check to determine if target is callable, in the spec 494 // this throws a TypeError, but we will just return undefined. 495 if ( !jQuery.isFunction( fn ) ) { 496 return undefined; 497 } 498 499 // Simulated bind 500 args = slice.call( arguments, 2 ); 501 proxy = function() { 502 return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); 503 }; 504 505 // Set the guid of unique handler to the same of original handler, so it can be removed 506 proxy.guid = fn.guid = fn.guid || jQuery.guid++; 507 508 return proxy; 509 }, 510 511 now: Date.now, 512 513 // jQuery.support is not used in Core but other projects attach their 514 // properties to it so it needs to exist. 515 support: support 516} ); 517 518// JSHint would error on this code due to the Symbol not being defined in ES5. 519// Defining this global in .jshintrc would create a danger of using the global 520// unguarded in another place, it seems safer to just disable JSHint for these 521// three lines. 522/* jshint ignore: start */ 523if ( typeof Symbol === "function" ) { 524 jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; 525} 526/* jshint ignore: end */ 527 528// Populate the class2type map 529jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 530function( i, name ) { 531 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 532} ); 533 534function isArrayLike( obj ) { 535 536 // Support: iOS 8.2 (not reproducible in simulator) 537 // `in` check used to prevent JIT error (gh-2145) 538 // hasOwn isn't used here due to false negatives 539 // regarding Nodelist length in IE 540 var length = !!obj && "length" in obj && obj.length, 541 type = jQuery.type( obj ); 542 543 if ( type === "function" || jQuery.isWindow( obj ) ) { 544 return false; 545 } 546 547 return type === "array" || length === 0 || 548 typeof length === "number" && length > 0 && ( length - 1 ) in obj; 549} 550var Sizzle = 551/*! 552 * Sizzle CSS Selector Engine v2.2.1 553 * http://sizzlejs.com/ 554 * 555 * Copyright jQuery Foundation and other contributors 556 * Released under the MIT license 557 * http://jquery.org/license 558 * 559 * Date: 2015-10-17 560 */ 561(function( window ) { 562 563var i, 564 support, 565 Expr, 566 getText, 567 isXML, 568 tokenize, 569 compile, 570 select, 571 outermostContext, 572 sortInput, 573 hasDuplicate, 574 575 // Local document vars 576 setDocument, 577 document, 578 docElem, 579 documentIsHTML, 580 rbuggyQSA, 581 rbuggyMatches, 582 matches, 583 contains, 584 585 // Instance-specific data 586 expando = "sizzle" + 1 * new Date(), 587 preferredDoc = window.document, 588 dirruns = 0, 589 done = 0, 590 classCache = createCache(), 591 tokenCache = createCache(), 592 compilerCache = createCache(), 593 sortOrder = function( a, b ) { 594 if ( a === b ) { 595 hasDuplicate = true; 596 } 597 return 0; 598 }, 599 600 // General-purpose constants 601 MAX_NEGATIVE = 1 << 31, 602 603 // Instance methods 604 hasOwn = ({}).hasOwnProperty, 605 arr = [], 606 pop = arr.pop, 607 push_native = arr.push, 608 push = arr.push, 609 slice = arr.slice, 610 // Use a stripped-down indexOf as it's faster than native 611 // http://jsperf.com/thor-indexof-vs-for/5 612 indexOf = function( list, elem ) { 613 var i = 0, 614 len = list.length; 615 for ( ; i < len; i++ ) { 616 if ( list[i] === elem ) { 617 return i; 618 } 619 } 620 return -1; 621 }, 622 623 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", 624 625 // Regular expressions 626 627 // http://www.w3.org/TR/css3-selectors/#whitespace 628 whitespace = "[\\x20\\t\\r\\n\\f]", 629 630 // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier 631 identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", 632 633 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors 634 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + 635 // Operator (capture 2) 636 "*([*^$|!~]?=)" + whitespace + 637 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" 638 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + 639 "*\\]", 640 641 pseudos = ":(" + identifier + ")(?:\\((" + 642 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 643 // 1. quoted (capture 3; capture 4 or capture 5) 644 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 645 // 2. simple (capture 6) 646 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 647 // 3. anything else (capture 2) 648 ".*" + 649 ")\\)|)", 650 651 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 652 rwhitespace = new RegExp( whitespace + "+", "g" ), 653 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), 654 655 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 656 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), 657 658 rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), 659 660 rpseudo = new RegExp( pseudos ), 661 ridentifier = new RegExp( "^" + identifier + "$" ), 662 663 matchExpr = { 664 "ID": new RegExp( "^#(" + identifier + ")" ), 665 "CLASS": new RegExp( "^\\.(" + identifier + ")" ), 666 "TAG": new RegExp( "^(" + identifier + "|[*])" ), 667 "ATTR": new RegExp( "^" + attributes ), 668 "PSEUDO": new RegExp( "^" + pseudos ), 669 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + 670 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + 671 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 672 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), 673 // For use in libraries implementing .is() 674 // We use this for POS matching in `select` 675 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + 676 whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) 677 }, 678 679 rinputs = /^(?:input|select|textarea|button)$/i, 680 rheader = /^h\d$/i, 681 682 rnative = /^[^{]+\{\s*\[native \w/, 683 684 // Easily-parseable/retrievable ID or TAG or CLASS selectors 685 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 686 687 rsibling = /[+~]/, 688 rescape = /'|\\/g, 689 690 // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters 691 runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), 692 funescape = function( _, escaped, escapedWhitespace ) { 693 var high = "0x" + escaped - 0x10000; 694 // NaN means non-codepoint 695 // Support: Firefox<24 696 // Workaround erroneous numeric interpretation of +"0x" 697 return high !== high || escapedWhitespace ? 698 escaped : 699 high < 0 ? 700 // BMP codepoint 701 String.fromCharCode( high + 0x10000 ) : 702 // Supplemental Plane codepoint (surrogate pair) 703 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); 704 }, 705 706 // Used for iframes 707 // See setDocument() 708 // Removing the function wrapper causes a "Permission Denied" 709 // error in IE 710 unloadHandler = function() { 711 setDocument(); 712 }; 713 714// Optimize for push.apply( _, NodeList ) 715try { 716 push.apply( 717 (arr = slice.call( preferredDoc.childNodes )), 718 preferredDoc.childNodes 719 ); 720 // Support: Android<4.0 721 // Detect silently failing push.apply 722 arr[ preferredDoc.childNodes.length ].nodeType; 723} catch ( e ) { 724 push = { apply: arr.length ? 725 726 // Leverage slice if possible 727 function( target, els ) { 728 push_native.apply( target, slice.call(els) ); 729 } : 730 731 // Support: IE<9 732 // Otherwise append directly 733 function( target, els ) { 734 var j = target.length, 735 i = 0; 736 // Can't trust NodeList.length 737 while ( (target[j++] = els[i++]) ) {} 738 target.length = j - 1; 739 } 740 }; 741} 742 743function Sizzle( selector, context, results, seed ) { 744 var m, i, elem, nid, nidselect, match, groups, newSelector, 745 newContext = context && context.ownerDocument, 746 747 // nodeType defaults to 9, since context defaults to document 748 nodeType = context ? context.nodeType : 9; 749 750 results = results || []; 751 752 // Return early from calls with invalid selector or context 753 if ( typeof selector !== "string" || !selector || 754 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { 755 756 return results; 757 } 758 759 // Try to shortcut find operations (as opposed to filters) in HTML documents 760 if ( !seed ) { 761 762 if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { 763 setDocument( context ); 764 } 765 context = context || document; 766 767 if ( documentIsHTML ) { 768 769 // If the selector is sufficiently simple, try using a "get*By*" DOM method 770 // (excepting DocumentFragment context, where the methods don't exist) 771 if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { 772 773 // ID selector 774 if ( (m = match[1]) ) { 775 776 // Document context 777 if ( nodeType === 9 ) { 778 if ( (elem = context.getElementById( m )) ) { 779 780 // Support: IE, Opera, Webkit 781 // TODO: identify versions 782 // getElementById can match elements by name instead of ID 783 if ( elem.id === m ) { 784 results.push( elem ); 785 return results; 786 } 787 } else { 788 return results; 789 } 790 791 // Element context 792 } else { 793 794 // Support: IE, Opera, Webkit 795 // TODO: identify versions 796 // getElementById can match elements by name instead of ID 797 if ( newContext && (elem = newContext.getElementById( m )) && 798 contains( context, elem ) && 799 elem.id === m ) { 800 801 results.push( elem ); 802 return results; 803 } 804 } 805 806 // Type selector 807 } else if ( match[2] ) { 808 push.apply( results, context.getElementsByTagName( selector ) ); 809 return results; 810 811 // Class selector 812 } else if ( (m = match[3]) && support.getElementsByClassName && 813 context.getElementsByClassName ) { 814 815 push.apply( results, context.getElementsByClassName( m ) ); 816 return results; 817 } 818 } 819 820 // Take advantage of querySelectorAll 821 if ( support.qsa && 822 !compilerCache[ selector + " " ] && 823 (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { 824 825 if ( nodeType !== 1 ) { 826 newContext = context; 827 newSelector = selector; 828 829 // qSA looks outside Element context, which is not what we want 830 // Thanks to Andrew Dupont for this workaround technique 831 // Support: IE <=8 832 // Exclude object elements 833 } else if ( context.nodeName.toLowerCase() !== "object" ) { 834 835 // Capture the context ID, setting it first if necessary 836 if ( (nid = context.getAttribute( "id" )) ) { 837 nid = nid.replace( rescape, "\\$&" ); 838 } else { 839 context.setAttribute( "id", (nid = expando) ); 840 } 841 842 // Prefix every selector in the list 843 groups = tokenize( selector ); 844 i = groups.length; 845 nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']"; 846 while ( i-- ) { 847 groups[i] = nidselect + " " + toSelector( groups[i] ); 848 } 849 newSelector = groups.join( "," ); 850 851 // Expand context for sibling selectors 852 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || 853 context; 854 } 855 856 if ( newSelector ) { 857 try { 858 push.apply( results, 859 newContext.querySelectorAll( newSelector ) 860 ); 861 return results; 862 } catch ( qsaError ) { 863 } finally { 864 if ( nid === expando ) { 865 context.removeAttribute( "id" ); 866 } 867 } 868 } 869 } 870 } 871 } 872 873 // All others 874 return select( selector.replace( rtrim, "$1" ), context, results, seed ); 875} 876 877/** 878 * Create key-value caches of limited size 879 * @returns {function(string, object)} Returns the Object data after storing it on itself with 880 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 881 * deleting the oldest entry 882 */ 883function createCache() { 884 var keys = []; 885 886 function cache( key, value ) { 887 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) 888 if ( keys.push( key + " " ) > Expr.cacheLength ) { 889 // Only keep the most recent entries 890 delete cache[ keys.shift() ]; 891 } 892 return (cache[ key + " " ] = value); 893 } 894 return cache; 895} 896 897/** 898 * Mark a function for special use by Sizzle 899 * @param {Function} fn The function to mark 900 */ 901function markFunction( fn ) { 902 fn[ expando ] = true; 903 return fn; 904} 905 906/** 907 * Support testing using an element 908 * @param {Function} fn Passed the created div and expects a boolean result 909 */ 910function assert( fn ) { 911 var div = document.createElement("div"); 912 913 try { 914 return !!fn( div ); 915 } catch (e) { 916 return false; 917 } finally { 918 // Remove from its parent by default 919 if ( div.parentNode ) { 920 div.parentNode.removeChild( div ); 921 } 922 // release memory in IE 923 div = null; 924 } 925} 926 927/** 928 * Adds the same handler for all of the specified attrs 929 * @param {String} attrs Pipe-separated list of attributes 930 * @param {Function} handler The method that will be applied 931 */ 932function addHandle( attrs, handler ) { 933 var arr = attrs.split("|"), 934 i = arr.length; 935 936 while ( i-- ) { 937 Expr.attrHandle[ arr[i] ] = handler; 938 } 939} 940 941/** 942 * Checks document order of two siblings 943 * @param {Element} a 944 * @param {Element} b 945 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b 946 */ 947function siblingCheck( a, b ) { 948 var cur = b && a, 949 diff = cur && a.nodeType === 1 && b.nodeType === 1 && 950 ( ~b.sourceIndex || MAX_NEGATIVE ) - 951 ( ~a.sourceIndex || MAX_NEGATIVE ); 952 953 // Use IE sourceIndex if available on both nodes 954 if ( diff ) { 955 return diff; 956 } 957 958 // Check if b follows a 959 if ( cur ) { 960 while ( (cur = cur.nextSibling) ) { 961 if ( cur === b ) { 962 return -1; 963 } 964 } 965 } 966 967 return a ? 1 : -1; 968} 969 970/** 971 * Returns a function to use in pseudos for input types 972 * @param {String} type 973 */ 974function createInputPseudo( type ) { 975 return function( elem ) { 976 var name = elem.nodeName.toLowerCase(); 977 return name === "input" && elem.type === type; 978 }; 979} 980 981/** 982 * Returns a function to use in pseudos for buttons 983 * @param {String} type 984 */ 985function createButtonPseudo( type ) { 986 return function( elem ) { 987 var name = elem.nodeName.toLowerCase(); 988 return (name === "input" || name === "button") && elem.type === type; 989 }; 990} 991 992/** 993 * Returns a function to use in pseudos for positionals 994 * @param {Function} fn 995 */ 996function createPositionalPseudo( fn ) { 997 return markFunction(function( argument ) { 998 argument = +argument; 999 return markFunction(function( seed, matches ) { 1000 var j, 1001 matchIndexes = fn( [], seed.length, argument ), 1002 i = matchIndexes.length; 1003 1004 // Match elements found at the specified indexes 1005 while ( i-- ) { 1006 if ( seed[ (j = matchIndexes[i]) ] ) { 1007 seed[j] = !(matches[j] = seed[j]); 1008 } 1009 } 1010 }); 1011 }); 1012} 1013 1014/** 1015 * Checks a node for validity as a Sizzle context 1016 * @param {Element|Object=} context 1017 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 1018 */ 1019function testContext( context ) { 1020 return context && typeof context.getElementsByTagName !== "undefined" && context; 1021} 1022 1023// Expose support vars for convenience 1024support = Sizzle.support = {}; 1025 1026/** 1027 * Detects XML nodes 1028 * @param {Element|Object} elem An element or a document 1029 * @returns {Boolean} True iff elem is a non-HTML XML node 1030 */ 1031isXML = Sizzle.isXML = function( elem ) { 1032 // documentElement is verified for cases where it doesn't yet exist 1033 // (such as loading iframes in IE - #4833) 1034 var documentElement = elem && (elem.ownerDocument || elem).documentElement; 1035 return documentElement ? documentElement.nodeName !== "HTML" : false; 1036}; 1037 1038/** 1039 * Sets document-related variables once based on the current document 1040 * @param {Element|Object} [doc] An element or document object to use to set the document 1041 * @returns {Object} Returns the current document 1042 */ 1043setDocument = Sizzle.setDocument = function( node ) { 1044 var hasCompare, parent, 1045 doc = node ? node.ownerDocument || node : preferredDoc; 1046 1047 // Return early if doc is invalid or already selected 1048 if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { 1049 return document; 1050 } 1051 1052 // Update global variables 1053 document = doc; 1054 docElem = document.documentElement; 1055 documentIsHTML = !isXML( document ); 1056 1057 // Support: IE 9-11, Edge 1058 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) 1059 if ( (parent = document.defaultView) && parent.top !== parent ) { 1060 // Support: IE 11 1061 if ( parent.addEventListener ) { 1062 parent.addEventListener( "unload", unloadHandler, false ); 1063 1064 // Support: IE 9 - 10 only 1065 } else if ( parent.attachEvent ) { 1066 parent.attachEvent( "onunload", unloadHandler ); 1067 } 1068 } 1069 1070 /* Attributes 1071 ---------------------------------------------------------------------- */ 1072 1073 // Support: IE<8 1074 // Verify that getAttribute really returns attributes and not properties 1075 // (excepting IE8 booleans) 1076 support.attributes = assert(function( div ) { 1077 div.className = "i"; 1078 return !div.getAttribute("className"); 1079 }); 1080 1081 /* getElement(s)By* 1082 ---------------------------------------------------------------------- */ 1083 1084 // Check if getElementsByTagName("*") returns only elements 1085 support.getElementsByTagName = assert(function( div ) { 1086 div.appendChild( document.createComment("") ); 1087 return !div.getElementsByTagName("*").length; 1088 }); 1089 1090 // Support: IE<9 1091 support.getElementsByClassName = rnative.test( document.getElementsByClassName ); 1092 1093 // Support: IE<10 1094 // Check if getElementById returns elements by name 1095 // The broken getElementById methods don't pick up programatically-set names, 1096 // so use a roundabout getElementsByName test 1097 support.getById = assert(function( div ) { 1098 docElem.appendChild( div ).id = expando; 1099 return !document.getElementsByName || !document.getElementsByName( expando ).length; 1100 }); 1101 1102 // ID find and filter 1103 if ( support.getById ) { 1104 Expr.find["ID"] = function( id, context ) { 1105 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 1106 var m = context.getElementById( id ); 1107 return m ? [ m ] : []; 1108 } 1109 }; 1110 Expr.filter["ID"] = function( id ) { 1111 var attrId = id.replace( runescape, funescape ); 1112 return function( elem ) { 1113 return elem.getAttribute("id") === attrId; 1114 }; 1115 }; 1116 } else { 1117 // Support: IE6/7 1118 // getElementById is not reliable as a find shortcut 1119 delete Expr.find["ID"]; 1120 1121 Expr.filter["ID"] = function( id ) { 1122 var attrId = id.replace( runescape, funescape ); 1123 return function( elem ) { 1124 var node = typeof elem.getAttributeNode !== "undefined" && 1125 elem.getAttributeNode("id"); 1126 return node && node.value === attrId; 1127 }; 1128 }; 1129 } 1130 1131 // Tag 1132 Expr.find["TAG"] = support.getElementsByTagName ? 1133 function( tag, context ) { 1134 if ( typeof context.getElementsByTagName !== "undefined" ) { 1135 return context.getElementsByTagName( tag ); 1136 1137 // DocumentFragment nodes don't have gEBTN 1138 } else if ( support.qsa ) { 1139 return context.querySelectorAll( tag ); 1140 } 1141 } : 1142 1143 function( tag, context ) { 1144 var elem, 1145 tmp = [], 1146 i = 0, 1147 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too 1148 results = context.getElementsByTagName( tag ); 1149 1150 // Filter out possible comments 1151 if ( tag === "*" ) { 1152 while ( (elem = results[i++]) ) { 1153 if ( elem.nodeType === 1 ) { 1154 tmp.push( elem ); 1155 } 1156 } 1157 1158 return tmp; 1159 } 1160 return results; 1161 }; 1162 1163 // Class 1164 Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { 1165 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { 1166 return context.getElementsByClassName( className ); 1167 } 1168 }; 1169 1170 /* QSA/matchesSelector 1171 ---------------------------------------------------------------------- */ 1172 1173 // QSA and matchesSelector support 1174 1175 // matchesSelector(:active) reports false when true (IE9/Opera 11.5) 1176 rbuggyMatches = []; 1177 1178 // qSa(:focus) reports false when true (Chrome 21) 1179 // We allow this because of a bug in IE8/9 that throws an error 1180 // whenever `document.activeElement` is accessed on an iframe 1181 // So, we allow :focus to pass through QSA all the time to avoid the IE error 1182 // See http://bugs.jquery.com/ticket/13378 1183 rbuggyQSA = []; 1184 1185 if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { 1186 // Build QSA regex 1187 // Regex strategy adopted from Diego Perini 1188 assert(function( div ) { 1189 // Select is set to empty string on purpose 1190 // This is to test IE's treatment of not explicitly 1191 // setting a boolean content attribute, 1192 // since its presence should be enough 1193 // http://bugs.jquery.com/ticket/12359 1194 docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" + 1195 "<select id='" + expando + "-\r\\' msallowcapture=''>" + 1196 "<option selected=''></option></select>"; 1197 1198 // Support: IE8, Opera 11-12.16 1199 // Nothing should be selected when empty strings follow ^= or $= or *= 1200 // The test attribute must be unknown in Opera but "safe" for WinRT 1201 // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section 1202 if ( div.querySelectorAll("[msallowcapture^='']").length ) { 1203 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); 1204 } 1205 1206 // Support: IE8 1207 // Boolean attributes and "value" are not treated correctly 1208 if ( !div.querySelectorAll("[selected]").length ) { 1209 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); 1210 } 1211 1212 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ 1213 if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { 1214 rbuggyQSA.push("~="); 1215 } 1216 1217 // Webkit/Opera - :checked should return selected option elements 1218 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 1219 // IE8 throws error here and will not see later tests 1220 if ( !div.querySelectorAll(":checked").length ) { 1221 rbuggyQSA.push(":checked"); 1222 } 1223 1224 // Support: Safari 8+, iOS 8+ 1225 // https://bugs.webkit.org/show_bug.cgi?id=136851 1226 // In-page `selector#id sibing-combinator selector` fails 1227 if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { 1228 rbuggyQSA.push(".#.+[+~]"); 1229 } 1230 }); 1231 1232 assert(function( div ) { 1233 // Support: Windows 8 Native Apps 1234 // The type and name attributes are restricted during .innerHTML assignment 1235 var input = document.createElement("input"); 1236 input.setAttribute( "type", "hidden" ); 1237 div.appendChild( input ).setAttribute( "name", "D" ); 1238 1239 // Support: IE8 1240 // Enforce case-sensitivity of name attribute 1241 if ( div.querySelectorAll("[name=d]").length ) { 1242 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); 1243 } 1244 1245 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) 1246 // IE8 throws error here and will not see later tests 1247 if ( !div.querySelectorAll(":enabled").length ) { 1248 rbuggyQSA.push( ":enabled", ":disabled" ); 1249 } 1250 1251 // Opera 10-11 does not throw on post-comma invalid pseudos 1252 div.querySelectorAll("*,:x"); 1253 rbuggyQSA.push(",.*:"); 1254 }); 1255 } 1256 1257 if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || 1258 docElem.webkitMatchesSelector || 1259 docElem.mozMatchesSelector || 1260 docElem.oMatchesSelector || 1261 docElem.msMatchesSelector) )) ) { 1262 1263 assert(function( div ) { 1264 // Check to see if it's possible to do matchesSelector 1265 // on a disconnected node (IE 9) 1266 support.disconnectedMatch = matches.call( div, "div" ); 1267 1268 // This should fail with an exception 1269 // Gecko does not error, returns false instead 1270 matches.call( div, "[s!='']:x" ); 1271 rbuggyMatches.push( "!=", pseudos ); 1272 }); 1273 } 1274 1275 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); 1276 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); 1277 1278 /* Contains 1279 ---------------------------------------------------------------------- */ 1280 hasCompare = rnative.test( docElem.compareDocumentPosition ); 1281 1282 // Element contains another 1283 // Purposefully self-exclusive 1284 // As in, an element does not contain itself 1285 contains = hasCompare || rnative.test( docElem.contains ) ? 1286 function( a, b ) { 1287 var adown = a.nodeType === 9 ? a.documentElement : a, 1288 bup = b && b.parentNode; 1289 return a === bup || !!( bup && bup.nodeType === 1 && ( 1290 adown.contains ? 1291 adown.contains( bup ) : 1292 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 1293 )); 1294 } : 1295 function( a, b ) { 1296 if ( b ) { 1297 while ( (b = b.parentNode) ) { 1298 if ( b === a ) { 1299 return true; 1300 } 1301 } 1302 } 1303 return false; 1304 }; 1305 1306 /* Sorting 1307 ---------------------------------------------------------------------- */ 1308 1309 // Document order sorting 1310 sortOrder = hasCompare ? 1311 function( a, b ) { 1312 1313 // Flag for duplicate removal 1314 if ( a === b ) { 1315 hasDuplicate = true; 1316 return 0; 1317 } 1318 1319 // Sort on method existence if only one input has compareDocumentPosition 1320 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 1321 if ( compare ) { 1322 return compare; 1323 } 1324 1325 // Calculate position if both inputs belong to the same document 1326 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? 1327 a.compareDocumentPosition( b ) : 1328 1329 // Otherwise we know they are disconnected 1330 1; 1331 1332 // Disconnected nodes 1333 if ( compare & 1 || 1334 (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { 1335 1336 // Choose the first element that is related to our preferred document 1337 if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { 1338 return -1; 1339 } 1340 if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { 1341 return 1; 1342 } 1343 1344 // Maintain original order 1345 return sortInput ? 1346 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 1347 0; 1348 } 1349 1350 return compare & 4 ? -1 : 1; 1351 } : 1352 function( a, b ) { 1353 // Exit early if the nodes are identical 1354 if ( a === b ) { 1355 hasDuplicate = true; 1356 return 0; 1357 } 1358 1359 var cur, 1360 i = 0, 1361 aup = a.parentNode, 1362 bup = b.parentNode, 1363 ap = [ a ], 1364 bp = [ b ]; 1365 1366 // Parentless nodes are either documents or disconnected 1367 if ( !aup || !bup ) { 1368 return a === document ? -1 : 1369 b === document ? 1 : 1370 aup ? -1 : 1371 bup ? 1 : 1372 sortInput ? 1373 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 1374 0; 1375 1376 // If the nodes are siblings, we can do a quick check 1377 } else if ( aup === bup ) { 1378 return siblingCheck( a, b ); 1379 } 1380 1381 // Otherwise we need full lists of their ancestors for comparison 1382 cur = a; 1383 while ( (cur = cur.parentNode) ) { 1384 ap.unshift( cur ); 1385 } 1386 cur = b; 1387 while ( (cur = cur.parentNode) ) { 1388 bp.unshift( cur ); 1389 } 1390 1391 // Walk down the tree looking for a discrepancy 1392 while ( ap[i] === bp[i] ) { 1393 i++; 1394 } 1395 1396 return i ? 1397 // Do a sibling check if the nodes have a common ancestor 1398 siblingCheck( ap[i], bp[i] ) : 1399 1400 // Otherwise nodes in our document sort first 1401 ap[i] === preferredDoc ? -1 : 1402 bp[i] === preferredDoc ? 1 : 1403 0; 1404 }; 1405 1406 return document; 1407}; 1408 1409Sizzle.matches = function( expr, elements ) { 1410 return Sizzle( expr, null, null, elements ); 1411}; 1412 1413Sizzle.matchesSelector = function( elem, expr ) { 1414 // Set document vars if needed 1415 if ( ( elem.ownerDocument || elem ) !== document ) { 1416 setDocument( elem ); 1417 } 1418 1419 // Make sure that attribute selectors are quoted 1420 expr = expr.replace( rattributeQuotes, "='$1']" ); 1421 1422 if ( support.matchesSelector && documentIsHTML && 1423 !compilerCache[ expr + " " ] && 1424 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && 1425 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { 1426 1427 try { 1428 var ret = matches.call( elem, expr ); 1429 1430 // IE 9's matchesSelector returns false on disconnected nodes 1431 if ( ret || support.disconnectedMatch || 1432 // As well, disconnected nodes are said to be in a document 1433 // fragment in IE 9 1434 elem.document && elem.document.nodeType !== 11 ) { 1435 return ret; 1436 } 1437 } catch (e) {} 1438 } 1439 1440 return Sizzle( expr, document, null, [ elem ] ).length > 0; 1441}; 1442 1443Sizzle.contains = function( context, elem ) { 1444 // Set document vars if needed 1445 if ( ( context.ownerDocument || context ) !== document ) { 1446 setDocument( context ); 1447 } 1448 return contains( context, elem ); 1449}; 1450 1451Sizzle.attr = function( elem, name ) { 1452 // Set document vars if needed 1453 if ( ( elem.ownerDocument || elem ) !== document ) { 1454 setDocument( elem ); 1455 } 1456 1457 var fn = Expr.attrHandle[ name.toLowerCase() ], 1458 // Don't get fooled by Object.prototype properties (jQuery #13807) 1459 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? 1460 fn( elem, name, !documentIsHTML ) : 1461 undefined; 1462 1463 return val !== undefined ? 1464 val : 1465 support.attributes || !documentIsHTML ? 1466 elem.getAttribute( name ) : 1467 (val = elem.getAttributeNode(name)) && val.specified ? 1468 val.value : 1469 null; 1470}; 1471 1472Sizzle.error = function( msg ) { 1473 throw new Error( "Syntax error, unrecognized expression: " + msg ); 1474}; 1475 1476/** 1477 * Document sorting and removing duplicates 1478 * @param {ArrayLike} results 1479 */ 1480Sizzle.uniqueSort = function( results ) { 1481 var elem, 1482 duplicates = [], 1483 j = 0, 1484 i = 0; 1485 1486 // Unless we *know* we can detect duplicates, assume their presence 1487 hasDuplicate = !support.detectDuplicates; 1488 sortInput = !support.sortStable && results.slice( 0 ); 1489 results.sort( sortOrder ); 1490 1491 if ( hasDuplicate ) { 1492 while ( (elem = results[i++]) ) { 1493 if ( elem === results[ i ] ) { 1494 j = duplicates.push( i ); 1495 } 1496 } 1497 while ( j-- ) { 1498 results.splice( duplicates[ j ], 1 ); 1499 } 1500 } 1501 1502 // Clear input after sorting to release objects 1503 // See https://github.com/jquery/sizzle/pull/225 1504 sortInput = null; 1505 1506 return results; 1507}; 1508 1509/** 1510 * Utility function for retrieving the text value of an array of DOM nodes 1511 * @param {Array|Element} elem 1512 */ 1513getText = Sizzle.getText = function( elem ) { 1514 var node, 1515 ret = "", 1516 i = 0, 1517 nodeType = elem.nodeType; 1518 1519 if ( !nodeType ) { 1520 // If no nodeType, this is expected to be an array 1521 while ( (node = elem[i++]) ) { 1522 // Do not traverse comment nodes 1523 ret += getText( node ); 1524 } 1525 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { 1526 // Use textContent for elements 1527 // innerText usage removed for consistency of new lines (jQuery #11153) 1528 if ( typeof elem.textContent === "string" ) { 1529 return elem.textContent; 1530 } else { 1531 // Traverse its children 1532 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 1533 ret += getText( elem ); 1534 } 1535 } 1536 } else if ( nodeType === 3 || nodeType === 4 ) { 1537 return elem.nodeValue; 1538 } 1539 // Do not include comment or processing instruction nodes 1540 1541 return ret; 1542}; 1543 1544Expr = Sizzle.selectors = { 1545 1546 // Can be adjusted by the user 1547 cacheLength: 50, 1548 1549 createPseudo: markFunction, 1550 1551 match: matchExpr, 1552 1553 attrHandle: {}, 1554 1555 find: {}, 1556 1557 relative: { 1558 ">": { dir: "parentNode", first: true }, 1559 " ": { dir: "parentNode" }, 1560 "+": { dir: "previousSibling", first: true }, 1561 "~": { dir: "previousSibling" } 1562 }, 1563 1564 preFilter: { 1565 "ATTR": function( match ) { 1566 match[1] = match[1].replace( runescape, funescape ); 1567 1568 // Move the given value to match[3] whether quoted or unquoted 1569 match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); 1570 1571 if ( match[2] === "~=" ) { 1572 match[3] = " " + match[3] + " "; 1573 } 1574 1575 return match.slice( 0, 4 ); 1576 }, 1577 1578 "CHILD": function( match ) { 1579 /* matches from matchExpr["CHILD"] 1580 1 type (only|nth|...) 1581 2 what (child|of-type) 1582 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 1583 4 xn-component of xn+y argument ([+-]?\d*n|) 1584 5 sign of xn-component 1585 6 x of xn-component 1586 7 sign of y-component 1587 8 y of y-component 1588 */ 1589 match[1] = match[1].toLowerCase(); 1590 1591 if ( match[1].slice( 0, 3 ) === "nth" ) { 1592 // nth-* requires argument 1593 if ( !match[3] ) { 1594 Sizzle.error( match[0] ); 1595 } 1596 1597 // numeric x and y parameters for Expr.filter.CHILD 1598 // remember that false/true cast respectively to 0/1 1599 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); 1600 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); 1601 1602 // other types prohibit arguments 1603 } else if ( match[3] ) { 1604 Sizzle.error( match[0] ); 1605 } 1606 1607 return match; 1608 }, 1609 1610 "PSEUDO": function( match ) { 1611 var excess, 1612 unquoted = !match[6] && match[2]; 1613 1614 if ( matchExpr["CHILD"].test( match[0] ) ) { 1615 return null; 1616 } 1617 1618 // Accept quoted arguments as-is 1619 if ( match[3] ) { 1620 match[2] = match[4] || match[5] || ""; 1621 1622 // Strip excess characters from unquoted arguments 1623 } else if ( unquoted && rpseudo.test( unquoted ) && 1624 // Get excess from tokenize (recursively) 1625 (excess = tokenize( unquoted, true )) && 1626 // advance to the next closing parenthesis 1627 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { 1628 1629 // excess is a negative index 1630 match[0] = match[0].slice( 0, excess ); 1631 match[2] = unquoted.slice( 0, excess ); 1632 } 1633 1634 // Return only captures needed by the pseudo filter method (type and argument) 1635 return match.slice( 0, 3 ); 1636 } 1637 }, 1638 1639 filter: { 1640 1641 "TAG": function( nodeNameSelector ) { 1642 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); 1643 return nodeNameSelector === "*" ? 1644 function() { return true; } : 1645 function( elem ) { 1646 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; 1647 }; 1648 }, 1649 1650 "CLASS": function( className ) { 1651 var pattern = classCache[ className + " " ]; 1652 1653 return pattern || 1654 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && 1655 classCache( className, function( elem ) { 1656 return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); 1657 }); 1658 }, 1659 1660 "ATTR": function( name, operator, check ) { 1661 return function( elem ) { 1662 var result = Sizzle.attr( elem, name ); 1663 1664 if ( result == null ) { 1665 return operator === "!="; 1666 } 1667 if ( !operator ) { 1668 return true; 1669 } 1670 1671 result += ""; 1672 1673 return operator === "=" ? result === check : 1674 operator === "!=" ? result !== check : 1675 operator === "^=" ? check && result.indexOf( check ) === 0 : 1676 operator === "*=" ? check && result.indexOf( check ) > -1 : 1677 operator === "$=" ? check && result.slice( -check.length ) === check : 1678 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : 1679 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : 1680 false; 1681 }; 1682 }, 1683 1684 "CHILD": function( type, what, argument, first, last ) { 1685 var simple = type.slice( 0, 3 ) !== "nth", 1686 forward = type.slice( -4 ) !== "last", 1687 ofType = what === "of-type"; 1688 1689 return first === 1 && last === 0 ? 1690 1691 // Shortcut for :nth-*(n) 1692 function( elem ) { 1693 return !!elem.parentNode; 1694 } : 1695 1696 function( elem, context, xml ) { 1697 var cache, uniqueCache, outerCache, node, nodeIndex, start, 1698 dir = simple !== forward ? "nextSibling" : "previousSibling", 1699 parent = elem.parentNode, 1700 name = ofType && elem.nodeName.toLowerCase(), 1701 useCache = !xml && !ofType, 1702 diff = false; 1703 1704 if ( parent ) { 1705 1706 // :(first|last|only)-(child|of-type) 1707 if ( simple ) { 1708 while ( dir ) { 1709 node = elem; 1710 while ( (node = node[ dir ]) ) { 1711 if ( ofType ? 1712 node.nodeName.toLowerCase() === name : 1713 node.nodeType === 1 ) { 1714 1715 return false; 1716 } 1717 } 1718 // Reverse direction for :only-* (if we haven't yet done so) 1719 start = dir = type === "only" && !start && "nextSibling"; 1720 } 1721 return true; 1722 } 1723 1724 start = [ forward ? parent.firstChild : parent.lastChild ]; 1725 1726 // non-xml :nth-child(...) stores cache data on `parent` 1727 if ( forward && useCache ) { 1728 1729 // Seek `elem` from a previously-cached index 1730 1731 // ...in a gzip-friendly way 1732 node = parent; 1733 outerCache = node[ expando ] || (node[ expando ] = {}); 1734 1735 // Support: IE <9 only 1736 // Defend against cloned attroperties (jQuery gh-1709) 1737 uniqueCache = outerCache[ node.uniqueID ] || 1738 (outerCache[ node.uniqueID ] = {}); 1739 1740 cache = uniqueCache[ type ] || []; 1741 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 1742 diff = nodeIndex && cache[ 2 ]; 1743 node = nodeIndex && parent.childNodes[ nodeIndex ]; 1744 1745 while ( (node = ++nodeIndex && node && node[ dir ] || 1746 1747 // Fallback to seeking `elem` from the start 1748 (diff = nodeIndex = 0) || start.pop()) ) { 1749 1750 // When found, cache indexes on `parent` and break 1751 if ( node.nodeType === 1 && ++diff && node === elem ) { 1752 uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; 1753 break; 1754 } 1755 } 1756 1757 } else { 1758 // Use previously-cached element index if available 1759 if ( useCache ) { 1760 // ...in a gzip-friendly way 1761 node = elem; 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; 1772 } 1773 1774 // xml :nth-child(...) 1775 // or :nth-last-child(...) or :nth(-last)?-of-type(...) 1776 if ( diff === false ) { 1777 // Use the same loop as above to seek `elem` from the start 1778 while ( (node = ++nodeIndex && node && node[ dir ] || 1779 (diff = nodeIndex = 0) || start.pop()) ) { 1780 1781 if ( ( ofType ? 1782 node.nodeName.toLowerCase() === name : 1783 node.nodeType === 1 ) && 1784 ++diff ) { 1785 1786 // Cache the index of each encountered element 1787 if ( useCache ) { 1788 outerCache = node[ expando ] || (node[ expando ] = {}); 1789 1790 // Support: IE <9 only 1791 // Defend against cloned attroperties (jQuery gh-1709) 1792 uniqueCache = outerCache[ node.uniqueID ] || 1793 (outerCache[ node.uniqueID ] = {}); 1794 1795 uniqueCache[ type ] = [ dirruns, diff ]; 1796 } 1797 1798 if ( node === elem ) { 1799 break; 1800 } 1801 } 1802 } 1803 } 1804 } 1805 1806 // Incorporate the offset, then check against cycle size 1807 diff -= last; 1808 return diff === first || ( diff % first === 0 && diff / first >= 0 ); 1809 } 1810 }; 1811 }, 1812 1813 "PSEUDO": function( pseudo, argument ) { 1814 // pseudo-class names are case-insensitive 1815 // http://www.w3.org/TR/selectors/#pseudo-classes 1816 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 1817 // Remember that setFilters inherits from pseudos 1818 var args, 1819 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 1820 Sizzle.error( "unsupported pseudo: " + pseudo ); 1821 1822 // The user may use createPseudo to indicate that 1823 // arguments are needed to create the filter function 1824 // just as Sizzle does 1825 if ( fn[ expando ] ) { 1826 return fn( argument ); 1827 } 1828 1829 // But maintain support for old signatures 1830 if ( fn.length > 1 ) { 1831 args = [ pseudo, pseudo, "", argument ]; 1832 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 1833 markFunction(function( seed, matches ) { 1834 var idx, 1835 matched = fn( seed, argument ), 1836 i = matched.length; 1837 while ( i-- ) { 1838 idx = indexOf( seed, matched[i] ); 1839 seed[ idx ] = !( matches[ idx ] = matched[i] ); 1840 } 1841 }) : 1842 function( elem ) { 1843 return fn( elem, 0, args ); 1844 }; 1845 } 1846 1847 return fn; 1848 } 1849 }, 1850 1851 pseudos: { 1852 // Potentially complex pseudos 1853 "not": markFunction(function( selector ) { 1854 // Trim the selector passed to compile 1855 // to avoid treating leading and trailing 1856 // spaces as combinators 1857 var input = [], 1858 results = [], 1859 matcher = compile( selector.replace( rtrim, "$1" ) ); 1860 1861 return matcher[ expando ] ? 1862 markFunction(function( seed, matches, context, xml ) { 1863 var elem, 1864 unmatched = matcher( seed, null, xml, [] ), 1865 i = seed.length; 1866 1867 // Match elements unmatched by `matcher` 1868 while ( i-- ) { 1869 if ( (elem = unmatched[i]) ) { 1870 seed[i] = !(matches[i] = elem); 1871 } 1872 } 1873 }) : 1874 function( elem, context, xml ) { 1875 input[0] = elem; 1876 matcher( input, null, xml, results ); 1877 // Don't keep the element (issue #299) 1878 input[0] = null; 1879 return !results.pop(); 1880 }; 1881 }), 1882 1883 "has": markFunction(function( selector ) { 1884 return function( elem ) { 1885 return Sizzle( selector, elem ).length > 0; 1886 }; 1887 }), 1888 1889 "contains": markFunction(function( text ) { 1890 text = text.replace( runescape, funescape ); 1891 return function( elem ) { 1892 return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; 1893 }; 1894 }), 1895 1896 // "Whether an element is represented by a :lang() selector 1897 // is based solely on the element's language value 1898 // being equal to the identifier C, 1899 // or beginning with the identifier C immediately followed by "-". 1900 // The matching of C against the element's language value is performed case-insensitively. 1901 // The identifier C does not have to be a valid language name." 1902 // http://www.w3.org/TR/selectors/#lang-pseudo 1903 "lang": markFunction( function( lang ) { 1904 // lang value must be a valid identifier 1905 if ( !ridentifier.test(lang || "") ) { 1906 Sizzle.error( "unsupported lang: " + lang ); 1907 } 1908 lang = lang.replace( runescape, funescape ).toLowerCase(); 1909 return function( elem ) { 1910 var elemLang; 1911 do { 1912 if ( (elemLang = documentIsHTML ? 1913 elem.lang : 1914 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { 1915 1916 elemLang = elemLang.toLowerCase(); 1917 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; 1918 } 1919 } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); 1920 return false; 1921 }; 1922 }), 1923 1924 // Miscellaneous 1925 "target": function( elem ) { 1926 var hash = window.location && window.location.hash; 1927 return hash && hash.slice( 1 ) === elem.id; 1928 }, 1929 1930 "root": function( elem ) { 1931 return elem === docElem; 1932 }, 1933 1934 "focus": function( elem ) { 1935 return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); 1936 }, 1937 1938 // Boolean properties 1939 "enabled": function( elem ) { 1940 return elem.disabled === false; 1941 }, 1942 1943 "disabled": function( elem ) { 1944 return elem.disabled === true; 1945 }, 1946 1947 "checked": function( elem ) { 1948 // In CSS3, :checked should return both checked and selected elements 1949 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 1950 var nodeName = elem.nodeName.toLowerCase(); 1951 return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); 1952 }, 1953 1954 "selected": function( elem ) { 1955 // Accessing this property makes selected-by-default 1956 // options in Safari work properly 1957 if ( elem.parentNode ) { 1958 elem.parentNode.selectedIndex; 1959 } 1960 1961 return elem.selected === true; 1962 }, 1963 1964 // Contents 1965 "empty": function( elem ) { 1966 // http://www.w3.org/TR/selectors/#empty-pseudo 1967 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 1968 // but not by others (comment: 8; processing instruction: 7; etc.) 1969 // nodeType < 6 works because attributes (2) do not appear as children 1970 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 1971 if ( elem.nodeType < 6 ) { 1972 return false; 1973 } 1974 } 1975 return true; 1976 }, 1977 1978 "parent": function( elem ) { 1979 return !Expr.pseudos["empty"]( elem ); 1980 }, 1981 1982 // Element/input types 1983 "header": function( elem ) { 1984 return rheader.test( elem.nodeName ); 1985 }, 1986 1987 "input": function( elem ) { 1988 return rinputs.test( elem.nodeName ); 1989 }, 1990 1991 "button": function( elem ) { 1992 var name = elem.nodeName.toLowerCase(); 1993 return name === "input" && elem.type === "button" || name === "button"; 1994 }, 1995 1996 "text": function( elem ) { 1997 var attr; 1998 return elem.nodeName.toLowerCase() === "input" && 1999 elem.type === "text" && 2000 2001 // Support: IE<8 2002 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" 2003 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); 2004 }, 2005 2006 // Position-in-collection 2007 "first": createPositionalPseudo(function() { 2008 return [ 0 ]; 2009 }), 2010 2011 "last": createPositionalPseudo(function( matchIndexes, length ) { 2012 return [ length - 1 ]; 2013 }), 2014 2015 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { 2016 return [ argument < 0 ? argument + length : argument ]; 2017 }), 2018 2019 "even": createPositionalPseudo(function( matchIndexes, length ) { 2020 var i = 0; 2021 for ( ; i < length; i += 2 ) { 2022 matchIndexes.push( i ); 2023 } 2024 return matchIndexes; 2025 }), 2026 2027 "odd": createPositionalPseudo(function( matchIndexes, length ) { 2028 var i = 1; 2029 for ( ; i < length; i += 2 ) { 2030 matchIndexes.push( i ); 2031 } 2032 return matchIndexes; 2033 }), 2034 2035 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { 2036 var i = argument < 0 ? argument + length : argument; 2037 for ( ; --i >= 0; ) { 2038 matchIndexes.push( i ); 2039 } 2040 return matchIndexes; 2041 }), 2042 2043 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { 2044 var i = argument < 0 ? argument + length : argument; 2045 for ( ; ++i < length; ) { 2046 matchIndexes.push( i ); 2047 } 2048 return matchIndexes; 2049 }) 2050 } 2051}; 2052 2053Expr.pseudos["nth"] = Expr.pseudos["eq"]; 2054 2055// Add button/input type pseudos 2056for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { 2057 Expr.pseudos[ i ] = createInputPseudo( i ); 2058} 2059for ( i in { submit: true, reset: true } ) { 2060 Expr.pseudos[ i ] = createButtonPseudo( i ); 2061} 2062 2063// Easy API for creating new setFilters 2064function setFilters() {} 2065setFilters.prototype = Expr.filters = Expr.pseudos; 2066Expr.setFilters = new setFilters(); 2067 2068tokenize = Sizzle.tokenize = function( selector, parseOnly ) { 2069 var matched, match, tokens, type, 2070 soFar, groups, preFilters, 2071 cached = tokenCache[ selector + " " ]; 2072 2073 if ( cached ) { 2074 return parseOnly ? 0 : cached.slice( 0 ); 2075 } 2076 2077 soFar = selector; 2078 groups = []; 2079 preFilters = Expr.preFilter; 2080 2081 while ( soFar ) { 2082 2083 // Comma and first run 2084 if ( !matched || (match = rcomma.exec( soFar )) ) { 2085 if ( match ) { 2086 // Don't consume trailing commas as valid 2087 soFar = soFar.slice( match[0].length ) || soFar; 2088 } 2089 groups.push( (tokens = []) ); 2090 } 2091 2092 matched = false; 2093 2094 // Combinators 2095 if ( (match = rcombinators.exec( soFar )) ) { 2096 matched = match.shift(); 2097 tokens.push({ 2098 value: matched, 2099 // Cast descendant combinators to space 2100 type: match[0].replace( rtrim, " " ) 2101 }); 2102 soFar = soFar.slice( matched.length ); 2103 } 2104 2105 // Filters 2106 for ( type in Expr.filter ) { 2107 if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || 2108 (match = preFilters[ type ]( match ))) ) { 2109 matched = match.shift(); 2110 tokens.push({ 2111 value: matched, 2112 type: type, 2113 matches: match 2114 }); 2115 soFar = soFar.slice( matched.length ); 2116 } 2117 } 2118 2119 if ( !matched ) { 2120 break; 2121 } 2122 } 2123 2124 // Return the length of the invalid excess 2125 // if we're just parsing 2126 // Otherwise, throw an error or return tokens 2127 return parseOnly ? 2128 soFar.length : 2129 soFar ? 2130 Sizzle.error( selector ) : 2131 // Cache the tokens 2132 tokenCache( selector, groups ).slice( 0 ); 2133}; 2134 2135function toSelector( tokens ) { 2136 var i = 0, 2137 len = tokens.length, 2138 selector = ""; 2139 for ( ; i < len; i++ ) { 2140 selector += tokens[i].value; 2141 } 2142 return selector; 2143} 2144 2145function addCombinator( matcher, combinator, base ) { 2146 var dir = combinator.dir, 2147 checkNonElements = base && dir === "parentNode", 2148 doneName = done++; 2149 2150 return combinator.first ? 2151 // Check against closest ancestor/preceding element 2152 function( elem, context, xml ) { 2153 while ( (elem = elem[ dir ]) ) { 2154 if ( elem.nodeType === 1 || checkNonElements ) { 2155 return matcher( elem, context, xml ); 2156 } 2157 } 2158 } : 2159 2160 // Check against all ancestor/preceding elements 2161 function( elem, context, xml ) { 2162 var oldCache, uniqueCache, outerCache, 2163 newCache = [ dirruns, doneName ]; 2164 2165 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching 2166 if ( xml ) { 2167 while ( (elem = elem[ dir ]) ) { 2168 if ( elem.nodeType === 1 || checkNonElements ) { 2169 if ( matcher( elem, context, xml ) ) { 2170 return true; 2171 } 2172 } 2173 } 2174 } else { 2175 while ( (elem = elem[ dir ]) ) { 2176 if ( elem.nodeType === 1 || checkNonElements ) { 2177 outerCache = elem[ expando ] || (elem[ expando ] = {}); 2178 2179 // Support: IE <9 only 2180 // Defend against cloned attroperties (jQuery gh-1709) 2181 uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); 2182 2183 if ( (oldCache = uniqueCache[ dir ]) && 2184 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { 2185 2186 // Assign to newCache so results back-propagate to previous elements 2187 return (newCache[ 2 ] = oldCache[ 2 ]); 2188 } else { 2189 // Reuse newcache so results back-propagate to previous elements 2190 uniqueCache[ dir ] = newCache; 2191 2192 // A match means we're done; a fail means we have to keep checking 2193 if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { 2194 return true; 2195 } 2196 } 2197 } 2198 } 2199 } 2200 }; 2201} 2202 2203function elementMatcher( matchers ) { 2204 return matchers.length > 1 ? 2205 function( elem, context, xml ) { 2206 var i = matchers.length; 2207 while ( i-- ) { 2208 if ( !matchers[i]( elem, context, xml ) ) { 2209 return false; 2210 } 2211 } 2212 return true; 2213 } : 2214 matchers[0]; 2215} 2216 2217function multipleContexts( selector, contexts, results ) { 2218 var i = 0, 2219 len = contexts.length; 2220 for ( ; i < len; i++ ) { 2221 Sizzle( selector, contexts[i], results ); 2222 } 2223 return results; 2224} 2225 2226function condense( unmatched, map, filter, context, xml ) { 2227 var elem, 2228 newUnmatched = [], 2229 i = 0, 2230 len = unmatched.length, 2231 mapped = map != null; 2232 2233 for ( ; i < len; i++ ) { 2234 if ( (elem = unmatched[i]) ) { 2235 if ( !filter || filter( elem, context, xml ) ) { 2236 newUnmatched.push( elem ); 2237 if ( mapped ) { 2238 map.push( i ); 2239 } 2240 } 2241 } 2242 } 2243 2244 return newUnmatched; 2245} 2246 2247function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 2248 if ( postFilter && !postFilter[ expando ] ) { 2249 postFilter = setMatcher( postFilter ); 2250 } 2251 if ( postFinder && !postFinder[ expando ] ) { 2252 postFinder = setMatcher( postFinder, postSelector ); 2253 } 2254 return markFunction(function( seed, results, context, xml ) { 2255 var temp, i, elem, 2256 preMap = [], 2257 postMap = [], 2258 preexisting = results.length, 2259 2260 // Get initial elements from seed or context 2261 elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), 2262 2263 // Prefilter to get matcher input, preserving a map for seed-results synchronization 2264 matcherIn = preFilter && ( seed || !selector ) ? 2265 condense( elems, preMap, preFilter, context, xml ) : 2266 elems, 2267 2268 matcherOut = matcher ? 2269 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, 2270 postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 2271 2272 // ...intermediate processing is necessary 2273 [] : 2274 2275 // ...otherwise use results directly 2276 results : 2277 matcherIn; 2278 2279 // Find primary matches 2280 if ( matcher ) { 2281 matcher( matcherIn, matcherOut, context, xml ); 2282 } 2283 2284 // Apply postFilter 2285 if ( postFilter ) { 2286 temp = condense( matcherOut, postMap ); 2287 postFilter( temp, [], context, xml ); 2288 2289 // Un-match failing elements by moving them back to matcherIn 2290 i = temp.length; 2291 while ( i-- ) { 2292 if ( (elem = temp[i]) ) { 2293 matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); 2294 } 2295 } 2296 } 2297 2298 if ( seed ) { 2299 if ( postFinder || preFilter ) { 2300 if ( postFinder ) { 2301 // Get the final matcherOut by condensing this intermediate into postFinder contexts 2302 temp = []; 2303 i = matcherOut.length; 2304 while ( i-- ) { 2305 if ( (elem = matcherOut[i]) ) { 2306 // Restore matcherIn since elem is not yet a final match 2307 temp.push( (matcherIn[i] = elem) ); 2308 } 2309 } 2310 postFinder( null, (matcherOut = []), temp, xml ); 2311 } 2312 2313 // Move matched elements from seed to results to keep them synchronized 2314 i = matcherOut.length; 2315 while ( i-- ) { 2316 if ( (elem = matcherOut[i]) && 2317 (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { 2318 2319 seed[temp] = !(results[temp] = elem); 2320 } 2321 } 2322 } 2323 2324 // Add elements to results, through postFinder if defined 2325 } else { 2326 matcherOut = condense( 2327 matcherOut === results ? 2328 matcherOut.splice( preexisting, matcherOut.length ) : 2329 matcherOut 2330 ); 2331 if ( postFinder ) { 2332 postFinder( null, results, matcherOut, xml ); 2333 } else { 2334 push.apply( results, matcherOut ); 2335 } 2336 } 2337 }); 2338} 2339 2340function matcherFromTokens( tokens ) { 2341 var checkContext, matcher, j, 2342 len = tokens.length, 2343 leadingRelative = Expr.relative[ tokens[0].type ], 2344 implicitRelative = leadingRelative || Expr.relative[" "], 2345 i = leadingRelative ? 1 : 0, 2346 2347 // The foundational matcher ensures that elements are reachable from top-level context(s) 2348 matchContext = addCombinator( function( elem ) { 2349 return elem === checkContext; 2350 }, implicitRelative, true ), 2351 matchAnyContext = addCombinator( function( elem ) { 2352 return indexOf( checkContext, elem ) > -1; 2353 }, implicitRelative, true ), 2354 matchers = [ function( elem, context, xml ) { 2355 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( 2356 (checkContext = context).nodeType ? 2357 matchContext( elem, context, xml ) : 2358 matchAnyContext( elem, context, xml ) ); 2359 // Avoid hanging onto element (issue #299) 2360 checkContext = null; 2361 return ret; 2362 } ]; 2363 2364 for ( ; i < len; i++ ) { 2365 if ( (matcher = Expr.relative[ tokens[i].type ]) ) { 2366 matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; 2367 } else { 2368 matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); 2369 2370 // Return special upon seeing a positional matcher 2371 if ( matcher[ expando ] ) { 2372 // Find the next relative operator (if any) for proper handling 2373 j = ++i; 2374 for ( ; j < len; j++ ) { 2375 if ( Expr.relative[ tokens[j].type ] ) { 2376 break; 2377 } 2378 } 2379 return setMatcher( 2380 i > 1 && elementMatcher( matchers ), 2381 i > 1 && toSelector( 2382 // If the preceding token was a descendant combinator, insert an implicit any-element `*` 2383 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) 2384 ).replace( rtrim, "$1" ), 2385 matcher, 2386 i < j && matcherFromTokens( tokens.slice( i, j ) ), 2387 j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), 2388 j < len && toSelector( tokens ) 2389 ); 2390 } 2391 matchers.push( matcher ); 2392 } 2393 } 2394 2395 return elementMatcher( matchers ); 2396} 2397 2398function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 2399 var bySet = setMatchers.length > 0, 2400 byElement = elementMatchers.length > 0, 2401 superMatcher = function( seed, context, xml, results, outermost ) { 2402 var elem, j, matcher, 2403 matchedCount = 0, 2404 i = "0", 2405 unmatched = seed && [], 2406 setMatched = [], 2407 contextBackup = outermostContext, 2408 // We must always have either seed elements or outermost context 2409 elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), 2410 // Use integer dirruns iff this is the outermost matcher 2411 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), 2412 len = elems.length; 2413 2414 if ( outermost ) { 2415 outermostContext = context === document || context || outermost; 2416 } 2417 2418 // Add elements passing elementMatchers directly to results 2419 // Support: IE<9, Safari 2420 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id 2421 for ( ; i !== len && (elem = elems[i]) != null; i++ ) { 2422 if ( byElement && elem ) { 2423 j = 0; 2424 if ( !context && elem.ownerDocument !== document ) { 2425 setDocument( elem ); 2426 xml = !documentIsHTML; 2427 } 2428 while ( (matcher = elementMatchers[j++]) ) { 2429 if ( matcher( elem, context || document, xml) ) { 2430 results.push( elem ); 2431 break; 2432 } 2433 } 2434 if ( outermost ) { 2435 dirruns = dirrunsUnique; 2436 } 2437 } 2438 2439 // Track unmatched elements for set filters 2440 if ( bySet ) { 2441 // They will have gone through all possible matchers 2442 if ( (elem = !matcher && elem) ) { 2443 matchedCount--; 2444 } 2445 2446 // Lengthen the array for every element, matched or not 2447 if ( seed ) { 2448 unmatched.push( elem ); 2449 } 2450 } 2451 } 2452 2453 // `i` is now the count of elements visited above, and adding it to `matchedCount` 2454 // makes the latter nonnegative. 2455 matchedCount += i; 2456 2457 // Apply set filters to unmatched elements 2458 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` 2459 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have 2460 // no element matchers and no seed. 2461 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that 2462 // case, which will result in a "00" `matchedCount` that differs from `i` but is also 2463 // numerically zero. 2464 if ( bySet && i !== matchedCount ) { 2465 j = 0; 2466 while ( (matcher = setMatchers[j++]) ) { 2467 matcher( unmatched, setMatched, context, xml ); 2468 } 2469 2470 if ( seed ) { 2471 // Reintegrate element matches to eliminate the need for sorting 2472 if ( matchedCount > 0 ) { 2473 while ( i-- ) { 2474 if ( !(unmatched[i] || setMatched[i]) ) { 2475 setMatched[i] = pop.call( results ); 2476 } 2477 } 2478 } 2479 2480 // Discard index placeholder values to get only actual matches 2481 setMatched = condense( setMatched ); 2482 } 2483 2484 // Add matches to results 2485 push.apply( results, setMatched ); 2486 2487 // Seedless set matches succeeding multiple successful matchers stipulate sorting 2488 if ( outermost && !seed && setMatched.length > 0 && 2489 ( matchedCount + setMatchers.length ) > 1 ) { 2490 2491 Sizzle.uniqueSort( results ); 2492 } 2493 } 2494 2495 // Override manipulation of globals by nested matchers 2496 if ( outermost ) { 2497 dirruns = dirrunsUnique; 2498 outermostContext = contextBackup; 2499 } 2500 2501 return unmatched; 2502 }; 2503 2504 return bySet ? 2505 markFunction( superMatcher ) : 2506 superMatcher; 2507} 2508 2509compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { 2510 var i, 2511 setMatchers = [], 2512 elementMatchers = [], 2513 cached = compilerCache[ selector + " " ]; 2514 2515 if ( !cached ) { 2516 // Generate a function of recursive functions that can be used to check each element 2517 if ( !match ) { 2518 match = tokenize( selector ); 2519 } 2520 i = match.length; 2521 while ( i-- ) { 2522 cached = matcherFromTokens( match[i] ); 2523 if ( cached[ expando ] ) { 2524 setMatchers.push( cached ); 2525 } else { 2526 elementMatchers.push( cached ); 2527 } 2528 } 2529 2530 // Cache the compiled function 2531 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); 2532 2533 // Save selector and tokenization 2534 cached.selector = selector; 2535 } 2536 return cached; 2537}; 2538 2539/** 2540 * A low-level selection function that works with Sizzle's compiled 2541 * selector functions 2542 * @param {String|Function} selector A selector or a pre-compiled 2543 * selector function built with Sizzle.compile 2544 * @param {Element} context 2545 * @param {Array} [results] 2546 * @param {Array} [seed] A set of elements to match against 2547 */ 2548select = Sizzle.select = function( selector, context, results, seed ) { 2549 var i, tokens, token, type, find, 2550 compiled = typeof selector === "function" && selector, 2551 match = !seed && tokenize( (selector = compiled.selector || selector) ); 2552 2553 results = results || []; 2554 2555 // Try to minimize operations if there is only one selector in the list and no seed 2556 // (the latter of which guarantees us context) 2557 if ( match.length === 1 ) { 2558 2559 // Reduce context if the leading compound selector is an ID 2560 tokens = match[0] = match[0].slice( 0 ); 2561 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && 2562 support.getById && context.nodeType === 9 && documentIsHTML && 2563 Expr.relative[ tokens[1].type ] ) { 2564 2565 context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; 2566 if ( !context ) { 2567 return results; 2568 2569 // Precompiled matchers will still verify ancestry, so step up a level 2570 } else if ( compiled ) { 2571 context = context.parentNode; 2572 } 2573 2574 selector = selector.slice( tokens.shift().value.length ); 2575 } 2576 2577 // Fetch a seed set for right-to-left matching 2578 i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; 2579 while ( i-- ) { 2580 token = tokens[i]; 2581 2582 // Abort if we hit a combinator 2583 if ( Expr.relative[ (type = token.type) ] ) { 2584 break; 2585 } 2586 if ( (find = Expr.find[ type ]) ) { 2587 // Search, expanding context for leading sibling combinators 2588 if ( (seed = find( 2589 token.matches[0].replace( runescape, funescape ), 2590 rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context 2591 )) ) { 2592 2593 // If seed is empty or no tokens remain, we can return early 2594 tokens.splice( i, 1 ); 2595 selector = seed.length && toSelector( tokens ); 2596 if ( !selector ) { 2597 push.apply( results, seed ); 2598 return results; 2599 } 2600 2601 break; 2602 } 2603 } 2604 } 2605 } 2606 2607 // Compile and execute a filtering function if one is not provided 2608 // Provide `match` to avoid retokenization if we modified the selector above 2609 ( compiled || compile( selector, match ) )( 2610 seed, 2611 context, 2612 !documentIsHTML, 2613 results, 2614 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context 2615 ); 2616 return results; 2617}; 2618 2619// One-time assignments 2620 2621// Sort stability 2622support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; 2623 2624// Support: Chrome 14-35+ 2625// Always assume duplicates if they aren't passed to the comparison function 2626support.detectDuplicates = !!hasDuplicate; 2627 2628// Initialize against the default document 2629setDocument(); 2630 2631// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) 2632// Detached nodes confoundingly follow *each other* 2633support.sortDetached = assert(function( div1 ) { 2634 // Should return 1, but returns 4 (following) 2635 return div1.compareDocumentPosition( document.createElement("div") ) & 1; 2636}); 2637 2638// Support: IE<8 2639// Prevent attribute/property "interpolation" 2640// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx 2641if ( !assert(function( div ) { 2642 div.innerHTML = "<a href='#'></a>"; 2643 return div.firstChild.getAttribute("href") === "#" ; 2644}) ) { 2645 addHandle( "type|href|height|width", function( elem, name, isXML ) { 2646 if ( !isXML ) { 2647 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); 2648 } 2649 }); 2650} 2651 2652// Support: IE<9 2653// Use defaultValue in place of getAttribute("value") 2654if ( !support.attributes || !assert(function( div ) { 2655 div.innerHTML = "<input/>"; 2656 div.firstChild.setAttribute( "value", "" ); 2657 return div.firstChild.getAttribute( "value" ) === ""; 2658}) ) { 2659 addHandle( "value", function( elem, name, isXML ) { 2660 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { 2661 return elem.defaultValue; 2662 } 2663 }); 2664} 2665 2666// Support: IE<9 2667// Use getAttributeNode to fetch booleans when getAttribute lies 2668if ( !assert(function( div ) { 2669 return div.getAttribute("disabled") == null; 2670}) ) { 2671 addHandle( booleans, function( elem, name, isXML ) { 2672 var val; 2673 if ( !isXML ) { 2674 return elem[ name ] === true ? name.toLowerCase() : 2675 (val = elem.getAttributeNode( name )) && val.specified ? 2676 val.value : 2677 null; 2678 } 2679 }); 2680} 2681 2682return Sizzle; 2683 2684})( window ); 2685 2686 2687 2688jQuery.find = Sizzle; 2689jQuery.expr = Sizzle.selectors; 2690jQuery.expr[ ":" ] = jQuery.expr.pseudos; 2691jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; 2692jQuery.text = Sizzle.getText; 2693jQuery.isXMLDoc = Sizzle.isXML; 2694jQuery.contains = Sizzle.contains; 2695 2696 2697 2698var dir = function( elem, dir, until ) { 2699 var matched = [], 2700 truncate = until !== undefined; 2701 2702 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { 2703 if ( elem.nodeType === 1 ) { 2704 if ( truncate && jQuery( elem ).is( until ) ) { 2705 break; 2706 } 2707 matched.push( elem ); 2708 } 2709 } 2710 return matched; 2711}; 2712 2713 2714var siblings = function( n, elem ) { 2715 var matched = []; 2716 2717 for ( ; n; n = n.nextSibling ) { 2718 if ( n.nodeType === 1 && n !== elem ) { 2719 matched.push( n ); 2720 } 2721 } 2722 2723 return matched; 2724}; 2725 2726 2727var rneedsContext = jQuery.expr.match.needsContext; 2728 2729var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ ); 2730 2731 2732 2733var risSimple = /^.[^:#\[\.,]*$/; 2734 2735// Implement the identical functionality for filter and not 2736function winnow( elements, qualifier, not ) { 2737 if ( jQuery.isFunction( qualifier ) ) { 2738 return jQuery.grep( elements, function( elem, i ) { 2739 /* jshint -W018 */ 2740 return !!qualifier.call( elem, i, elem ) !== not; 2741 } ); 2742 2743 } 2744 2745 if ( qualifier.nodeType ) { 2746 return jQuery.grep( elements, function( elem ) { 2747 return ( elem === qualifier ) !== not; 2748 } ); 2749 2750 } 2751 2752 if ( typeof qualifier === "string" ) { 2753 if ( risSimple.test( qualifier ) ) { 2754 return jQuery.filter( qualifier, elements, not ); 2755 } 2756 2757 qualifier = jQuery.filter( qualifier, elements ); 2758 } 2759 2760 return jQuery.grep( elements, function( elem ) { 2761 return ( indexOf.call( qualifier, elem ) > -1 ) !== not; 2762 } ); 2763} 2764 2765jQuery.filter = function( expr, elems, not ) { 2766 var elem = elems[ 0 ]; 2767 2768 if ( not ) { 2769 expr = ":not(" + expr + ")"; 2770 } 2771 2772 return elems.length === 1 && elem.nodeType === 1 ? 2773 jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : 2774 jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { 2775 return elem.nodeType === 1; 2776 } ) ); 2777}; 2778 2779jQuery.fn.extend( { 2780 find: function( selector ) { 2781 var i, 2782 len = this.length, 2783 ret = [], 2784 self = this; 2785 2786 if ( typeof selector !== "string" ) { 2787 return this.pushStack( jQuery( selector ).filter( function() { 2788 for ( i = 0; i < len; i++ ) { 2789 if ( jQuery.contains( self[ i ], this ) ) { 2790 return true; 2791 } 2792 } 2793 } ) ); 2794 } 2795 2796 for ( i = 0; i < len; i++ ) { 2797 jQuery.find( selector, self[ i ], ret ); 2798 } 2799 2800 // Needed because $( selector, context ) becomes $( context ).find( selector ) 2801 ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); 2802 ret.selector = this.selector ? this.selector + " " + selector : selector; 2803 return ret; 2804 }, 2805 filter: function( selector ) { 2806 return this.pushStack( winnow( this, selector || [], false ) ); 2807 }, 2808 not: function( selector ) { 2809 return this.pushStack( winnow( this, selector || [], true ) ); 2810 }, 2811 is: function( selector ) { 2812 return !!winnow( 2813 this, 2814 2815 // If this is a positional/relative selector, check membership in the returned set 2816 // so $("p:first").is("p:last") won't return true for a doc with two "p". 2817 typeof selector === "string" && rneedsContext.test( selector ) ? 2818 jQuery( selector ) : 2819 selector || [], 2820 false 2821 ).length; 2822 } 2823} ); 2824 2825 2826// Initialize a jQuery object 2827 2828 2829// A central reference to the root jQuery(document) 2830var rootjQuery, 2831 2832 // A simple way to check for HTML strings 2833 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) 2834 // Strict HTML recognition (#11290: must start with <) 2835 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, 2836 2837 init = jQuery.fn.init = function( selector, context, root ) { 2838 var match, elem; 2839 2840 // HANDLE: $(""), $(null), $(undefined), $(false) 2841 if ( !selector ) { 2842 return this; 2843 } 2844 2845 // Method init() accepts an alternate rootjQuery 2846 // so migrate can support jQuery.sub (gh-2101) 2847 root = root || rootjQuery; 2848 2849 // Handle HTML strings 2850 if ( typeof selector === "string" ) { 2851 if ( selector[ 0 ] === "<" && 2852 selector[ selector.length - 1 ] === ">" && 2853 selector.length >= 3 ) { 2854 2855 // Assume that strings that start and end with <> are HTML and skip the regex check 2856 match = [ null, selector, null ]; 2857 2858 } else { 2859 match = rquickExpr.exec( selector ); 2860 } 2861 2862 // Match html or make sure no context is specified for #id 2863 if ( match && ( match[ 1 ] || !context ) ) { 2864 2865 // HANDLE: $(html) -> $(array) 2866 if ( match[ 1 ] ) { 2867 context = context instanceof jQuery ? context[ 0 ] : context; 2868 2869 // Option to run scripts is true for back-compat 2870 // Intentionally let the error be thrown if parseHTML is not present 2871 jQuery.merge( this, jQuery.parseHTML( 2872 match[ 1 ], 2873 context && context.nodeType ? context.ownerDocument || context : document, 2874 true 2875 ) ); 2876 2877 // HANDLE: $(html, props) 2878 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { 2879 for ( match in context ) { 2880 2881 // Properties of context are called as methods if possible 2882 if ( jQuery.isFunction( this[ match ] ) ) { 2883 this[ match ]( context[ match ] ); 2884 2885 // ...and otherwise set as attributes 2886 } else { 2887 this.attr( match, context[ match ] ); 2888 } 2889 } 2890 } 2891 2892 return this; 2893 2894 // HANDLE: $(#id) 2895 } else { 2896 elem = document.getElementById( match[ 2 ] ); 2897 2898 // Support: Blackberry 4.6 2899 // gEBID returns nodes no longer in the document (#6963) 2900 if ( elem && elem.parentNode ) { 2901 2902 // Inject the element directly into the jQuery object 2903 this.length = 1; 2904 this[ 0 ] = elem; 2905 } 2906 2907 this.context = document; 2908 this.selector = selector; 2909 return this; 2910 } 2911 2912 // HANDLE: $(expr, $(...)) 2913 } else if ( !context || context.jquery ) { 2914 return ( context || root ).find( selector ); 2915 2916 // HANDLE: $(expr, context) 2917 // (which is just equivalent to: $(context).find(expr) 2918 } else { 2919 return this.constructor( context ).find( selector ); 2920 } 2921 2922 // HANDLE: $(DOMElement) 2923 } else if ( selector.nodeType ) { 2924 this.context = this[ 0 ] = selector; 2925 this.length = 1; 2926 return this; 2927 2928 // HANDLE: $(function) 2929 // Shortcut for document ready 2930 } else if ( jQuery.isFunction( selector ) ) { 2931 return root.ready !== undefined ? 2932 root.ready( selector ) : 2933 2934 // Execute immediately if ready is not present 2935 selector( jQuery ); 2936 } 2937 2938 if ( selector.selector !== undefined ) { 2939 this.selector = selector.selector; 2940 this.context = selector.context; 2941 } 2942 2943 return jQuery.makeArray( selector, this ); 2944 }; 2945 2946// Give the init function the jQuery prototype for later instantiation 2947init.prototype = jQuery.fn; 2948 2949// Initialize central reference 2950rootjQuery = jQuery( document ); 2951 2952 2953var rparentsprev = /^(?:parents|prev(?:Until|All))/, 2954 2955 // Methods guaranteed to produce a unique set when starting from a unique set 2956 guaranteedUnique = { 2957 children: true, 2958 contents: true, 2959 next: true, 2960 prev: true 2961 }; 2962 2963jQuery.fn.extend( { 2964 has: function( target ) { 2965 var targets = jQuery( target, this ), 2966 l = targets.length; 2967 2968 return this.filter( function() { 2969 var i = 0; 2970 for ( ; i < l; i++ ) { 2971 if ( jQuery.contains( this, targets[ i ] ) ) { 2972 return true; 2973 } 2974 } 2975 } ); 2976 }, 2977 2978 closest: function( selectors, context ) { 2979 var cur, 2980 i = 0, 2981 l = this.length, 2982 matched = [], 2983 pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? 2984 jQuery( selectors, context || this.context ) : 2985 0; 2986 2987 for ( ; i < l; i++ ) { 2988 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { 2989 2990 // Always skip document fragments 2991 if ( cur.nodeType < 11 && ( pos ? 2992 pos.index( cur ) > -1 : 2993 2994 // Don't pass non-elements to Sizzle 2995 cur.nodeType === 1 && 2996 jQuery.find.matchesSelector( cur, selectors ) ) ) { 2997 2998 matched.push( cur ); 2999 break; 3000 } 3001 } 3002 } 3003 3004 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); 3005 }, 3006 3007 // Determine the position of an element within the set 3008 index: function( elem ) { 3009 3010 // No argument, return index in parent 3011 if ( !elem ) { 3012 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; 3013 } 3014 3015 // Index in selector 3016 if ( typeof elem === "string" ) { 3017 return indexOf.call( jQuery( elem ), this[ 0 ] ); 3018 } 3019 3020 // Locate the position of the desired element 3021 return indexOf.call( this, 3022 3023 // If it receives a jQuery object, the first element is used 3024 elem.jquery ? elem[ 0 ] : elem 3025 ); 3026 }, 3027 3028 add: function( selector, context ) { 3029 return this.pushStack( 3030 jQuery.uniqueSort( 3031 jQuery.merge( this.get(), jQuery( selector, context ) ) 3032 ) 3033 ); 3034 }, 3035 3036 addBack: function( selector ) { 3037 return this.add( selector == null ? 3038 this.prevObject : this.prevObject.filter( selector ) 3039 ); 3040 } 3041} ); 3042 3043function sibling( cur, dir ) { 3044 while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} 3045 return cur; 3046} 3047 3048jQuery.each( { 3049 parent: function( elem ) { 3050 var parent = elem.parentNode; 3051 return parent && parent.nodeType !== 11 ? parent : null; 3052 }, 3053 parents: function( elem ) { 3054 return dir( elem, "parentNode" ); 3055 }, 3056 parentsUntil: function( elem, i, until ) { 3057 return dir( elem, "parentNode", until ); 3058 }, 3059 next: function( elem ) { 3060 return sibling( elem, "nextSibling" ); 3061 }, 3062 prev: function( elem ) { 3063 return sibling( elem, "previousSibling" ); 3064 }, 3065 nextAll: function( elem ) { 3066 return dir( elem, "nextSibling" ); 3067 }, 3068 prevAll: function( elem ) { 3069 return dir( elem, "previousSibling" ); 3070 }, 3071 nextUntil: function( elem, i, until ) { 3072 return dir( elem, "nextSibling", until ); 3073 }, 3074 prevUntil: function( elem, i, until ) { 3075 return dir( elem, "previousSibling", until ); 3076 }, 3077 siblings: function( elem ) { 3078 return siblings( ( elem.parentNode || {} ).firstChild, elem ); 3079 }, 3080 children: function( elem ) { 3081 return siblings( elem.firstChild ); 3082 }, 3083 contents: function( elem ) { 3084 return elem.contentDocument || jQuery.merge( [], elem.childNodes ); 3085 } 3086}, function( name, fn ) { 3087 jQuery.fn[ name ] = function( until, selector ) { 3088 var matched = jQuery.map( this, fn, until ); 3089 3090 if ( name.slice( -5 ) !== "Until" ) { 3091 selector = until; 3092 } 3093 3094 if ( selector && typeof selector === "string" ) { 3095 matched = jQuery.filter( selector, matched ); 3096 } 3097 3098 if ( this.length > 1 ) { 3099 3100 // Remove duplicates 3101 if ( !guaranteedUnique[ name ] ) { 3102 jQuery.uniqueSort( matched ); 3103 } 3104 3105 // Reverse order for parents* and prev-derivatives 3106 if ( rparentsprev.test( name ) ) { 3107 matched.reverse(); 3108 } 3109 } 3110 3111 return this.pushStack( matched ); 3112 }; 3113} ); 3114var rnotwhite = ( /\S+/g ); 3115 3116 3117 3118// Convert String-formatted options into Object-formatted ones 3119function createOptions( options ) { 3120 var object = {}; 3121 jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { 3122 object[ flag ] = true; 3123 } ); 3124 return object; 3125} 3126 3127/* 3128 * Create a callback list using the following parameters: 3129 * 3130 * options: an optional list of space-separated options that will change how 3131 * the callback list behaves or a more traditional option object 3132 * 3133 * By default a callback list will act like an event callback list and can be 3134 * "fired" multiple times. 3135 * 3136 * Possible options: 3137 * 3138 * once: will ensure the callback list can only be fired once (like a Deferred) 3139 * 3140 * memory: will keep track of previous values and will call any callback added 3141 * after the list has been fired right away with the latest "memorized" 3142 * values (like a Deferred) 3143 * 3144 * unique: will ensure a callback can only be added once (no duplicate in the list) 3145 * 3146 * stopOnFalse: interrupt callings when a callback returns false 3147 * 3148 */ 3149jQuery.Callbacks = function( options ) { 3150 3151 // Convert options from String-formatted to Object-formatted if needed 3152 // (we check in cache first) 3153 options = typeof options === "string" ? 3154 createOptions( options ) : 3155 jQuery.extend( {}, options ); 3156 3157 var // Flag to know if list is currently firing 3158 firing, 3159 3160 // Last fire value for non-forgettable lists 3161 memory, 3162 3163 // Flag to know if list was already fired 3164 fired, 3165 3166 // Flag to prevent firing 3167 locked, 3168 3169 // Actual callback list 3170 list = [], 3171 3172 // Queue of execution data for repeatable lists 3173 queue = [], 3174 3175 // Index of currently firing callback (modified by add/remove as needed) 3176 firingIndex = -1, 3177 3178 // Fire callbacks 3179 fire = function() { 3180 3181 // Enforce single-firing 3182 locked = options.once; 3183 3184 // Execute callbacks for all pending executions, 3185 // respecting firingIndex overrides and runtime changes 3186 fired = firing = true; 3187 for ( ; queue.length; firingIndex = -1 ) { 3188 memory = queue.shift(); 3189 while ( ++firingIndex < list.length ) { 3190 3191 // Run callback and check for early termination 3192 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && 3193 options.stopOnFalse ) { 3194 3195 // Jump to end and forget the data so .add doesn't re-fire 3196 firingIndex = list.length; 3197 memory = false; 3198 } 3199 } 3200 } 3201 3202 // Forget the data if we're done with it 3203 if ( !options.memory ) { 3204 memory = false; 3205 } 3206 3207 firing = false; 3208 3209 // Clean up if we're done firing for good 3210 if ( locked ) { 3211 3212 // Keep an empty list if we have data for future add calls 3213 if ( memory ) { 3214 list = []; 3215 3216 // Otherwise, this object is spent 3217 } else { 3218 list = ""; 3219 } 3220 } 3221 }, 3222 3223 // Actual Callbacks object 3224 self = { 3225 3226 // Add a callback or a collection of callbacks to the list 3227 add: function() { 3228 if ( list ) { 3229 3230 // If we have memory from a past run, we should fire after adding 3231 if ( memory && !firing ) { 3232 firingIndex = list.length - 1; 3233 queue.push( memory ); 3234 } 3235 3236 ( function add( args ) { 3237 jQuery.each( args, function( _, arg ) { 3238 if ( jQuery.isFunction( arg ) ) { 3239 if ( !options.unique || !self.has( arg ) ) { 3240 list.push( arg ); 3241 } 3242 } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { 3243 3244 // Inspect recursively 3245 add( arg ); 3246 } 3247 } ); 3248 } )( arguments ); 3249 3250 if ( memory && !firing ) { 3251 fire(); 3252 } 3253 } 3254 return this; 3255 }, 3256 3257 // Remove a callback from the list 3258 remove: function() { 3259 jQuery.each( arguments, function( _, arg ) { 3260 var index; 3261 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { 3262 list.splice( index, 1 ); 3263 3264 // Handle firing indexes 3265 if ( index <= firingIndex ) { 3266 firingIndex--; 3267 } 3268 } 3269 } ); 3270 return this; 3271 }, 3272 3273 // Check if a given callback is in the list. 3274 // If no argument is given, return whether or not list has callbacks attached. 3275 has: function( fn ) { 3276 return fn ? 3277 jQuery.inArray( fn, list ) > -1 : 3278 list.length > 0; 3279 }, 3280 3281 // Remove all callbacks from the list 3282 empty: function() { 3283 if ( list ) { 3284 list = []; 3285 } 3286 return this; 3287 }, 3288 3289 // Disable .fire and .add 3290 // Abort any current/pending executions 3291 // Clear all callbacks and values 3292 disable: function() { 3293 locked = queue = []; 3294 list = memory = ""; 3295 return this; 3296 }, 3297 disabled: function() { 3298 return !list; 3299 }, 3300 3301 // Disable .fire 3302 // Also disable .add unless we have memory (since it would have no effect) 3303 // Abort any pending executions 3304 lock: function() { 3305 locked = queue = []; 3306 if ( !memory ) { 3307 list = memory = ""; 3308 } 3309 return this; 3310 }, 3311 locked: function() { 3312 return !!locked; 3313 }, 3314 3315 // Call all callbacks with the given context and arguments 3316 fireWith: function( context, args ) { 3317 if ( !locked ) { 3318 args = args || []; 3319 args = [ context, args.slice ? args.slice() : args ]; 3320 queue.push( args ); 3321 if ( !firing ) { 3322 fire(); 3323 } 3324 } 3325 return this; 3326 }, 3327 3328 // Call all the callbacks with the given arguments 3329 fire: function() { 3330 self.fireWith( this, arguments ); 3331 return this; 3332 }, 3333 3334 // To know if the callbacks have already been called at least once 3335 fired: function() { 3336 return !!fired; 3337 } 3338 }; 3339 3340 return self; 3341}; 3342 3343 3344jQuery.extend( { 3345 3346 Deferred: function( func ) { 3347 var tuples = [ 3348 3349 // action, add listener, listener list, final state 3350 [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ], 3351 [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ], 3352 [ "notify", "progress", jQuery.Callbacks( "memory" ) ] 3353 ], 3354 state = "pending", 3355 promise = { 3356 state: function() { 3357 return state; 3358 }, 3359 always: function() { 3360 deferred.done( arguments ).fail( arguments ); 3361 return this; 3362 }, 3363 then: function( /* fnDone, fnFail, fnProgress */ ) { 3364 var fns = arguments; 3365 return jQuery.Deferred( function( newDefer ) { 3366 jQuery.each( tuples, function( i, tuple ) { 3367 var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; 3368 3369 // deferred[ done | fail | progress ] for forwarding actions to newDefer 3370 deferred[ tuple[ 1 ] ]( function() { 3371 var returned = fn && fn.apply( this, arguments ); 3372 if ( returned && jQuery.isFunction( returned.promise ) ) { 3373 returned.promise() 3374 .progress( newDefer.notify ) 3375 .done( newDefer.resolve ) 3376 .fail( newDefer.reject ); 3377 } else { 3378 newDefer[ tuple[ 0 ] + "With" ]( 3379 this === promise ? newDefer.promise() : this, 3380 fn ? [ returned ] : arguments 3381 ); 3382 } 3383 } ); 3384 } ); 3385 fns = null; 3386 } ).promise(); 3387 }, 3388 3389 // Get a promise for this deferred 3390 // If obj is provided, the promise aspect is added to the object 3391 promise: function( obj ) { 3392 return obj != null ? jQuery.extend( obj, promise ) : promise; 3393 } 3394 }, 3395 deferred = {}; 3396 3397 // Keep pipe for back-compat 3398 promise.pipe = promise.then; 3399 3400 // Add list-specific methods 3401 jQuery.each( tuples, function( i, tuple ) { 3402 var list = tuple[ 2 ], 3403 stateString = tuple[ 3 ]; 3404 3405 // promise[ done | fail | progress ] = list.add 3406 promise[ tuple[ 1 ] ] = list.add; 3407 3408 // Handle state 3409 if ( stateString ) { 3410 list.add( function() { 3411 3412 // state = [ resolved | rejected ] 3413 state = stateString; 3414 3415 // [ reject_list | resolve_list ].disable; progress_list.lock 3416 }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); 3417 } 3418 3419 // deferred[ resolve | reject | notify ] 3420 deferred[ tuple[ 0 ] ] = function() { 3421 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments ); 3422 return this; 3423 }; 3424 deferred[ tuple[ 0 ] + "With" ] = list.fireWith; 3425 } ); 3426 3427 // Make the deferred a promise 3428 promise.promise( deferred ); 3429 3430 // Call given func if any 3431 if ( func ) { 3432 func.call( deferred, deferred ); 3433 } 3434 3435 // All done! 3436 return deferred; 3437 }, 3438 3439 // Deferred helper 3440 when: function( subordinate /* , ..., subordinateN */ ) { 3441 var i = 0, 3442 resolveValues = slice.call( arguments ), 3443 length = resolveValues.length, 3444 3445 // the count of uncompleted subordinates 3446 remaining = length !== 1 || 3447 ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, 3448 3449 // the master Deferred. 3450 // If resolveValues consist of only a single Deferred, just use that. 3451 deferred = remaining === 1 ? subordinate : jQuery.Deferred(), 3452 3453 // Update function for both resolve and progress values 3454 updateFunc = function( i, contexts, values ) { 3455 return function( value ) { 3456 contexts[ i ] = this; 3457 values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; 3458 if ( values === progressValues ) { 3459 deferred.notifyWith( contexts, values ); 3460 } else if ( !( --remaining ) ) { 3461 deferred.resolveWith( contexts, values ); 3462 } 3463 }; 3464 }, 3465 3466 progressValues, progressContexts, resolveContexts; 3467 3468 // Add listeners to Deferred subordinates; treat others as resolved 3469 if ( length > 1 ) { 3470 progressValues = new Array( length ); 3471 progressContexts = new Array( length ); 3472 resolveContexts = new Array( length ); 3473 for ( ; i < length; i++ ) { 3474 if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { 3475 resolveValues[ i ].promise() 3476 .progress( updateFunc( i, progressContexts, progressValues ) ) 3477 .done( updateFunc( i, resolveContexts, resolveValues ) ) 3478 .fail( deferred.reject ); 3479 } else { 3480 --remaining; 3481 } 3482 } 3483 } 3484 3485 // If we're not waiting on anything, resolve the master 3486 if ( !remaining ) { 3487 deferred.resolveWith( resolveContexts, resolveValues ); 3488 } 3489 3490 return deferred.promise(); 3491 } 3492} ); 3493 3494 3495// The deferred used on DOM ready 3496var readyList; 3497 3498jQuery.fn.ready = function( fn ) { 3499 3500 // Add the callback 3501 jQuery.ready.promise().done( fn ); 3502 3503 return this; 3504}; 3505 3506jQuery.extend( { 3507 3508 // Is the DOM ready to be used? Set to true once it occurs. 3509 isReady: false, 3510 3511 // A counter to track how many items to wait for before 3512 // the ready event fires. See #6781 3513 readyWait: 1, 3514 3515 // Hold (or release) the ready event 3516 holdReady: function( hold ) { 3517 if ( hold ) { 3518 jQuery.readyWait++; 3519 } else { 3520 jQuery.ready( true ); 3521 } 3522 }, 3523 3524 // Handle when the DOM is ready 3525 ready: function( wait ) { 3526 3527 // Abort if there are pending holds or we're already ready 3528 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { 3529 return; 3530 } 3531 3532 // Remember that the DOM is ready 3533 jQuery.isReady = true; 3534 3535 // If a normal DOM Ready event fired, decrement, and wait if need be 3536 if ( wait !== true && --jQuery.readyWait > 0 ) { 3537 return; 3538 } 3539 3540 // If there are functions bound, to execute 3541 readyList.resolveWith( document, [ jQuery ] ); 3542 3543 // Trigger any bound ready events 3544 if ( jQuery.fn.triggerHandler ) { 3545 jQuery( document ).triggerHandler( "ready" ); 3546 jQuery( document ).off( "ready" ); 3547 } 3548 } 3549} ); 3550 3551/** 3552 * The ready event handler and self cleanup method 3553 */ 3554function completed() { 3555 document.removeEventListener( "DOMContentLoaded", completed ); 3556 window.removeEventListener( "load", completed ); 3557 jQuery.ready(); 3558} 3559 3560jQuery.ready.promise = function( obj ) { 3561 if ( !readyList ) { 3562 3563 readyList = jQuery.Deferred(); 3564 3565 // Catch cases where $(document).ready() is called 3566 // after the browser event has already occurred. 3567 // Support: IE9-10 only 3568 // Older IE sometimes signals "interactive" too soon 3569 if ( document.readyState === "complete" || 3570 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { 3571 3572 // Handle it asynchronously to allow scripts the opportunity to delay ready 3573 window.setTimeout( jQuery.ready ); 3574 3575 } else { 3576 3577 // Use the handy event callback 3578 document.addEventListener( "DOMContentLoaded", completed ); 3579 3580 // A fallback to window.onload, that will always work 3581 window.addEventListener( "load", completed ); 3582 } 3583 } 3584 return readyList.promise( obj ); 3585}; 3586 3587// Kick off the DOM ready check even if the user does not 3588jQuery.ready.promise(); 3589 3590 3591 3592 3593// Multifunctional method to get and set values of a collection 3594// The value/s can optionally be executed if it's a function 3595var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { 3596 var i = 0, 3597 len = elems.length, 3598 bulk = key == null; 3599 3600 // Sets many values 3601 if ( jQuery.type( key ) === "object" ) { 3602 chainable = true; 3603 for ( i in key ) { 3604 access( elems, fn, i, key[ i ], true, emptyGet, raw ); 3605 } 3606 3607 // Sets one value 3608 } else if ( value !== undefined ) { 3609 chainable = true; 3610 3611 if ( !jQuery.isFunction( value ) ) { 3612 raw = true; 3613 } 3614 3615 if ( bulk ) { 3616 3617 // Bulk operations run against the entire set 3618 if ( raw ) { 3619 fn.call( elems, value ); 3620 fn = null; 3621 3622 // ...except when executing function values 3623 } else { 3624 bulk = fn; 3625 fn = function( elem, key, value ) { 3626 return bulk.call( jQuery( elem ), value ); 3627 }; 3628 } 3629 } 3630 3631 if ( fn ) { 3632 for ( ; i < len; i++ ) { 3633 fn( 3634 elems[ i ], key, raw ? 3635 value : 3636 value.call( elems[ i ], i, fn( elems[ i ], key ) ) 3637 ); 3638 } 3639 } 3640 } 3641 3642 return chainable ? 3643 elems : 3644 3645 // Gets 3646 bulk ? 3647 fn.call( elems ) : 3648 len ? fn( elems[ 0 ], key ) : emptyGet; 3649}; 3650var acceptData = function( owner ) { 3651 3652 // Accepts only: 3653 // - Node 3654 // - Node.ELEMENT_NODE 3655 // - Node.DOCUMENT_NODE 3656 // - Object 3657 // - Any 3658 /* jshint -W018 */ 3659 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); 3660}; 3661 3662 3663 3664 3665function Data() { 3666 this.expando = jQuery.expando + Data.uid++; 3667} 3668 3669Data.uid = 1; 3670 3671Data.prototype = { 3672 3673 register: function( owner, initial ) { 3674 var value = initial || {}; 3675 3676 // If it is a node unlikely to be stringify-ed or looped over 3677 // use plain assignment 3678 if ( owner.nodeType ) { 3679 owner[ this.expando ] = value; 3680 3681 // Otherwise secure it in a non-enumerable, non-writable property 3682 // configurability must be true to allow the property to be 3683 // deleted with the delete operator 3684 } else { 3685 Object.defineProperty( owner, this.expando, { 3686 value: value, 3687 writable: true, 3688 configurable: true 3689 } ); 3690 } 3691 return owner[ this.expando ]; 3692 }, 3693 cache: function( owner ) { 3694 3695 // We can accept data for non-element nodes in modern browsers, 3696 // but we should not, see #8335. 3697 // Always return an empty object. 3698 if ( !acceptData( owner ) ) { 3699 return {}; 3700 } 3701 3702 // Check if the owner object already has a cache 3703 var value = owner[ this.expando ]; 3704 3705 // If not, create one 3706 if ( !value ) { 3707 value = {}; 3708 3709 // We can accept data for non-element nodes in modern browsers, 3710 // but we should not, see #8335. 3711 // Always return an empty object. 3712 if ( acceptData( owner ) ) { 3713 3714 // If it is a node unlikely to be stringify-ed or looped over 3715 // use plain assignment 3716 if ( owner.nodeType ) { 3717 owner[ this.expando ] = value; 3718 3719 // Otherwise secure it in a non-enumerable property 3720 // configurable must be true to allow the property to be 3721 // deleted when data is removed 3722 } else { 3723 Object.defineProperty( owner, this.expando, { 3724 value: value, 3725 configurable: true 3726 } ); 3727 } 3728 } 3729 } 3730 3731 return value; 3732 }, 3733 set: function( owner, data, value ) { 3734 var prop, 3735 cache = this.cache( owner ); 3736 3737 // Handle: [ owner, key, value ] args 3738 if ( typeof data === "string" ) { 3739 cache[ data ] = value; 3740 3741 // Handle: [ owner, { properties } ] args 3742 } else { 3743 3744 // Copy the properties one-by-one to the cache object 3745 for ( prop in data ) { 3746 cache[ prop ] = data[ prop ]; 3747 } 3748 } 3749 return cache; 3750 }, 3751 get: function( owner, key ) { 3752 return key === undefined ? 3753 this.cache( owner ) : 3754 owner[ this.expando ] && owner[ this.expando ][ key ]; 3755 }, 3756 access: function( owner, key, value ) { 3757 var stored; 3758 3759 // In cases where either: 3760 // 3761 // 1. No key was specified 3762 // 2. A string key was specified, but no value provided 3763 // 3764 // Take the "read" path and allow the get method to determine 3765 // which value to return, respectively either: 3766 // 3767 // 1. The entire cache object 3768 // 2. The data stored at the key 3769 // 3770 if ( key === undefined || 3771 ( ( key && typeof key === "string" ) && value === undefined ) ) { 3772 3773 stored = this.get( owner, key ); 3774 3775 return stored !== undefined ? 3776 stored : this.get( owner, jQuery.camelCase( key ) ); 3777 } 3778 3779 // When the key is not a string, or both a key and value 3780 // are specified, set or extend (existing objects) with either: 3781 // 3782 // 1. An object of properties 3783 // 2. A key and value 3784 // 3785 this.set( owner, key, value ); 3786 3787 // Since the "set" path can have two possible entry points 3788 // return the expected data based on which path was taken[*] 3789 return value !== undefined ? value : key; 3790 }, 3791 remove: function( owner, key ) { 3792 var i, name, camel, 3793 cache = owner[ this.expando ]; 3794 3795 if ( cache === undefined ) { 3796 return; 3797 } 3798 3799 if ( key === undefined ) { 3800 this.register( owner ); 3801 3802 } else { 3803 3804 // Support array or space separated string of keys 3805 if ( jQuery.isArray( key ) ) { 3806 3807 // If "name" is an array of keys... 3808 // When data is initially created, via ("key", "val") signature, 3809 // keys will be converted to camelCase. 3810 // Since there is no way to tell _how_ a key was added, remove 3811 // both plain key and camelCase key. #12786 3812 // This will only penalize the array argument path. 3813 name = key.concat( key.map( jQuery.camelCase ) ); 3814 } else { 3815 camel = jQuery.camelCase( key ); 3816 3817 // Try the string as a key before any manipulation 3818 if ( key in cache ) { 3819 name = [ key, camel ]; 3820 } else { 3821 3822 // If a key with the spaces exists, use it. 3823 // Otherwise, create an array by matching non-whitespace 3824 name = camel; 3825 name = name in cache ? 3826 [ name ] : ( name.match( rnotwhite ) || [] ); 3827 } 3828 } 3829 3830 i = name.length; 3831 3832 while ( i-- ) { 3833 delete cache[ name[ i ] ]; 3834 } 3835 } 3836 3837 // Remove the expando if there's no more data 3838 if ( key === undefined || jQuery.isEmptyObject( cache ) ) { 3839 3840 // Support: Chrome <= 35-45+ 3841 // Webkit & Blink performance suffers when deleting properties 3842 // from DOM nodes, so set to undefined instead 3843 // https://code.google.com/p/chromium/issues/detail?id=378607 3844 if ( owner.nodeType ) { 3845 owner[ this.expando ] = undefined; 3846 } else { 3847 delete owner[ this.expando ]; 3848 } 3849 } 3850 }, 3851 hasData: function( owner ) { 3852 var cache = owner[ this.expando ]; 3853 return cache !== undefined && !jQuery.isEmptyObject( cache ); 3854 } 3855}; 3856var dataPriv = new Data(); 3857 3858var dataUser = new Data(); 3859 3860 3861 3862// Implementation Summary 3863// 3864// 1. Enforce API surface and semantic compatibility with 1.9.x branch 3865// 2. Improve the module's maintainability by reducing the storage 3866// paths to a single mechanism. 3867// 3. Use the same single mechanism to support "private" and "user" data. 3868// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) 3869// 5. Avoid exposing implementation details on user objects (eg. expando properties) 3870// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 3871 3872var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, 3873 rmultiDash = /[A-Z]/g; 3874 3875function dataAttr( elem, key, data ) { 3876 var name; 3877 3878 // If nothing was found internally, try to fetch any 3879 // data from the HTML5 data-* attribute 3880 if ( data === undefined && elem.nodeType === 1 ) { 3881 name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); 3882 data = elem.getAttribute( name ); 3883 3884 if ( typeof data === "string" ) { 3885 try { 3886 data = data === "true" ? true : 3887 data === "false" ? false : 3888 data === "null" ? null : 3889 3890 // Only convert to a number if it doesn't change the string 3891 +data + "" === data ? +data : 3892 rbrace.test( data ) ? jQuery.parseJSON( data ) : 3893 data; 3894 } catch ( e ) {} 3895 3896 // Make sure we set the data so it isn't changed later 3897 dataUser.set( elem, key, data ); 3898 } else { 3899 data = undefined; 3900 } 3901 } 3902 return data; 3903} 3904 3905jQuery.extend( { 3906 hasData: function( elem ) { 3907 return dataUser.hasData( elem ) || dataPriv.hasData( elem ); 3908 }, 3909 3910 data: function( elem, name, data ) { 3911 return dataUser.access( elem, name, data ); 3912 }, 3913 3914 removeData: function( elem, name ) { 3915 dataUser.remove( elem, name ); 3916 }, 3917 3918 // TODO: Now that all calls to _data and _removeData have been replaced 3919 // with direct calls to dataPriv methods, these can be deprecated. 3920 _data: function( elem, name, data ) { 3921 return dataPriv.access( elem, name, data ); 3922 }, 3923 3924 _removeData: function( elem, name ) { 3925 dataPriv.remove( elem, name ); 3926 } 3927} ); 3928 3929jQuery.fn.extend( { 3930 data: function( key, value ) { 3931 var i, name, data, 3932 elem = this[ 0 ], 3933 attrs = elem && elem.attributes; 3934 3935 // Gets all values 3936 if ( key === undefined ) { 3937 if ( this.length ) { 3938 data = dataUser.get( elem ); 3939 3940 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { 3941 i = attrs.length; 3942 while ( i-- ) { 3943 3944 // Support: IE11+ 3945 // The attrs elements can be null (#14894) 3946 if ( attrs[ i ] ) { 3947 name = attrs[ i ].name; 3948 if ( name.indexOf( "data-" ) === 0 ) { 3949 name = jQuery.camelCase( name.slice( 5 ) ); 3950 dataAttr( elem, name, data[ name ] ); 3951 } 3952 } 3953 } 3954 dataPriv.set( elem, "hasDataAttrs", true ); 3955 } 3956 } 3957 3958 return data; 3959 } 3960 3961 // Sets multiple values 3962 if ( typeof key === "object" ) { 3963 return this.each( function() { 3964 dataUser.set( this, key ); 3965 } ); 3966 } 3967 3968 return access( this, function( value ) { 3969 var data, camelKey; 3970 3971 // The calling jQuery object (element matches) is not empty 3972 // (and therefore has an element appears at this[ 0 ]) and the 3973 // `value` parameter was not undefined. An empty jQuery object 3974 // will result in `undefined` for elem = this[ 0 ] which will 3975 // throw an exception if an attempt to read a data cache is made. 3976 if ( elem && value === undefined ) { 3977 3978 // Attempt to get data from the cache 3979 // with the key as-is 3980 data = dataUser.get( elem, key ) || 3981 3982 // Try to find dashed key if it exists (gh-2779) 3983 // This is for 2.2.x only 3984 dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() ); 3985 3986 if ( data !== undefined ) { 3987 return data; 3988 } 3989 3990 camelKey = jQuery.camelCase( key ); 3991 3992 // Attempt to get data from the cache 3993 // with the key camelized 3994 data = dataUser.get( elem, camelKey ); 3995 if ( data !== undefined ) { 3996 return data; 3997 } 3998 3999 // Attempt to "discover" the data in 4000 // HTML5 custom data-* attrs 4001 data = dataAttr( elem, camelKey, undefined ); 4002 if ( data !== undefined ) { 4003 return data; 4004 } 4005 4006 // We tried really hard, but the data doesn't exist. 4007 return; 4008 } 4009 4010 // Set the data... 4011 camelKey = jQuery.camelCase( key ); 4012 this.each( function() { 4013 4014 // First, attempt to store a copy or reference of any 4015 // data that might've been store with a camelCased key. 4016 var data = dataUser.get( this, camelKey ); 4017 4018 // For HTML5 data-* attribute interop, we have to 4019 // store property names with dashes in a camelCase form. 4020 // This might not apply to all properties...* 4021 dataUser.set( this, camelKey, value ); 4022 4023 // *... In the case of properties that might _actually_ 4024 // have dashes, we need to also store a copy of that 4025 // unchanged property. 4026 if ( key.indexOf( "-" ) > -1 && data !== undefined ) { 4027 dataUser.set( this, key, value ); 4028 } 4029 } ); 4030 }, null, value, arguments.length > 1, null, true ); 4031 }, 4032 4033 removeData: function( key ) { 4034 return this.each( function() { 4035 dataUser.remove( this, key ); 4036 } ); 4037 } 4038} ); 4039 4040 4041jQuery.extend( { 4042 queue: function( elem, type, data ) { 4043 var queue; 4044 4045 if ( elem ) { 4046 type = ( type || "fx" ) + "queue"; 4047 queue = dataPriv.get( elem, type ); 4048 4049 // Speed up dequeue by getting out quickly if this is just a lookup 4050 if ( data ) { 4051 if ( !queue || jQuery.isArray( data ) ) { 4052 queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); 4053 } else { 4054 queue.push( data ); 4055 } 4056 } 4057 return queue || []; 4058 } 4059 }, 4060 4061 dequeue: function( elem, type ) { 4062 type = type || "fx"; 4063 4064 var queue = jQuery.queue( elem, type ), 4065 startLength = queue.length, 4066 fn = queue.shift(), 4067 hooks = jQuery._queueHooks( elem, type ), 4068 next = function() { 4069 jQuery.dequeue( elem, type ); 4070 }; 4071 4072 // If the fx queue is dequeued, always remove the progress sentinel 4073 if ( fn === "inprogress" ) { 4074 fn = queue.shift(); 4075 startLength--; 4076 } 4077 4078 if ( fn ) { 4079 4080 // Add a progress sentinel to prevent the fx queue from being 4081 // automatically dequeued 4082 if ( type === "fx" ) { 4083 queue.unshift( "inprogress" ); 4084 } 4085 4086 // Clear up the last queue stop function 4087 delete hooks.stop; 4088 fn.call( elem, next, hooks ); 4089 } 4090 4091 if ( !startLength && hooks ) { 4092 hooks.empty.fire(); 4093 } 4094 }, 4095 4096 // Not public - generate a queueHooks object, or return the current one 4097 _queueHooks: function( elem, type ) { 4098 var key = type + "queueHooks"; 4099 return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { 4100 empty: jQuery.Callbacks( "once memory" ).add( function() { 4101 dataPriv.remove( elem, [ type + "queue", key ] ); 4102 } ) 4103 } ); 4104 } 4105} ); 4106 4107jQuery.fn.extend( { 4108 queue: function( type, data ) { 4109 var setter = 2; 4110 4111 if ( typeof type !== "string" ) { 4112 data = type; 4113 type = "fx"; 4114 setter--; 4115 } 4116 4117 if ( arguments.length < setter ) { 4118 return jQuery.queue( this[ 0 ], type ); 4119 } 4120 4121 return data === undefined ? 4122 this : 4123 this.each( function() { 4124 var queue = jQuery.queue( this, type, data ); 4125 4126 // Ensure a hooks for this queue 4127 jQuery._queueHooks( this, type ); 4128 4129 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { 4130 jQuery.dequeue( this, type ); 4131 } 4132 } ); 4133 }, 4134 dequeue: function( type ) { 4135 return this.each( function() { 4136 jQuery.dequeue( this, type ); 4137 } ); 4138 }, 4139 clearQueue: function( type ) { 4140 return this.queue( type || "fx", [] ); 4141 }, 4142 4143 // Get a promise resolved when queues of a certain type 4144 // are emptied (fx is the type by default) 4145 promise: function( type, obj ) { 4146 var tmp, 4147 count = 1, 4148 defer = jQuery.Deferred(), 4149 elements = this, 4150 i = this.length, 4151 resolve = function() { 4152 if ( !( --count ) ) { 4153 defer.resolveWith( elements, [ elements ] ); 4154 } 4155 }; 4156 4157 if ( typeof type !== "string" ) { 4158 obj = type; 4159 type = undefined; 4160 } 4161 type = type || "fx"; 4162 4163 while ( i-- ) { 4164 tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); 4165 if ( tmp && tmp.empty ) { 4166 count++; 4167 tmp.empty.add( resolve ); 4168 } 4169 } 4170 resolve(); 4171 return defer.promise( obj ); 4172 } 4173} ); 4174var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; 4175 4176var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); 4177 4178 4179var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; 4180 4181var isHidden = function( elem, el ) { 4182 4183 // isHidden might be called from jQuery#filter function; 4184 // in that case, element will be second argument 4185 elem = el || elem; 4186 return jQuery.css( elem, "display" ) === "none" || 4187 !jQuery.contains( elem.ownerDocument, elem ); 4188 }; 4189 4190 4191 4192function adjustCSS( elem, prop, valueParts, tween ) { 4193 var adjusted, 4194 scale = 1, 4195 maxIterations = 20, 4196 currentValue = tween ? 4197 function() { return tween.cur(); } : 4198 function() { return jQuery.css( elem, prop, "" ); }, 4199 initial = currentValue(), 4200 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), 4201 4202 // Starting value computation is required for potential unit mismatches 4203 initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && 4204 rcssNum.exec( jQuery.css( elem, prop ) ); 4205 4206 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { 4207 4208 // Trust units reported by jQuery.css 4209 unit = unit || initialInUnit[ 3 ]; 4210 4211 // Make sure we update the tween properties later on 4212 valueParts = valueParts || []; 4213 4214 // Iteratively approximate from a nonzero starting point 4215 initialInUnit = +initial || 1; 4216 4217 do { 4218 4219 // If previous iteration zeroed out, double until we get *something*. 4220 // Use string for doubling so we don't accidentally see scale as unchanged below 4221 scale = scale || ".5"; 4222 4223 // Adjust and apply 4224 initialInUnit = initialInUnit / scale; 4225 jQuery.style( elem, prop, initialInUnit + unit ); 4226 4227 // Update scale, tolerating zero or NaN from tween.cur() 4228 // Break the loop if scale is unchanged or perfect, or if we've just had enough. 4229 } while ( 4230 scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations 4231 ); 4232 } 4233 4234 if ( valueParts ) { 4235 initialInUnit = +initialInUnit || +initial || 0; 4236 4237 // Apply relative offset (+=/-=) if specified 4238 adjusted = valueParts[ 1 ] ? 4239 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : 4240 +valueParts[ 2 ]; 4241 if ( tween ) { 4242 tween.unit = unit; 4243 tween.start = initialInUnit; 4244 tween.end = adjusted; 4245 } 4246 } 4247 return adjusted; 4248} 4249var rcheckableType = ( /^(?:checkbox|radio)$/i ); 4250 4251var rtagName = ( /<([\w:-]+)/ ); 4252 4253var rscriptType = ( /^$|\/(?:java|ecma)script/i ); 4254 4255 4256 4257// We have to close these tags to support XHTML (#13200) 4258var wrapMap = { 4259 4260 // Support: IE9 4261 option: [ 1, "<select multiple='multiple'>", "</select>" ], 4262 4263 // XHTML parsers do not magically insert elements in the 4264 // same way that tag soup parsers do. So we cannot shorten 4265 // this by omitting <tbody> or other required elements. 4266 thead: [ 1, "<table>", "</table>" ], 4267 col: [ 2, "<table><colgroup>", "</colgroup></table>" ], 4268 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 4269 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 4270 4271 _default: [ 0, "", "" ] 4272}; 4273 4274// Support: IE9 4275wrapMap.optgroup = wrapMap.option; 4276 4277wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 4278wrapMap.th = wrapMap.td; 4279 4280 4281function getAll( context, tag ) { 4282 4283 // Support: IE9-11+ 4284 // Use typeof to avoid zero-argument method invocation on host objects (#15151) 4285 var ret = typeof context.getElementsByTagName !== "undefined" ? 4286 context.getElementsByTagName( tag || "*" ) : 4287 typeof context.querySelectorAll !== "undefined" ? 4288 context.querySelectorAll( tag || "*" ) : 4289 []; 4290 4291 return tag === undefined || tag && jQuery.nodeName( context, tag ) ? 4292 jQuery.merge( [ context ], ret ) : 4293 ret; 4294} 4295 4296 4297// Mark scripts as having already been evaluated 4298function setGlobalEval( elems, refElements ) { 4299 var i = 0, 4300 l = elems.length; 4301 4302 for ( ; i < l; i++ ) { 4303 dataPriv.set( 4304 elems[ i ], 4305 "globalEval", 4306 !refElements || dataPriv.get( refElements[ i ], "globalEval" ) 4307 ); 4308 } 4309} 4310 4311 4312var rhtml = /<|&#?\w+;/; 4313 4314function buildFragment( elems, context, scripts, selection, ignored ) { 4315 var elem, tmp, tag, wrap, contains, j, 4316 fragment = context.createDocumentFragment(), 4317 nodes = [], 4318 i = 0, 4319 l = elems.length; 4320 4321 for ( ; i < l; i++ ) { 4322 elem = elems[ i ]; 4323 4324 if ( elem || elem === 0 ) { 4325 4326 // Add nodes directly 4327 if ( jQuery.type( elem ) === "object" ) { 4328 4329 // Support: Android<4.1, PhantomJS<2 4330 // push.apply(_, arraylike) throws on ancient WebKit 4331 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); 4332 4333 // Convert non-html into a text node 4334 } else if ( !rhtml.test( elem ) ) { 4335 nodes.push( context.createTextNode( elem ) ); 4336 4337 // Convert html into DOM nodes 4338 } else { 4339 tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); 4340 4341 // Deserialize a standard representation 4342 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); 4343 wrap = wrapMap[ tag ] || wrapMap._default; 4344 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; 4345 4346 // Descend through wrappers to the right content 4347 j = wrap[ 0 ]; 4348 while ( j-- ) { 4349 tmp = tmp.lastChild; 4350 } 4351 4352 // Support: Android<4.1, PhantomJS<2 4353 // push.apply(_, arraylike) throws on ancient WebKit 4354 jQuery.merge( nodes, tmp.childNodes ); 4355 4356 // Remember the top-level container 4357 tmp = fragment.firstChild; 4358 4359 // Ensure the created nodes are orphaned (#12392) 4360 tmp.textContent = ""; 4361 } 4362 } 4363 } 4364 4365 // Remove wrapper from fragment 4366 fragment.textContent = ""; 4367 4368 i = 0; 4369 while ( ( elem = nodes[ i++ ] ) ) { 4370 4371 // Skip elements already in the context collection (trac-4087) 4372 if ( selection && jQuery.inArray( elem, selection ) > -1 ) { 4373 if ( ignored ) { 4374 ignored.push( elem ); 4375 } 4376 continue; 4377 } 4378 4379 contains = jQuery.contains( elem.ownerDocument, elem ); 4380 4381 // Append to fragment 4382 tmp = getAll( fragment.appendChild( elem ), "script" ); 4383 4384 // Preserve script evaluation history 4385 if ( contains ) { 4386 setGlobalEval( tmp ); 4387 } 4388 4389 // Capture executables 4390 if ( scripts ) { 4391 j = 0; 4392 while ( ( elem = tmp[ j++ ] ) ) { 4393 if ( rscriptType.test( elem.type || "" ) ) { 4394 scripts.push( elem ); 4395 } 4396 } 4397 } 4398 } 4399 4400 return fragment; 4401} 4402 4403 4404( function() { 4405 var fragment = document.createDocumentFragment(), 4406 div = fragment.appendChild( document.createElement( "div" ) ), 4407 input = document.createElement( "input" ); 4408 4409 // Support: Android 4.0-4.3, Safari<=5.1 4410 // Check state lost if the name is set (#11217) 4411 // Support: Windows Web Apps (WWA) 4412 // `name` and `type` must use .setAttribute for WWA (#14901) 4413 input.setAttribute( "type", "radio" ); 4414 input.setAttribute( "checked", "checked" ); 4415 input.setAttribute( "name", "t" ); 4416 4417 div.appendChild( input ); 4418 4419 // Support: Safari<=5.1, Android<4.2 4420 // Older WebKit doesn't clone checked state correctly in fragments 4421 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; 4422 4423 // Support: IE<=11+ 4424 // Make sure textarea (and checkbox) defaultValue is properly cloned 4425 div.innerHTML = "<textarea>x</textarea>"; 4426 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; 4427} )(); 4428 4429 4430var 4431 rkeyEvent = /^key/, 4432 rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, 4433 rtypenamespace = /^([^.]*)(?:\.(.+)|)/; 4434 4435function returnTrue() { 4436 return true; 4437} 4438 4439function returnFalse() { 4440 return false; 4441} 4442 4443// Support: IE9 4444// See #13393 for more info 4445function safeActiveElement() { 4446 try { 4447 return document.activeElement; 4448 } catch ( err ) { } 4449} 4450 4451function on( elem, types, selector, data, fn, one ) { 4452 var origFn, type; 4453 4454 // Types can be a map of types/handlers 4455 if ( typeof types === "object" ) { 4456 4457 // ( types-Object, selector, data ) 4458 if ( typeof selector !== "string" ) { 4459 4460 // ( types-Object, data ) 4461 data = data || selector; 4462 selector = undefined; 4463 } 4464 for ( type in types ) { 4465 on( elem, type, selector, data, types[ type ], one ); 4466 } 4467 return elem; 4468 } 4469 4470 if ( data == null && fn == null ) { 4471 4472 // ( types, fn ) 4473 fn = selector; 4474 data = selector = undefined; 4475 } else if ( fn == null ) { 4476 if ( typeof selector === "string" ) { 4477 4478 // ( types, selector, fn ) 4479 fn = data; 4480 data = undefined; 4481 } else { 4482 4483 // ( types, data, fn ) 4484 fn = data; 4485 data = selector; 4486 selector = undefined; 4487 } 4488 } 4489 if ( fn === false ) { 4490 fn = returnFalse; 4491 } else if ( !fn ) { 4492 return elem; 4493 } 4494 4495 if ( one === 1 ) { 4496 origFn = fn; 4497 fn = function( event ) { 4498 4499 // Can use an empty set, since event contains the info 4500 jQuery().off( event ); 4501 return origFn.apply( this, arguments ); 4502 }; 4503 4504 // Use same guid so caller can remove using origFn 4505 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); 4506 } 4507 return elem.each( function() { 4508 jQuery.event.add( this, types, fn, data, selector ); 4509 } ); 4510} 4511 4512/* 4513 * Helper functions for managing events -- not part of the public interface. 4514 * Props to Dean Edwards' addEvent library for many of the ideas. 4515 */ 4516jQuery.event = { 4517 4518 global: {}, 4519 4520 add: function( elem, types, handler, data, selector ) { 4521 4522 var handleObjIn, eventHandle, tmp, 4523 events, t, handleObj, 4524 special, handlers, type, namespaces, origType, 4525 elemData = dataPriv.get( elem ); 4526 4527 // Don't attach events to noData or text/comment nodes (but allow plain objects) 4528 if ( !elemData ) { 4529 return; 4530 } 4531 4532 // Caller can pass in an object of custom data in lieu of the handler 4533 if ( handler.handler ) { 4534 handleObjIn = handler; 4535 handler = handleObjIn.handler; 4536 selector = handleObjIn.selector; 4537 } 4538 4539 // Make sure that the handler has a unique ID, used to find/remove it later 4540 if ( !handler.guid ) { 4541 handler.guid = jQuery.guid++; 4542 } 4543 4544 // Init the element's event structure and main handler, if this is the first 4545 if ( !( events = elemData.events ) ) { 4546 events = elemData.events = {}; 4547 } 4548 if ( !( eventHandle = elemData.handle ) ) { 4549 eventHandle = elemData.handle = function( e ) { 4550 4551 // Discard the second event of a jQuery.event.trigger() and 4552 // when an event is called after a page has unloaded 4553 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? 4554 jQuery.event.dispatch.apply( elem, arguments ) : undefined; 4555 }; 4556 } 4557 4558 // Handle multiple events separated by a space 4559 types = ( types || "" ).match( rnotwhite ) || [ "" ]; 4560 t = types.length; 4561 while ( t-- ) { 4562 tmp = rtypenamespace.exec( types[ t ] ) || []; 4563 type = origType = tmp[ 1 ]; 4564 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 4565 4566 // There *must* be a type, no attaching namespace-only handlers 4567 if ( !type ) { 4568 continue; 4569 } 4570 4571 // If event changes its type, use the special event handlers for the changed type 4572 special = jQuery.event.special[ type ] || {}; 4573 4574 // If selector defined, determine special event api type, otherwise given type 4575 type = ( selector ? special.delegateType : special.bindType ) || type; 4576 4577 // Update special based on newly reset type 4578 special = jQuery.event.special[ type ] || {}; 4579 4580 // handleObj is passed to all event handlers 4581 handleObj = jQuery.extend( { 4582 type: type, 4583 origType: origType, 4584 data: data, 4585 handler: handler, 4586 guid: handler.guid, 4587 selector: selector, 4588 needsContext: selector && jQuery.expr.match.needsContext.test( selector ), 4589 namespace: namespaces.join( "." ) 4590 }, handleObjIn ); 4591 4592 // Init the event handler queue if we're the first 4593 if ( !( handlers = events[ type ] ) ) { 4594 handlers = events[ type ] = []; 4595 handlers.delegateCount = 0; 4596 4597 // Only use addEventListener if the special events handler returns false 4598 if ( !special.setup || 4599 special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 4600 4601 if ( elem.addEventListener ) { 4602 elem.addEventListener( type, eventHandle ); 4603 } 4604 } 4605 } 4606 4607 if ( special.add ) { 4608 special.add.call( elem, handleObj ); 4609 4610 if ( !handleObj.handler.guid ) { 4611 handleObj.handler.guid = handler.guid; 4612 } 4613 } 4614 4615 // Add to the element's handler list, delegates in front 4616 if ( selector ) { 4617 handlers.splice( handlers.delegateCount++, 0, handleObj ); 4618 } else { 4619 handlers.push( handleObj ); 4620 } 4621 4622 // Keep track of which events have ever been used, for event optimization 4623 jQuery.event.global[ type ] = true; 4624 } 4625 4626 }, 4627 4628 // Detach an event or set of events from an element 4629 remove: function( elem, types, handler, selector, mappedTypes ) { 4630 4631 var j, origCount, tmp, 4632 events, t, handleObj, 4633 special, handlers, type, namespaces, origType, 4634 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); 4635 4636 if ( !elemData || !( events = elemData.events ) ) { 4637 return; 4638 } 4639 4640 // Once for each type.namespace in types; type may be omitted 4641 types = ( types || "" ).match( rnotwhite ) || [ "" ]; 4642 t = types.length; 4643 while ( t-- ) { 4644 tmp = rtypenamespace.exec( types[ t ] ) || []; 4645 type = origType = tmp[ 1 ]; 4646 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 4647 4648 // Unbind all events (on this namespace, if provided) for the element 4649 if ( !type ) { 4650 for ( type in events ) { 4651 jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); 4652 } 4653 continue; 4654 } 4655 4656 special = jQuery.event.special[ type ] || {}; 4657 type = ( selector ? special.delegateType : special.bindType ) || type; 4658 handlers = events[ type ] || []; 4659 tmp = tmp[ 2 ] && 4660 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); 4661 4662 // Remove matching events 4663 origCount = j = handlers.length; 4664 while ( j-- ) { 4665 handleObj = handlers[ j ]; 4666 4667 if ( ( mappedTypes || origType === handleObj.origType ) && 4668 ( !handler || handler.guid === handleObj.guid ) && 4669 ( !tmp || tmp.test( handleObj.namespace ) ) && 4670 ( !selector || selector === handleObj.selector || 4671 selector === "**" && handleObj.selector ) ) { 4672 handlers.splice( j, 1 ); 4673 4674 if ( handleObj.selector ) { 4675 handlers.delegateCount--; 4676 } 4677 if ( special.remove ) { 4678 special.remove.call( elem, handleObj ); 4679 } 4680 } 4681 } 4682 4683 // Remove generic event handler if we removed something and no more handlers exist 4684 // (avoids potential for endless recursion during removal of special event handlers) 4685 if ( origCount && !handlers.length ) { 4686 if ( !special.teardown || 4687 special.teardown.call( elem, namespaces, elemData.handle ) === false ) { 4688 4689 jQuery.removeEvent( elem, type, elemData.handle ); 4690 } 4691 4692 delete events[ type ]; 4693 } 4694 } 4695 4696 // Remove data and the expando if it's no longer used 4697 if ( jQuery.isEmptyObject( events ) ) { 4698 dataPriv.remove( elem, "handle events" ); 4699 } 4700 }, 4701 4702 dispatch: function( event ) { 4703 4704 // Make a writable jQuery.Event from the native event object 4705 event = jQuery.event.fix( event ); 4706 4707 var i, j, ret, matched, handleObj, 4708 handlerQueue = [], 4709 args = slice.call( arguments ), 4710 handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], 4711 special = jQuery.event.special[ event.type ] || {}; 4712 4713 // Use the fix-ed jQuery.Event rather than the (read-only) native event 4714 args[ 0 ] = event; 4715 event.delegateTarget = this; 4716 4717 // Call the preDispatch hook for the mapped type, and let it bail if desired 4718 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { 4719 return; 4720 } 4721 4722 // Determine handlers 4723 handlerQueue = jQuery.event.handlers.call( this, event, handlers ); 4724 4725 // Run delegates first; they may want to stop propagation beneath us 4726 i = 0; 4727 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { 4728 event.currentTarget = matched.elem; 4729 4730 j = 0; 4731 while ( ( handleObj = matched.handlers[ j++ ] ) && 4732 !event.isImmediatePropagationStopped() ) { 4733 4734 // Triggered event must either 1) have no namespace, or 2) have namespace(s) 4735 // a subset or equal to those in the bound event (both can have no namespace). 4736 if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { 4737 4738 event.handleObj = handleObj; 4739 event.data = handleObj.data; 4740 4741 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || 4742 handleObj.handler ).apply( matched.elem, args ); 4743 4744 if ( ret !== undefined ) { 4745 if ( ( event.result = ret ) === false ) { 4746 event.preventDefault(); 4747 event.stopPropagation(); 4748 } 4749 } 4750 } 4751 } 4752 } 4753 4754 // Call the postDispatch hook for the mapped type 4755 if ( special.postDispatch ) { 4756 special.postDispatch.call( this, event ); 4757 } 4758 4759 return event.result; 4760 }, 4761 4762 handlers: function( event, handlers ) { 4763 var i, matches, sel, handleObj, 4764 handlerQueue = [], 4765 delegateCount = handlers.delegateCount, 4766 cur = event.target; 4767 4768 // Support (at least): Chrome, IE9 4769 // Find delegate handlers 4770 // Black-hole SVG <use> instance trees (#13180) 4771 // 4772 // Support: Firefox<=42+ 4773 // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343) 4774 if ( delegateCount && cur.nodeType && 4775 ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) { 4776 4777 for ( ; cur !== this; cur = cur.parentNode || this ) { 4778 4779 // Don't check non-elements (#13208) 4780 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) 4781 if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) { 4782 matches = []; 4783 for ( i = 0; i < delegateCount; i++ ) { 4784 handleObj = handlers[ i ]; 4785 4786 // Don't conflict with Object.prototype properties (#13203) 4787 sel = handleObj.selector + " "; 4788 4789 if ( matches[ sel ] === undefined ) { 4790 matches[ sel ] = handleObj.needsContext ? 4791 jQuery( sel, this ).index( cur ) > -1 : 4792 jQuery.find( sel, this, null, [ cur ] ).length; 4793 } 4794 if ( matches[ sel ] ) { 4795 matches.push( handleObj ); 4796 } 4797 } 4798 if ( matches.length ) { 4799 handlerQueue.push( { elem: cur, handlers: matches } ); 4800 } 4801 } 4802 } 4803 } 4804 4805 // Add the remaining (directly-bound) handlers 4806 if ( delegateCount < handlers.length ) { 4807 handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } ); 4808 } 4809 4810 return handlerQueue; 4811 }, 4812 4813 // Includes some event props shared by KeyEvent and MouseEvent 4814 props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + 4815 "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ), 4816 4817 fixHooks: {}, 4818 4819 keyHooks: { 4820 props: "char charCode key keyCode".split( " " ), 4821 filter: function( event, original ) { 4822 4823 // Add which for key events 4824 if ( event.which == null ) { 4825 event.which = original.charCode != null ? original.charCode : original.keyCode; 4826 } 4827 4828 return event; 4829 } 4830 }, 4831 4832 mouseHooks: { 4833 props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " + 4834 "screenX screenY toElement" ).split( " " ), 4835 filter: function( event, original ) { 4836 var eventDoc, doc, body, 4837 button = original.button; 4838 4839 // Calculate pageX/Y if missing and clientX/Y available 4840 if ( event.pageX == null && original.clientX != null ) { 4841 eventDoc = event.target.ownerDocument || document; 4842 doc = eventDoc.documentElement; 4843 body = eventDoc.body; 4844 4845 event.pageX = original.clientX + 4846 ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - 4847 ( doc && doc.clientLeft || body && body.clientLeft || 0 ); 4848 event.pageY = original.clientY + 4849 ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - 4850 ( doc && doc.clientTop || body && body.clientTop || 0 ); 4851 } 4852 4853 // Add which for click: 1 === left; 2 === middle; 3 === right 4854 // Note: button is not normalized, so don't use it 4855 if ( !event.which && button !== undefined ) { 4856 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); 4857 } 4858 4859 return event; 4860 } 4861 }, 4862 4863 fix: function( event ) { 4864 if ( event[ jQuery.expando ] ) { 4865 return event; 4866 } 4867 4868 // Create a writable copy of the event object and normalize some properties 4869 var i, prop, copy, 4870 type = event.type, 4871 originalEvent = event, 4872 fixHook = this.fixHooks[ type ]; 4873 4874 if ( !fixHook ) { 4875 this.fixHooks[ type ] = fixHook = 4876 rmouseEvent.test( type ) ? this.mouseHooks : 4877 rkeyEvent.test( type ) ? this.keyHooks : 4878 {}; 4879 } 4880 copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; 4881 4882 event = new jQuery.Event( originalEvent ); 4883 4884 i = copy.length; 4885 while ( i-- ) { 4886 prop = copy[ i ]; 4887 event[ prop ] = originalEvent[ prop ]; 4888 } 4889 4890 // Support: Cordova 2.5 (WebKit) (#13255) 4891 // All events should have a target; Cordova deviceready doesn't 4892 if ( !event.target ) { 4893 event.target = document; 4894 } 4895 4896 // Support: Safari 6.0+, Chrome<28 4897 // Target should not be a text node (#504, #13143) 4898 if ( event.target.nodeType === 3 ) { 4899 event.target = event.target.parentNode; 4900 } 4901 4902 return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; 4903 }, 4904 4905 special: { 4906 load: { 4907 4908 // Prevent triggered image.load events from bubbling to window.load 4909 noBubble: true 4910 }, 4911 focus: { 4912 4913 // Fire native event if possible so blur/focus sequence is correct 4914 trigger: function() { 4915 if ( this !== safeActiveElement() && this.focus ) { 4916 this.focus(); 4917 return false; 4918 } 4919 }, 4920 delegateType: "focusin" 4921 }, 4922 blur: { 4923 trigger: function() { 4924 if ( this === safeActiveElement() && this.blur ) { 4925 this.blur(); 4926 return false; 4927 } 4928 }, 4929 delegateType: "focusout" 4930 }, 4931 click: { 4932 4933 // For checkbox, fire native event so checked state will be right 4934 trigger: function() { 4935 if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { 4936 this.click(); 4937 return false; 4938 } 4939 }, 4940 4941 // For cross-browser consistency, don't fire native .click() on links 4942 _default: function( event ) { 4943 return jQuery.nodeName( event.target, "a" ); 4944 } 4945 }, 4946 4947 beforeunload: { 4948 postDispatch: function( event ) { 4949 4950 // Support: Firefox 20+ 4951 // Firefox doesn't alert if the returnValue field is not set. 4952 if ( event.result !== undefined && event.originalEvent ) { 4953 event.originalEvent.returnValue = event.result; 4954 } 4955 } 4956 } 4957 } 4958}; 4959 4960jQuery.removeEvent = function( elem, type, handle ) { 4961 4962 // This "if" is needed for plain objects 4963 if ( elem.removeEventListener ) { 4964 elem.removeEventListener( type, handle ); 4965 } 4966}; 4967 4968jQuery.Event = function( src, props ) { 4969 4970 // Allow instantiation without the 'new' keyword 4971 if ( !( this instanceof jQuery.Event ) ) { 4972 return new jQuery.Event( src, props ); 4973 } 4974 4975 // Event object 4976 if ( src && src.type ) { 4977 this.originalEvent = src; 4978 this.type = src.type; 4979 4980 // Events bubbling up the document may have been marked as prevented 4981 // by a handler lower down the tree; reflect the correct value. 4982 this.isDefaultPrevented = src.defaultPrevented || 4983 src.defaultPrevented === undefined && 4984 4985 // Support: Android<4.0 4986 src.returnValue === false ? 4987 returnTrue : 4988 returnFalse; 4989 4990 // Event type 4991 } else { 4992 this.type = src; 4993 } 4994 4995 // Put explicitly provided properties onto the event object 4996 if ( props ) { 4997 jQuery.extend( this, props ); 4998 } 4999 5000 // Create a timestamp if incoming event doesn't have one 5001 this.timeStamp = src && src.timeStamp || jQuery.now(); 5002 5003 // Mark it as fixed 5004 this[ jQuery.expando ] = true; 5005}; 5006 5007// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 5008// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 5009jQuery.Event.prototype = { 5010 constructor: jQuery.Event, 5011 isDefaultPrevented: returnFalse, 5012 isPropagationStopped: returnFalse, 5013 isImmediatePropagationStopped: returnFalse, 5014 isSimulated: false, 5015 5016 preventDefault: function() { 5017 var e = this.originalEvent; 5018 5019 this.isDefaultPrevented = returnTrue; 5020 5021 if ( e && !this.isSimulated ) { 5022 e.preventDefault(); 5023 } 5024 }, 5025 stopPropagation: function() { 5026 var e = this.originalEvent; 5027 5028 this.isPropagationStopped = returnTrue; 5029 5030 if ( e && !this.isSimulated ) { 5031 e.stopPropagation(); 5032 } 5033 }, 5034 stopImmediatePropagation: function() { 5035 var e = this.originalEvent; 5036 5037 this.isImmediatePropagationStopped = returnTrue; 5038 5039 if ( e && !this.isSimulated ) { 5040 e.stopImmediatePropagation(); 5041 } 5042 5043 this.stopPropagation(); 5044 } 5045}; 5046 5047// Create mouseenter/leave events using mouseover/out and event-time checks 5048// so that event delegation works in jQuery. 5049// Do the same for pointerenter/pointerleave and pointerover/pointerout 5050// 5051// Support: Safari 7 only 5052// Safari sends mouseenter too often; see: 5053// https://code.google.com/p/chromium/issues/detail?id=470258 5054// for the description of the bug (it existed in older Chrome versions as well). 5055jQuery.each( { 5056 mouseenter: "mouseover", 5057 mouseleave: "mouseout", 5058 pointerenter: "pointerover", 5059 pointerleave: "pointerout" 5060}, function( orig, fix ) { 5061 jQuery.event.special[ orig ] = { 5062 delegateType: fix, 5063 bindType: fix, 5064 5065 handle: function( event ) { 5066 var ret, 5067 target = this, 5068 related = event.relatedTarget, 5069 handleObj = event.handleObj; 5070 5071 // For mouseenter/leave call the handler if related is outside the target. 5072 // NB: No relatedTarget if the mouse left/entered the browser window 5073 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { 5074 event.type = handleObj.origType; 5075 ret = handleObj.handler.apply( this, arguments ); 5076 event.type = fix; 5077 } 5078 return ret; 5079 } 5080 }; 5081} ); 5082 5083jQuery.fn.extend( { 5084 on: function( types, selector, data, fn ) { 5085 return on( this, types, selector, data, fn ); 5086 }, 5087 one: function( types, selector, data, fn ) { 5088 return on( this, types, selector, data, fn, 1 ); 5089 }, 5090 off: function( types, selector, fn ) { 5091 var handleObj, type; 5092 if ( types && types.preventDefault && types.handleObj ) { 5093 5094 // ( event ) dispatched jQuery.Event 5095 handleObj = types.handleObj; 5096 jQuery( types.delegateTarget ).off( 5097 handleObj.namespace ? 5098 handleObj.origType + "." + handleObj.namespace : 5099 handleObj.origType, 5100 handleObj.selector, 5101 handleObj.handler 5102 ); 5103 return this; 5104 } 5105 if ( typeof types === "object" ) { 5106 5107 // ( types-object [, selector] ) 5108 for ( type in types ) { 5109 this.off( type, selector, types[ type ] ); 5110 } 5111 return this; 5112 } 5113 if ( selector === false || typeof selector === "function" ) { 5114 5115 // ( types [, fn] ) 5116 fn = selector; 5117 selector = undefined; 5118 } 5119 if ( fn === false ) { 5120 fn = returnFalse; 5121 } 5122 return this.each( function() { 5123 jQuery.event.remove( this, types, fn, selector ); 5124 } ); 5125 } 5126} ); 5127 5128 5129var 5130 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi, 5131 5132 // Support: IE 10-11, Edge 10240+ 5133 // In IE/Edge using regex groups here causes severe slowdowns. 5134 // See https://connect.microsoft.com/IE/feedback/details/1736512/ 5135 rnoInnerhtml = /<script|<style|<link/i, 5136 5137 // checked="checked" or checked 5138 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 5139 rscriptTypeMasked = /^true\/(.*)/, 5140 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; 5141 5142// Manipulating tables requires a tbody 5143function manipulationTarget( elem, content ) { 5144 return jQuery.nodeName( elem, "table" ) && 5145 jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? 5146 5147 elem.getElementsByTagName( "tbody" )[ 0 ] || 5148 elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) : 5149 elem; 5150} 5151 5152// Replace/restore the type attribute of script elements for safe DOM manipulation 5153function disableScript( elem ) { 5154 elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; 5155 return elem; 5156} 5157function restoreScript( elem ) { 5158 var match = rscriptTypeMasked.exec( elem.type ); 5159 5160 if ( match ) { 5161 elem.type = match[ 1 ]; 5162 } else { 5163 elem.removeAttribute( "type" ); 5164 } 5165 5166 return elem; 5167} 5168 5169function cloneCopyEvent( src, dest ) { 5170 var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; 5171 5172 if ( dest.nodeType !== 1 ) { 5173 return; 5174 } 5175 5176 // 1. Copy private data: events, handlers, etc. 5177 if ( dataPriv.hasData( src ) ) { 5178 pdataOld = dataPriv.access( src ); 5179 pdataCur = dataPriv.set( dest, pdataOld ); 5180 events = pdataOld.events; 5181 5182 if ( events ) { 5183 delete pdataCur.handle; 5184 pdataCur.events = {}; 5185 5186 for ( type in events ) { 5187 for ( i = 0, l = events[ type ].length; i < l; i++ ) { 5188 jQuery.event.add( dest, type, events[ type ][ i ] ); 5189 } 5190 } 5191 } 5192 } 5193 5194 // 2. Copy user data 5195 if ( dataUser.hasData( src ) ) { 5196 udataOld = dataUser.access( src ); 5197 udataCur = jQuery.extend( {}, udataOld ); 5198 5199 dataUser.set( dest, udataCur ); 5200 } 5201} 5202 5203// Fix IE bugs, see support tests 5204function fixInput( src, dest ) { 5205 var nodeName = dest.nodeName.toLowerCase(); 5206 5207 // Fails to persist the checked state of a cloned checkbox or radio button. 5208 if ( nodeName === "input" && rcheckableType.test( src.type ) ) { 5209 dest.checked = src.checked; 5210 5211 // Fails to return the selected option to the default selected state when cloning options 5212 } else if ( nodeName === "input" || nodeName === "textarea" ) { 5213 dest.defaultValue = src.defaultValue; 5214 } 5215} 5216 5217function domManip( collection, args, callback, ignored ) { 5218 5219 // Flatten any nested arrays 5220 args = concat.apply( [], args ); 5221 5222 var fragment, first, scripts, hasScripts, node, doc, 5223 i = 0, 5224 l = collection.length, 5225 iNoClone = l - 1, 5226 value = args[ 0 ], 5227 isFunction = jQuery.isFunction( value ); 5228 5229 // We can't cloneNode fragments that contain checked, in WebKit 5230 if ( isFunction || 5231 ( l > 1 && typeof value === "string" && 5232 !support.checkClone && rchecked.test( value ) ) ) { 5233 return collection.each( function( index ) { 5234 var self = collection.eq( index ); 5235 if ( isFunction ) { 5236 args[ 0 ] = value.call( this, index, self.html() ); 5237 } 5238 domManip( self, args, callback, ignored ); 5239 } ); 5240 } 5241 5242 if ( l ) { 5243 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); 5244 first = fragment.firstChild; 5245 5246 if ( fragment.childNodes.length === 1 ) { 5247 fragment = first; 5248 } 5249 5250 // Require either new content or an interest in ignored elements to invoke the callback 5251 if ( first || ignored ) { 5252 scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); 5253 hasScripts = scripts.length; 5254 5255 // Use the original fragment for the last item 5256 // instead of the first because it can end up 5257 // being emptied incorrectly in certain situations (#8070). 5258 for ( ; i < l; i++ ) { 5259 node = fragment; 5260 5261 if ( i !== iNoClone ) { 5262 node = jQuery.clone( node, true, true ); 5263 5264 // Keep references to cloned scripts for later restoration 5265 if ( hasScripts ) { 5266 5267 // Support: Android<4.1, PhantomJS<2 5268 // push.apply(_, arraylike) throws on ancient WebKit 5269 jQuery.merge( scripts, getAll( node, "script" ) ); 5270 } 5271 } 5272 5273 callback.call( collection[ i ], node, i ); 5274 } 5275 5276 if ( hasScripts ) { 5277 doc = scripts[ scripts.length - 1 ].ownerDocument; 5278 5279 // Reenable scripts 5280 jQuery.map( scripts, restoreScript ); 5281 5282 // Evaluate executable scripts on first document insertion 5283 for ( i = 0; i < hasScripts; i++ ) { 5284 node = scripts[ i ]; 5285 if ( rscriptType.test( node.type || "" ) && 5286 !dataPriv.access( node, "globalEval" ) && 5287 jQuery.contains( doc, node ) ) { 5288 5289 if ( node.src ) { 5290 5291 // Optional AJAX dependency, but won't run scripts if not present 5292 if ( jQuery._evalUrl ) { 5293 jQuery._evalUrl( node.src ); 5294 } 5295 } else { 5296 jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); 5297 } 5298 } 5299 } 5300 } 5301 } 5302 } 5303 5304 return collection; 5305} 5306 5307function remove( elem, selector, keepData ) { 5308 var node, 5309 nodes = selector ? jQuery.filter( selector, elem ) : elem, 5310 i = 0; 5311 5312 for ( ; ( node = nodes[ i ] ) != null; i++ ) { 5313 if ( !keepData && node.nodeType === 1 ) { 5314 jQuery.cleanData( getAll( node ) ); 5315 } 5316 5317 if ( node.parentNode ) { 5318 if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { 5319 setGlobalEval( getAll( node, "script" ) ); 5320 } 5321 node.parentNode.removeChild( node ); 5322 } 5323 } 5324 5325 return elem; 5326} 5327 5328jQuery.extend( { 5329 htmlPrefilter: function( html ) { 5330 return html.replace( rxhtmlTag, "<$1></$2>" ); 5331 }, 5332 5333 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 5334 var i, l, srcElements, destElements, 5335 clone = elem.cloneNode( true ), 5336 inPage = jQuery.contains( elem.ownerDocument, elem ); 5337 5338 // Fix IE cloning issues 5339 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && 5340 !jQuery.isXMLDoc( elem ) ) { 5341 5342 // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 5343 destElements = getAll( clone ); 5344 srcElements = getAll( elem ); 5345 5346 for ( i = 0, l = srcElements.length; i < l; i++ ) { 5347 fixInput( srcElements[ i ], destElements[ i ] ); 5348 } 5349 } 5350 5351 // Copy the events from the original to the clone 5352 if ( dataAndEvents ) { 5353 if ( deepDataAndEvents ) { 5354 srcElements = srcElements || getAll( elem ); 5355 destElements = destElements || getAll( clone ); 5356 5357 for ( i = 0, l = srcElements.length; i < l; i++ ) { 5358 cloneCopyEvent( srcElements[ i ], destElements[ i ] ); 5359 } 5360 } else { 5361 cloneCopyEvent( elem, clone ); 5362 } 5363 } 5364 5365 // Preserve script evaluation history 5366 destElements = getAll( clone, "script" ); 5367 if ( destElements.length > 0 ) { 5368 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); 5369 } 5370 5371 // Return the cloned set 5372 return clone; 5373 }, 5374 5375 cleanData: function( elems ) { 5376 var data, elem, type, 5377 special = jQuery.event.special, 5378 i = 0; 5379 5380 for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { 5381 if ( acceptData( elem ) ) { 5382 if ( ( data = elem[ dataPriv.expando ] ) ) { 5383 if ( data.events ) { 5384 for ( type in data.events ) { 5385 if ( special[ type ] ) { 5386 jQuery.event.remove( elem, type ); 5387 5388 // This is a shortcut to avoid jQuery.event.remove's overhead 5389 } else { 5390 jQuery.removeEvent( elem, type, data.handle ); 5391 } 5392 } 5393 } 5394 5395 // Support: Chrome <= 35-45+ 5396 // Assign undefined instead of using delete, see Data#remove 5397 elem[ dataPriv.expando ] = undefined; 5398 } 5399 if ( elem[ dataUser.expando ] ) { 5400 5401 // Support: Chrome <= 35-45+ 5402 // Assign undefined instead of using delete, see Data#remove 5403 elem[ dataUser.expando ] = undefined; 5404 } 5405 } 5406 } 5407 } 5408} ); 5409 5410jQuery.fn.extend( { 5411 5412 // Keep domManip exposed until 3.0 (gh-2225) 5413 domManip: domManip, 5414 5415 detach: function( selector ) { 5416 return remove( this, selector, true ); 5417 }, 5418 5419 remove: function( selector ) { 5420 return remove( this, selector ); 5421 }, 5422 5423 text: function( value ) { 5424 return access( this, function( value ) { 5425 return value === undefined ? 5426 jQuery.text( this ) : 5427 this.empty().each( function() { 5428 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 5429 this.textContent = value; 5430 } 5431 } ); 5432 }, null, value, arguments.length ); 5433 }, 5434 5435 append: function() { 5436 return domManip( this, arguments, function( elem ) { 5437 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 5438 var target = manipulationTarget( this, elem ); 5439 target.appendChild( elem ); 5440 } 5441 } ); 5442 }, 5443 5444 prepend: function() { 5445 return domManip( this, arguments, function( elem ) { 5446 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 5447 var target = manipulationTarget( this, elem ); 5448 target.insertBefore( elem, target.firstChild ); 5449 } 5450 } ); 5451 }, 5452 5453 before: function() { 5454 return domManip( this, arguments, function( elem ) { 5455 if ( this.parentNode ) { 5456 this.parentNode.insertBefore( elem, this ); 5457 } 5458 } ); 5459 }, 5460 5461 after: function() { 5462 return domManip( this, arguments, function( elem ) { 5463 if ( this.parentNode ) { 5464 this.parentNode.insertBefore( elem, this.nextSibling ); 5465 } 5466 } ); 5467 }, 5468 5469 empty: function() { 5470 var elem, 5471 i = 0; 5472 5473 for ( ; ( elem = this[ i ] ) != null; i++ ) { 5474 if ( elem.nodeType === 1 ) { 5475 5476 // Prevent memory leaks 5477 jQuery.cleanData( getAll( elem, false ) ); 5478 5479 // Remove any remaining nodes 5480 elem.textContent = ""; 5481 } 5482 } 5483 5484 return this; 5485 }, 5486 5487 clone: function( dataAndEvents, deepDataAndEvents ) { 5488 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 5489 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 5490 5491 return this.map( function() { 5492 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 5493 } ); 5494 }, 5495 5496 html: function( value ) { 5497 return access( this, function( value ) { 5498 var elem = this[ 0 ] || {}, 5499 i = 0, 5500 l = this.length; 5501 5502 if ( value === undefined && elem.nodeType === 1 ) { 5503 return elem.innerHTML; 5504 } 5505 5506 // See if we can take a shortcut and just use innerHTML 5507 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && 5508 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { 5509 5510 value = jQuery.htmlPrefilter( value ); 5511 5512 try { 5513 for ( ; i < l; i++ ) { 5514 elem = this[ i ] || {}; 5515 5516 // Remove element nodes and prevent memory leaks 5517 if ( elem.nodeType === 1 ) { 5518 jQuery.cleanData( getAll( elem, false ) ); 5519 elem.innerHTML = value; 5520 } 5521 } 5522 5523 elem = 0; 5524 5525 // If using innerHTML throws an exception, use the fallback method 5526 } catch ( e ) {} 5527 } 5528 5529 if ( elem ) { 5530 this.empty().append( value ); 5531 } 5532 }, null, value, arguments.length ); 5533 }, 5534 5535 replaceWith: function() { 5536 var ignored = []; 5537 5538 // Make the changes, replacing each non-ignored context element with the new content 5539 return domManip( this, arguments, function( elem ) { 5540 var parent = this.parentNode; 5541 5542 if ( jQuery.inArray( this, ignored ) < 0 ) { 5543 jQuery.cleanData( getAll( this ) ); 5544 if ( parent ) { 5545 parent.replaceChild( elem, this ); 5546 } 5547 } 5548 5549 // Force callback invocation 5550 }, ignored ); 5551 } 5552} ); 5553 5554jQuery.each( { 5555 appendTo: "append", 5556 prependTo: "prepend", 5557 insertBefore: "before", 5558 insertAfter: "after", 5559 replaceAll: "replaceWith" 5560}, function( name, original ) { 5561 jQuery.fn[ name ] = function( selector ) { 5562 var elems, 5563 ret = [], 5564 insert = jQuery( selector ), 5565 last = insert.length - 1, 5566 i = 0; 5567 5568 for ( ; i <= last; i++ ) { 5569 elems = i === last ? this : this.clone( true ); 5570 jQuery( insert[ i ] )[ original ]( elems ); 5571 5572 // Support: QtWebKit 5573 // .get() because push.apply(_, arraylike) throws 5574 push.apply( ret, elems.get() ); 5575 } 5576 5577 return this.pushStack( ret ); 5578 }; 5579} ); 5580 5581 5582var iframe, 5583 elemdisplay = { 5584 5585 // Support: Firefox 5586 // We have to pre-define these values for FF (#10227) 5587 HTML: "block", 5588 BODY: "block" 5589 }; 5590 5591/** 5592 * Retrieve the actual display of a element 5593 * @param {String} name nodeName of the element 5594 * @param {Object} doc Document object 5595 */ 5596 5597// Called only from within defaultDisplay 5598function actualDisplay( name, doc ) { 5599 var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), 5600 5601 display = jQuery.css( elem[ 0 ], "display" ); 5602 5603 // We don't have any data stored on the element, 5604 // so use "detach" method as fast way to get rid of the element 5605 elem.detach(); 5606 5607 return display; 5608} 5609 5610/** 5611 * Try to determine the default display value of an element 5612 * @param {String} nodeName 5613 */ 5614function defaultDisplay( nodeName ) { 5615 var doc = document, 5616 display = elemdisplay[ nodeName ]; 5617 5618 if ( !display ) { 5619 display = actualDisplay( nodeName, doc ); 5620 5621 // If the simple way fails, read from inside an iframe 5622 if ( display === "none" || !display ) { 5623 5624 // Use the already-created iframe if possible 5625 iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) ) 5626 .appendTo( doc.documentElement ); 5627 5628 // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse 5629 doc = iframe[ 0 ].contentDocument; 5630 5631 // Support: IE 5632 doc.write(); 5633 doc.close(); 5634 5635 display = actualDisplay( nodeName, doc ); 5636 iframe.detach(); 5637 } 5638 5639 // Store the correct default display 5640 elemdisplay[ nodeName ] = display; 5641 } 5642 5643 return display; 5644} 5645var rmargin = ( /^margin/ ); 5646 5647var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); 5648 5649var getStyles = function( elem ) { 5650 5651 // Support: IE<=11+, Firefox<=30+ (#15098, #14150) 5652 // IE throws on elements created in popups 5653 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" 5654 var view = elem.ownerDocument.defaultView; 5655 5656 if ( !view || !view.opener ) { 5657 view = window; 5658 } 5659 5660 return view.getComputedStyle( elem ); 5661 }; 5662 5663var swap = function( elem, options, callback, args ) { 5664 var ret, name, 5665 old = {}; 5666 5667 // Remember the old values, and insert the new ones 5668 for ( name in options ) { 5669 old[ name ] = elem.style[ name ]; 5670 elem.style[ name ] = options[ name ]; 5671 } 5672 5673 ret = callback.apply( elem, args || [] ); 5674 5675 // Revert the old values 5676 for ( name in options ) { 5677 elem.style[ name ] = old[ name ]; 5678 } 5679 5680 return ret; 5681}; 5682 5683 5684var documentElement = document.documentElement; 5685 5686 5687 5688( function() { 5689 var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal, 5690 container = document.createElement( "div" ), 5691 div = document.createElement( "div" ); 5692 5693 // Finish early in limited (non-browser) environments 5694 if ( !div.style ) { 5695 return; 5696 } 5697 5698 // Support: IE9-11+ 5699 // Style of cloned element affects source element cloned (#8908) 5700 div.style.backgroundClip = "content-box"; 5701 div.cloneNode( true ).style.backgroundClip = ""; 5702 support.clearCloneStyle = div.style.backgroundClip === "content-box"; 5703 5704 container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" + 5705 "padding:0;margin-top:1px;position:absolute"; 5706 container.appendChild( div ); 5707 5708 // Executing both pixelPosition & boxSizingReliable tests require only one layout 5709 // so they're executed at the same time to save the second computation. 5710 function computeStyleTests() { 5711 div.style.cssText = 5712 5713 // Support: Firefox<29, Android 2.3 5714 // Vendor-prefix box-sizing 5715 "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;" + 5716 "position:relative;display:block;" + 5717 "margin:auto;border:1px;padding:1px;" + 5718 "top:1%;width:50%"; 5719 div.innerHTML = ""; 5720 documentElement.appendChild( container ); 5721 5722 var divStyle = window.getComputedStyle( div ); 5723 pixelPositionVal = divStyle.top !== "1%"; 5724 reliableMarginLeftVal = divStyle.marginLeft === "2px"; 5725 boxSizingReliableVal = divStyle.width === "4px"; 5726 5727 // Support: Android 4.0 - 4.3 only 5728 // Some styles come back with percentage values, even though they shouldn't 5729 div.style.marginRight = "50%"; 5730 pixelMarginRightVal = divStyle.marginRight === "4px"; 5731 5732 documentElement.removeChild( container ); 5733 } 5734 5735 jQuery.extend( support, { 5736 pixelPosition: function() { 5737 5738 // This test is executed only once but we still do memoizing 5739 // since we can use the boxSizingReliable pre-computing. 5740 // No need to check if the test was already performed, though. 5741 computeStyleTests(); 5742 return pixelPositionVal; 5743 }, 5744 boxSizingReliable: function() { 5745 if ( boxSizingReliableVal == null ) { 5746 computeStyleTests(); 5747 } 5748 return boxSizingReliableVal; 5749 }, 5750 pixelMarginRight: function() { 5751 5752 // Support: Android 4.0-4.3 5753 // We're checking for boxSizingReliableVal here instead of pixelMarginRightVal 5754 // since that compresses better and they're computed together anyway. 5755 if ( boxSizingReliableVal == null ) { 5756 computeStyleTests(); 5757 } 5758 return pixelMarginRightVal; 5759 }, 5760 reliableMarginLeft: function() { 5761 5762 // Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37 5763 if ( boxSizingReliableVal == null ) { 5764 computeStyleTests(); 5765 } 5766 return reliableMarginLeftVal; 5767 }, 5768 reliableMarginRight: function() { 5769 5770 // Support: Android 2.3 5771 // Check if div with explicit width and no margin-right incorrectly 5772 // gets computed margin-right based on width of container. (#3333) 5773 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right 5774 // This support function is only executed once so no memoizing is needed. 5775 var ret, 5776 marginDiv = div.appendChild( document.createElement( "div" ) ); 5777 5778 // Reset CSS: box-sizing; display; margin; border; padding 5779 marginDiv.style.cssText = div.style.cssText = 5780 5781 // Support: Android 2.3 5782 // Vendor-prefix box-sizing 5783 "-webkit-box-sizing:content-box;box-sizing:content-box;" + 5784 "display:block;margin:0;border:0;padding:0"; 5785 marginDiv.style.marginRight = marginDiv.style.width = "0"; 5786 div.style.width = "1px"; 5787 documentElement.appendChild( container ); 5788 5789 ret = !parseFloat( window.getComputedStyle( marginDiv ).marginRight ); 5790 5791 documentElement.removeChild( container ); 5792 div.removeChild( marginDiv ); 5793 5794 return ret; 5795 } 5796 } ); 5797} )(); 5798 5799 5800function curCSS( elem, name, computed ) { 5801 var width, minWidth, maxWidth, ret, 5802 style = elem.style; 5803 5804 computed = computed || getStyles( elem ); 5805 ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined; 5806 5807 // Support: Opera 12.1x only 5808 // Fall back to style even without computed 5809 // computed is undefined for elems on document fragments 5810 if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) { 5811 ret = jQuery.style( elem, name ); 5812 } 5813 5814 // Support: IE9 5815 // getPropertyValue is only needed for .css('filter') (#12537) 5816 if ( computed ) { 5817 5818 // A tribute to the "awesome hack by Dean Edwards" 5819 // Android Browser returns percentage for some values, 5820 // but width seems to be reliably pixels. 5821 // This is against the CSSOM draft spec: 5822 // http://dev.w3.org/csswg/cssom/#resolved-values 5823 if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) { 5824 5825 // Remember the original values 5826 width = style.width; 5827 minWidth = style.minWidth; 5828 maxWidth = style.maxWidth; 5829 5830 // Put in the new values to get a computed value out 5831 style.minWidth = style.maxWidth = style.width = ret; 5832 ret = computed.width; 5833 5834 // Revert the changed values 5835 style.width = width; 5836 style.minWidth = minWidth; 5837 style.maxWidth = maxWidth; 5838 } 5839 } 5840 5841 return ret !== undefined ? 5842 5843 // Support: IE9-11+ 5844 // IE returns zIndex value as an integer. 5845 ret + "" : 5846 ret; 5847} 5848 5849 5850function addGetHookIf( conditionFn, hookFn ) { 5851 5852 // Define the hook, we'll check on the first run if it's really needed. 5853 return { 5854 get: function() { 5855 if ( conditionFn() ) { 5856 5857 // Hook not needed (or it's not possible to use it due 5858 // to missing dependency), remove it. 5859 delete this.get; 5860 return; 5861 } 5862 5863 // Hook needed; redefine it so that the support test is not executed again. 5864 return ( this.get = hookFn ).apply( this, arguments ); 5865 } 5866 }; 5867} 5868 5869 5870var 5871 5872 // Swappable if display is none or starts with table 5873 // except "table", "table-cell", or "table-caption" 5874 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display 5875 rdisplayswap = /^(none|table(?!-c[ea]).+)/, 5876 5877 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 5878 cssNormalTransform = { 5879 letterSpacing: "0", 5880 fontWeight: "400" 5881 }, 5882 5883 cssPrefixes = [ "Webkit", "O", "Moz", "ms" ], 5884 emptyStyle = document.createElement( "div" ).style; 5885 5886// Return a css property mapped to a potentially vendor prefixed property 5887function vendorPropName( name ) { 5888 5889 // Shortcut for names that are not vendor prefixed 5890 if ( name in emptyStyle ) { 5891 return name; 5892 } 5893 5894 // Check for vendor prefixed names 5895 var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), 5896 i = cssPrefixes.length; 5897 5898 while ( i-- ) { 5899 name = cssPrefixes[ i ] + capName; 5900 if ( name in emptyStyle ) { 5901 return name; 5902 } 5903 } 5904} 5905 5906function setPositiveNumber( elem, value, subtract ) { 5907 5908 // Any relative (+/-) values have already been 5909 // normalized at this point 5910 var matches = rcssNum.exec( value ); 5911 return matches ? 5912 5913 // Guard against undefined "subtract", e.g., when used as in cssHooks 5914 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : 5915 value; 5916} 5917 5918function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { 5919 var i = extra === ( isBorderBox ? "border" : "content" ) ? 5920 5921 // If we already have the right measurement, avoid augmentation 5922 4 : 5923 5924 // Otherwise initialize for horizontal or vertical properties 5925 name === "width" ? 1 : 0, 5926 5927 val = 0; 5928 5929 for ( ; i < 4; i += 2 ) { 5930 5931 // Both box models exclude margin, so add it if we want it 5932 if ( extra === "margin" ) { 5933 val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); 5934 } 5935 5936 if ( isBorderBox ) { 5937 5938 // border-box includes padding, so remove it if we want content 5939 if ( extra === "content" ) { 5940 val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 5941 } 5942 5943 // At this point, extra isn't border nor margin, so remove border 5944 if ( extra !== "margin" ) { 5945 val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 5946 } 5947 } else { 5948 5949 // At this point, extra isn't content, so add padding 5950 val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 5951 5952 // At this point, extra isn't content nor padding, so add border 5953 if ( extra !== "padding" ) { 5954 val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 5955 } 5956 } 5957 } 5958 5959 return val; 5960} 5961 5962function getWidthOrHeight( elem, name, extra ) { 5963 5964 // Start with offset property, which is equivalent to the border-box value 5965 var valueIsBorderBox = true, 5966 val = name === "width" ? elem.offsetWidth : elem.offsetHeight, 5967 styles = getStyles( elem ), 5968 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; 5969 5970 // Some non-html elements return undefined for offsetWidth, so check for null/undefined 5971 // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 5972 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 5973 if ( val <= 0 || val == null ) { 5974 5975 // Fall back to computed then uncomputed css if necessary 5976 val = curCSS( elem, name, styles ); 5977 if ( val < 0 || val == null ) { 5978 val = elem.style[ name ]; 5979 } 5980 5981 // Computed unit is not pixels. Stop here and return. 5982 if ( rnumnonpx.test( val ) ) { 5983 return val; 5984 } 5985 5986 // Check for style in case a browser which returns unreliable values 5987 // for getComputedStyle silently falls back to the reliable elem.style 5988 valueIsBorderBox = isBorderBox && 5989 ( support.boxSizingReliable() || val === elem.style[ name ] ); 5990 5991 // Normalize "", auto, and prepare for extra 5992 val = parseFloat( val ) || 0; 5993 } 5994 5995 // Use the active box-sizing model to add/subtract irrelevant styles 5996 return ( val + 5997 augmentWidthOrHeight( 5998 elem, 5999 name, 6000 extra || ( isBorderBox ? "border" : "content" ), 6001 valueIsBorderBox, 6002 styles 6003 ) 6004 ) + "px"; 6005} 6006 6007function showHide( elements, show ) { 6008 var display, elem, hidden, 6009 values = [], 6010 index = 0, 6011 length = elements.length; 6012 6013 for ( ; index < length; index++ ) { 6014 elem = elements[ index ]; 6015 if ( !elem.style ) { 6016 continue; 6017 } 6018 6019 values[ index ] = dataPriv.get( elem, "olddisplay" ); 6020 display = elem.style.display; 6021 if ( show ) { 6022 6023 // Reset the inline display of this element to learn if it is 6024 // being hidden by cascaded rules or not 6025 if ( !values[ index ] && display === "none" ) { 6026 elem.style.display = ""; 6027 } 6028 6029 // Set elements which have been overridden with display: none 6030 // in a stylesheet to whatever the default browser style is 6031 // for such an element 6032 if ( elem.style.display === "" && isHidden( elem ) ) { 6033 values[ index ] = dataPriv.access( 6034 elem, 6035 "olddisplay", 6036 defaultDisplay( elem.nodeName ) 6037 ); 6038 } 6039 } else { 6040 hidden = isHidden( elem ); 6041 6042 if ( display !== "none" || !hidden ) { 6043 dataPriv.set( 6044 elem, 6045 "olddisplay", 6046 hidden ? display : jQuery.css( elem, "display" ) 6047 ); 6048 } 6049 } 6050 } 6051 6052 // Set the display of most of the elements in a second loop 6053 // to avoid the constant reflow 6054 for ( index = 0; index < length; index++ ) { 6055 elem = elements[ index ]; 6056 if ( !elem.style ) { 6057 continue; 6058 } 6059 if ( !show || elem.style.display === "none" || elem.style.display === "" ) { 6060 elem.style.display = show ? values[ index ] || "" : "none"; 6061 } 6062 } 6063 6064 return elements; 6065} 6066 6067jQuery.extend( { 6068 6069 // Add in style property hooks for overriding the default 6070 // behavior of getting and setting a style property 6071 cssHooks: { 6072 opacity: { 6073 get: function( elem, computed ) { 6074 if ( computed ) { 6075 6076 // We should always get a number back from opacity 6077 var ret = curCSS( elem, "opacity" ); 6078 return ret === "" ? "1" : ret; 6079 } 6080 } 6081 } 6082 }, 6083 6084 // Don't automatically add "px" to these possibly-unitless properties 6085 cssNumber: { 6086 "animationIterationCount": true, 6087 "columnCount": true, 6088 "fillOpacity": true, 6089 "flexGrow": true, 6090 "flexShrink": true, 6091 "fontWeight": true, 6092 "lineHeight": true, 6093 "opacity": true, 6094 "order": true, 6095 "orphans": true, 6096 "widows": true, 6097 "zIndex": true, 6098 "zoom": true 6099 }, 6100 6101 // Add in properties whose names you wish to fix before 6102 // setting or getting the value 6103 cssProps: { 6104 "float": "cssFloat" 6105 }, 6106 6107 // Get and set the style property on a DOM Node 6108 style: function( elem, name, value, extra ) { 6109 6110 // Don't set styles on text and comment nodes 6111 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 6112 return; 6113 } 6114 6115 // Make sure that we're working with the right name 6116 var ret, type, hooks, 6117 origName = jQuery.camelCase( name ), 6118 style = elem.style; 6119 6120 name = jQuery.cssProps[ origName ] || 6121 ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName ); 6122 6123 // Gets hook for the prefixed version, then unprefixed version 6124 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 6125 6126 // Check if we're setting a value 6127 if ( value !== undefined ) { 6128 type = typeof value; 6129 6130 // Convert "+=" or "-=" to relative numbers (#7345) 6131 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { 6132 value = adjustCSS( elem, name, ret ); 6133 6134 // Fixes bug #9237 6135 type = "number"; 6136 } 6137 6138 // Make sure that null and NaN values aren't set (#7116) 6139 if ( value == null || value !== value ) { 6140 return; 6141 } 6142 6143 // If a number was passed in, add the unit (except for certain CSS properties) 6144 if ( type === "number" ) { 6145 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); 6146 } 6147 6148 // Support: IE9-11+ 6149 // background-* props affect original clone's values 6150 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { 6151 style[ name ] = "inherit"; 6152 } 6153 6154 // If a hook was provided, use that value, otherwise just set the specified value 6155 if ( !hooks || !( "set" in hooks ) || 6156 ( value = hooks.set( elem, value, extra ) ) !== undefined ) { 6157 6158 style[ name ] = value; 6159 } 6160 6161 } else { 6162 6163 // If a hook was provided get the non-computed value from there 6164 if ( hooks && "get" in hooks && 6165 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { 6166 6167 return ret; 6168 } 6169 6170 // Otherwise just get the value from the style object 6171 return style[ name ]; 6172 } 6173 }, 6174 6175 css: function( elem, name, extra, styles ) { 6176 var val, num, hooks, 6177 origName = jQuery.camelCase( name ); 6178 6179 // Make sure that we're working with the right name 6180 name = jQuery.cssProps[ origName ] || 6181 ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName ); 6182 6183 // Try prefixed name followed by the unprefixed name 6184 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 6185 6186 // If a hook was provided get the computed value from there 6187 if ( hooks && "get" in hooks ) { 6188 val = hooks.get( elem, true, extra ); 6189 } 6190 6191 // Otherwise, if a way to get the computed value exists, use that 6192 if ( val === undefined ) { 6193 val = curCSS( elem, name, styles ); 6194 } 6195 6196 // Convert "normal" to computed value 6197 if ( val === "normal" && name in cssNormalTransform ) { 6198 val = cssNormalTransform[ name ]; 6199 } 6200 6201 // Make numeric if forced or a qualifier was provided and val looks numeric 6202 if ( extra === "" || extra ) { 6203 num = parseFloat( val ); 6204 return extra === true || isFinite( num ) ? num || 0 : val; 6205 } 6206 return val; 6207 } 6208} ); 6209 6210jQuery.each( [ "height", "width" ], function( i, name ) { 6211 jQuery.cssHooks[ name ] = { 6212 get: function( elem, computed, extra ) { 6213 if ( computed ) { 6214 6215 // Certain elements can have dimension info if we invisibly show them 6216 // but it must have a current display style that would benefit 6217 return rdisplayswap.test( jQuery.css( elem, "display" ) ) && 6218 elem.offsetWidth === 0 ? 6219 swap( elem, cssShow, function() { 6220 return getWidthOrHeight( elem, name, extra ); 6221 } ) : 6222 getWidthOrHeight( elem, name, extra ); 6223 } 6224 }, 6225 6226 set: function( elem, value, extra ) { 6227 var matches, 6228 styles = extra && getStyles( elem ), 6229 subtract = extra && augmentWidthOrHeight( 6230 elem, 6231 name, 6232 extra, 6233 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 6234 styles 6235 ); 6236 6237 // Convert to pixels if value adjustment is needed 6238 if ( subtract && ( matches = rcssNum.exec( value ) ) && 6239 ( matches[ 3 ] || "px" ) !== "px" ) { 6240 6241 elem.style[ name ] = value; 6242 value = jQuery.css( elem, name ); 6243 } 6244 6245 return setPositiveNumber( elem, value, subtract ); 6246 } 6247 }; 6248} ); 6249 6250jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, 6251 function( elem, computed ) { 6252 if ( computed ) { 6253 return ( parseFloat( curCSS( elem, "marginLeft" ) ) || 6254 elem.getBoundingClientRect().left - 6255 swap( elem, { marginLeft: 0 }, function() { 6256 return elem.getBoundingClientRect().left; 6257 } ) 6258 ) + "px"; 6259 } 6260 } 6261); 6262 6263// Support: Android 2.3 6264jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight, 6265 function( elem, computed ) { 6266 if ( computed ) { 6267 return swap( elem, { "display": "inline-block" }, 6268 curCSS, [ elem, "marginRight" ] ); 6269 } 6270 } 6271); 6272 6273// These hooks are used by animate to expand properties 6274jQuery.each( { 6275 margin: "", 6276 padding: "", 6277 border: "Width" 6278}, function( prefix, suffix ) { 6279 jQuery.cssHooks[ prefix + suffix ] = { 6280 expand: function( value ) { 6281 var i = 0, 6282 expanded = {}, 6283 6284 // Assumes a single number if not a string 6285 parts = typeof value === "string" ? value.split( " " ) : [ value ]; 6286 6287 for ( ; i < 4; i++ ) { 6288 expanded[ prefix + cssExpand[ i ] + suffix ] = 6289 parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; 6290 } 6291 6292 return expanded; 6293 } 6294 }; 6295 6296 if ( !rmargin.test( prefix ) ) { 6297 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; 6298 } 6299} ); 6300 6301jQuery.fn.extend( { 6302 css: function( name, value ) { 6303 return access( this, function( elem, name, value ) { 6304 var styles, len, 6305 map = {}, 6306 i = 0; 6307 6308 if ( jQuery.isArray( name ) ) { 6309 styles = getStyles( elem ); 6310 len = name.length; 6311 6312 for ( ; i < len; i++ ) { 6313 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); 6314 } 6315 6316 return map; 6317 } 6318 6319 return value !== undefined ? 6320 jQuery.style( elem, name, value ) : 6321 jQuery.css( elem, name ); 6322 }, name, value, arguments.length > 1 ); 6323 }, 6324 show: function() { 6325 return showHide( this, true ); 6326 }, 6327 hide: function() { 6328 return showHide( this ); 6329 }, 6330 toggle: function( state ) { 6331 if ( typeof state === "boolean" ) { 6332 return state ? this.show() : this.hide(); 6333 } 6334 6335 return this.each( function() { 6336 if ( isHidden( this ) ) { 6337 jQuery( this ).show(); 6338 } else { 6339 jQuery( this ).hide(); 6340 } 6341 } ); 6342 } 6343} ); 6344 6345 6346function Tween( elem, options, prop, end, easing ) { 6347 return new Tween.prototype.init( elem, options, prop, end, easing ); 6348} 6349jQuery.Tween = Tween; 6350 6351Tween.prototype = { 6352 constructor: Tween, 6353 init: function( elem, options, prop, end, easing, unit ) { 6354 this.elem = elem; 6355 this.prop = prop; 6356 this.easing = easing || jQuery.easing._default; 6357 this.options = options; 6358 this.start = this.now = this.cur(); 6359 this.end = end; 6360 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); 6361 }, 6362 cur: function() { 6363 var hooks = Tween.propHooks[ this.prop ]; 6364 6365 return hooks && hooks.get ? 6366 hooks.get( this ) : 6367 Tween.propHooks._default.get( this ); 6368 }, 6369 run: function( percent ) { 6370 var eased, 6371 hooks = Tween.propHooks[ this.prop ]; 6372 6373 if ( this.options.duration ) { 6374 this.pos = eased = jQuery.easing[ this.easing ]( 6375 percent, this.options.duration * percent, 0, 1, this.options.duration 6376 ); 6377 } else { 6378 this.pos = eased = percent; 6379 } 6380 this.now = ( this.end - this.start ) * eased + this.start; 6381 6382 if ( this.options.step ) { 6383 this.options.step.call( this.elem, this.now, this ); 6384 } 6385 6386 if ( hooks && hooks.set ) { 6387 hooks.set( this ); 6388 } else { 6389 Tween.propHooks._default.set( this ); 6390 } 6391 return this; 6392 } 6393}; 6394 6395Tween.prototype.init.prototype = Tween.prototype; 6396 6397Tween.propHooks = { 6398 _default: { 6399 get: function( tween ) { 6400 var result; 6401 6402 // Use a property on the element directly when it is not a DOM element, 6403 // or when there is no matching style property that exists. 6404 if ( tween.elem.nodeType !== 1 || 6405 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { 6406 return tween.elem[ tween.prop ]; 6407 } 6408 6409 // Passing an empty string as a 3rd parameter to .css will automatically 6410 // attempt a parseFloat and fallback to a string if the parse fails. 6411 // Simple values such as "10px" are parsed to Float; 6412 // complex values such as "rotate(1rad)" are returned as-is. 6413 result = jQuery.css( tween.elem, tween.prop, "" ); 6414 6415 // Empty strings, null, undefined and "auto" are converted to 0. 6416 return !result || result === "auto" ? 0 : result; 6417 }, 6418 set: function( tween ) { 6419 6420 // Use step hook for back compat. 6421 // Use cssHook if its there. 6422 // Use .style if available and use plain properties where available. 6423 if ( jQuery.fx.step[ tween.prop ] ) { 6424 jQuery.fx.step[ tween.prop ]( tween ); 6425 } else if ( tween.elem.nodeType === 1 && 6426 ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || 6427 jQuery.cssHooks[ tween.prop ] ) ) { 6428 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); 6429 } else { 6430 tween.elem[ tween.prop ] = tween.now; 6431 } 6432 } 6433 } 6434}; 6435 6436// Support: IE9 6437// Panic based approach to setting things on disconnected nodes 6438Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { 6439 set: function( tween ) { 6440 if ( tween.elem.nodeType && tween.elem.parentNode ) { 6441 tween.elem[ tween.prop ] = tween.now; 6442 } 6443 } 6444}; 6445 6446jQuery.easing = { 6447 linear: function( p ) { 6448 return p; 6449 }, 6450 swing: function( p ) { 6451 return 0.5 - Math.cos( p * Math.PI ) / 2; 6452 }, 6453 _default: "swing" 6454}; 6455 6456jQuery.fx = Tween.prototype.init; 6457 6458// Back Compat <1.8 extension point 6459jQuery.fx.step = {}; 6460 6461 6462 6463 6464var 6465 fxNow, timerId, 6466 rfxtypes = /^(?:toggle|show|hide)$/, 6467 rrun = /queueHooks$/; 6468 6469// Animations created synchronously will run synchronously 6470function createFxNow() { 6471 window.setTimeout( function() { 6472 fxNow = undefined; 6473 } ); 6474 return ( fxNow = jQuery.now() ); 6475} 6476 6477// Generate parameters to create a standard animation 6478function genFx( type, includeWidth ) { 6479 var which, 6480 i = 0, 6481 attrs = { height: type }; 6482 6483 // If we include width, step value is 1 to do all cssExpand values, 6484 // otherwise step value is 2 to skip over Left and Right 6485 includeWidth = includeWidth ? 1 : 0; 6486 for ( ; i < 4 ; i += 2 - includeWidth ) { 6487 which = cssExpand[ i ]; 6488 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; 6489 } 6490 6491 if ( includeWidth ) { 6492 attrs.opacity = attrs.width = type; 6493 } 6494 6495 return attrs; 6496} 6497 6498function createTween( value, prop, animation ) { 6499 var tween, 6500 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), 6501 index = 0, 6502 length = collection.length; 6503 for ( ; index < length; index++ ) { 6504 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { 6505 6506 // We're done with this property 6507 return tween; 6508 } 6509 } 6510} 6511 6512function defaultPrefilter( elem, props, opts ) { 6513 /* jshint validthis: true */ 6514 var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay, 6515 anim = this, 6516 orig = {}, 6517 style = elem.style, 6518 hidden = elem.nodeType && isHidden( elem ), 6519 dataShow = dataPriv.get( elem, "fxshow" ); 6520 6521 // Handle queue: false promises 6522 if ( !opts.queue ) { 6523 hooks = jQuery._queueHooks( elem, "fx" ); 6524 if ( hooks.unqueued == null ) { 6525 hooks.unqueued = 0; 6526 oldfire = hooks.empty.fire; 6527 hooks.empty.fire = function() { 6528 if ( !hooks.unqueued ) { 6529 oldfire(); 6530 } 6531 }; 6532 } 6533 hooks.unqueued++; 6534 6535 anim.always( function() { 6536 6537 // Ensure the complete handler is called before this completes 6538 anim.always( function() { 6539 hooks.unqueued--; 6540 if ( !jQuery.queue( elem, "fx" ).length ) { 6541 hooks.empty.fire(); 6542 } 6543 } ); 6544 } ); 6545 } 6546 6547 // Height/width overflow pass 6548 if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { 6549 6550 // Make sure that nothing sneaks out 6551 // Record all 3 overflow attributes because IE9-10 do not 6552 // change the overflow attribute when overflowX and 6553 // overflowY are set to the same value 6554 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; 6555 6556 // Set display property to inline-block for height/width 6557 // animations on inline elements that are having width/height animated 6558 display = jQuery.css( elem, "display" ); 6559 6560 // Test default display if display is currently "none" 6561 checkDisplay = display === "none" ? 6562 dataPriv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display; 6563 6564 if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) { 6565 style.display = "inline-block"; 6566 } 6567 } 6568 6569 if ( opts.overflow ) { 6570 style.overflow = "hidden"; 6571 anim.always( function() { 6572 style.overflow = opts.overflow[ 0 ]; 6573 style.overflowX = opts.overflow[ 1 ]; 6574 style.overflowY = opts.overflow[ 2 ]; 6575 } ); 6576 } 6577 6578 // show/hide pass 6579 for ( prop in props ) { 6580 value = props[ prop ]; 6581 if ( rfxtypes.exec( value ) ) { 6582 delete props[ prop ]; 6583 toggle = toggle || value === "toggle"; 6584 if ( value === ( hidden ? "hide" : "show" ) ) { 6585 6586 // If there is dataShow left over from a stopped hide or show 6587 // and we are going to proceed with show, we should pretend to be hidden 6588 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { 6589 hidden = true; 6590 } else { 6591 continue; 6592 } 6593 } 6594 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); 6595 6596 // Any non-fx value stops us from restoring the original display value 6597 } else { 6598 display = undefined; 6599 } 6600 } 6601 6602 if ( !jQuery.isEmptyObject( orig ) ) { 6603 if ( dataShow ) { 6604 if ( "hidden" in dataShow ) { 6605 hidden = dataShow.hidden; 6606 } 6607 } else { 6608 dataShow = dataPriv.access( elem, "fxshow", {} ); 6609 } 6610 6611 // Store state if its toggle - enables .stop().toggle() to "reverse" 6612 if ( toggle ) { 6613 dataShow.hidden = !hidden; 6614 } 6615 if ( hidden ) { 6616 jQuery( elem ).show(); 6617 } else { 6618 anim.done( function() { 6619 jQuery( elem ).hide(); 6620 } ); 6621 } 6622 anim.done( function() { 6623 var prop; 6624 6625 dataPriv.remove( elem, "fxshow" ); 6626 for ( prop in orig ) { 6627 jQuery.style( elem, prop, orig[ prop ] ); 6628 } 6629 } ); 6630 for ( prop in orig ) { 6631 tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); 6632 6633 if ( !( prop in dataShow ) ) { 6634 dataShow[ prop ] = tween.start; 6635 if ( hidden ) { 6636 tween.end = tween.start; 6637 tween.start = prop === "width" || prop === "height" ? 1 : 0; 6638 } 6639 } 6640 } 6641 6642 // If this is a noop like .hide().hide(), restore an overwritten display value 6643 } else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) { 6644 style.display = display; 6645 } 6646} 6647 6648function propFilter( props, specialEasing ) { 6649 var index, name, easing, value, hooks; 6650 6651 // camelCase, specialEasing and expand cssHook pass 6652 for ( index in props ) { 6653 name = jQuery.camelCase( index ); 6654 easing = specialEasing[ name ]; 6655 value = props[ index ]; 6656 if ( jQuery.isArray( value ) ) { 6657 easing = value[ 1 ]; 6658 value = props[ index ] = value[ 0 ]; 6659 } 6660 6661 if ( index !== name ) { 6662 props[ name ] = value; 6663 delete props[ index ]; 6664 } 6665 6666 hooks = jQuery.cssHooks[ name ]; 6667 if ( hooks && "expand" in hooks ) { 6668 value = hooks.expand( value ); 6669 delete props[ name ]; 6670 6671 // Not quite $.extend, this won't overwrite existing keys. 6672 // Reusing 'index' because we have the correct "name" 6673 for ( index in value ) { 6674 if ( !( index in props ) ) { 6675 props[ index ] = value[ index ]; 6676 specialEasing[ index ] = easing; 6677 } 6678 } 6679 } else { 6680 specialEasing[ name ] = easing; 6681 } 6682 } 6683} 6684 6685function Animation( elem, properties, options ) { 6686 var result, 6687 stopped, 6688 index = 0, 6689 length = Animation.prefilters.length, 6690 deferred = jQuery.Deferred().always( function() { 6691 6692 // Don't match elem in the :animated selector 6693 delete tick.elem; 6694 } ), 6695 tick = function() { 6696 if ( stopped ) { 6697 return false; 6698 } 6699 var currentTime = fxNow || createFxNow(), 6700 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), 6701 6702 // Support: Android 2.3 6703 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) 6704 temp = remaining / animation.duration || 0, 6705 percent = 1 - temp, 6706 index = 0, 6707 length = animation.tweens.length; 6708 6709 for ( ; index < length ; index++ ) { 6710 animation.tweens[ index ].run( percent ); 6711 } 6712 6713 deferred.notifyWith( elem, [ animation, percent, remaining ] ); 6714 6715 if ( percent < 1 && length ) { 6716 return remaining; 6717 } else { 6718 deferred.resolveWith( elem, [ animation ] ); 6719 return false; 6720 } 6721 }, 6722 animation = deferred.promise( { 6723 elem: elem, 6724 props: jQuery.extend( {}, properties ), 6725 opts: jQuery.extend( true, { 6726 specialEasing: {}, 6727 easing: jQuery.easing._default 6728 }, options ), 6729 originalProperties: properties, 6730 originalOptions: options, 6731 startTime: fxNow || createFxNow(), 6732 duration: options.duration, 6733 tweens: [], 6734 createTween: function( prop, end ) { 6735 var tween = jQuery.Tween( elem, animation.opts, prop, end, 6736 animation.opts.specialEasing[ prop ] || animation.opts.easing ); 6737 animation.tweens.push( tween ); 6738 return tween; 6739 }, 6740 stop: function( gotoEnd ) { 6741 var index = 0, 6742 6743 // If we are going to the end, we want to run all the tweens 6744 // otherwise we skip this part 6745 length = gotoEnd ? animation.tweens.length : 0; 6746 if ( stopped ) { 6747 return this; 6748 } 6749 stopped = true; 6750 for ( ; index < length ; index++ ) { 6751 animation.tweens[ index ].run( 1 ); 6752 } 6753 6754 // Resolve when we played the last frame; otherwise, reject 6755 if ( gotoEnd ) { 6756 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 6757 deferred.resolveWith( elem, [ animation, gotoEnd ] ); 6758 } else { 6759 deferred.rejectWith( elem, [ animation, gotoEnd ] ); 6760 } 6761 return this; 6762 } 6763 } ), 6764 props = animation.props; 6765 6766 propFilter( props, animation.opts.specialEasing ); 6767 6768 for ( ; index < length ; index++ ) { 6769 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); 6770 if ( result ) { 6771 if ( jQuery.isFunction( result.stop ) ) { 6772 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = 6773 jQuery.proxy( result.stop, result ); 6774 } 6775 return result; 6776 } 6777 } 6778 6779 jQuery.map( props, createTween, animation ); 6780 6781 if ( jQuery.isFunction( animation.opts.start ) ) { 6782 animation.opts.start.call( elem, animation ); 6783 } 6784 6785 jQuery.fx.timer( 6786 jQuery.extend( tick, { 6787 elem: elem, 6788 anim: animation, 6789 queue: animation.opts.queue 6790 } ) 6791 ); 6792 6793 // attach callbacks from options 6794 return animation.progress( animation.opts.progress ) 6795 .done( animation.opts.done, animation.opts.complete ) 6796 .fail( animation.opts.fail ) 6797 .always( animation.opts.always ); 6798} 6799 6800jQuery.Animation = jQuery.extend( Animation, { 6801 tweeners: { 6802 "*": [ function( prop, value ) { 6803 var tween = this.createTween( prop, value ); 6804 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); 6805 return tween; 6806 } ] 6807 }, 6808 6809 tweener: function( props, callback ) { 6810 if ( jQuery.isFunction( props ) ) { 6811 callback = props; 6812 props = [ "*" ]; 6813 } else { 6814 props = props.match( rnotwhite ); 6815 } 6816 6817 var prop, 6818 index = 0, 6819 length = props.length; 6820 6821 for ( ; index < length ; index++ ) { 6822 prop = props[ index ]; 6823 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; 6824 Animation.tweeners[ prop ].unshift( callback ); 6825 } 6826 }, 6827 6828 prefilters: [ defaultPrefilter ], 6829 6830 prefilter: function( callback, prepend ) { 6831 if ( prepend ) { 6832 Animation.prefilters.unshift( callback ); 6833 } else { 6834 Animation.prefilters.push( callback ); 6835 } 6836 } 6837} ); 6838 6839jQuery.speed = function( speed, easing, fn ) { 6840 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { 6841 complete: fn || !fn && easing || 6842 jQuery.isFunction( speed ) && speed, 6843 duration: speed, 6844 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing 6845 }; 6846 6847 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? 6848 opt.duration : opt.duration in jQuery.fx.speeds ? 6849 jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; 6850 6851 // Normalize opt.queue - true/undefined/null -> "fx" 6852 if ( opt.queue == null || opt.queue === true ) { 6853 opt.queue = "fx"; 6854 } 6855 6856 // Queueing 6857 opt.old = opt.complete; 6858 6859 opt.complete = function() { 6860 if ( jQuery.isFunction( opt.old ) ) { 6861 opt.old.call( this ); 6862 } 6863 6864 if ( opt.queue ) { 6865 jQuery.dequeue( this, opt.queue ); 6866 } 6867 }; 6868 6869 return opt; 6870}; 6871 6872jQuery.fn.extend( { 6873 fadeTo: function( speed, to, easing, callback ) { 6874 6875 // Show any hidden elements after setting opacity to 0 6876 return this.filter( isHidden ).css( "opacity", 0 ).show() 6877 6878 // Animate to the value specified 6879 .end().animate( { opacity: to }, speed, easing, callback ); 6880 }, 6881 animate: function( prop, speed, easing, callback ) { 6882 var empty = jQuery.isEmptyObject( prop ), 6883 optall = jQuery.speed( speed, easing, callback ), 6884 doAnimation = function() { 6885 6886 // Operate on a copy of prop so per-property easing won't be lost 6887 var anim = Animation( this, jQuery.extend( {}, prop ), optall ); 6888 6889 // Empty animations, or finishing resolves immediately 6890 if ( empty || dataPriv.get( this, "finish" ) ) { 6891 anim.stop( true ); 6892 } 6893 }; 6894 doAnimation.finish = doAnimation; 6895 6896 return empty || optall.queue === false ? 6897 this.each( doAnimation ) : 6898 this.queue( optall.queue, doAnimation ); 6899 }, 6900 stop: function( type, clearQueue, gotoEnd ) { 6901 var stopQueue = function( hooks ) { 6902 var stop = hooks.stop; 6903 delete hooks.stop; 6904 stop( gotoEnd ); 6905 }; 6906 6907 if ( typeof type !== "string" ) { 6908 gotoEnd = clearQueue; 6909 clearQueue = type; 6910 type = undefined; 6911 } 6912 if ( clearQueue && type !== false ) { 6913 this.queue( type || "fx", [] ); 6914 } 6915 6916 return this.each( function() { 6917 var dequeue = true, 6918 index = type != null && type + "queueHooks", 6919 timers = jQuery.timers, 6920 data = dataPriv.get( this ); 6921 6922 if ( index ) { 6923 if ( data[ index ] && data[ index ].stop ) { 6924 stopQueue( data[ index ] ); 6925 } 6926 } else { 6927 for ( index in data ) { 6928 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { 6929 stopQueue( data[ index ] ); 6930 } 6931 } 6932 } 6933 6934 for ( index = timers.length; index--; ) { 6935 if ( timers[ index ].elem === this && 6936 ( type == null || timers[ index ].queue === type ) ) { 6937 6938 timers[ index ].anim.stop( gotoEnd ); 6939 dequeue = false; 6940 timers.splice( index, 1 ); 6941 } 6942 } 6943 6944 // Start the next in the queue if the last step wasn't forced. 6945 // Timers currently will call their complete callbacks, which 6946 // will dequeue but only if they were gotoEnd. 6947 if ( dequeue || !gotoEnd ) { 6948 jQuery.dequeue( this, type ); 6949 } 6950 } ); 6951 }, 6952 finish: function( type ) { 6953 if ( type !== false ) { 6954 type = type || "fx"; 6955 } 6956 return this.each( function() { 6957 var index, 6958 data = dataPriv.get( this ), 6959 queue = data[ type + "queue" ], 6960 hooks = data[ type + "queueHooks" ], 6961 timers = jQuery.timers, 6962 length = queue ? queue.length : 0; 6963 6964 // Enable finishing flag on private data 6965 data.finish = true; 6966 6967 // Empty the queue first 6968 jQuery.queue( this, type, [] ); 6969 6970 if ( hooks && hooks.stop ) { 6971 hooks.stop.call( this, true ); 6972 } 6973 6974 // Look for any active animations, and finish them 6975 for ( index = timers.length; index--; ) { 6976 if ( timers[ index ].elem === this && timers[ index ].queue === type ) { 6977 timers[ index ].anim.stop( true ); 6978 timers.splice( index, 1 ); 6979 } 6980 } 6981 6982 // Look for any animations in the old queue and finish them 6983 for ( index = 0; index < length; index++ ) { 6984 if ( queue[ index ] && queue[ index ].finish ) { 6985 queue[ index ].finish.call( this ); 6986 } 6987 } 6988 6989 // Turn off finishing flag 6990 delete data.finish; 6991 } ); 6992 } 6993} ); 6994 6995jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { 6996 var cssFn = jQuery.fn[ name ]; 6997 jQuery.fn[ name ] = function( speed, easing, callback ) { 6998 return speed == null || typeof speed === "boolean" ? 6999 cssFn.apply( this, arguments ) : 7000 this.animate( genFx( name, true ), speed, easing, callback ); 7001 }; 7002} ); 7003 7004// Generate shortcuts for custom animations 7005jQuery.each( { 7006 slideDown: genFx( "show" ), 7007 slideUp: genFx( "hide" ), 7008 slideToggle: genFx( "toggle" ), 7009 fadeIn: { opacity: "show" }, 7010 fadeOut: { opacity: "hide" }, 7011 fadeToggle: { opacity: "toggle" } 7012}, function( name, props ) { 7013 jQuery.fn[ name ] = function( speed, easing, callback ) { 7014 return this.animate( props, speed, easing, callback ); 7015 }; 7016} ); 7017 7018jQuery.timers = []; 7019jQuery.fx.tick = function() { 7020 var timer, 7021 i = 0, 7022 timers = jQuery.timers; 7023 7024 fxNow = jQuery.now(); 7025 7026 for ( ; i < timers.length; i++ ) { 7027 timer = timers[ i ]; 7028 7029 // Checks the timer has not already been removed 7030 if ( !timer() && timers[ i ] === timer ) { 7031 timers.splice( i--, 1 ); 7032 } 7033 } 7034 7035 if ( !timers.length ) { 7036 jQuery.fx.stop(); 7037 } 7038 fxNow = undefined; 7039}; 7040 7041jQuery.fx.timer = function( timer ) { 7042 jQuery.timers.push( timer ); 7043 if ( timer() ) { 7044 jQuery.fx.start(); 7045 } else { 7046 jQuery.timers.pop(); 7047 } 7048}; 7049 7050jQuery.fx.interval = 13; 7051jQuery.fx.start = function() { 7052 if ( !timerId ) { 7053 timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval ); 7054 } 7055}; 7056 7057jQuery.fx.stop = function() { 7058 window.clearInterval( timerId ); 7059 7060 timerId = null; 7061}; 7062 7063jQuery.fx.speeds = { 7064 slow: 600, 7065 fast: 200, 7066 7067 // Default speed 7068 _default: 400 7069}; 7070 7071 7072// Based off of the plugin by Clint Helfers, with permission. 7073// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ 7074jQuery.fn.delay = function( time, type ) { 7075 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 7076 type = type || "fx"; 7077 7078 return this.queue( type, function( next, hooks ) { 7079 var timeout = window.setTimeout( next, time ); 7080 hooks.stop = function() { 7081 window.clearTimeout( timeout ); 7082 }; 7083 } ); 7084}; 7085 7086 7087( function() { 7088 var input = document.createElement( "input" ), 7089 select = document.createElement( "select" ), 7090 opt = select.appendChild( document.createElement( "option" ) ); 7091 7092 input.type = "checkbox"; 7093 7094 // Support: iOS<=5.1, Android<=4.2+ 7095 // Default value for a checkbox should be "on" 7096 support.checkOn = input.value !== ""; 7097 7098 // Support: IE<=11+ 7099 // Must access selectedIndex to make default options select 7100 support.optSelected = opt.selected; 7101 7102 // Support: Android<=2.3 7103 // Options inside disabled selects are incorrectly marked as disabled 7104 select.disabled = true; 7105 support.optDisabled = !opt.disabled; 7106 7107 // Support: IE<=11+ 7108 // An input loses its value after becoming a radio 7109 input = document.createElement( "input" ); 7110 input.value = "t"; 7111 input.type = "radio"; 7112 support.radioValue = input.value === "t"; 7113} )(); 7114 7115 7116var boolHook, 7117 attrHandle = jQuery.expr.attrHandle; 7118 7119jQuery.fn.extend( { 7120 attr: function( name, value ) { 7121 return access( this, jQuery.attr, name, value, arguments.length > 1 ); 7122 }, 7123 7124 removeAttr: function( name ) { 7125 return this.each( function() { 7126 jQuery.removeAttr( this, name ); 7127 } ); 7128 } 7129} ); 7130 7131jQuery.extend( { 7132 attr: function( elem, name, value ) { 7133 var ret, hooks, 7134 nType = elem.nodeType; 7135 7136 // Don't get/set attributes on text, comment and attribute nodes 7137 if ( nType === 3 || nType === 8 || nType === 2 ) { 7138 return; 7139 } 7140 7141 // Fallback to prop when attributes are not supported 7142 if ( typeof elem.getAttribute === "undefined" ) { 7143 return jQuery.prop( elem, name, value ); 7144 } 7145 7146 // All attributes are lowercase 7147 // Grab necessary hook if one is defined 7148 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 7149 name = name.toLowerCase(); 7150 hooks = jQuery.attrHooks[ name ] || 7151 ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); 7152 } 7153 7154 if ( value !== undefined ) { 7155 if ( value === null ) { 7156 jQuery.removeAttr( elem, name ); 7157 return; 7158 } 7159 7160 if ( hooks && "set" in hooks && 7161 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 7162 return ret; 7163 } 7164 7165 elem.setAttribute( name, value + "" ); 7166 return value; 7167 } 7168 7169 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 7170 return ret; 7171 } 7172 7173 ret = jQuery.find.attr( elem, name ); 7174 7175 // Non-existent attributes return null, we normalize to undefined 7176 return ret == null ? undefined : ret; 7177 }, 7178 7179 attrHooks: { 7180 type: { 7181 set: function( elem, value ) { 7182 if ( !support.radioValue && value === "radio" && 7183 jQuery.nodeName( elem, "input" ) ) { 7184 var val = elem.value; 7185 elem.setAttribute( "type", value ); 7186 if ( val ) { 7187 elem.value = val; 7188 } 7189 return value; 7190 } 7191 } 7192 } 7193 }, 7194 7195 removeAttr: function( elem, value ) { 7196 var name, propName, 7197 i = 0, 7198 attrNames = value && value.match( rnotwhite ); 7199 7200 if ( attrNames && elem.nodeType === 1 ) { 7201 while ( ( name = attrNames[ i++ ] ) ) { 7202 propName = jQuery.propFix[ name ] || name; 7203 7204 // Boolean attributes get special treatment (#10870) 7205 if ( jQuery.expr.match.bool.test( name ) ) { 7206 7207 // Set corresponding property to false 7208 elem[ propName ] = false; 7209 } 7210 7211 elem.removeAttribute( name ); 7212 } 7213 } 7214 } 7215} ); 7216 7217// Hooks for boolean attributes 7218boolHook = { 7219 set: function( elem, value, name ) { 7220 if ( value === false ) { 7221 7222 // Remove boolean attributes when set to false 7223 jQuery.removeAttr( elem, name ); 7224 } else { 7225 elem.setAttribute( name, name ); 7226 } 7227 return name; 7228 } 7229}; 7230jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { 7231 var getter = attrHandle[ name ] || jQuery.find.attr; 7232 7233 attrHandle[ name ] = function( elem, name, isXML ) { 7234 var ret, handle; 7235 if ( !isXML ) { 7236 7237 // Avoid an infinite loop by temporarily removing this function from the getter 7238 handle = attrHandle[ name ]; 7239 attrHandle[ name ] = ret; 7240 ret = getter( elem, name, isXML ) != null ? 7241 name.toLowerCase() : 7242 null; 7243 attrHandle[ name ] = handle; 7244 } 7245 return ret; 7246 }; 7247} ); 7248 7249 7250 7251 7252var rfocusable = /^(?:input|select|textarea|button)$/i, 7253 rclickable = /^(?:a|area)$/i; 7254 7255jQuery.fn.extend( { 7256 prop: function( name, value ) { 7257 return access( this, jQuery.prop, name, value, arguments.length > 1 ); 7258 }, 7259 7260 removeProp: function( name ) { 7261 return this.each( function() { 7262 delete this[ jQuery.propFix[ name ] || name ]; 7263 } ); 7264 } 7265} ); 7266 7267jQuery.extend( { 7268 prop: function( elem, name, value ) { 7269 var ret, hooks, 7270 nType = elem.nodeType; 7271 7272 // Don't get/set properties on text, comment and attribute nodes 7273 if ( nType === 3 || nType === 8 || nType === 2 ) { 7274 return; 7275 } 7276 7277 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 7278 7279 // Fix name and attach hooks 7280 name = jQuery.propFix[ name ] || name; 7281 hooks = jQuery.propHooks[ name ]; 7282 } 7283 7284 if ( value !== undefined ) { 7285 if ( hooks && "set" in hooks && 7286 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 7287 return ret; 7288 } 7289 7290 return ( elem[ name ] = value ); 7291 } 7292 7293 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 7294 return ret; 7295 } 7296 7297 return elem[ name ]; 7298 }, 7299 7300 propHooks: { 7301 tabIndex: { 7302 get: function( elem ) { 7303 7304 // elem.tabIndex doesn't always return the 7305 // correct value when it hasn't been explicitly set 7306 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 7307 // Use proper attribute retrieval(#12072) 7308 var tabindex = jQuery.find.attr( elem, "tabindex" ); 7309 7310 return tabindex ? 7311 parseInt( tabindex, 10 ) : 7312 rfocusable.test( elem.nodeName ) || 7313 rclickable.test( elem.nodeName ) && elem.href ? 7314 0 : 7315 -1; 7316 } 7317 } 7318 }, 7319 7320 propFix: { 7321 "for": "htmlFor", 7322 "class": "className" 7323 } 7324} ); 7325 7326// Support: IE <=11 only 7327// Accessing the selectedIndex property 7328// forces the browser to respect setting selected 7329// on the option 7330// The getter ensures a default option is selected 7331// when in an optgroup 7332if ( !support.optSelected ) { 7333 jQuery.propHooks.selected = { 7334 get: function( elem ) { 7335 var parent = elem.parentNode; 7336 if ( parent && parent.parentNode ) { 7337 parent.parentNode.selectedIndex; 7338 } 7339 return null; 7340 }, 7341 set: function( elem ) { 7342 var parent = elem.parentNode; 7343 if ( parent ) { 7344 parent.selectedIndex; 7345 7346 if ( parent.parentNode ) { 7347 parent.parentNode.selectedIndex; 7348 } 7349 } 7350 } 7351 }; 7352} 7353 7354jQuery.each( [ 7355 "tabIndex", 7356 "readOnly", 7357 "maxLength", 7358 "cellSpacing", 7359 "cellPadding", 7360 "rowSpan", 7361 "colSpan", 7362 "useMap", 7363 "frameBorder", 7364 "contentEditable" 7365], function() { 7366 jQuery.propFix[ this.toLowerCase() ] = this; 7367} ); 7368 7369 7370 7371 7372var rclass = /[\t\r\n\f]/g; 7373 7374function getClass( elem ) { 7375 return elem.getAttribute && elem.getAttribute( "class" ) || ""; 7376} 7377 7378jQuery.fn.extend( { 7379 addClass: function( value ) { 7380 var classes, elem, cur, curValue, clazz, j, finalValue, 7381 i = 0; 7382 7383 if ( jQuery.isFunction( value ) ) { 7384 return this.each( function( j ) { 7385 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); 7386 } ); 7387 } 7388 7389 if ( typeof value === "string" && value ) { 7390 classes = value.match( rnotwhite ) || []; 7391 7392 while ( ( elem = this[ i++ ] ) ) { 7393 curValue = getClass( elem ); 7394 cur = elem.nodeType === 1 && 7395 ( " " + curValue + " " ).replace( rclass, " " ); 7396 7397 if ( cur ) { 7398 j = 0; 7399 while ( ( clazz = classes[ j++ ] ) ) { 7400 if ( cur.indexOf( " " + clazz + " " ) < 0 ) { 7401 cur += clazz + " "; 7402 } 7403 } 7404 7405 // Only assign if different to avoid unneeded rendering. 7406 finalValue = jQuery.trim( cur ); 7407 if ( curValue !== finalValue ) { 7408 elem.setAttribute( "class", finalValue ); 7409 } 7410 } 7411 } 7412 } 7413 7414 return this; 7415 }, 7416 7417 removeClass: function( value ) { 7418 var classes, elem, cur, curValue, clazz, j, finalValue, 7419 i = 0; 7420 7421 if ( jQuery.isFunction( value ) ) { 7422 return this.each( function( j ) { 7423 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); 7424 } ); 7425 } 7426 7427 if ( !arguments.length ) { 7428 return this.attr( "class", "" ); 7429 } 7430 7431 if ( typeof value === "string" && value ) { 7432 classes = value.match( rnotwhite ) || []; 7433 7434 while ( ( elem = this[ i++ ] ) ) { 7435 curValue = getClass( elem ); 7436 7437 // This expression is here for better compressibility (see addClass) 7438 cur = elem.nodeType === 1 && 7439 ( " " + curValue + " " ).replace( rclass, " " ); 7440 7441 if ( cur ) { 7442 j = 0; 7443 while ( ( clazz = classes[ j++ ] ) ) { 7444 7445 // Remove *all* instances 7446 while ( cur.indexOf( " " + clazz + " " ) > -1 ) { 7447 cur = cur.replace( " " + clazz + " ", " " ); 7448 } 7449 } 7450 7451 // Only assign if different to avoid unneeded rendering. 7452 finalValue = jQuery.trim( cur ); 7453 if ( curValue !== finalValue ) { 7454 elem.setAttribute( "class", finalValue ); 7455 } 7456 } 7457 } 7458 } 7459 7460 return this; 7461 }, 7462 7463 toggleClass: function( value, stateVal ) { 7464 var type = typeof value; 7465 7466 if ( typeof stateVal === "boolean" && type === "string" ) { 7467 return stateVal ? this.addClass( value ) : this.removeClass( value ); 7468 } 7469 7470 if ( jQuery.isFunction( value ) ) { 7471 return this.each( function( i ) { 7472 jQuery( this ).toggleClass( 7473 value.call( this, i, getClass( this ), stateVal ), 7474 stateVal 7475 ); 7476 } ); 7477 } 7478 7479 return this.each( function() { 7480 var className, i, self, classNames; 7481 7482 if ( type === "string" ) { 7483 7484 // Toggle individual class names 7485 i = 0; 7486 self = jQuery( this ); 7487 classNames = value.match( rnotwhite ) || []; 7488 7489 while ( ( className = classNames[ i++ ] ) ) { 7490 7491 // Check each className given, space separated list 7492 if ( self.hasClass( className ) ) { 7493 self.removeClass( className ); 7494 } else { 7495 self.addClass( className ); 7496 } 7497 } 7498 7499 // Toggle whole class name 7500 } else if ( value === undefined || type === "boolean" ) { 7501 className = getClass( this ); 7502 if ( className ) { 7503 7504 // Store className if set 7505 dataPriv.set( this, "__className__", className ); 7506 } 7507 7508 // If the element has a class name or if we're passed `false`, 7509 // then remove the whole classname (if there was one, the above saved it). 7510 // Otherwise bring back whatever was previously saved (if anything), 7511 // falling back to the empty string if nothing was stored. 7512 if ( this.setAttribute ) { 7513 this.setAttribute( "class", 7514 className || value === false ? 7515 "" : 7516 dataPriv.get( this, "__className__" ) || "" 7517 ); 7518 } 7519 } 7520 } ); 7521 }, 7522 7523 hasClass: function( selector ) { 7524 var className, elem, 7525 i = 0; 7526 7527 className = " " + selector + " "; 7528 while ( ( elem = this[ i++ ] ) ) { 7529 if ( elem.nodeType === 1 && 7530 ( " " + getClass( elem ) + " " ).replace( rclass, " " ) 7531 .indexOf( className ) > -1 7532 ) { 7533 return true; 7534 } 7535 } 7536 7537 return false; 7538 } 7539} ); 7540 7541 7542 7543 7544var rreturn = /\r/g, 7545 rspaces = /[\x20\t\r\n\f]+/g; 7546 7547jQuery.fn.extend( { 7548 val: function( value ) { 7549 var hooks, ret, isFunction, 7550 elem = this[ 0 ]; 7551 7552 if ( !arguments.length ) { 7553 if ( elem ) { 7554 hooks = jQuery.valHooks[ elem.type ] || 7555 jQuery.valHooks[ elem.nodeName.toLowerCase() ]; 7556 7557 if ( hooks && 7558 "get" in hooks && 7559 ( ret = hooks.get( elem, "value" ) ) !== undefined 7560 ) { 7561 return ret; 7562 } 7563 7564 ret = elem.value; 7565 7566 return typeof ret === "string" ? 7567 7568 // Handle most common string cases 7569 ret.replace( rreturn, "" ) : 7570 7571 // Handle cases where value is null/undef or number 7572 ret == null ? "" : ret; 7573 } 7574 7575 return; 7576 } 7577 7578 isFunction = jQuery.isFunction( value ); 7579 7580 return this.each( function( i ) { 7581 var val; 7582 7583 if ( this.nodeType !== 1 ) { 7584 return; 7585 } 7586 7587 if ( isFunction ) { 7588 val = value.call( this, i, jQuery( this ).val() ); 7589 } else { 7590 val = value; 7591 } 7592 7593 // Treat null/undefined as ""; convert numbers to string 7594 if ( val == null ) { 7595 val = ""; 7596 7597 } else if ( typeof val === "number" ) { 7598 val += ""; 7599 7600 } else if ( jQuery.isArray( val ) ) { 7601 val = jQuery.map( val, function( value ) { 7602 return value == null ? "" : value + ""; 7603 } ); 7604 } 7605 7606 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; 7607 7608 // If set returns undefined, fall back to normal setting 7609 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { 7610 this.value = val; 7611 } 7612 } ); 7613 } 7614} ); 7615 7616jQuery.extend( { 7617 valHooks: { 7618 option: { 7619 get: function( elem ) { 7620 7621 var val = jQuery.find.attr( elem, "value" ); 7622 return val != null ? 7623 val : 7624 7625 // Support: IE10-11+ 7626 // option.text throws exceptions (#14686, #14858) 7627 // Strip and collapse whitespace 7628 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace 7629 jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " ); 7630 } 7631 }, 7632 select: { 7633 get: function( elem ) { 7634 var value, option, 7635 options = elem.options, 7636 index = elem.selectedIndex, 7637 one = elem.type === "select-one" || index < 0, 7638 values = one ? null : [], 7639 max = one ? index + 1 : options.length, 7640 i = index < 0 ? 7641 max : 7642 one ? index : 0; 7643 7644 // Loop through all the selected options 7645 for ( ; i < max; i++ ) { 7646 option = options[ i ]; 7647 7648 // IE8-9 doesn't update selected after form reset (#2551) 7649 if ( ( option.selected || i === index ) && 7650 7651 // Don't return options that are disabled or in a disabled optgroup 7652 ( support.optDisabled ? 7653 !option.disabled : option.getAttribute( "disabled" ) === null ) && 7654 ( !option.parentNode.disabled || 7655 !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { 7656 7657 // Get the specific value for the option 7658 value = jQuery( option ).val(); 7659 7660 // We don't need an array for one selects 7661 if ( one ) { 7662 return value; 7663 } 7664 7665 // Multi-Selects return an array 7666 values.push( value ); 7667 } 7668 } 7669 7670 return values; 7671 }, 7672 7673 set: function( elem, value ) { 7674 var optionSet, option, 7675 options = elem.options, 7676 values = jQuery.makeArray( value ), 7677 i = options.length; 7678 7679 while ( i-- ) { 7680 option = options[ i ]; 7681 if ( option.selected = 7682 jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 7683 ) { 7684 optionSet = true; 7685 } 7686 } 7687 7688 // Force browsers to behave consistently when non-matching value is set 7689 if ( !optionSet ) { 7690 elem.selectedIndex = -1; 7691 } 7692 return values; 7693 } 7694 } 7695 } 7696} ); 7697 7698// Radios and checkboxes getter/setter 7699jQuery.each( [ "radio", "checkbox" ], function() { 7700 jQuery.valHooks[ this ] = { 7701 set: function( elem, value ) { 7702 if ( jQuery.isArray( value ) ) { 7703 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); 7704 } 7705 } 7706 }; 7707 if ( !support.checkOn ) { 7708 jQuery.valHooks[ this ].get = function( elem ) { 7709 return elem.getAttribute( "value" ) === null ? "on" : elem.value; 7710 }; 7711 } 7712} ); 7713 7714 7715 7716 7717// Return jQuery for attributes-only inclusion 7718 7719 7720var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/; 7721 7722jQuery.extend( jQuery.event, { 7723 7724 trigger: function( event, data, elem, onlyHandlers ) { 7725 7726 var i, cur, tmp, bubbleType, ontype, handle, special, 7727 eventPath = [ elem || document ], 7728 type = hasOwn.call( event, "type" ) ? event.type : event, 7729 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; 7730 7731 cur = tmp = elem = elem || document; 7732 7733 // Don't do events on text and comment nodes 7734 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 7735 return; 7736 } 7737 7738 // focus/blur morphs to focusin/out; ensure we're not firing them right now 7739 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { 7740 return; 7741 } 7742 7743 if ( type.indexOf( "." ) > -1 ) { 7744 7745 // Namespaced trigger; create a regexp to match event type in handle() 7746 namespaces = type.split( "." ); 7747 type = namespaces.shift(); 7748 namespaces.sort(); 7749 } 7750 ontype = type.indexOf( ":" ) < 0 && "on" + type; 7751 7752 // Caller can pass in a jQuery.Event object, Object, or just an event type string 7753 event = event[ jQuery.expando ] ? 7754 event : 7755 new jQuery.Event( type, typeof event === "object" && event ); 7756 7757 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) 7758 event.isTrigger = onlyHandlers ? 2 : 3; 7759 event.namespace = namespaces.join( "." ); 7760 event.rnamespace = event.namespace ? 7761 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : 7762 null; 7763 7764 // Clean up the event in case it is being reused 7765 event.result = undefined; 7766 if ( !event.target ) { 7767 event.target = elem; 7768 } 7769 7770 // Clone any incoming data and prepend the event, creating the handler arg list 7771 data = data == null ? 7772 [ event ] : 7773 jQuery.makeArray( data, [ event ] ); 7774 7775 // Allow special events to draw outside the lines 7776 special = jQuery.event.special[ type ] || {}; 7777 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { 7778 return; 7779 } 7780 7781 // Determine event propagation path in advance, per W3C events spec (#9951) 7782 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) 7783 if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { 7784 7785 bubbleType = special.delegateType || type; 7786 if ( !rfocusMorph.test( bubbleType + type ) ) { 7787 cur = cur.parentNode; 7788 } 7789 for ( ; cur; cur = cur.parentNode ) { 7790 eventPath.push( cur ); 7791 tmp = cur; 7792 } 7793 7794 // Only add window if we got to document (e.g., not plain obj or detached DOM) 7795 if ( tmp === ( elem.ownerDocument || document ) ) { 7796 eventPath.push( tmp.defaultView || tmp.parentWindow || window ); 7797 } 7798 } 7799 7800 // Fire handlers on the event path 7801 i = 0; 7802 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { 7803 7804 event.type = i > 1 ? 7805 bubbleType : 7806 special.bindType || type; 7807 7808 // jQuery handler 7809 handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && 7810 dataPriv.get( cur, "handle" ); 7811 if ( handle ) { 7812 handle.apply( cur, data ); 7813 } 7814 7815 // Native handler 7816 handle = ontype && cur[ ontype ]; 7817 if ( handle && handle.apply && acceptData( cur ) ) { 7818 event.result = handle.apply( cur, data ); 7819 if ( event.result === false ) { 7820 event.preventDefault(); 7821 } 7822 } 7823 } 7824 event.type = type; 7825 7826 // If nobody prevented the default action, do it now 7827 if ( !onlyHandlers && !event.isDefaultPrevented() ) { 7828 7829 if ( ( !special._default || 7830 special._default.apply( eventPath.pop(), data ) === false ) && 7831 acceptData( elem ) ) { 7832 7833 // Call a native DOM method on the target with the same name name as the event. 7834 // Don't do default actions on window, that's where global variables be (#6170) 7835 if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { 7836 7837 // Don't re-trigger an onFOO event when we call its FOO() method 7838 tmp = elem[ ontype ]; 7839 7840 if ( tmp ) { 7841 elem[ ontype ] = null; 7842 } 7843 7844 // Prevent re-triggering of the same event, since we already bubbled it above 7845 jQuery.event.triggered = type; 7846 elem[ type ](); 7847 jQuery.event.triggered = undefined; 7848 7849 if ( tmp ) { 7850 elem[ ontype ] = tmp; 7851 } 7852 } 7853 } 7854 } 7855 7856 return event.result; 7857 }, 7858 7859 // Piggyback on a donor event to simulate a different one 7860 // Used only for `focus(in | out)` events 7861 simulate: function( type, elem, event ) { 7862 var e = jQuery.extend( 7863 new jQuery.Event(), 7864 event, 7865 { 7866 type: type, 7867 isSimulated: true 7868 } 7869 ); 7870 7871 jQuery.event.trigger( e, null, elem ); 7872 } 7873 7874} ); 7875 7876jQuery.fn.extend( { 7877 7878 trigger: function( type, data ) { 7879 return this.each( function() { 7880 jQuery.event.trigger( type, data, this ); 7881 } ); 7882 }, 7883 triggerHandler: function( type, data ) { 7884 var elem = this[ 0 ]; 7885 if ( elem ) { 7886 return jQuery.event.trigger( type, data, elem, true ); 7887 } 7888 } 7889} ); 7890 7891 7892jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " + 7893 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 7894 "change select submit keydown keypress keyup error contextmenu" ).split( " " ), 7895 function( i, name ) { 7896 7897 // Handle event binding 7898 jQuery.fn[ name ] = function( data, fn ) { 7899 return arguments.length > 0 ? 7900 this.on( name, null, data, fn ) : 7901 this.trigger( name ); 7902 }; 7903} ); 7904 7905jQuery.fn.extend( { 7906 hover: function( fnOver, fnOut ) { 7907 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 7908 } 7909} ); 7910 7911 7912 7913 7914support.focusin = "onfocusin" in window; 7915 7916 7917// Support: Firefox 7918// Firefox doesn't have focus(in | out) events 7919// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 7920// 7921// Support: Chrome, Safari 7922// focus(in | out) events fire after focus & blur events, 7923// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order 7924// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857 7925if ( !support.focusin ) { 7926 jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { 7927 7928 // Attach a single capturing handler on the document while someone wants focusin/focusout 7929 var handler = function( event ) { 7930 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); 7931 }; 7932 7933 jQuery.event.special[ fix ] = { 7934 setup: function() { 7935 var doc = this.ownerDocument || this, 7936 attaches = dataPriv.access( doc, fix ); 7937 7938 if ( !attaches ) { 7939 doc.addEventListener( orig, handler, true ); 7940 } 7941 dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); 7942 }, 7943 teardown: function() { 7944 var doc = this.ownerDocument || this, 7945 attaches = dataPriv.access( doc, fix ) - 1; 7946 7947 if ( !attaches ) { 7948 doc.removeEventListener( orig, handler, true ); 7949 dataPriv.remove( doc, fix ); 7950 7951 } else { 7952 dataPriv.access( doc, fix, attaches ); 7953 } 7954 } 7955 }; 7956 } ); 7957} 7958var location = window.location; 7959 7960var nonce = jQuery.now(); 7961 7962var rquery = ( /\?/ ); 7963 7964 7965 7966// Support: Android 2.3 7967// Workaround failure to string-cast null input 7968jQuery.parseJSON = function( data ) { 7969 return JSON.parse( data + "" ); 7970}; 7971 7972 7973// Cross-browser xml parsing 7974jQuery.parseXML = function( data ) { 7975 var xml; 7976 if ( !data || typeof data !== "string" ) { 7977 return null; 7978 } 7979 7980 // Support: IE9 7981 try { 7982 xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); 7983 } catch ( e ) { 7984 xml = undefined; 7985 } 7986 7987 if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { 7988 jQuery.error( "Invalid XML: " + data ); 7989 } 7990 return xml; 7991}; 7992 7993 7994var 7995 rhash = /#.*$/, 7996 rts = /([?&])_=[^&]*/, 7997 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, 7998 7999 // #7653, #8125, #8152: local protocol detection 8000 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, 8001 rnoContent = /^(?:GET|HEAD)$/, 8002 rprotocol = /^\/\//, 8003 8004 /* Prefilters 8005 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 8006 * 2) These are called: 8007 * - BEFORE asking for a transport 8008 * - AFTER param serialization (s.data is a string if s.processData is true) 8009 * 3) key is the dataType 8010 * 4) the catchall symbol "*" can be used 8011 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 8012 */ 8013 prefilters = {}, 8014 8015 /* Transports bindings 8016 * 1) key is the dataType 8017 * 2) the catchall symbol "*" can be used 8018 * 3) selection will start with transport dataType and THEN go to "*" if needed 8019 */ 8020 transports = {}, 8021 8022 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression 8023 allTypes = "*/".concat( "*" ), 8024 8025 // Anchor tag for parsing the document origin 8026 originAnchor = document.createElement( "a" ); 8027 originAnchor.href = location.href; 8028 8029// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 8030function addToPrefiltersOrTransports( structure ) { 8031 8032 // dataTypeExpression is optional and defaults to "*" 8033 return function( dataTypeExpression, func ) { 8034 8035 if ( typeof dataTypeExpression !== "string" ) { 8036 func = dataTypeExpression; 8037 dataTypeExpression = "*"; 8038 } 8039 8040 var dataType, 8041 i = 0, 8042 dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || []; 8043 8044 if ( jQuery.isFunction( func ) ) { 8045 8046 // For each dataType in the dataTypeExpression 8047 while ( ( dataType = dataTypes[ i++ ] ) ) { 8048 8049 // Prepend if requested 8050 if ( dataType[ 0 ] === "+" ) { 8051 dataType = dataType.slice( 1 ) || "*"; 8052 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); 8053 8054 // Otherwise append 8055 } else { 8056 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); 8057 } 8058 } 8059 } 8060 }; 8061} 8062 8063// Base inspection function for prefilters and transports 8064function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { 8065 8066 var inspected = {}, 8067 seekingTransport = ( structure === transports ); 8068 8069 function inspect( dataType ) { 8070 var selected; 8071 inspected[ dataType ] = true; 8072 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { 8073 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); 8074 if ( typeof dataTypeOrTransport === "string" && 8075 !seekingTransport && !inspected[ dataTypeOrTransport ] ) { 8076 8077 options.dataTypes.unshift( dataTypeOrTransport ); 8078 inspect( dataTypeOrTransport ); 8079 return false; 8080 } else if ( seekingTransport ) { 8081 return !( selected = dataTypeOrTransport ); 8082 } 8083 } ); 8084 return selected; 8085 } 8086 8087 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); 8088} 8089 8090// A special extend for ajax options 8091// that takes "flat" options (not to be deep extended) 8092// Fixes #9887 8093function ajaxExtend( target, src ) { 8094 var key, deep, 8095 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 8096 8097 for ( key in src ) { 8098 if ( src[ key ] !== undefined ) { 8099 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; 8100 } 8101 } 8102 if ( deep ) { 8103 jQuery.extend( true, target, deep ); 8104 } 8105 8106 return target; 8107} 8108 8109/* Handles responses to an ajax request: 8110 * - finds the right dataType (mediates between content-type and expected dataType) 8111 * - returns the corresponding response 8112 */ 8113function ajaxHandleResponses( s, jqXHR, responses ) { 8114 8115 var ct, type, finalDataType, firstDataType, 8116 contents = s.contents, 8117 dataTypes = s.dataTypes; 8118 8119 // Remove auto dataType and get content-type in the process 8120 while ( dataTypes[ 0 ] === "*" ) { 8121 dataTypes.shift(); 8122 if ( ct === undefined ) { 8123 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); 8124 } 8125 } 8126 8127 // Check if we're dealing with a known content-type 8128 if ( ct ) { 8129 for ( type in contents ) { 8130 if ( contents[ type ] && contents[ type ].test( ct ) ) { 8131 dataTypes.unshift( type ); 8132 break; 8133 } 8134 } 8135 } 8136 8137 // Check to see if we have a response for the expected dataType 8138 if ( dataTypes[ 0 ] in responses ) { 8139 finalDataType = dataTypes[ 0 ]; 8140 } else { 8141 8142 // Try convertible dataTypes 8143 for ( type in responses ) { 8144 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { 8145 finalDataType = type; 8146 break; 8147 } 8148 if ( !firstDataType ) { 8149 firstDataType = type; 8150 } 8151 } 8152 8153 // Or just use first one 8154 finalDataType = finalDataType || firstDataType; 8155 } 8156 8157 // If we found a dataType 8158 // We add the dataType to the list if needed 8159 // and return the corresponding response 8160 if ( finalDataType ) { 8161 if ( finalDataType !== dataTypes[ 0 ] ) { 8162 dataTypes.unshift( finalDataType ); 8163 } 8164 return responses[ finalDataType ]; 8165 } 8166} 8167 8168/* Chain conversions given the request and the original response 8169 * Also sets the responseXXX fields on the jqXHR instance 8170 */ 8171function ajaxConvert( s, response, jqXHR, isSuccess ) { 8172 var conv2, current, conv, tmp, prev, 8173 converters = {}, 8174 8175 // Work with a copy of dataTypes in case we need to modify it for conversion 8176 dataTypes = s.dataTypes.slice(); 8177 8178 // Create converters map with lowercased keys 8179 if ( dataTypes[ 1 ] ) { 8180 for ( conv in s.converters ) { 8181 converters[ conv.toLowerCase() ] = s.converters[ conv ]; 8182 } 8183 } 8184 8185 current = dataTypes.shift(); 8186 8187 // Convert to each sequential dataType 8188 while ( current ) { 8189 8190 if ( s.responseFields[ current ] ) { 8191 jqXHR[ s.responseFields[ current ] ] = response; 8192 } 8193 8194 // Apply the dataFilter if provided 8195 if ( !prev && isSuccess && s.dataFilter ) { 8196 response = s.dataFilter( response, s.dataType ); 8197 } 8198 8199 prev = current; 8200 current = dataTypes.shift(); 8201 8202 if ( current ) { 8203 8204 // There's only work to do if current dataType is non-auto 8205 if ( current === "*" ) { 8206 8207 current = prev; 8208 8209 // Convert response if prev dataType is non-auto and differs from current 8210 } else if ( prev !== "*" && prev !== current ) { 8211 8212 // Seek a direct converter 8213 conv = converters[ prev + " " + current ] || converters[ "* " + current ]; 8214 8215 // If none found, seek a pair 8216 if ( !conv ) { 8217 for ( conv2 in converters ) { 8218 8219 // If conv2 outputs current 8220 tmp = conv2.split( " " ); 8221 if ( tmp[ 1 ] === current ) { 8222 8223 // If prev can be converted to accepted input 8224 conv = converters[ prev + " " + tmp[ 0 ] ] || 8225 converters[ "* " + tmp[ 0 ] ]; 8226 if ( conv ) { 8227 8228 // Condense equivalence converters 8229 if ( conv === true ) { 8230 conv = converters[ conv2 ]; 8231 8232 // Otherwise, insert the intermediate dataType 8233 } else if ( converters[ conv2 ] !== true ) { 8234 current = tmp[ 0 ]; 8235 dataTypes.unshift( tmp[ 1 ] ); 8236 } 8237 break; 8238 } 8239 } 8240 } 8241 } 8242 8243 // Apply converter (if not an equivalence) 8244 if ( conv !== true ) { 8245 8246 // Unless errors are allowed to bubble, catch and return them 8247 if ( conv && s.throws ) { 8248 response = conv( response ); 8249 } else { 8250 try { 8251 response = conv( response ); 8252 } catch ( e ) { 8253 return { 8254 state: "parsererror", 8255 error: conv ? e : "No conversion from " + prev + " to " + current 8256 }; 8257 } 8258 } 8259 } 8260 } 8261 } 8262 } 8263 8264 return { state: "success", data: response }; 8265} 8266 8267jQuery.extend( { 8268 8269 // Counter for holding the number of active queries 8270 active: 0, 8271 8272 // Last-Modified header cache for next request 8273 lastModified: {}, 8274 etag: {}, 8275 8276 ajaxSettings: { 8277 url: location.href, 8278 type: "GET", 8279 isLocal: rlocalProtocol.test( location.protocol ), 8280 global: true, 8281 processData: true, 8282 async: true, 8283 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 8284 /* 8285 timeout: 0, 8286 data: null, 8287 dataType: null, 8288 username: null, 8289 password: null, 8290 cache: null, 8291 throws: false, 8292 traditional: false, 8293 headers: {}, 8294 */ 8295 8296 accepts: { 8297 "*": allTypes, 8298 text: "text/plain", 8299 html: "text/html", 8300 xml: "application/xml, text/xml", 8301 json: "application/json, text/javascript" 8302 }, 8303 8304 contents: { 8305 xml: /\bxml\b/, 8306 html: /\bhtml/, 8307 json: /\bjson\b/ 8308 }, 8309 8310 responseFields: { 8311 xml: "responseXML", 8312 text: "responseText", 8313 json: "responseJSON" 8314 }, 8315 8316 // Data converters 8317 // Keys separate source (or catchall "*") and destination types with a single space 8318 converters: { 8319 8320 // Convert anything to text 8321 "* text": String, 8322 8323 // Text to html (true = no transformation) 8324 "text html": true, 8325 8326 // Evaluate text as a json expression 8327 "text json": jQuery.parseJSON, 8328 8329 // Parse text as xml 8330 "text xml": jQuery.parseXML 8331 }, 8332 8333 // For options that shouldn't be deep extended: 8334 // you can add your own custom options here if 8335 // and when you create one that shouldn't be 8336 // deep extended (see ajaxExtend) 8337 flatOptions: { 8338 url: true, 8339 context: true 8340 } 8341 }, 8342 8343 // Creates a full fledged settings object into target 8344 // with both ajaxSettings and settings fields. 8345 // If target is omitted, writes into ajaxSettings. 8346 ajaxSetup: function( target, settings ) { 8347 return settings ? 8348 8349 // Building a settings object 8350 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : 8351 8352 // Extending ajaxSettings 8353 ajaxExtend( jQuery.ajaxSettings, target ); 8354 }, 8355 8356 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 8357 ajaxTransport: addToPrefiltersOrTransports( transports ), 8358 8359 // Main method 8360 ajax: function( url, options ) { 8361 8362 // If url is an object, simulate pre-1.5 signature 8363 if ( typeof url === "object" ) { 8364 options = url; 8365 url = undefined; 8366 } 8367 8368 // Force options to be an object 8369 options = options || {}; 8370 8371 var transport, 8372 8373 // URL without anti-cache param 8374 cacheURL, 8375 8376 // Response headers 8377 responseHeadersString, 8378 responseHeaders, 8379 8380 // timeout handle 8381 timeoutTimer, 8382 8383 // Url cleanup var 8384 urlAnchor, 8385 8386 // To know if global events are to be dispatched 8387 fireGlobals, 8388 8389 // Loop variable 8390 i, 8391 8392 // Create the final options object 8393 s = jQuery.ajaxSetup( {}, options ), 8394 8395 // Callbacks context 8396 callbackContext = s.context || s, 8397 8398 // Context for global events is callbackContext if it is a DOM node or jQuery collection 8399 globalEventContext = s.context && 8400 ( callbackContext.nodeType || callbackContext.jquery ) ? 8401 jQuery( callbackContext ) : 8402 jQuery.event, 8403 8404 // Deferreds 8405 deferred = jQuery.Deferred(), 8406 completeDeferred = jQuery.Callbacks( "once memory" ), 8407 8408 // Status-dependent callbacks 8409 statusCode = s.statusCode || {}, 8410 8411 // Headers (they are sent all at once) 8412 requestHeaders = {}, 8413 requestHeadersNames = {}, 8414 8415 // The jqXHR state 8416 state = 0, 8417 8418 // Default abort message 8419 strAbort = "canceled", 8420 8421 // Fake xhr 8422 jqXHR = { 8423 readyState: 0, 8424 8425 // Builds headers hashtable if needed 8426 getResponseHeader: function( key ) { 8427 var match; 8428 if ( state === 2 ) { 8429 if ( !responseHeaders ) { 8430 responseHeaders = {}; 8431 while ( ( match = rheaders.exec( responseHeadersString ) ) ) { 8432 responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; 8433 } 8434 } 8435 match = responseHeaders[ key.toLowerCase() ]; 8436 } 8437 return match == null ? null : match; 8438 }, 8439 8440 // Raw string 8441 getAllResponseHeaders: function() { 8442 return state === 2 ? responseHeadersString : null; 8443 }, 8444 8445 // Caches the header 8446 setRequestHeader: function( name, value ) { 8447 var lname = name.toLowerCase(); 8448 if ( !state ) { 8449 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; 8450 requestHeaders[ name ] = value; 8451 } 8452 return this; 8453 }, 8454 8455 // Overrides response content-type header 8456 overrideMimeType: function( type ) { 8457 if ( !state ) { 8458 s.mimeType = type; 8459 } 8460 return this; 8461 }, 8462 8463 // Status-dependent callbacks 8464 statusCode: function( map ) { 8465 var code; 8466 if ( map ) { 8467 if ( state < 2 ) { 8468 for ( code in map ) { 8469 8470 // Lazy-add the new callback in a way that preserves old ones 8471 statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; 8472 } 8473 } else { 8474 8475 // Execute the appropriate callbacks 8476 jqXHR.always( map[ jqXHR.status ] ); 8477 } 8478 } 8479 return this; 8480 }, 8481 8482 // Cancel the request 8483 abort: function( statusText ) { 8484 var finalText = statusText || strAbort; 8485 if ( transport ) { 8486 transport.abort( finalText ); 8487 } 8488 done( 0, finalText ); 8489 return this; 8490 } 8491 }; 8492 8493 // Attach deferreds 8494 deferred.promise( jqXHR ).complete = completeDeferred.add; 8495 jqXHR.success = jqXHR.done; 8496 jqXHR.error = jqXHR.fail; 8497 8498 // Remove hash character (#7531: and string promotion) 8499 // Add protocol if not provided (prefilters might expect it) 8500 // Handle falsy url in the settings object (#10093: consistency with old signature) 8501 // We also use the url parameter if available 8502 s.url = ( ( url || s.url || location.href ) + "" ).replace( rhash, "" ) 8503 .replace( rprotocol, location.protocol + "//" ); 8504 8505 // Alias method option to type as per ticket #12004 8506 s.type = options.method || options.type || s.method || s.type; 8507 8508 // Extract dataTypes list 8509 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ]; 8510 8511 // A cross-domain request is in order when the origin doesn't match the current origin. 8512 if ( s.crossDomain == null ) { 8513 urlAnchor = document.createElement( "a" ); 8514 8515 // Support: IE8-11+ 8516 // IE throws exception if url is malformed, e.g. http://example.com:80x/ 8517 try { 8518 urlAnchor.href = s.url; 8519 8520 // Support: IE8-11+ 8521 // Anchor's host property isn't correctly set when s.url is relative 8522 urlAnchor.href = urlAnchor.href; 8523 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== 8524 urlAnchor.protocol + "//" + urlAnchor.host; 8525 } catch ( e ) { 8526 8527 // If there is an error parsing the URL, assume it is crossDomain, 8528 // it can be rejected by the transport if it is invalid 8529 s.crossDomain = true; 8530 } 8531 } 8532 8533 // Convert data if not already a string 8534 if ( s.data && s.processData && typeof s.data !== "string" ) { 8535 s.data = jQuery.param( s.data, s.traditional ); 8536 } 8537 8538 // Apply prefilters 8539 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 8540 8541 // If request was aborted inside a prefilter, stop there 8542 if ( state === 2 ) { 8543 return jqXHR; 8544 } 8545 8546 // We can fire global events as of now if asked to 8547 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) 8548 fireGlobals = jQuery.event && s.global; 8549 8550 // Watch for a new set of requests 8551 if ( fireGlobals && jQuery.active++ === 0 ) { 8552 jQuery.event.trigger( "ajaxStart" ); 8553 } 8554 8555 // Uppercase the type 8556 s.type = s.type.toUpperCase(); 8557 8558 // Determine if request has content 8559 s.hasContent = !rnoContent.test( s.type ); 8560 8561 // Save the URL in case we're toying with the If-Modified-Since 8562 // and/or If-None-Match header later on 8563 cacheURL = s.url; 8564 8565 // More options handling for requests with no content 8566 if ( !s.hasContent ) { 8567 8568 // If data is available, append data to url 8569 if ( s.data ) { 8570 cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); 8571 8572 // #9682: remove data so that it's not used in an eventual retry 8573 delete s.data; 8574 } 8575 8576 // Add anti-cache in url if needed 8577 if ( s.cache === false ) { 8578 s.url = rts.test( cacheURL ) ? 8579 8580 // If there is already a '_' parameter, set its value 8581 cacheURL.replace( rts, "$1_=" + nonce++ ) : 8582 8583 // Otherwise add one to the end 8584 cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++; 8585 } 8586 } 8587 8588 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 8589 if ( s.ifModified ) { 8590 if ( jQuery.lastModified[ cacheURL ] ) { 8591 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); 8592 } 8593 if ( jQuery.etag[ cacheURL ] ) { 8594 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); 8595 } 8596 } 8597 8598 // Set the correct header, if data is being sent 8599 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 8600 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 8601 } 8602 8603 // Set the Accepts header for the server, depending on the dataType 8604 jqXHR.setRequestHeader( 8605 "Accept", 8606 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? 8607 s.accepts[ s.dataTypes[ 0 ] ] + 8608 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : 8609 s.accepts[ "*" ] 8610 ); 8611 8612 // Check for headers option 8613 for ( i in s.headers ) { 8614 jqXHR.setRequestHeader( i, s.headers[ i ] ); 8615 } 8616 8617 // Allow custom headers/mimetypes and early abort 8618 if ( s.beforeSend && 8619 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { 8620 8621 // Abort if not done already and return 8622 return jqXHR.abort(); 8623 } 8624 8625 // Aborting is no longer a cancellation 8626 strAbort = "abort"; 8627 8628 // Install callbacks on deferreds 8629 for ( i in { success: 1, error: 1, complete: 1 } ) { 8630 jqXHR[ i ]( s[ i ] ); 8631 } 8632 8633 // Get transport 8634 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 8635 8636 // If no transport, we auto-abort 8637 if ( !transport ) { 8638 done( -1, "No Transport" ); 8639 } else { 8640 jqXHR.readyState = 1; 8641 8642 // Send global event 8643 if ( fireGlobals ) { 8644 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 8645 } 8646 8647 // If request was aborted inside ajaxSend, stop there 8648 if ( state === 2 ) { 8649 return jqXHR; 8650 } 8651 8652 // Timeout 8653 if ( s.async && s.timeout > 0 ) { 8654 timeoutTimer = window.setTimeout( function() { 8655 jqXHR.abort( "timeout" ); 8656 }, s.timeout ); 8657 } 8658 8659 try { 8660 state = 1; 8661 transport.send( requestHeaders, done ); 8662 } catch ( e ) { 8663 8664 // Propagate exception as error if not done 8665 if ( state < 2 ) { 8666 done( -1, e ); 8667 8668 // Simply rethrow otherwise 8669 } else { 8670 throw e; 8671 } 8672 } 8673 } 8674 8675 // Callback for when everything is done 8676 function done( status, nativeStatusText, responses, headers ) { 8677 var isSuccess, success, error, response, modified, 8678 statusText = nativeStatusText; 8679 8680 // Called once 8681 if ( state === 2 ) { 8682 return; 8683 } 8684 8685 // State is "done" now 8686 state = 2; 8687 8688 // Clear timeout if it exists 8689 if ( timeoutTimer ) { 8690 window.clearTimeout( timeoutTimer ); 8691 } 8692 8693 // Dereference transport for early garbage collection 8694 // (no matter how long the jqXHR object will be used) 8695 transport = undefined; 8696 8697 // Cache response headers 8698 responseHeadersString = headers || ""; 8699 8700 // Set readyState 8701 jqXHR.readyState = status > 0 ? 4 : 0; 8702 8703 // Determine if successful 8704 isSuccess = status >= 200 && status < 300 || status === 304; 8705 8706 // Get response data 8707 if ( responses ) { 8708 response = ajaxHandleResponses( s, jqXHR, responses ); 8709 } 8710 8711 // Convert no matter what (that way responseXXX fields are always set) 8712 response = ajaxConvert( s, response, jqXHR, isSuccess ); 8713 8714 // If successful, handle type chaining 8715 if ( isSuccess ) { 8716 8717 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 8718 if ( s.ifModified ) { 8719 modified = jqXHR.getResponseHeader( "Last-Modified" ); 8720 if ( modified ) { 8721 jQuery.lastModified[ cacheURL ] = modified; 8722 } 8723 modified = jqXHR.getResponseHeader( "etag" ); 8724 if ( modified ) { 8725 jQuery.etag[ cacheURL ] = modified; 8726 } 8727 } 8728 8729 // if no content 8730 if ( status === 204 || s.type === "HEAD" ) { 8731 statusText = "nocontent"; 8732 8733 // if not modified 8734 } else if ( status === 304 ) { 8735 statusText = "notmodified"; 8736 8737 // If we have data, let's convert it 8738 } else { 8739 statusText = response.state; 8740 success = response.data; 8741 error = response.error; 8742 isSuccess = !error; 8743 } 8744 } else { 8745 8746 // Extract error from statusText and normalize for non-aborts 8747 error = statusText; 8748 if ( status || !statusText ) { 8749 statusText = "error"; 8750 if ( status < 0 ) { 8751 status = 0; 8752 } 8753 } 8754 } 8755 8756 // Set data for the fake xhr object 8757 jqXHR.status = status; 8758 jqXHR.statusText = ( nativeStatusText || statusText ) + ""; 8759 8760 // Success/Error 8761 if ( isSuccess ) { 8762 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 8763 } else { 8764 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 8765 } 8766 8767 // Status-dependent callbacks 8768 jqXHR.statusCode( statusCode ); 8769 statusCode = undefined; 8770 8771 if ( fireGlobals ) { 8772 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", 8773 [ jqXHR, s, isSuccess ? success : error ] ); 8774 } 8775 8776 // Complete 8777 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); 8778 8779 if ( fireGlobals ) { 8780 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); 8781 8782 // Handle the global AJAX counter 8783 if ( !( --jQuery.active ) ) { 8784 jQuery.event.trigger( "ajaxStop" ); 8785 } 8786 } 8787 } 8788 8789 return jqXHR; 8790 }, 8791 8792 getJSON: function( url, data, callback ) { 8793 return jQuery.get( url, data, callback, "json" ); 8794 }, 8795 8796 getScript: function( url, callback ) { 8797 return jQuery.get( url, undefined, callback, "script" ); 8798 } 8799} ); 8800 8801jQuery.each( [ "get", "post" ], function( i, method ) { 8802 jQuery[ method ] = function( url, data, callback, type ) { 8803 8804 // Shift arguments if data argument was omitted 8805 if ( jQuery.isFunction( data ) ) { 8806 type = type || callback; 8807 callback = data; 8808 data = undefined; 8809 } 8810 8811 // The url can be an options object (which then must have .url) 8812 return jQuery.ajax( jQuery.extend( { 8813 url: url, 8814 type: method, 8815 dataType: type, 8816 data: data, 8817 success: callback 8818 }, jQuery.isPlainObject( url ) && url ) ); 8819 }; 8820} ); 8821 8822 8823jQuery._evalUrl = function( url ) { 8824 return jQuery.ajax( { 8825 url: url, 8826 8827 // Make this explicit, since user can override this through ajaxSetup (#11264) 8828 type: "GET", 8829 dataType: "script", 8830 async: false, 8831 global: false, 8832 "throws": true 8833 } ); 8834}; 8835 8836 8837jQuery.fn.extend( { 8838 wrapAll: function( html ) { 8839 var wrap; 8840 8841 if ( jQuery.isFunction( html ) ) { 8842 return this.each( function( i ) { 8843 jQuery( this ).wrapAll( html.call( this, i ) ); 8844 } ); 8845 } 8846 8847 if ( this[ 0 ] ) { 8848 8849 // The elements to wrap the target around 8850 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); 8851 8852 if ( this[ 0 ].parentNode ) { 8853 wrap.insertBefore( this[ 0 ] ); 8854 } 8855 8856 wrap.map( function() { 8857 var elem = this; 8858 8859 while ( elem.firstElementChild ) { 8860 elem = elem.firstElementChild; 8861 } 8862 8863 return elem; 8864 } ).append( this ); 8865 } 8866 8867 return this; 8868 }, 8869 8870 wrapInner: function( html ) { 8871 if ( jQuery.isFunction( html ) ) { 8872 return this.each( function( i ) { 8873 jQuery( this ).wrapInner( html.call( this, i ) ); 8874 } ); 8875 } 8876 8877 return this.each( function() { 8878 var self = jQuery( this ), 8879 contents = self.contents(); 8880 8881 if ( contents.length ) { 8882 contents.wrapAll( html ); 8883 8884 } else { 8885 self.append( html ); 8886 } 8887 } ); 8888 }, 8889 8890 wrap: function( html ) { 8891 var isFunction = jQuery.isFunction( html ); 8892 8893 return this.each( function( i ) { 8894 jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html ); 8895 } ); 8896 }, 8897 8898 unwrap: function() { 8899 return this.parent().each( function() { 8900 if ( !jQuery.nodeName( this, "body" ) ) { 8901 jQuery( this ).replaceWith( this.childNodes ); 8902 } 8903 } ).end(); 8904 } 8905} ); 8906 8907 8908jQuery.expr.filters.hidden = function( elem ) { 8909 return !jQuery.expr.filters.visible( elem ); 8910}; 8911jQuery.expr.filters.visible = function( elem ) { 8912 8913 // Support: Opera <= 12.12 8914 // Opera reports offsetWidths and offsetHeights less than zero on some elements 8915 // Use OR instead of AND as the element is not visible if either is true 8916 // See tickets #10406 and #13132 8917 return elem.offsetWidth > 0 || elem.offsetHeight > 0 || elem.getClientRects().length > 0; 8918}; 8919 8920 8921 8922 8923var r20 = /%20/g, 8924 rbracket = /\[\]$/, 8925 rCRLF = /\r?\n/g, 8926 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, 8927 rsubmittable = /^(?:input|select|textarea|keygen)/i; 8928 8929function buildParams( prefix, obj, traditional, add ) { 8930 var name; 8931 8932 if ( jQuery.isArray( obj ) ) { 8933 8934 // Serialize array item. 8935 jQuery.each( obj, function( i, v ) { 8936 if ( traditional || rbracket.test( prefix ) ) { 8937 8938 // Treat each array item as a scalar. 8939 add( prefix, v ); 8940 8941 } else { 8942 8943 // Item is non-scalar (array or object), encode its numeric index. 8944 buildParams( 8945 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", 8946 v, 8947 traditional, 8948 add 8949 ); 8950 } 8951 } ); 8952 8953 } else if ( !traditional && jQuery.type( obj ) === "object" ) { 8954 8955 // Serialize object item. 8956 for ( name in obj ) { 8957 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 8958 } 8959 8960 } else { 8961 8962 // Serialize scalar item. 8963 add( prefix, obj ); 8964 } 8965} 8966 8967// Serialize an array of form elements or a set of 8968// key/values into a query string 8969jQuery.param = function( a, traditional ) { 8970 var prefix, 8971 s = [], 8972 add = function( key, value ) { 8973 8974 // If value is a function, invoke it and return its value 8975 value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); 8976 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); 8977 }; 8978 8979 // Set traditional to true for jQuery <= 1.3.2 behavior. 8980 if ( traditional === undefined ) { 8981 traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; 8982 } 8983 8984 // If an array was passed in, assume that it is an array of form elements. 8985 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 8986 8987 // Serialize the form elements 8988 jQuery.each( a, function() { 8989 add( this.name, this.value ); 8990 } ); 8991 8992 } else { 8993 8994 // If traditional, encode the "old" way (the way 1.3.2 or older 8995 // did it), otherwise encode params recursively. 8996 for ( prefix in a ) { 8997 buildParams( prefix, a[ prefix ], traditional, add ); 8998 } 8999 } 9000 9001 // Return the resulting serialization 9002 return s.join( "&" ).replace( r20, "+" ); 9003}; 9004 9005jQuery.fn.extend( { 9006 serialize: function() { 9007 return jQuery.param( this.serializeArray() ); 9008 }, 9009 serializeArray: function() { 9010 return this.map( function() { 9011 9012 // Can add propHook for "elements" to filter or add form elements 9013 var elements = jQuery.prop( this, "elements" ); 9014 return elements ? jQuery.makeArray( elements ) : this; 9015 } ) 9016 .filter( function() { 9017 var type = this.type; 9018 9019 // Use .is( ":disabled" ) so that fieldset[disabled] works 9020 return this.name && !jQuery( this ).is( ":disabled" ) && 9021 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && 9022 ( this.checked || !rcheckableType.test( type ) ); 9023 } ) 9024 .map( function( i, elem ) { 9025 var val = jQuery( this ).val(); 9026 9027 return val == null ? 9028 null : 9029 jQuery.isArray( val ) ? 9030 jQuery.map( val, function( val ) { 9031 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 9032 } ) : 9033 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 9034 } ).get(); 9035 } 9036} ); 9037 9038 9039jQuery.ajaxSettings.xhr = function() { 9040 try { 9041 return new window.XMLHttpRequest(); 9042 } catch ( e ) {} 9043}; 9044 9045var xhrSuccessStatus = { 9046 9047 // File protocol always yields status code 0, assume 200 9048 0: 200, 9049 9050 // Support: IE9 9051 // #1450: sometimes IE returns 1223 when it should be 204 9052 1223: 204 9053 }, 9054 xhrSupported = jQuery.ajaxSettings.xhr(); 9055 9056support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); 9057support.ajax = xhrSupported = !!xhrSupported; 9058 9059jQuery.ajaxTransport( function( options ) { 9060 var callback, errorCallback; 9061 9062 // Cross domain only allowed if supported through XMLHttpRequest 9063 if ( support.cors || xhrSupported && !options.crossDomain ) { 9064 return { 9065 send: function( headers, complete ) { 9066 var i, 9067 xhr = options.xhr(); 9068 9069 xhr.open( 9070 options.type, 9071 options.url, 9072 options.async, 9073 options.username, 9074 options.password 9075 ); 9076 9077 // Apply custom fields if provided 9078 if ( options.xhrFields ) { 9079 for ( i in options.xhrFields ) { 9080 xhr[ i ] = options.xhrFields[ i ]; 9081 } 9082 } 9083 9084 // Override mime type if needed 9085 if ( options.mimeType && xhr.overrideMimeType ) { 9086 xhr.overrideMimeType( options.mimeType ); 9087 } 9088 9089 // X-Requested-With header 9090 // For cross-domain requests, seeing as conditions for a preflight are 9091 // akin to a jigsaw puzzle, we simply never set it to be sure. 9092 // (it can always be set on a per-request basis or even using ajaxSetup) 9093 // For same-domain requests, won't change header if already provided. 9094 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { 9095 headers[ "X-Requested-With" ] = "XMLHttpRequest"; 9096 } 9097 9098 // Set headers 9099 for ( i in headers ) { 9100 xhr.setRequestHeader( i, headers[ i ] ); 9101 } 9102 9103 // Callback 9104 callback = function( type ) { 9105 return function() { 9106 if ( callback ) { 9107 callback = errorCallback = xhr.onload = 9108 xhr.onerror = xhr.onabort = xhr.onreadystatechange = null; 9109 9110 if ( type === "abort" ) { 9111 xhr.abort(); 9112 } else if ( type === "error" ) { 9113 9114 // Support: IE9 9115 // On a manual native abort, IE9 throws 9116 // errors on any property access that is not readyState 9117 if ( typeof xhr.status !== "number" ) { 9118 complete( 0, "error" ); 9119 } else { 9120 complete( 9121 9122 // File: protocol always yields status 0; see #8605, #14207 9123 xhr.status, 9124 xhr.statusText 9125 ); 9126 } 9127 } else { 9128 complete( 9129 xhrSuccessStatus[ xhr.status ] || xhr.status, 9130 xhr.statusText, 9131 9132 // Support: IE9 only 9133 // IE9 has no XHR2 but throws on binary (trac-11426) 9134 // For XHR2 non-text, let the caller handle it (gh-2498) 9135 ( xhr.responseType || "text" ) !== "text" || 9136 typeof xhr.responseText !== "string" ? 9137 { binary: xhr.response } : 9138 { text: xhr.responseText }, 9139 xhr.getAllResponseHeaders() 9140 ); 9141 } 9142 } 9143 }; 9144 }; 9145 9146 // Listen to events 9147 xhr.onload = callback(); 9148 errorCallback = xhr.onerror = callback( "error" ); 9149 9150 // Support: IE9 9151 // Use onreadystatechange to replace onabort 9152 // to handle uncaught aborts 9153 if ( xhr.onabort !== undefined ) { 9154 xhr.onabort = errorCallback; 9155 } else { 9156 xhr.onreadystatechange = function() { 9157 9158 // Check readyState before timeout as it changes 9159 if ( xhr.readyState === 4 ) { 9160 9161 // Allow onerror to be called first, 9162 // but that will not handle a native abort 9163 // Also, save errorCallback to a variable 9164 // as xhr.onerror cannot be accessed 9165 window.setTimeout( function() { 9166 if ( callback ) { 9167 errorCallback(); 9168 } 9169 } ); 9170 } 9171 }; 9172 } 9173 9174 // Create the abort callback 9175 callback = callback( "abort" ); 9176 9177 try { 9178 9179 // Do send the request (this may raise an exception) 9180 xhr.send( options.hasContent && options.data || null ); 9181 } catch ( e ) { 9182 9183 // #14683: Only rethrow if this hasn't been notified as an error yet 9184 if ( callback ) { 9185 throw e; 9186 } 9187 } 9188 }, 9189 9190 abort: function() { 9191 if ( callback ) { 9192 callback(); 9193 } 9194 } 9195 }; 9196 } 9197} ); 9198 9199 9200 9201 9202// Install script dataType 9203jQuery.ajaxSetup( { 9204 accepts: { 9205 script: "text/javascript, application/javascript, " + 9206 "application/ecmascript, application/x-ecmascript" 9207 }, 9208 contents: { 9209 script: /\b(?:java|ecma)script\b/ 9210 }, 9211 converters: { 9212 "text script": function( text ) { 9213 jQuery.globalEval( text ); 9214 return text; 9215 } 9216 } 9217} ); 9218 9219// Handle cache's special case and crossDomain 9220jQuery.ajaxPrefilter( "script", function( s ) { 9221 if ( s.cache === undefined ) { 9222 s.cache = false; 9223 } 9224 if ( s.crossDomain ) { 9225 s.type = "GET"; 9226 } 9227} ); 9228 9229// Bind script tag hack transport 9230jQuery.ajaxTransport( "script", function( s ) { 9231 9232 // This transport only deals with cross domain requests 9233 if ( s.crossDomain ) { 9234 var script, callback; 9235 return { 9236 send: function( _, complete ) { 9237 script = jQuery( "<script>" ).prop( { 9238 charset: s.scriptCharset, 9239 src: s.url 9240 } ).on( 9241 "load error", 9242 callback = function( evt ) { 9243 script.remove(); 9244 callback = null; 9245 if ( evt ) { 9246 complete( evt.type === "error" ? 404 : 200, evt.type ); 9247 } 9248 } 9249 ); 9250 9251 // Use native DOM manipulation to avoid our domManip AJAX trickery 9252 document.head.appendChild( script[ 0 ] ); 9253 }, 9254 abort: function() { 9255 if ( callback ) { 9256 callback(); 9257 } 9258 } 9259 }; 9260 } 9261} ); 9262 9263 9264 9265 9266var oldCallbacks = [], 9267 rjsonp = /(=)\?(?=&|$)|\?\?/; 9268 9269// Default jsonp settings 9270jQuery.ajaxSetup( { 9271 jsonp: "callback", 9272 jsonpCallback: function() { 9273 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); 9274 this[ callback ] = true; 9275 return callback; 9276 } 9277} ); 9278 9279// Detect, normalize options and install callbacks for jsonp requests 9280jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 9281 9282 var callbackName, overwritten, responseContainer, 9283 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? 9284 "url" : 9285 typeof s.data === "string" && 9286 ( s.contentType || "" ) 9287 .indexOf( "application/x-www-form-urlencoded" ) === 0 && 9288 rjsonp.test( s.data ) && "data" 9289 ); 9290 9291 // Handle iff the expected data type is "jsonp" or we have a parameter to set 9292 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { 9293 9294 // Get callback name, remembering preexisting value associated with it 9295 callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? 9296 s.jsonpCallback() : 9297 s.jsonpCallback; 9298 9299 // Insert callback into url or form data 9300 if ( jsonProp ) { 9301 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); 9302 } else if ( s.jsonp !== false ) { 9303 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; 9304 } 9305 9306 // Use data converter to retrieve json after script execution 9307 s.converters[ "script json" ] = function() { 9308 if ( !responseContainer ) { 9309 jQuery.error( callbackName + " was not called" ); 9310 } 9311 return responseContainer[ 0 ]; 9312 }; 9313 9314 // Force json dataType 9315 s.dataTypes[ 0 ] = "json"; 9316 9317 // Install callback 9318 overwritten = window[ callbackName ]; 9319 window[ callbackName ] = function() { 9320 responseContainer = arguments; 9321 }; 9322 9323 // Clean-up function (fires after converters) 9324 jqXHR.always( function() { 9325 9326 // If previous value didn't exist - remove it 9327 if ( overwritten === undefined ) { 9328 jQuery( window ).removeProp( callbackName ); 9329 9330 // Otherwise restore preexisting value 9331 } else { 9332 window[ callbackName ] = overwritten; 9333 } 9334 9335 // Save back as free 9336 if ( s[ callbackName ] ) { 9337 9338 // Make sure that re-using the options doesn't screw things around 9339 s.jsonpCallback = originalSettings.jsonpCallback; 9340 9341 // Save the callback name for future use 9342 oldCallbacks.push( callbackName ); 9343 } 9344 9345 // Call if it was a function and we have a response 9346 if ( responseContainer && jQuery.isFunction( overwritten ) ) { 9347 overwritten( responseContainer[ 0 ] ); 9348 } 9349 9350 responseContainer = overwritten = undefined; 9351 } ); 9352 9353 // Delegate to script 9354 return "script"; 9355 } 9356} ); 9357 9358 9359 9360 9361// Argument "data" should be string of html 9362// context (optional): If specified, the fragment will be created in this context, 9363// defaults to document 9364// keepScripts (optional): If true, will include scripts passed in the html string 9365jQuery.parseHTML = function( data, context, keepScripts ) { 9366 if ( !data || typeof data !== "string" ) { 9367 return null; 9368 } 9369 if ( typeof context === "boolean" ) { 9370 keepScripts = context; 9371 context = false; 9372 } 9373 context = context || document; 9374 9375 var parsed = rsingleTag.exec( data ), 9376 scripts = !keepScripts && []; 9377 9378 // Single tag 9379 if ( parsed ) { 9380 return [ context.createElement( parsed[ 1 ] ) ]; 9381 } 9382 9383 parsed = buildFragment( [ data ], context, scripts ); 9384 9385 if ( scripts && scripts.length ) { 9386 jQuery( scripts ).remove(); 9387 } 9388 9389 return jQuery.merge( [], parsed.childNodes ); 9390}; 9391 9392 9393// Keep a copy of the old load method 9394var _load = jQuery.fn.load; 9395 9396/** 9397 * Load a url into a page 9398 */ 9399jQuery.fn.load = function( url, params, callback ) { 9400 if ( typeof url !== "string" && _load ) { 9401 return _load.apply( this, arguments ); 9402 } 9403 9404 var selector, type, response, 9405 self = this, 9406 off = url.indexOf( " " ); 9407 9408 if ( off > -1 ) { 9409 selector = jQuery.trim( url.slice( off ) ); 9410 url = url.slice( 0, off ); 9411 } 9412 9413 // If it's a function 9414 if ( jQuery.isFunction( params ) ) { 9415 9416 // We assume that it's the callback 9417 callback = params; 9418 params = undefined; 9419 9420 // Otherwise, build a param string 9421 } else if ( params && typeof params === "object" ) { 9422 type = "POST"; 9423 } 9424 9425 // If we have elements to modify, make the request 9426 if ( self.length > 0 ) { 9427 jQuery.ajax( { 9428 url: url, 9429 9430 // If "type" variable is undefined, then "GET" method will be used. 9431 // Make value of this field explicit since 9432 // user can override it through ajaxSetup method 9433 type: type || "GET", 9434 dataType: "html", 9435 data: params 9436 } ).done( function( responseText ) { 9437 9438 // Save response for use in complete callback 9439 response = arguments; 9440 9441 self.html( selector ? 9442 9443 // If a selector was specified, locate the right elements in a dummy div 9444 // Exclude scripts to avoid IE 'Permission Denied' errors 9445 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : 9446 9447 // Otherwise use the full result 9448 responseText ); 9449 9450 // If the request succeeds, this function gets "data", "status", "jqXHR" 9451 // but they are ignored because response was set above. 9452 // If it fails, this function gets "jqXHR", "status", "error" 9453 } ).always( callback && function( jqXHR, status ) { 9454 self.each( function() { 9455 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); 9456 } ); 9457 } ); 9458 } 9459 9460 return this; 9461}; 9462 9463 9464 9465 9466// Attach a bunch of functions for handling common AJAX events 9467jQuery.each( [ 9468 "ajaxStart", 9469 "ajaxStop", 9470 "ajaxComplete", 9471 "ajaxError", 9472 "ajaxSuccess", 9473 "ajaxSend" 9474], function( i, type ) { 9475 jQuery.fn[ type ] = function( fn ) { 9476 return this.on( type, fn ); 9477 }; 9478} ); 9479 9480 9481 9482 9483jQuery.expr.filters.animated = function( elem ) { 9484 return jQuery.grep( jQuery.timers, function( fn ) { 9485 return elem === fn.elem; 9486 } ).length; 9487}; 9488 9489 9490 9491 9492/** 9493 * Gets a window from an element 9494 */ 9495function getWindow( elem ) { 9496 return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView; 9497} 9498 9499jQuery.offset = { 9500 setOffset: function( elem, options, i ) { 9501 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, 9502 position = jQuery.css( elem, "position" ), 9503 curElem = jQuery( elem ), 9504 props = {}; 9505 9506 // Set position first, in-case top/left are set even on static elem 9507 if ( position === "static" ) { 9508 elem.style.position = "relative"; 9509 } 9510 9511 curOffset = curElem.offset(); 9512 curCSSTop = jQuery.css( elem, "top" ); 9513 curCSSLeft = jQuery.css( elem, "left" ); 9514 calculatePosition = ( position === "absolute" || position === "fixed" ) && 9515 ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; 9516 9517 // Need to be able to calculate position if either 9518 // top or left is auto and position is either absolute or fixed 9519 if ( calculatePosition ) { 9520 curPosition = curElem.position(); 9521 curTop = curPosition.top; 9522 curLeft = curPosition.left; 9523 9524 } else { 9525 curTop = parseFloat( curCSSTop ) || 0; 9526 curLeft = parseFloat( curCSSLeft ) || 0; 9527 } 9528 9529 if ( jQuery.isFunction( options ) ) { 9530 9531 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) 9532 options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); 9533 } 9534 9535 if ( options.top != null ) { 9536 props.top = ( options.top - curOffset.top ) + curTop; 9537 } 9538 if ( options.left != null ) { 9539 props.left = ( options.left - curOffset.left ) + curLeft; 9540 } 9541 9542 if ( "using" in options ) { 9543 options.using.call( elem, props ); 9544 9545 } else { 9546 curElem.css( props ); 9547 } 9548 } 9549}; 9550 9551jQuery.fn.extend( { 9552 offset: function( options ) { 9553 if ( arguments.length ) { 9554 return options === undefined ? 9555 this : 9556 this.each( function( i ) { 9557 jQuery.offset.setOffset( this, options, i ); 9558 } ); 9559 } 9560 9561 var docElem, win, 9562 elem = this[ 0 ], 9563 box = { top: 0, left: 0 }, 9564 doc = elem && elem.ownerDocument; 9565 9566 if ( !doc ) { 9567 return; 9568 } 9569 9570 docElem = doc.documentElement; 9571 9572 // Make sure it's not a disconnected DOM node 9573 if ( !jQuery.contains( docElem, elem ) ) { 9574 return box; 9575 } 9576 9577 box = elem.getBoundingClientRect(); 9578 win = getWindow( doc ); 9579 return { 9580 top: box.top + win.pageYOffset - docElem.clientTop, 9581 left: box.left + win.pageXOffset - docElem.clientLeft 9582 }; 9583 }, 9584 9585 position: function() { 9586 if ( !this[ 0 ] ) { 9587 return; 9588 } 9589 9590 var offsetParent, offset, 9591 elem = this[ 0 ], 9592 parentOffset = { top: 0, left: 0 }; 9593 9594 // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, 9595 // because it is its only offset parent 9596 if ( jQuery.css( elem, "position" ) === "fixed" ) { 9597 9598 // Assume getBoundingClientRect is there when computed position is fixed 9599 offset = elem.getBoundingClientRect(); 9600 9601 } else { 9602 9603 // Get *real* offsetParent 9604 offsetParent = this.offsetParent(); 9605 9606 // Get correct offsets 9607 offset = this.offset(); 9608 if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) { 9609 parentOffset = offsetParent.offset(); 9610 } 9611 9612 // Add offsetParent borders 9613 parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ); 9614 parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ); 9615 } 9616 9617 // Subtract parent offsets and element margins 9618 return { 9619 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), 9620 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) 9621 }; 9622 }, 9623 9624 // This method will return documentElement in the following cases: 9625 // 1) For the element inside the iframe without offsetParent, this method will return 9626 // documentElement of the parent window 9627 // 2) For the hidden or detached element 9628 // 3) For body or html element, i.e. in case of the html node - it will return itself 9629 // 9630 // but those exceptions were never presented as a real life use-cases 9631 // and might be considered as more preferable results. 9632 // 9633 // This logic, however, is not guaranteed and can change at any point in the future 9634 offsetParent: function() { 9635 return this.map( function() { 9636 var offsetParent = this.offsetParent; 9637 9638 while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { 9639 offsetParent = offsetParent.offsetParent; 9640 } 9641 9642 return offsetParent || documentElement; 9643 } ); 9644 } 9645} ); 9646 9647// Create scrollLeft and scrollTop methods 9648jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { 9649 var top = "pageYOffset" === prop; 9650 9651 jQuery.fn[ method ] = function( val ) { 9652 return access( this, function( elem, method, val ) { 9653 var win = getWindow( elem ); 9654 9655 if ( val === undefined ) { 9656 return win ? win[ prop ] : elem[ method ]; 9657 } 9658 9659 if ( win ) { 9660 win.scrollTo( 9661 !top ? val : win.pageXOffset, 9662 top ? val : win.pageYOffset 9663 ); 9664 9665 } else { 9666 elem[ method ] = val; 9667 } 9668 }, method, val, arguments.length ); 9669 }; 9670} ); 9671 9672// Support: Safari<7-8+, Chrome<37-44+ 9673// Add the top/left cssHooks using jQuery.fn.position 9674// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 9675// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280 9676// getComputedStyle returns percent when specified for top/left/bottom/right; 9677// rather than make the css module depend on the offset module, just check for it here 9678jQuery.each( [ "top", "left" ], function( i, prop ) { 9679 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, 9680 function( elem, computed ) { 9681 if ( computed ) { 9682 computed = curCSS( elem, prop ); 9683 9684 // If curCSS returns percentage, fallback to offset 9685 return rnumnonpx.test( computed ) ? 9686 jQuery( elem ).position()[ prop ] + "px" : 9687 computed; 9688 } 9689 } 9690 ); 9691} ); 9692 9693 9694// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods 9695jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { 9696 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, 9697 function( defaultExtra, funcName ) { 9698 9699 // Margin is only for outerHeight, outerWidth 9700 jQuery.fn[ funcName ] = function( margin, value ) { 9701 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), 9702 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); 9703 9704 return access( this, function( elem, type, value ) { 9705 var doc; 9706 9707 if ( jQuery.isWindow( elem ) ) { 9708 9709 // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there 9710 // isn't a whole lot we can do. See pull request at this URL for discussion: 9711 // https://github.com/jquery/jquery/pull/764 9712 return elem.document.documentElement[ "client" + name ]; 9713 } 9714 9715 // Get document width or height 9716 if ( elem.nodeType === 9 ) { 9717 doc = elem.documentElement; 9718 9719 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], 9720 // whichever is greatest 9721 return Math.max( 9722 elem.body[ "scroll" + name ], doc[ "scroll" + name ], 9723 elem.body[ "offset" + name ], doc[ "offset" + name ], 9724 doc[ "client" + name ] 9725 ); 9726 } 9727 9728 return value === undefined ? 9729 9730 // Get width or height on the element, requesting but not forcing parseFloat 9731 jQuery.css( elem, type, extra ) : 9732 9733 // Set width or height on the element 9734 jQuery.style( elem, type, value, extra ); 9735 }, type, chainable ? margin : undefined, chainable, null ); 9736 }; 9737 } ); 9738} ); 9739 9740 9741jQuery.fn.extend( { 9742 9743 bind: function( types, data, fn ) { 9744 return this.on( types, null, data, fn ); 9745 }, 9746 unbind: function( types, fn ) { 9747 return this.off( types, null, fn ); 9748 }, 9749 9750 delegate: function( selector, types, data, fn ) { 9751 return this.on( types, selector, data, fn ); 9752 }, 9753 undelegate: function( selector, types, fn ) { 9754 9755 // ( namespace ) or ( selector, types [, fn] ) 9756 return arguments.length === 1 ? 9757 this.off( selector, "**" ) : 9758 this.off( types, selector || "**", fn ); 9759 }, 9760 size: function() { 9761 return this.length; 9762 } 9763} ); 9764 9765jQuery.fn.andSelf = jQuery.fn.addBack; 9766 9767 9768 9769 9770// Register as a named AMD module, since jQuery can be concatenated with other 9771// files that may use define, but not via a proper concatenation script that 9772// understands anonymous AMD modules. A named AMD is safest and most robust 9773// way to register. Lowercase jquery is used because AMD module names are 9774// derived from file names, and jQuery is normally delivered in a lowercase 9775// file name. Do this after creating the global so that if an AMD module wants 9776// to call noConflict to hide this version of jQuery, it will work. 9777 9778// Note that for maximum portability, libraries that are not jQuery should 9779// declare themselves as anonymous modules, and avoid setting a global if an 9780// AMD loader is present. jQuery is a special case. For more information, see 9781// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon 9782 9783if ( typeof define === "function" && define.amd ) { 9784 define( "jquery", [], function() { 9785 return jQuery; 9786 } ); 9787} 9788 9789 9790 9791var 9792 9793 // Map over jQuery in case of overwrite 9794 _jQuery = window.jQuery, 9795 9796 // Map over the $ in case of overwrite 9797 _$ = window.$; 9798 9799jQuery.noConflict = function( deep ) { 9800 if ( window.$ === jQuery ) { 9801 window.$ = _$; 9802 } 9803 9804 if ( deep && window.jQuery === jQuery ) { 9805 window.jQuery = _jQuery; 9806 } 9807 9808 return jQuery; 9809}; 9810 9811// Expose jQuery and $ identifiers, even in AMD 9812// (#7102#comment:10, https://github.com/jquery/jquery/pull/557) 9813// and CommonJS for browser emulators (#13566) 9814if ( !noGlobal ) { 9815 window.jQuery = window.$ = jQuery; 9816} 9817 9818return jQuery; 9819})); 9820
9821 9822 9823 9824// add 9825revslider_migrate_jquery(); 9826 9827function revslider_migrate_jquery() { 9828 for(var k in jQuery_backup) 9829 { 9830 if(typeof jQuery[k] === 'undefined') 9831 jQuery[k] = jQuery_backup[k]; 9832 } 9833 for(k in jQuery_backup.fn) 9834 { 9835 if(typeof jQuery.fn[k] === 'undefined') 9836 jQuery.fn[k] = jQuery_backup.fn[k]; 9837 } 9838}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.