1/*! 2 * jQuery JavaScript Library v1.6.1 3 * http://jquery.com/ 4 * 5 * Copyright 2011, John Resig 6 * Dual licensed under the MIT or GPL Version 2 licenses. 7 * http://jquery.org/license 8 * 9 * Includes Sizzle.js 10 * http://sizzlejs.com/ 11 * Copyright 2011, The Dojo Foundation 12 * Released under the MIT, BSD, and GPL Licenses. 13 * 14 * Date: Thu May 12 15:04:36 2011 -0400 15 */ 16(function( window, undefined ) { 17 18// Use the correct document accordingly with window argument (sandbox) 19var document = window.document, 20 navigator = window.navigator, 21 location = window.location; 22var jQuery = (function() { 23 24// Define a local copy of jQuery 25var jQuery = function( selector, context ) { 26 // The jQuery object is actually just the init constructor 'enhanced' 27 return new jQuery.fn.init( selector, context, rootjQuery ); 28 }, 29 30 // Map over jQuery in case of overwrite 31 _jQuery = window.jQuery, 32 33 // Map over the $ in case of overwrite 34 _$ = window.$, 35 36 // A central reference to the root jQuery(document) 37 rootjQuery, 38 39 // A simple way to check for HTML strings or ID strings 40 // (both of which we optimize for) 41 quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, 42 43 // Check if a string has a non-whitespace character in it 44 rnotwhite = /\S/, 45 46 // Used for trimming whitespace 47 trimLeft = /^\s+/, 48 trimRight = /\s+$/, 49 50 // Check for digits 51 rdigit = /\d/, 52 53 // Match a standalone tag 54 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, 55 56 // JSON RegExp 57 rvalidchars = /^[\],:{}\s]*$/, 58 rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, 59 rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, 60 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, 61 62 // Useragent RegExp 63 rwebkit = /(webkit)[ \/]([\w.]+)/, 64 ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, 65 rmsie = /(msie) ([\w.]+)/, 66 rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, 67 68 // Keep a UserAgent string for use with jQuery.browser 69 userAgent = navigator.userAgent, 70 71 // For matching the engine and version of the browser 72 browserMatch, 73 74 // The deferred used on DOM ready 75 readyList, 76 77 // The ready event handler 78 DOMContentLoaded, 79 80 // Save a reference to some core methods 81 toString = Object.prototype.toString, 82 hasOwn = Object.prototype.hasOwnProperty, 83 push = Array.prototype.push, 84 slice = Array.prototype.slice, 85 trim = String.prototype.trim, 86 indexOf = Array.prototype.indexOf, 87 88 // [[Class]] -> type pairs 89 class2type = {}; 90 91jQuery.fn = jQuery.prototype = { 92 constructor: jQuery, 93 init: function( selector, context, rootjQuery ) { 94 var match, elem, ret, doc; 95 96 // Handle $(""), $(null), or $(undefined) 97 if ( !selector ) { 98 return this; 99 } 100 101 // Handle $(DOMElement) 102 if ( selector.nodeType ) { 103 this.context = this[0] = selector; 104 this.length = 1; 105 return this; 106 } 107 108 // The body element only exists once, optimize finding it 109 if ( selector === "body" && !context && document.body ) { 110 this.context = document; 111 this[0] = document.body; 112 this.selector = selector; 113 this.length = 1; 114 return this; 115 } 116 117 // Handle HTML strings 118 if ( typeof selector === "string" ) { 119 // Are we dealing with HTML string or an ID? 120 if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { 121 // Assume that strings that start and end with <> are HTML and skip the regex check 122 match = [ null, selector, null ]; 123 124 } else { 125 match = quickExpr.exec( selector ); 126 } 127 128 // Verify a match, and that no context was specified for #id 129 if ( match && (match[1] || !context) ) { 130 131 // HANDLE: $(html) -> $(array) 132 if ( match[1] ) { 133 context = context instanceof jQuery ? context[0] : context; 134 doc = (context ? context.ownerDocument || context : document); 135 136 // If a single string is passed in and it's a single tag 137 // just do a createElement and skip the rest 138 ret = rsingleTag.exec( selector ); 139 140 if ( ret ) { 141 if ( jQuery.isPlainObject( context ) ) { 142 selector = [ document.createElement( ret[1] ) ]; 143 jQuery.fn.attr.call( selector, context, true ); 144 145 } else { 146 selector = [ doc.createElement( ret[1] ) ]; 147 } 148 149 } else { 150 ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); 151 selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes; 152 } 153 154 return jQuery.merge( this, selector ); 155 156 // HANDLE: $("#id") 157 } else { 158 elem = document.getElementById( match[2] ); 159 160 // Check parentNode to catch when Blackberry 4.6 returns 161 // nodes that are no longer in the document #6963 162 if ( elem && elem.parentNode ) { 163 // Handle the case where IE and Opera return items 164 // by name instead of ID 165 if ( elem.id !== match[2] ) { 166 return rootjQuery.find( selector ); 167 } 168 169 // Otherwise, we inject the element directly into the jQuery object 170 this.length = 1; 171 this[0] = elem; 172 } 173 174 this.context = document; 175 this.selector = selector; 176 return this; 177 } 178 179 // HANDLE: $(expr, $(...)) 180 } else if ( !context || context.jquery ) { 181 return (context || rootjQuery).find( selector ); 182 183 // HANDLE: $(expr, context) 184 // (which is just equivalent to: $(context).find(expr) 185 } else { 186 return this.constructor( context ).find( selector ); 187 } 188 189 // HANDLE: $(function) 190 // Shortcut for document ready 191 } else if ( jQuery.isFunction( selector ) ) { 192 return rootjQuery.ready( selector ); 193 } 194 195 if (selector.selector !== undefined) { 196 this.selector = selector.selector; 197 this.context = selector.context; 198 } 199 200 return jQuery.makeArray( selector, this ); 201 }, 202 203 // Start with an empty selector 204 selector: "", 205 206 // The current version of jQuery being used 207 jquery: "1.6.1", 208 209 // The default length of a jQuery object is 0 210 length: 0, 211 212 // The number of elements contained in the matched element set 213 size: function() { 214 return this.length; 215 }, 216 217 toArray: function() { 218 return slice.call( this, 0 ); 219 }, 220 221 // Get the Nth element in the matched element set OR 222 // Get the whole matched element set as a clean array 223 get: function( num ) { 224 return num == null ? 225 226 // Return a 'clean' array 227 this.toArray() : 228 229 // Return just the object 230 ( num < 0 ? this[ this.length + num ] : this[ num ] ); 231 }, 232 233 // Take an array of elements and push it onto the stack 234 // (returning the new matched element set) 235 pushStack: function( elems, name, selector ) { 236 // Build a new jQuery matched element set 237 var ret = this.constructor(); 238 239 if ( jQuery.isArray( elems ) ) { 240 push.apply( ret, elems ); 241 242 } else { 243 jQuery.merge( ret, elems ); 244 } 245 246 // Add the old object onto the stack (as a reference) 247 ret.prevObject = this; 248 249 ret.context = this.context; 250 251 if ( name === "find" ) { 252 ret.selector = this.selector + (this.selector ? " " : "") + selector; 253 } else if ( name ) { 254 ret.selector = this.selector + "." + name + "(" + selector + ")"; 255 } 256 257 // Return the newly-formed element set 258 return ret; 259 }, 260 261 // Execute a callback for every element in the matched set. 262 // (You can seed the arguments with an array of args, but this is 263 // only used internally.) 264 each: function( callback, args ) { 265 return jQuery.each( this, callback, args ); 266 }, 267 268 ready: function( fn ) { 269 // Attach the listeners 270 jQuery.bindReady(); 271 272 // Add the callback 273 readyList.done( fn ); 274 275 return this; 276 }, 277 278 eq: function( i ) { 279 return i === -1 ? 280 this.slice( i ) : 281 this.slice( i, +i + 1 ); 282 }, 283 284 first: function() { 285 return this.eq( 0 ); 286 }, 287 288 last: function() { 289 return this.eq( -1 ); 290 }, 291 292 slice: function() { 293 return this.pushStack( slice.apply( this, arguments ), 294 "slice", slice.call(arguments).join(",") ); 295 }, 296 297 map: function( callback ) { 298 return this.pushStack( jQuery.map(this, function( elem, i ) { 299 return callback.call( elem, i, elem ); 300 })); 301 }, 302 303 end: function() { 304 return this.prevObject || this.constructor(null); 305 }, 306 307 // For internal use only. 308 // Behaves like an Array's method, not like a jQuery method. 309 push: push, 310 sort: [].sort, 311 splice: [].splice 312}; 313 314// Give the init function the jQuery prototype for later instantiation 315jQuery.fn.init.prototype = jQuery.fn; 316 317jQuery.extend = jQuery.fn.extend = function() { 318 var options, name, src, copy, copyIsArray, clone, 319 target = arguments[0] || {}, 320 i = 1, 321 length = arguments.length, 322 deep = false; 323 324 // Handle a deep copy situation 325 if ( typeof target === "boolean" ) { 326 deep = target; 327 target = arguments[1] || {}; 328 // skip the boolean and the target 329 i = 2; 330 } 331 332 // Handle case when target is a string or something (possible in deep copy) 333 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { 334 target = {}; 335 } 336 337 // extend jQuery itself if only one argument is passed 338 if ( length === i ) { 339 target = this; 340 --i; 341 } 342 343 for ( ; i < length; i++ ) { 344 // Only deal with non-null/undefined values 345 if ( (options = arguments[ i ]) != null ) { 346 // Extend the base object 347 for ( name in options ) { 348 src = target[ name ]; 349 copy = options[ name ]; 350 351 // Prevent never-ending loop 352 if ( target === copy ) { 353 continue; 354 } 355 356 // Recurse if we're merging plain objects or arrays 357 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { 358 if ( copyIsArray ) { 359 copyIsArray = false; 360 clone = src && jQuery.isArray(src) ? src : []; 361 362 } else { 363 clone = src && jQuery.isPlainObject(src) ? src : {}; 364 } 365 366 // Never move original objects, clone them 367 target[ name ] = jQuery.extend( deep, clone, copy ); 368 369 // Don't bring in undefined values 370 } else if ( copy !== undefined ) { 371 target[ name ] = copy; 372 } 373 } 374 } 375 } 376 377 // Return the modified object 378 return target; 379}; 380 381jQuery.extend({ 382 noConflict: function( deep ) { 383 if ( window.$ === jQuery ) { 384 window.$ = _$; 385 } 386 387 if ( deep && window.jQuery === jQuery ) { 388 window.jQuery = _jQuery; 389 } 390 391 return jQuery; 392 }, 393 394 // Is the DOM ready to be used? Set to true once it occurs. 395 isReady: false, 396 397 // A counter to track how many items to wait for before 398 // the ready event fires. See #6781 399 readyWait: 1, 400 401 // Hold (or release) the ready event 402 holdReady: function( hold ) { 403 if ( hold ) { 404 jQuery.readyWait++; 405 } else { 406 jQuery.ready( true ); 407 } 408 }, 409 410 // Handle when the DOM is ready 411 ready: function( wait ) { 412 // Either a released hold or an DOMready/load event and not yet ready 413 if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { 414 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 415 if ( !document.body ) { 416 return setTimeout( jQuery.ready, 1 ); 417 } 418 419 // Remember that the DOM is ready 420 jQuery.isReady = true; 421 422 // If a normal DOM Ready event fired, decrement, and wait if need be 423 if ( wait !== true && --jQuery.readyWait > 0 ) { 424 return; 425 } 426 427 // If there are functions bound, to execute 428 readyList.resolveWith( document, [ jQuery ] ); 429 430 // Trigger any bound ready events 431 if ( jQuery.fn.trigger ) { 432 jQuery( document ).trigger( "ready" ).unbind( "ready" ); 433 } 434 } 435 }, 436 437 bindReady: function() { 438 if ( readyList ) { 439 return; 440 } 441 442 readyList = jQuery._Deferred(); 443 444 // Catch cases where $(document).ready() is called after the 445 // browser event has already occurred. 446 if ( document.readyState === "complete" ) { 447 // Handle it asynchronously to allow scripts the opportunity to delay ready 448 return setTimeout( jQuery.ready, 1 ); 449 } 450 451 // Mozilla, Opera and webkit nightlies currently support this event 452 if ( document.addEventListener ) { 453 // Use the handy event callback 454 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 455 456 // A fallback to window.onload, that will always work 457 window.addEventListener( "load", jQuery.ready, false ); 458 459 // If IE event model is used 460 } else if ( document.attachEvent ) { 461 // ensure firing before onload, 462 // maybe late but safe also for iframes 463 document.attachEvent( "onreadystatechange", DOMContentLoaded ); 464 465 // A fallback to window.onload, that will always work 466 window.attachEvent( "onload", jQuery.ready ); 467 468 // If IE and not a frame 469 // continually check to see if the document is ready 470 var toplevel = false; 471 472 try { 473 toplevel = window.frameElement == null; 474 } catch(e) {} 475 476 if ( document.documentElement.doScroll && toplevel ) { 477 doScrollCheck(); 478 } 479 } 480 }, 481 482 // See test/unit/core.js for details concerning isFunction. 483 // Since version 1.3, DOM methods and functions like alert 484 // aren't supported. They return false on IE (#2968). 485 isFunction: function( obj ) { 486 return jQuery.type(obj) === "function"; 487 }, 488 489 isArray: Array.isArray || function( obj ) { 490 return jQuery.type(obj) === "array"; 491 }, 492 493 // A crude way of determining if an object is a window 494 isWindow: function( obj ) { 495 return obj && typeof obj === "object" && "setInterval" in obj; 496 }, 497 498 isNaN: function( obj ) { 499 return obj == null || !rdigit.test( obj ) || isNaN( obj ); 500 }, 501 502 type: function( obj ) { 503 return obj == null ? 504 String( obj ) : 505 class2type[ toString.call(obj) ] || "object"; 506 }, 507 508 isPlainObject: function( obj ) { 509 // Must be an Object. 510 // Because of IE, we also have to check the presence of the constructor property. 511 // Make sure that DOM nodes and window objects don't pass through, as well 512 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { 513 return false; 514 } 515 516 // Not own constructor property must be Object 517 if ( obj.constructor && 518 !hasOwn.call(obj, "constructor") && 519 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { 520 return false; 521 } 522 523 // Own properties are enumerated firstly, so to speed up, 524 // if last one is own, then all properties are own. 525 526 var key; 527 for ( key in obj ) {} 528 529 return key === undefined || hasOwn.call( obj, key ); 530 }, 531 532 isEmptyObject: function( obj ) { 533 for ( var name in obj ) { 534 return false; 535 } 536 return true; 537 }, 538 539 error: function( msg ) { 540 throw msg; 541 }, 542 543 parseJSON: function( data ) { 544 if ( typeof data !== "string" || !data ) { 545 return null; 546 } 547 548 // Make sure leading/trailing whitespace is removed (IE can't handle it) 549 data = jQuery.trim( data ); 550 551 // Attempt to parse using the native JSON parser first 552 if ( window.JSON && window.JSON.parse ) { 553 return window.JSON.parse( data ); 554 } 555 556 // Make sure the incoming data is actual JSON 557 // Logic borrowed from http://json.org/json2.js 558 if ( rvalidchars.test( data.replace( rvalidescape, "@" ) 559 .replace( rvalidtokens, "]" ) 560 .replace( rvalidbraces, "")) ) { 561 562 return (new Function( "return " + data ))(); 563 564 } 565 jQuery.error( "Invalid JSON: " + data ); 566 }, 567 568 // Cross-browser xml parsing 569 // (xml & tmp used internally) 570 parseXML: function( data , xml , tmp ) { 571 572 if ( window.DOMParser ) { // Standard 573 tmp = new DOMParser(); 574 xml = tmp.parseFromString( data , "text/xml" ); 575 } else { // IE 576 xml = new ActiveXObject( "Microsoft.XMLDOM" ); 577 xml.async = "false"; 578 xml.loadXML( data ); 579 } 580 581 tmp = xml.documentElement; 582 583 if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) { 584 jQuery.error( "Invalid XML: " + data ); 585 } 586 587 return xml; 588 }, 589 590 noop: function() {}, 591 592 // Evaluates a script in a global context 593 // Workarounds based on findings by Jim Driscoll 594 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context 595 globalEval: function( data ) { 596 if ( data && rnotwhite.test( data ) ) { 597 // We use execScript on Internet Explorer 598 // We use an anonymous function so that context is window 599 // rather than jQuery in Firefox 600 ( window.execScript || function( data ) { 601 window[ "eval" ].call( window, data ); 602 } )( data ); 603 } 604 }, 605 606 nodeName: function( elem, name ) { 607 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); 608 }, 609 610 // args is for internal usage only 611 each: function( object, callback, args ) { 612 var name, i = 0, 613 length = object.length, 614 isObj = length === undefined || jQuery.isFunction( object ); 615 616 if ( args ) { 617 if ( isObj ) { 618 for ( name in object ) { 619 if ( callback.apply( object[ name ], args ) === false ) { 620 break; 621 } 622 } 623 } else { 624 for ( ; i < length; ) { 625 if ( callback.apply( object[ i++ ], args ) === false ) { 626 break; 627 } 628 } 629 } 630 631 // A special, fast, case for the most common use of each 632 } else { 633 if ( isObj ) { 634 for ( name in object ) { 635 if ( callback.call( object[ name ], name, object[ name ] ) === false ) { 636 break; 637 } 638 } 639 } else { 640 for ( ; i < length; ) { 641 if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { 642 break; 643 } 644 } 645 } 646 } 647 648 return object; 649 }, 650 651 // Use native String.trim function wherever possible 652 trim: trim ? 653 function( text ) { 654 return text == null ? 655 "" : 656 trim.call( text ); 657 } : 658 659 // Otherwise use our own trimming functionality 660 function( text ) { 661 return text == null ? 662 "" : 663 text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); 664 }, 665 666 // results is for internal usage only 667 makeArray: function( array, results ) { 668 var ret = results || []; 669 670 if ( array != null ) { 671 // The window, strings (and functions) also have 'length' 672 // The extra typeof function check is to prevent crashes 673 // in Safari 2 (See: #3039) 674 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 675 var type = jQuery.type( array ); 676 677 if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { 678 push.call( ret, array ); 679 } else { 680 jQuery.merge( ret, array ); 681 } 682 } 683 684 return ret; 685 }, 686 687 inArray: function( elem, array ) { 688 689 if ( indexOf ) { 690 return indexOf.call( array, elem ); 691 } 692 693 for ( var i = 0, length = array.length; i < length; i++ ) { 694 if ( array[ i ] === elem ) { 695 return i; 696 } 697 } 698 699 return -1; 700 }, 701 702 merge: function( first, second ) { 703 var i = first.length, 704 j = 0; 705 706 if ( typeof second.length === "number" ) { 707 for ( var l = second.length; j < l; j++ ) { 708 first[ i++ ] = second[ j ]; 709 } 710 711 } else { 712 while ( second[j] !== undefined ) { 713 first[ i++ ] = second[ j++ ]; 714 } 715 } 716 717 first.length = i; 718 719 return first; 720 }, 721 722 grep: function( elems, callback, inv ) { 723 var ret = [], retVal; 724 inv = !!inv; 725 726 // Go through the array, only saving the items 727 // that pass the validator function 728 for ( var i = 0, length = elems.length; i < length; i++ ) { 729 retVal = !!callback( elems[ i ], i ); 730 if ( inv !== retVal ) { 731 ret.push( elems[ i ] ); 732 } 733 } 734 735 return ret; 736 }, 737 738 // arg is for internal usage only 739 map: function( elems, callback, arg ) { 740 var value, key, ret = [], 741 i = 0, 742 length = elems.length, 743 // jquery objects are treated as arrays 744 isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; 745 746 // Go through the array, translating each of the items to their 747 if ( isArray ) { 748 for ( ; i < length; i++ ) { 749 value = callback( elems[ i ], i, arg ); 750 751 if ( value != null ) { 752 ret[ ret.length ] = value; 753 } 754 } 755 756 // Go through every key on the object, 757 } else { 758 for ( key in elems ) { 759 value = callback( elems[ key ], key, arg ); 760 761 if ( value != null ) { 762 ret[ ret.length ] = value; 763 } 764 } 765 } 766 767 // Flatten any nested arrays 768 return ret.concat.apply( [], ret ); 769 }, 770 771 // A global GUID counter for objects 772 guid: 1, 773 774 // Bind a function to a context, optionally partially applying any 775 // arguments. 776 proxy: function( fn, context ) { 777 if ( typeof context === "string" ) { 778 var tmp = fn[ context ]; 779 context = fn; 780 fn = tmp; 781 } 782 783 // Quick check to determine if target is callable, in the spec 784 // this throws a TypeError, but we will just return undefined. 785 if ( !jQuery.isFunction( fn ) ) { 786 return undefined; 787 } 788 789 // Simulated bind 790 var args = slice.call( arguments, 2 ), 791 proxy = function() { 792 return fn.apply( context, args.concat( slice.call( arguments ) ) ); 793 }; 794 795 // Set the guid of unique handler to the same of original handler, so it can be removed 796 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; 797 798 return proxy; 799 }, 800 801 // Mutifunctional method to get and set values to a collection 802 // The value/s can be optionally by executed if its a function 803 access: function( elems, key, value, exec, fn, pass ) { 804 var length = elems.length; 805 806 // Setting many attributes 807 if ( typeof key === "object" ) { 808 for ( var k in key ) { 809 jQuery.access( elems, k, key[k], exec, fn, value ); 810 } 811 return elems; 812 } 813 814 // Setting one attribute 815 if ( value !== undefined ) { 816 // Optionally, function values get executed if exec is true 817 exec = !pass && exec && jQuery.isFunction(value); 818 819 for ( var i = 0; i < length; i++ ) { 820 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); 821 } 822 823 return elems; 824 } 825 826 // Getting an attribute 827 return length ? fn( elems[0], key ) : undefined; 828 }, 829 830 now: function() { 831 return (new Date()).getTime(); 832 }, 833 834 // Use of jQuery.browser is frowned upon. 835 // More details: http://docs.jquery.com/Utilities/jQuery.browser 836 uaMatch: function( ua ) { 837 ua = ua.toLowerCase(); 838 839 var match = rwebkit.exec( ua ) || 840 ropera.exec( ua ) || 841 rmsie.exec( ua ) || 842 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || 843 []; 844 845 return { browser: match[1] || "", version: match[2] || "0" }; 846 }, 847 848 sub: function() { 849 function jQuerySub( selector, context ) { 850 return new jQuerySub.fn.init( selector, context ); 851 } 852 jQuery.extend( true, jQuerySub, this ); 853 jQuerySub.superclass = this; 854 jQuerySub.fn = jQuerySub.prototype = this(); 855 jQuerySub.fn.constructor = jQuerySub; 856 jQuerySub.sub = this.sub; 857 jQuerySub.fn.init = function init( selector, context ) { 858 if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { 859 context = jQuerySub( context ); 860 } 861 862 return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); 863 }; 864 jQuerySub.fn.init.prototype = jQuerySub.fn; 865 var rootjQuerySub = jQuerySub(document); 866 return jQuerySub; 867 }, 868 869 browser: {} 870}); 871 872// Populate the class2type map 873jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { 874 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 875}); 876 877browserMatch = jQuery.uaMatch( userAgent ); 878if ( browserMatch.browser ) { 879 jQuery.browser[ browserMatch.browser ] = true; 880 jQuery.browser.version = browserMatch.version; 881} 882 883// Deprecated, use jQuery.browser.webkit instead 884if ( jQuery.browser.webkit ) { 885 jQuery.browser.safari = true; 886} 887 888// IE doesn't match non-breaking spaces with \s 889if ( rnotwhite.test( "\xA0" ) ) { 890 trimLeft = /^[\s\xA0]+/; 891 trimRight = /[\s\xA0]+$/; 892} 893 894// All jQuery objects should point back to these 895rootjQuery = jQuery(document); 896 897// Cleanup functions for the document ready method 898if ( document.addEventListener ) { 899 DOMContentLoaded = function() { 900 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 901 jQuery.ready(); 902 }; 903 904} else if ( document.attachEvent ) { 905 DOMContentLoaded = function() { 906 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 907 if ( document.readyState === "complete" ) { 908 document.detachEvent( "onreadystatechange", DOMContentLoaded ); 909 jQuery.ready(); 910 } 911 }; 912} 913 914// The DOM ready check for Internet Explorer 915function doScrollCheck() { 916 if ( jQuery.isReady ) { 917 return; 918 } 919 920 try { 921 // If IE is used, use the trick by Diego Perini 922 // http://javascript.nwbox.com/IEContentLoaded/ 923 document.documentElement.doScroll("left"); 924 } catch(e) { 925 setTimeout( doScrollCheck, 1 ); 926 return; 927 } 928 929 // and execute any waiting functions 930 jQuery.ready(); 931} 932 933// Expose jQuery to the global object 934return jQuery; 935 936})(); 937 938 939var // Promise methods 940 promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ), 941 // Static reference to slice 942 sliceDeferred = [].slice; 943 944jQuery.extend({ 945 // Create a simple deferred (one callbacks list) 946 _Deferred: function() { 947 var // callbacks list 948 callbacks = [], 949 // stored [ context , args ] 950 fired, 951 // to avoid firing when already doing so 952 firing, 953 // flag to know if the deferred has been cancelled 954 cancelled, 955 // the deferred itself 956 deferred = { 957 958 // done( f1, f2, ...) 959 done: function() { 960 if ( !cancelled ) { 961 var args = arguments, 962 i, 963 length, 964 elem, 965 type, 966 _fired; 967 if ( fired ) { 968 _fired = fired; 969 fired = 0; 970 } 971 for ( i = 0, length = args.length; i < length; i++ ) { 972 elem = args[ i ]; 973 type = jQuery.type( elem ); 974 if ( type === "array" ) { 975 deferred.done.apply( deferred, elem ); 976 } else if ( type === "function" ) { 977 callbacks.push( elem ); 978 } 979 } 980 if ( _fired ) { 981 deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] ); 982 } 983 } 984 return this; 985 }, 986 987 // resolve with given context and args 988 resolveWith: function( context, args ) { 989 if ( !cancelled && !fired && !firing ) { 990 // make sure args are available (#8421) 991 args = args || []; 992 firing = 1; 993 try { 994 while( callbacks[ 0 ] ) { 995 callbacks.shift().apply( context, args ); 996 } 997 } 998 finally { 999 fired = [ context, args ]; 1000 firing = 0; 1001 } 1002 } 1003 return this; 1004 }, 1005 1006 // resolve with this as context and given arguments 1007 resolve: function() { 1008 deferred.resolveWith( this, arguments ); 1009 return this; 1010 }, 1011 1012 // Has this deferred been resolved? 1013 isResolved: function() { 1014 return !!( firing || fired ); 1015 }, 1016 1017 // Cancel 1018 cancel: function() { 1019 cancelled = 1; 1020 callbacks = []; 1021 return this; 1022 } 1023 }; 1024 1025 return deferred; 1026 }, 1027 1028 // Full fledged deferred (two callbacks list) 1029 Deferred: function( func ) { 1030 var deferred = jQuery._Deferred(), 1031 failDeferred = jQuery._Deferred(), 1032 promise; 1033 // Add errorDeferred methods, then and promise 1034 jQuery.extend( deferred, { 1035 then: function( doneCallbacks, failCallbacks ) { 1036 deferred.done( doneCallbacks ).fail( failCallbacks ); 1037 return this; 1038 }, 1039 always: function() { 1040 return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments ); 1041 }, 1042 fail: failDeferred.done, 1043 rejectWith: failDeferred.resolveWith, 1044 reject: failDeferred.resolve, 1045 isRejected: failDeferred.isResolved, 1046 pipe: function( fnDone, fnFail ) { 1047 return jQuery.Deferred(function( newDefer ) { 1048 jQuery.each( { 1049 done: [ fnDone, "resolve" ], 1050 fail: [ fnFail, "reject" ] 1051 }, function( handler, data ) { 1052 var fn = data[ 0 ], 1053 action = data[ 1 ], 1054 returned; 1055 if ( jQuery.isFunction( fn ) ) { 1056 deferred[ handler ](function() { 1057 returned = fn.apply( this, arguments ); 1058 if ( returned && jQuery.isFunction( returned.promise ) ) { 1059 returned.promise().then( newDefer.resolve, newDefer.reject ); 1060 } else { 1061 newDefer[ action ]( returned ); 1062 } 1063 }); 1064 } else { 1065 deferred[ handler ]( newDefer[ action ] ); 1066 } 1067 }); 1068 }).promise(); 1069 }, 1070 // Get a promise for this deferred 1071 // If obj is provided, the promise aspect is added to the object 1072 promise: function( obj ) { 1073 if ( obj == null ) { 1074 if ( promise ) { 1075 return promise; 1076 } 1077 promise = obj = {}; 1078 } 1079 var i = promiseMethods.length; 1080 while( i-- ) { 1081 obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ]; 1082 } 1083 return obj; 1084 } 1085 }); 1086 // Make sure only one callback list will be used 1087 deferred.done( failDeferred.cancel ).fail( deferred.cancel ); 1088 // Unexpose cancel 1089 delete deferred.cancel; 1090 // Call given func if any 1091 if ( func ) { 1092 func.call( deferred, deferred ); 1093 } 1094 return deferred; 1095 }, 1096 1097 // Deferred helper 1098 when: function( firstParam ) { 1099 var args = arguments, 1100 i = 0, 1101 length = args.length, 1102 count = length, 1103 deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? 1104 firstParam : 1105 jQuery.Deferred(); 1106 function resolveFunc( i ) { 1107 return function( value ) { 1108 args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; 1109 if ( !( --count ) ) { 1110 // Strange bug in FF4: 1111 // Values changed onto the arguments object sometimes end up as undefined values 1112 // outside the $.when method. Cloning the object into a fresh array solves the issue 1113 deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) ); 1114 } 1115 }; 1116 } 1117 if ( length > 1 ) { 1118 for( ; i < length; i++ ) { 1119 if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) { 1120 args[ i ].promise().then( resolveFunc(i), deferred.reject ); 1121 } else { 1122 --count; 1123 } 1124 } 1125 if ( !count ) { 1126 deferred.resolveWith( deferred, args ); 1127 } 1128 } else if ( deferred !== firstParam ) { 1129 deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); 1130 } 1131 return deferred.promise(); 1132 } 1133}); 1134 1135 1136 1137jQuery.support = (function() { 1138 1139 var div = document.createElement( "div" ), 1140 documentElement = document.documentElement, 1141 all, 1142 a, 1143 select, 1144 opt, 1145 input, 1146 marginDiv, 1147 support, 1148 fragment, 1149 body, 1150 bodyStyle, 1151 tds, 1152 events, 1153 eventName, 1154 i, 1155 isSupported; 1156 1157 // Preliminary tests 1158 div.setAttribute("className", "t"); 1159 div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>"; 1160 1161 all = div.getElementsByTagName( "*" ); 1162 a = div.getElementsByTagName( "a" )[ 0 ]; 1163 1164 // Can't get basic test support 1165 if ( !all || !all.length || !a ) { 1166 return {}; 1167 } 1168 1169 // First batch of supports tests 1170 select = document.createElement( "select" ); 1171 opt = select.appendChild( document.createElement("option") ); 1172 input = div.getElementsByTagName( "input" )[ 0 ]; 1173 1174 support = { 1175 // IE strips leading whitespace when .innerHTML is used 1176 leadingWhitespace: ( div.firstChild.nodeType === 3 ), 1177 1178 // Make sure that tbody elements aren't automatically inserted 1179 // IE will insert them into empty tables 1180 tbody: !div.getElementsByTagName( "tbody" ).length, 1181 1182 // Make sure that link elements get serialized correctly by innerHTML 1183 // This requires a wrapper element in IE 1184 htmlSerialize: !!div.getElementsByTagName( "link" ).length, 1185 1186 // Get the style information from getAttribute 1187 // (IE uses .cssText instead) 1188 style: /top/.test( a.getAttribute("style") ), 1189 1190 // Make sure that URLs aren't manipulated 1191 // (IE normalizes it by default) 1192 hrefNormalized: ( a.getAttribute( "href" ) === "/a" ), 1193 1194 // Make sure that element opacity exists 1195 // (IE uses filter instead) 1196 // Use a regex to work around a WebKit issue. See #5145 1197 opacity: /^0.55$/.test( a.style.opacity ), 1198 1199 // Verify style float existence 1200 // (IE uses styleFloat instead of cssFloat) 1201 cssFloat: !!a.style.cssFloat, 1202 1203 // Make sure that if no value is specified for a checkbox 1204 // that it defaults to "on". 1205 // (WebKit defaults to "" instead) 1206 checkOn: ( input.value === "on" ), 1207 1208 // Make sure that a selected-by-default option has a working selected property. 1209 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) 1210 optSelected: opt.selected, 1211 1212 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) 1213 getSetAttribute: div.className !== "t", 1214 1215 // Will be defined later 1216 submitBubbles: true, 1217 changeBubbles: true, 1218 focusinBubbles: false, 1219 deleteExpando: true, 1220 noCloneEvent: true, 1221 inlineBlockNeedsLayout: false, 1222 shrinkWrapBlocks: false, 1223 reliableMarginRight: true 1224 }; 1225 1226 // Make sure checked status is properly cloned 1227 input.checked = true; 1228 support.noCloneChecked = input.cloneNode( true ).checked; 1229 1230 // Make sure that the options inside disabled selects aren't marked as disabled 1231 // (WebKit marks them as disabled) 1232 select.disabled = true; 1233 support.optDisabled = !opt.disabled; 1234 1235 // Test to see if it's possible to delete an expando from an element 1236 // Fails in Internet Explorer 1237 try { 1238 delete div.test; 1239 } catch( e ) { 1240 support.deleteExpando = false; 1241 } 1242 1243 if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { 1244 div.attachEvent( "onclick", function click() { 1245 // Cloning a node shouldn't copy over any 1246 // bound event handlers (IE does this) 1247 support.noCloneEvent = false; 1248 div.detachEvent( "onclick", click ); 1249 }); 1250 div.cloneNode( true ).fireEvent( "onclick" ); 1251 } 1252 1253 // Check if a radio maintains it's value 1254 // after being appended to the DOM 1255 input = document.createElement("input"); 1256 input.value = "t"; 1257 input.setAttribute("type", "radio"); 1258 support.radioValue = input.value === "t"; 1259 1260 input.setAttribute("checked", "checked"); 1261 div.appendChild( input ); 1262 fragment = document.createDocumentFragment(); 1263 fragment.appendChild( div.firstChild ); 1264 1265 // WebKit doesn't clone checked state correctly in fragments 1266 support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; 1267 1268 div.innerHTML = ""; 1269 1270 // Figure out if the W3C box model works as expected 1271 div.style.width = div.style.paddingLeft = "1px"; 1272 1273 // We use our own, invisible, body 1274 body = document.createElement( "body" ); 1275 bodyStyle = { 1276 visibility: "hidden", 1277 width: 0, 1278 height: 0, 1279 border: 0, 1280 margin: 0, 1281 // Set background to avoid IE crashes when removing (#9028) 1282 background: "none" 1283 }; 1284 for ( i in bodyStyle ) { 1285 body.style[ i ] = bodyStyle[ i ]; 1286 } 1287 body.appendChild( div ); 1288 documentElement.insertBefore( body, documentElement.firstChild ); 1289 1290 // Check if a disconnected checkbox will retain its checked 1291 // value of true after appended to the DOM (IE6/7) 1292 support.appendChecked = input.checked; 1293 1294 support.boxModel = div.offsetWidth === 2; 1295 1296 if ( "zoom" in div.style ) { 1297 // Check if natively block-level elements act like inline-block 1298 // elements when setting their display to 'inline' and giving 1299 // them layout 1300 // (IE < 8 does this) 1301 div.style.display = "inline"; 1302 div.style.zoom = 1; 1303 support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); 1304 1305 // Check if elements with layout shrink-wrap their children 1306 // (IE 6 does this) 1307 div.style.display = ""; 1308 div.innerHTML = "<div style='width:4px;'></div>"; 1309 support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); 1310 } 1311 1312 div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>"; 1313 tds = div.getElementsByTagName( "td" ); 1314 1315 // Check if table cells still have offsetWidth/Height when they are set 1316 // to display:none and there are still other visible table cells in a 1317 // table row; if so, offsetWidth/Height are not reliable for use when 1318 // determining if an element has been hidden directly using 1319 // display:none (it is still safe to use offsets if a parent element is 1320 // hidden; don safety goggles and see bug #4512 for more information). 1321 // (only IE 8 fails this test) 1322 isSupported = ( tds[ 0 ].offsetHeight === 0 ); 1323 1324 tds[ 0 ].style.display = ""; 1325 tds[ 1 ].style.display = "none"; 1326 1327 // Check if empty table cells still have offsetWidth/Height 1328 // (IE < 8 fail this test) 1329 support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); 1330 div.innerHTML = ""; 1331 1332 // Check if div with explicit width and no margin-right incorrectly 1333 // gets computed margin-right based on width of container. For more 1334 // info see bug #3333 1335 // Fails in WebKit before Feb 2011 nightlies 1336 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right 1337 if ( document.defaultView && document.defaultView.getComputedStyle ) { 1338 marginDiv = document.createElement( "div" ); 1339 marginDiv.style.width = "0"; 1340 marginDiv.style.marginRight = "0"; 1341 div.appendChild( marginDiv ); 1342 support.reliableMarginRight = 1343 ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; 1344 } 1345 1346 // Remove the body element we added 1347 body.innerHTML = ""; 1348 documentElement.removeChild( body ); 1349 1350 // Technique from Juriy Zaytsev 1351 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ 1352 // We only care about the case where non-standard event systems 1353 // are used, namely in IE. Short-circuiting here helps us to 1354 // avoid an eval call (in setAttribute) which can cause CSP 1355 // to go haywire. See: https://developer.mozilla.org/en/Security/CSP 1356 if ( div.attachEvent ) { 1357 for( i in { 1358 submit: 1, 1359 change: 1, 1360 focusin: 1 1361 } ) { 1362 eventName = "on" + i; 1363 isSupported = ( eventName in div ); 1364 if ( !isSupported ) { 1365 div.setAttribute( eventName, "return;" ); 1366 isSupported = ( typeof div[ eventName ] === "function" ); 1367 } 1368 support[ i + "Bubbles" ] = isSupported; 1369 } 1370 } 1371 1372 return support; 1373})(); 1374 1375// Keep track of boxModel 1376jQuery.boxModel = jQuery.support.boxModel; 1377 1378 1379 1380 1381var rbrace = /^(?:\{.*\}|\[.*\])$/, 1382 rmultiDash = /([a-z])([A-Z])/g; 1383 1384jQuery.extend({ 1385 cache: {}, 1386 1387 // Please use with caution 1388 uuid: 0, 1389 1390 // Unique for each copy of jQuery on the page 1391 // Non-digits removed to match rinlinejQuery 1392 expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), 1393 1394 // The following elements throw uncatchable exceptions if you 1395 // attempt to add expando properties to them. 1396 noData: { 1397 "embed": true, 1398 // Ban all objects except for Flash (which handle expandos) 1399 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", 1400 "applet": true 1401 }, 1402 1403 hasData: function( elem ) { 1404 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; 1405 1406 return !!elem && !isEmptyDataObject( elem ); 1407 }, 1408 1409 data: function( elem, name, data, pvt /* Internal Use Only */ ) { 1410 if ( !jQuery.acceptData( elem ) ) { 1411 return; 1412 } 1413 1414 var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache, 1415 1416 // We have to handle DOM nodes and JS objects differently because IE6-7 1417 // can't GC object references properly across the DOM-JS boundary 1418 isNode = elem.nodeType, 1419 1420 // Only DOM nodes need the global jQuery cache; JS object data is 1421 // attached directly to the object so GC can occur automatically 1422 cache = isNode ? jQuery.cache : elem, 1423 1424 // Only defining an ID for JS objects if its cache already exists allows 1425 // the code to shortcut on the same path as a DOM node with no cache 1426 id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando; 1427 1428 // Avoid doing any more work than we need to when trying to get data on an 1429 // object that has no data at all 1430 if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) { 1431 return; 1432 } 1433 1434 if ( !id ) { 1435 // Only DOM nodes need a new unique ID for each element since their data 1436 // ends up in the global cache 1437 if ( isNode ) { 1438 elem[ jQuery.expando ] = id = ++jQuery.uuid; 1439 } else { 1440 id = jQuery.expando; 1441 } 1442 } 1443 1444 if ( !cache[ id ] ) { 1445 cache[ id ] = {}; 1446 1447 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery 1448 // metadata on plain JS objects when the object is serialized using 1449 // JSON.stringify 1450 if ( !isNode ) { 1451 cache[ id ].toJSON = jQuery.noop; 1452 } 1453 } 1454 1455 // An object can be passed to jQuery.data instead of a key/value pair; this gets 1456 // shallow copied over onto the existing cache 1457 if ( typeof name === "object" || typeof name === "function" ) { 1458 if ( pvt ) { 1459 cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name); 1460 } else { 1461 cache[ id ] = jQuery.extend(cache[ id ], name); 1462 } 1463 } 1464 1465 thisCache = cache[ id ]; 1466 1467 // Internal jQuery data is stored in a separate object inside the object's data 1468 // cache in order to avoid key collisions between internal data and user-defined 1469 // data 1470 if ( pvt ) { 1471 if ( !thisCache[ internalKey ] ) { 1472 thisCache[ internalKey ] = {}; 1473 } 1474 1475 thisCache = thisCache[ internalKey ]; 1476 } 1477 1478 if ( data !== undefined ) { 1479 thisCache[ jQuery.camelCase( name ) ] = data; 1480 } 1481 1482 // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should 1483 // not attempt to inspect the internal events object using jQuery.data, as this 1484 // internal data object is undocumented and subject to change. 1485 if ( name === "events" && !thisCache[name] ) { 1486 return thisCache[ internalKey ] && thisCache[ internalKey ].events; 1487 } 1488 1489 return getByName ? thisCache[ jQuery.camelCase( name ) ] : thisCache; 1490 }, 1491 1492 removeData: function( elem, name, pvt /* Internal Use Only */ ) { 1493 if ( !jQuery.acceptData( elem ) ) { 1494 return; 1495 } 1496 1497 var internalKey = jQuery.expando, isNode = elem.nodeType, 1498 1499 // See jQuery.data for more information 1500 cache = isNode ? jQuery.cache : elem, 1501 1502 // See jQuery.data for more information 1503 id = isNode ? elem[ jQuery.expando ] : jQuery.expando; 1504 1505 // If there is already no cache entry for this object, there is no 1506 // purpose in continuing 1507 if ( !cache[ id ] ) { 1508 return; 1509 } 1510 1511 if ( name ) { 1512 var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ]; 1513 1514 if ( thisCache ) { 1515 delete thisCache[ name ]; 1516 1517 // If there is no data left in the cache, we want to continue 1518 // and let the cache object itself get destroyed 1519 if ( !isEmptyDataObject(thisCache) ) { 1520 return; 1521 } 1522 } 1523 } 1524 1525 // See jQuery.data for more information 1526 if ( pvt ) { 1527 delete cache[ id ][ internalKey ]; 1528 1529 // Don't destroy the parent cache unless the internal data object 1530 // had been the only thing left in it 1531 if ( !isEmptyDataObject(cache[ id ]) ) { 1532 return; 1533 } 1534 } 1535 1536 var internalCache = cache[ id ][ internalKey ]; 1537 1538 // Browsers that fail expando deletion also refuse to delete expandos on 1539 // the window, but it will allow it on all other JS objects; other browsers 1540 // don't care 1541 if ( jQuery.support.deleteExpando || cache != window ) { 1542 delete cache[ id ]; 1543 } else { 1544 cache[ id ] = null; 1545 } 1546 1547 // We destroyed the entire user cache at once because it's faster than 1548 // iterating through each key, but we need to continue to persist internal 1549 // data if it existed 1550 if ( internalCache ) { 1551 cache[ id ] = {}; 1552 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery 1553 // metadata on plain JS objects when the object is serialized using 1554 // JSON.stringify 1555 if ( !isNode ) { 1556 cache[ id ].toJSON = jQuery.noop; 1557 } 1558 1559 cache[ id ][ internalKey ] = internalCache; 1560 1561 // Otherwise, we need to eliminate the expando on the node to avoid 1562 // false lookups in the cache for entries that no longer exist 1563 } else if ( isNode ) { 1564 // IE does not allow us to delete expando properties from nodes, 1565 // nor does it have a removeAttribute function on Document nodes; 1566 // we must handle all of these cases 1567 if ( jQuery.support.deleteExpando ) { 1568 delete elem[ jQuery.expando ]; 1569 } else if ( elem.removeAttribute ) { 1570 elem.removeAttribute( jQuery.expando ); 1571 } else { 1572 elem[ jQuery.expando ] = null; 1573 } 1574 } 1575 }, 1576 1577 // For internal use only. 1578 _data: function( elem, name, data ) { 1579 return jQuery.data( elem, name, data, true ); 1580 }, 1581 1582 // A method for determining if a DOM node can handle the data expando 1583 acceptData: function( elem ) { 1584 if ( elem.nodeName ) { 1585 var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; 1586 1587 if ( match ) { 1588 return !(match === true || elem.getAttribute("classid") !== match); 1589 } 1590 } 1591 1592 return true; 1593 } 1594}); 1595 1596jQuery.fn.extend({ 1597 data: function( key, value ) { 1598 var data = null; 1599 1600 if ( typeof key === "undefined" ) { 1601 if ( this.length ) { 1602 data = jQuery.data( this[0] ); 1603 1604 if ( this[0].nodeType === 1 ) { 1605 var attr = this[0].attributes, name; 1606 for ( var i = 0, l = attr.length; i < l; i++ ) { 1607 name = attr[i].name; 1608 1609 if ( name.indexOf( "data-" ) === 0 ) { 1610 name = jQuery.camelCase( name.substring(5) ); 1611 1612 dataAttr( this[0], name, data[ name ] ); 1613 } 1614 } 1615 } 1616 } 1617 1618 return data; 1619 1620 } else if ( typeof key === "object" ) { 1621 return this.each(function() { 1622 jQuery.data( this, key ); 1623 }); 1624 } 1625 1626 var parts = key.split("."); 1627 parts[1] = parts[1] ? "." + parts[1] : ""; 1628 1629 if ( value === undefined ) { 1630 data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); 1631 1632 // Try to fetch any internally stored data first 1633 if ( data === undefined && this.length ) { 1634 data = jQuery.data( this[0], key ); 1635 data = dataAttr( this[0], key, data ); 1636 } 1637 1638 return data === undefined && parts[1] ? 1639 this.data( parts[0] ) : 1640 data; 1641 1642 } else { 1643 return this.each(function() { 1644 var $this = jQuery( this ), 1645 args = [ parts[0], value ]; 1646 1647 $this.triggerHandler( "setData" + parts[1] + "!", args ); 1648 jQuery.data( this, key, value ); 1649 $this.triggerHandler( "changeData" + parts[1] + "!", args ); 1650 }); 1651 } 1652 }, 1653 1654 removeData: function( key ) { 1655 return this.each(function() { 1656 jQuery.removeData( this, key ); 1657 }); 1658 } 1659}); 1660 1661function dataAttr( elem, key, data ) { 1662 // If nothing was found internally, try to fetch any 1663 // data from the HTML5 data-* attribute 1664 if ( data === undefined && elem.nodeType === 1 ) { 1665 var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase(); 1666 1667 data = elem.getAttribute( name ); 1668 1669 if ( typeof data === "string" ) { 1670 try { 1671 data = data === "true" ? true : 1672 data === "false" ? false : 1673 data === "null" ? null : 1674 !jQuery.isNaN( data ) ? parseFloat( data ) : 1675 rbrace.test( data ) ? jQuery.parseJSON( data ) : 1676 data; 1677 } catch( e ) {} 1678 1679 // Make sure we set the data so it isn't changed later 1680 jQuery.data( elem, key, data ); 1681 1682 } else { 1683 data = undefined; 1684 } 1685 } 1686 1687 return data; 1688} 1689 1690// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON 1691// property to be considered empty objects; this property always exists in 1692// order to make sure JSON.stringify does not expose internal metadata 1693function isEmptyDataObject( obj ) { 1694 for ( var name in obj ) { 1695 if ( name !== "toJSON" ) { 1696 return false; 1697 } 1698 } 1699 1700 return true; 1701} 1702 1703 1704 1705 1706function handleQueueMarkDefer( elem, type, src ) { 1707 var deferDataKey = type + "defer", 1708 queueDataKey = type + "queue", 1709 markDataKey = type + "mark", 1710 defer = jQuery.data( elem, deferDataKey, undefined, true ); 1711 if ( defer && 1712 ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) && 1713 ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) { 1714 // Give room for hard-coded callbacks to fire first 1715 // and eventually mark/queue something else on the element 1716 setTimeout( function() { 1717 if ( !jQuery.data( elem, queueDataKey, undefined, true ) && 1718 !jQuery.data( elem, markDataKey, undefined, true ) ) { 1719 jQuery.removeData( elem, deferDataKey, true ); 1720 defer.resolve(); 1721 } 1722 }, 0 ); 1723 } 1724} 1725 1726jQuery.extend({ 1727 1728 _mark: function( elem, type ) { 1729 if ( elem ) { 1730 type = (type || "fx") + "mark"; 1731 jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true ); 1732 } 1733 }, 1734 1735 _unmark: function( force, elem, type ) { 1736 if ( force !== true ) { 1737 type = elem; 1738 elem = force; 1739 force = false; 1740 } 1741 if ( elem ) { 1742 type = type || "fx"; 1743 var key = type + "mark", 1744 count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 ); 1745 if ( count ) { 1746 jQuery.data( elem, key, count, true ); 1747 } else { 1748 jQuery.removeData( elem, key, true ); 1749 handleQueueMarkDefer( elem, type, "mark" ); 1750 } 1751 } 1752 }, 1753 1754 queue: function( elem, type, data ) { 1755 if ( elem ) { 1756 type = (type || "fx") + "queue"; 1757 var q = jQuery.data( elem, type, undefined, true ); 1758 // Speed up dequeue by getting out quickly if this is just a lookup 1759 if ( data ) { 1760 if ( !q || jQuery.isArray(data) ) { 1761 q = jQuery.data( elem, type, jQuery.makeArray(data), true ); 1762 } else { 1763 q.push( data ); 1764 } 1765 } 1766 return q || []; 1767 } 1768 }, 1769 1770 dequeue: function( elem, type ) { 1771 type = type || "fx"; 1772 1773 var queue = jQuery.queue( elem, type ), 1774 fn = queue.shift(), 1775 defer; 1776 1777 // If the fx queue is dequeued, always remove the progress sentinel 1778 if ( fn === "inprogress" ) { 1779 fn = queue.shift(); 1780 } 1781 1782 if ( fn ) { 1783 // Add a progress sentinel to prevent the fx queue from being 1784 // automatically dequeued 1785 if ( type === "fx" ) { 1786 queue.unshift("inprogress"); 1787 } 1788 1789 fn.call(elem, function() { 1790 jQuery.dequeue(elem, type); 1791 }); 1792 } 1793 1794 if ( !queue.length ) { 1795 jQuery.removeData( elem, type + "queue", true ); 1796 handleQueueMarkDefer( elem, type, "queue" ); 1797 } 1798 } 1799}); 1800 1801jQuery.fn.extend({ 1802 queue: function( type, data ) { 1803 if ( typeof type !== "string" ) { 1804 data = type; 1805 type = "fx"; 1806 } 1807 1808 if ( data === undefined ) { 1809 return jQuery.queue( this[0], type ); 1810 } 1811 return this.each(function() { 1812 var queue = jQuery.queue( this, type, data ); 1813 1814 if ( type === "fx" && queue[0] !== "inprogress" ) { 1815 jQuery.dequeue( this, type ); 1816 } 1817 }); 1818 }, 1819 dequeue: function( type ) { 1820 return this.each(function() { 1821 jQuery.dequeue( this, type ); 1822 }); 1823 }, 1824 // Based off of the plugin by Clint Helfers, with permission. 1825 // http://blindsignals.com/index.php/2009/07/jquery-delay/ 1826 delay: function( time, type ) { 1827 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; 1828 type = type || "fx"; 1829 1830 return this.queue( type, function() { 1831 var elem = this; 1832 setTimeout(function() { 1833 jQuery.dequeue( elem, type ); 1834 }, time ); 1835 }); 1836 }, 1837 clearQueue: function( type ) { 1838 return this.queue( type || "fx", [] ); 1839 }, 1840 // Get a promise resolved when queues of a certain type 1841 // are emptied (fx is the type by default) 1842 promise: function( type, object ) { 1843 if ( typeof type !== "string" ) { 1844 object = type; 1845 type = undefined; 1846 } 1847 type = type || "fx"; 1848 var defer = jQuery.Deferred(), 1849 elements = this, 1850 i = elements.length, 1851 count = 1, 1852 deferDataKey = type + "defer", 1853 queueDataKey = type + "queue", 1854 markDataKey = type + "mark", 1855 tmp; 1856 function resolve() { 1857 if ( !( --count ) ) { 1858 defer.resolveWith( elements, [ elements ] ); 1859 } 1860 } 1861 while( i-- ) { 1862 if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || 1863 ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || 1864 jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && 1865 jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) { 1866 count++; 1867 tmp.done( resolve ); 1868 } 1869 } 1870 resolve(); 1871 return defer.promise(); 1872 } 1873}); 1874 1875 1876 1877 1878var rclass = /[\n\t\r]/g, 1879 rspace = /\s+/, 1880 rreturn = /\r/g, 1881 rtype = /^(?:button|input)$/i, 1882 rfocusable = /^(?:button|input|object|select|textarea)$/i, 1883 rclickable = /^a(?:rea)?$/i, 1884 rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, 1885 rinvalidChar = /\:/, 1886 formHook, boolHook; 1887 1888jQuery.fn.extend({ 1889 attr: function( name, value ) { 1890 return jQuery.access( this, name, value, true, jQuery.attr ); 1891 }, 1892 1893 removeAttr: function( name ) { 1894 return this.each(function() { 1895 jQuery.removeAttr( this, name ); 1896 }); 1897 }, 1898 1899 prop: function( name, value ) { 1900 return jQuery.access( this, name, value, true, jQuery.prop ); 1901 }, 1902 1903 removeProp: function( name ) { 1904 name = jQuery.propFix[ name ] || name; 1905 return this.each(function() { 1906 // try/catch handles cases where IE balks (such as removing a property on window) 1907 try { 1908 this[ name ] = undefined; 1909 delete this[ name ]; 1910 } catch( e ) {} 1911 }); 1912 }, 1913 1914 addClass: function( value ) { 1915 if ( jQuery.isFunction( value ) ) { 1916 return this.each(function(i) { 1917 var self = jQuery(this); 1918 self.addClass( value.call(this, i, self.attr("class") || "") ); 1919 }); 1920 } 1921 1922 if ( value && typeof value === "string" ) { 1923 var classNames = (value || "").split( rspace ); 1924 1925 for ( var i = 0, l = this.length; i < l; i++ ) { 1926 var elem = this[i]; 1927 1928 if ( elem.nodeType === 1 ) { 1929 if ( !elem.className ) { 1930 elem.className = value; 1931 1932 } else { 1933 var className = " " + elem.className + " ", 1934 setClass = elem.className; 1935 1936 for ( var c = 0, cl = classNames.length; c < cl; c++ ) { 1937 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) { 1938 setClass += " " + classNames[c]; 1939 } 1940 } 1941 elem.className = jQuery.trim( setClass ); 1942 } 1943 } 1944 } 1945 } 1946 1947 return this; 1948 }, 1949 1950 removeClass: function( value ) { 1951 if ( jQuery.isFunction(value) ) { 1952 return this.each(function(i) { 1953 var self = jQuery(this); 1954 self.removeClass( value.call(this, i, self.attr("class")) ); 1955 }); 1956 } 1957 1958 if ( (value && typeof value === "string") || value === undefined ) { 1959 var classNames = (value || "").split( rspace ); 1960 1961 for ( var i = 0, l = this.length; i < l; i++ ) { 1962 var elem = this[i]; 1963 1964 if ( elem.nodeType === 1 && elem.className ) { 1965 if ( value ) { 1966 var className = (" " + elem.className + " ").replace(rclass, " "); 1967 for ( var c = 0, cl = classNames.length; c < cl; c++ ) { 1968 className = className.replace(" " + classNames[c] + " ", " "); 1969 } 1970 elem.className = jQuery.trim( className ); 1971 1972 } else { 1973 elem.className = ""; 1974 } 1975 } 1976 } 1977 } 1978 1979 return this; 1980 }, 1981 1982 toggleClass: function( value, stateVal ) { 1983 var type = typeof value, 1984 isBool = typeof stateVal === "boolean"; 1985 1986 if ( jQuery.isFunction( value ) ) { 1987 return this.each(function(i) { 1988 var self = jQuery(this); 1989 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); 1990 }); 1991 } 1992 1993 return this.each(function() { 1994 if ( type === "string" ) { 1995 // toggle individual class names 1996 var className, 1997 i = 0, 1998 self = jQuery( this ), 1999 state = stateVal, 2000 classNames = value.split( rspace ); 2001 2002 while ( (className = classNames[ i++ ]) ) { 2003 // check each className given, space seperated list 2004 state = isBool ? state : !self.hasClass( className ); 2005 self[ state ? "addClass" : "removeClass" ]( className ); 2006 } 2007 2008 } else if ( type === "undefined" || type === "boolean" ) { 2009 if ( this.className ) { 2010 // store className if set 2011 jQuery._data( this, "__className__", this.className ); 2012 } 2013 2014 // toggle whole className 2015 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; 2016 } 2017 }); 2018 }, 2019 2020 hasClass: function( selector ) { 2021 var className = " " + selector + " "; 2022 for ( var i = 0, l = this.length; i < l; i++ ) { 2023 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { 2024 return true; 2025 } 2026 } 2027 2028 return false; 2029 }, 2030 2031 val: function( value ) { 2032 var hooks, ret, 2033 elem = this[0]; 2034 2035 if ( !arguments.length ) { 2036 if ( elem ) { 2037 hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; 2038 2039 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { 2040 return ret; 2041 } 2042 2043 return (elem.value || "").replace(rreturn, ""); 2044 } 2045 2046 return undefined; 2047 } 2048 2049 var isFunction = jQuery.isFunction( value ); 2050 2051 return this.each(function( i ) { 2052 var self = jQuery(this), val; 2053 2054 if ( this.nodeType !== 1 ) { 2055 return; 2056 } 2057 2058 if ( isFunction ) { 2059 val = value.call( this, i, self.val() ); 2060 } else { 2061 val = value; 2062 } 2063 2064 // Treat null/undefined as ""; convert numbers to string 2065 if ( val == null ) { 2066 val = ""; 2067 } else if ( typeof val === "number" ) { 2068 val += ""; 2069 } else if ( jQuery.isArray( val ) ) { 2070 val = jQuery.map(val, function ( value ) { 2071 return value == null ? "" : value + ""; 2072 }); 2073 } 2074 2075 hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; 2076 2077 // If set returns undefined, fall back to normal setting 2078 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { 2079 this.value = val; 2080 } 2081 }); 2082 } 2083}); 2084 2085jQuery.extend({ 2086 valHooks: { 2087 option: { 2088 get: function( elem ) { 2089 // attributes.value is undefined in Blackberry 4.7 but 2090 // uses .value. See #6932 2091 var val = elem.attributes.value; 2092 return !val || val.specified ? elem.value : elem.text; 2093 } 2094 }, 2095 select: { 2096 get: function( elem ) { 2097 var value, 2098 index = elem.selectedIndex, 2099 values = [], 2100 options = elem.options, 2101 one = elem.type === "select-one"; 2102 2103 // Nothing was selected 2104 if ( index < 0 ) { 2105 return null; 2106 } 2107 2108 // Loop through all the selected options 2109 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { 2110 var option = options[ i ]; 2111 2112 // Don't return options that are disabled or in a disabled optgroup 2113 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && 2114 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { 2115 2116 // Get the specific value for the option 2117 value = jQuery( option ).val(); 2118 2119 // We don't need an array for one selects 2120 if ( one ) { 2121 return value; 2122 } 2123 2124 // Multi-Selects return an array 2125 values.push( value ); 2126 } 2127 } 2128 2129 // Fixes Bug #2551 -- select.val() broken in IE after form.reset() 2130 if ( one && !values.length && options.length ) { 2131 return jQuery( options[ index ] ).val(); 2132 } 2133 2134 return values; 2135 }, 2136 2137 set: function( elem, value ) { 2138 var values = jQuery.makeArray( value ); 2139 2140 jQuery(elem).find("option").each(function() { 2141 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; 2142 }); 2143 2144 if ( !values.length ) { 2145 elem.selectedIndex = -1; 2146 } 2147 return values; 2148 } 2149 } 2150 }, 2151 2152 attrFn: { 2153 val: true, 2154 css: true, 2155 html: true, 2156 text: true, 2157 data: true, 2158 width: true, 2159 height: true, 2160 offset: true 2161 }, 2162 2163 attrFix: { 2164 // Always normalize to ensure hook usage 2165 tabindex: "tabIndex" 2166 }, 2167 2168 attr: function( elem, name, value, pass ) { 2169 var nType = elem.nodeType; 2170 2171 // don't get/set attributes on text, comment and attribute nodes 2172 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { 2173 return undefined; 2174 } 2175 2176 if ( pass && name in jQuery.attrFn ) { 2177 return jQuery( elem )[ name ]( value ); 2178 } 2179 2180 // Fallback to prop when attributes are not supported 2181 if ( !("getAttribute" in elem) ) { 2182 return jQuery.prop( elem, name, value ); 2183 } 2184 2185 var ret, hooks, 2186 notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); 2187 2188 // Normalize the name if needed 2189 name = notxml && jQuery.attrFix[ name ] || name; 2190 2191 hooks = jQuery.attrHooks[ name ]; 2192 2193 if ( !hooks ) { 2194 // Use boolHook for boolean attributes 2195 if ( rboolean.test( name ) && 2196 (typeof value === "boolean" || value === undefined || value.toLowerCase() === name.toLowerCase()) ) { 2197 2198 hooks = boolHook; 2199 2200 // Use formHook for forms and if the name contains certain characters 2201 } else if ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) { 2202 hooks = formHook; 2203 } 2204 } 2205 2206 if ( value !== undefined ) { 2207 2208 if ( value === null ) { 2209 jQuery.removeAttr( elem, name ); 2210 return undefined; 2211 2212 } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { 2213 return ret; 2214 2215 } else { 2216 elem.setAttribute( name, "" + value ); 2217 return value; 2218 } 2219 2220 } else if ( hooks && "get" in hooks && notxml ) { 2221 return hooks.get( elem, name ); 2222 2223 } else { 2224 2225 ret = elem.getAttribute( name ); 2226 2227 // Non-existent attributes return null, we normalize to undefined 2228 return ret === null ? 2229 undefined : 2230 ret; 2231 } 2232 }, 2233 2234 removeAttr: function( elem, name ) { 2235 var propName; 2236 if ( elem.nodeType === 1 ) { 2237 name = jQuery.attrFix[ name ] || name; 2238 2239 if ( jQuery.support.getSetAttribute ) { 2240 // Use removeAttribute in browsers that support it 2241 elem.removeAttribute( name ); 2242 } else { 2243 jQuery.attr( elem, name, "" ); 2244 elem.removeAttributeNode( elem.getAttributeNode( name ) ); 2245 } 2246 2247 // Set corresponding property to false for boolean attributes 2248 if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) { 2249 elem[ propName ] = false; 2250 } 2251 } 2252 }, 2253 2254 attrHooks: { 2255 type: { 2256 set: function( elem, value ) { 2257 // We can't allow the type property to be changed (since it causes problems in IE) 2258 if ( rtype.test( elem.nodeName ) && elem.parentNode ) { 2259 jQuery.error( "type property can't be changed" ); 2260 } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { 2261 // Setting the type on a radio button after the value resets the value in IE6-9 2262 // Reset value to it's default in case type is set after value 2263 // This is for element creation 2264 var val = elem.value; 2265 elem.setAttribute( "type", value ); 2266 if ( val ) { 2267 elem.value = val; 2268 } 2269 return value; 2270 } 2271 } 2272 }, 2273 tabIndex: { 2274 get: function( elem ) { 2275 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set 2276 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 2277 var attributeNode = elem.getAttributeNode("tabIndex"); 2278 2279 return attributeNode && attributeNode.specified ? 2280 parseInt( attributeNode.value, 10 ) : 2281 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? 2282 0 : 2283 undefined; 2284 } 2285 } 2286 }, 2287 2288 propFix: { 2289 tabindex: "tabIndex", 2290 readonly: "readOnly", 2291 "for": "htmlFor", 2292 "class": "className", 2293 maxlength: "maxLength", 2294 cellspacing: "cellSpacing", 2295 cellpadding: "cellPadding", 2296 rowspan: "rowSpan", 2297 colspan: "colSpan", 2298 usemap: "useMap", 2299 frameborder: "frameBorder", 2300 contenteditable: "contentEditable" 2301 }, 2302 2303 prop: function( elem, name, value ) { 2304 var nType = elem.nodeType; 2305 2306 // don't get/set properties on text, comment and attribute nodes 2307 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { 2308 return undefined; 2309 } 2310 2311 var ret, hooks, 2312 notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); 2313 2314 // Try to normalize/fix the name 2315 name = notxml && jQuery.propFix[ name ] || name; 2316 2317 hooks = jQuery.propHooks[ name ]; 2318 2319 if ( value !== undefined ) { 2320 if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { 2321 return ret; 2322 2323 } else { 2324 return (elem[ name ] = value); 2325 } 2326 2327 } else { 2328 if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) { 2329 return ret; 2330 2331 } else { 2332 return elem[ name ]; 2333 } 2334 } 2335 }, 2336 2337 propHooks: {} 2338}); 2339 2340// Hook for boolean attributes 2341boolHook = { 2342 get: function( elem, name ) { 2343 // Align boolean attributes with corresponding properties 2344 return elem[ jQuery.propFix[ name ] || name ] ? 2345 name.toLowerCase() : 2346 undefined; 2347 }, 2348 set: function( elem, value, name ) { 2349 var propName; 2350 if ( value === false ) { 2351 // Remove boolean attributes when set to false 2352 jQuery.removeAttr( elem, name ); 2353 } else { 2354 // value is true since we know at this point it's type boolean and not false 2355 // Set boolean attributes to the same name and set the DOM property 2356 propName = jQuery.propFix[ name ] || name; 2357 if ( propName in elem ) { 2358 // Only set the IDL specifically if it already exists on the element 2359 elem[ propName ] = value; 2360 } 2361 2362 elem.setAttribute( name, name.toLowerCase() ); 2363 } 2364 return name; 2365 } 2366}; 2367 2368// Use the value property for back compat 2369// Use the formHook for button elements in IE6/7 (#1954) 2370jQuery.attrHooks.value = { 2371 get: function( elem, name ) { 2372 if ( formHook && jQuery.nodeName( elem, "button" ) ) { 2373 return formHook.get( elem, name ); 2374 } 2375 return elem.value; 2376 }, 2377 set: function( elem, value, name ) { 2378 if ( formHook && jQuery.nodeName( elem, "button" ) ) { 2379 return formHook.set( elem, value, name ); 2380 } 2381 // Does not return so that setAttribute is also used 2382 elem.value = value; 2383 } 2384}; 2385 2386// IE6/7 do not support getting/setting some attributes with get/setAttribute 2387if ( !jQuery.support.getSetAttribute ) { 2388 2389 // propFix is more comprehensive and contains all fixes 2390 jQuery.attrFix = jQuery.propFix; 2391 2392 // Use this for any attribute on a form in IE6/7 2393 formHook = jQuery.attrHooks.name = jQuery.valHooks.button = { 2394 get: function( elem, name ) { 2395 var ret; 2396 ret = elem.getAttributeNode( name ); 2397 // Return undefined if nodeValue is empty string 2398 return ret && ret.nodeValue !== "" ? 2399 ret.nodeValue : 2400 undefined; 2401 }, 2402 set: function( elem, value, name ) { 2403 // Check form objects in IE (multiple bugs related) 2404 // Only use nodeValue if the attribute node exists on the form 2405 var ret = elem.getAttributeNode( name ); 2406 if ( ret ) { 2407 ret.nodeValue = value; 2408 return value; 2409 } 2410 } 2411 }; 2412 2413 // Set width and height to auto instead of 0 on empty string( Bug #8150 ) 2414 // This is for removals 2415 jQuery.each([ "width", "height" ], function( i, name ) { 2416 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { 2417 set: function( elem, value ) { 2418 if ( value === "" ) { 2419 elem.setAttribute( name, "auto" ); 2420 return value; 2421 } 2422 } 2423 }); 2424 }); 2425} 2426 2427 2428// Some attributes require a special call on IE 2429if ( !jQuery.support.hrefNormalized ) { 2430 jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { 2431 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { 2432 get: function( elem ) { 2433 var ret = elem.getAttribute( name, 2 ); 2434 return ret === null ? undefined : ret; 2435 } 2436 }); 2437 }); 2438} 2439 2440if ( !jQuery.support.style ) { 2441 jQuery.attrHooks.style = { 2442 get: function( elem ) { 2443 // Return undefined in the case of empty string 2444 // Normalize to lowercase since IE uppercases css property names 2445 return elem.style.cssText.toLowerCase() || undefined; 2446 }, 2447 set: function( elem, value ) { 2448 return (elem.style.cssText = "" + value); 2449 } 2450 }; 2451} 2452 2453// Safari mis-reports the default selected property of an option 2454// Accessing the parent's selectedIndex property fixes it 2455if ( !jQuery.support.optSelected ) { 2456 jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { 2457 get: function( elem ) { 2458 var parent = elem.parentNode; 2459 2460 if ( parent ) { 2461 parent.selectedIndex; 2462 2463 // Make sure that it also works with optgroups, see #5701 2464 if ( parent.parentNode ) { 2465 parent.parentNode.selectedIndex; 2466 } 2467 } 2468 } 2469 }); 2470} 2471 2472// Radios and checkboxes getter/setter 2473if ( !jQuery.support.checkOn ) { 2474 jQuery.each([ "radio", "checkbox" ], function() { 2475 jQuery.valHooks[ this ] = { 2476 get: function( elem ) { 2477 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified 2478 return elem.getAttribute("value") === null ? "on" : elem.value; 2479 } 2480 }; 2481 }); 2482} 2483jQuery.each([ "radio", "checkbox" ], function() { 2484 jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { 2485 set: function( elem, value ) { 2486 if ( jQuery.isArray( value ) ) { 2487 return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0); 2488 } 2489 } 2490 }); 2491}); 2492 2493 2494 2495 2496var hasOwn = Object.prototype.hasOwnProperty, 2497 rnamespaces = /\.(.*)$/, 2498 rformElems = /^(?:textarea|input|select)$/i, 2499 rperiod = /\./g, 2500 rspaces = / /g, 2501 rescape = /[^\w\s.|`]/g, 2502 fcleanup = function( nm ) { 2503 return nm.replace(rescape, "\\$&"); 2504 }; 2505 2506/* 2507 * A number of helper functions used for managing events. 2508 * Many of the ideas behind this code originated from 2509 * Dean Edwards' addEvent library. 2510 */ 2511jQuery.event = { 2512 2513 // Bind an event to an element 2514 // Original by Dean Edwards 2515 add: function( elem, types, handler, data ) { 2516 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 2517 return; 2518 } 2519 2520 if ( handler === false ) { 2521 handler = returnFalse; 2522 } else if ( !handler ) { 2523 // Fixes bug #7229. Fix recommended by jdalton 2524 return; 2525 } 2526 2527 var handleObjIn, handleObj; 2528 2529 if ( handler.handler ) { 2530 handleObjIn = handler; 2531 handler = handleObjIn.handler; 2532 } 2533 2534 // Make sure that the function being executed has a unique ID 2535 if ( !handler.guid ) { 2536 handler.guid = jQuery.guid++; 2537 } 2538 2539 // Init the element's event structure 2540 var elemData = jQuery._data( elem ); 2541 2542 // If no elemData is found then we must be trying to bind to one of the 2543 // banned noData elements 2544 if ( !elemData ) { 2545 return; 2546 } 2547 2548 var events = elemData.events, 2549 eventHandle = elemData.handle; 2550 2551 if ( !events ) { 2552 elemData.events = events = {}; 2553 } 2554 2555 if ( !eventHandle ) { 2556 elemData.handle = eventHandle = function( e ) { 2557 // Discard the second event of a jQuery.event.trigger() and 2558 // when an event is called after a page has unloaded 2559 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? 2560 jQuery.event.handle.apply( eventHandle.elem, arguments ) : 2561 undefined; 2562 }; 2563 } 2564 2565 // Add elem as a property of the handle function 2566 // This is to prevent a memory leak with non-native events in IE. 2567 eventHandle.elem = elem; 2568 2569 // Handle multiple events separated by a space 2570 // jQuery(...).bind("mouseover mouseout", fn); 2571 types = types.split(" "); 2572 2573 var type, i = 0, namespaces; 2574 2575 while ( (type = types[ i++ ]) ) { 2576 handleObj = handleObjIn ? 2577 jQuery.extend({}, handleObjIn) : 2578 { handler: handler, data: data }; 2579 2580 // Namespaced event handlers 2581 if ( type.indexOf(".") > -1 ) { 2582 namespaces = type.split("."); 2583 type = namespaces.shift(); 2584 handleObj.namespace = namespaces.slice(0).sort().join("."); 2585 2586 } else { 2587 namespaces = []; 2588 handleObj.namespace = ""; 2589 } 2590 2591 handleObj.type = type; 2592 if ( !handleObj.guid ) { 2593 handleObj.guid = handler.guid; 2594 } 2595 2596 // Get the current list of functions bound to this event 2597 var handlers = events[ type ], 2598 special = jQuery.event.special[ type ] || {}; 2599 2600 // Init the event handler queue 2601 if ( !handlers ) { 2602 handlers = events[ type ] = []; 2603 2604 // Check for a special event handler 2605 // Only use addEventListener/attachEvent if the special 2606 // events handler returns false 2607 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 2608 // Bind the global event handler to the element 2609 if ( elem.addEventListener ) { 2610 elem.addEventListener( type, eventHandle, false ); 2611 2612 } else if ( elem.attachEvent ) { 2613 elem.attachEvent( "on" + type, eventHandle ); 2614 } 2615 } 2616 } 2617 2618 if ( special.add ) { 2619 special.add.call( elem, handleObj ); 2620 2621 if ( !handleObj.handler.guid ) { 2622 handleObj.handler.guid = handler.guid; 2623 } 2624 } 2625 2626 // Add the function to the element's handler list 2627 handlers.push( handleObj ); 2628 2629 // Keep track of which events have been used, for event optimization 2630 jQuery.event.global[ type ] = true; 2631 } 2632 2633 // Nullify elem to prevent memory leaks in IE 2634 elem = null; 2635 }, 2636 2637 global: {}, 2638 2639 // Detach an event or set of events from an element 2640 remove: function( elem, types, handler, pos ) { 2641 // don't do events on text and comment nodes 2642 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 2643 return; 2644 } 2645 2646 if ( handler === false ) { 2647 handler = returnFalse; 2648 } 2649 2650 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType, 2651 elemData = jQuery.hasData( elem ) && jQuery._data( elem ), 2652 events = elemData && elemData.events; 2653 2654 if ( !elemData || !events ) { 2655 return; 2656 } 2657 2658 // types is actually an event object here 2659 if ( types && types.type ) { 2660 handler = types.handler; 2661 types = types.type; 2662 } 2663 2664 // Unbind all events for the element 2665 if ( !types || typeof types === "string" && types.charAt(0) === "." ) { 2666 types = types || ""; 2667 2668 for ( type in events ) { 2669 jQuery.event.remove( elem, type + types ); 2670 } 2671 2672 return; 2673 } 2674 2675 // Handle multiple events separated by a space 2676 // jQuery(...).unbind("mouseover mouseout", fn); 2677 types = types.split(" "); 2678 2679 while ( (type = types[ i++ ]) ) { 2680 origType = type; 2681 handleObj = null; 2682 all = type.indexOf(".") < 0; 2683 namespaces = []; 2684 2685 if ( !all ) { 2686 // Namespaced event handlers 2687 namespaces = type.split("."); 2688 type = namespaces.shift(); 2689 2690 namespace = new RegExp("(^|\\.)" + 2691 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)"); 2692 } 2693 2694 eventType = events[ type ]; 2695 2696 if ( !eventType ) { 2697 continue; 2698 } 2699 2700 if ( !handler ) { 2701 for ( j = 0; j < eventType.length; j++ ) { 2702 handleObj = eventType[ j ]; 2703 2704 if ( all || namespace.test( handleObj.namespace ) ) { 2705 jQuery.event.remove( elem, origType, handleObj.handler, j ); 2706 eventType.splice( j--, 1 ); 2707 } 2708 } 2709 2710 continue; 2711 } 2712 2713 special = jQuery.event.special[ type ] || {}; 2714 2715 for ( j = pos || 0; j < eventType.length; j++ ) { 2716 handleObj = eventType[ j ]; 2717 2718 if ( handler.guid === handleObj.guid ) { 2719 // remove the given handler for the given type 2720 if ( all || namespace.test( handleObj.namespace ) ) { 2721 if ( pos == null ) { 2722 eventType.splice( j--, 1 ); 2723 } 2724 2725 if ( special.remove ) { 2726 special.remove.call( elem, handleObj ); 2727 } 2728 } 2729 2730 if ( pos != null ) { 2731 break; 2732 } 2733 } 2734 } 2735 2736 // remove generic event handler if no more handlers exist 2737 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) { 2738 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { 2739 jQuery.removeEvent( elem, type, elemData.handle ); 2740 } 2741 2742 ret = null; 2743 delete events[ type ]; 2744 } 2745 } 2746 2747 // Remove the expando if it's no longer used 2748 if ( jQuery.isEmptyObject( events ) ) { 2749 var handle = elemData.handle; 2750 if ( handle ) { 2751 handle.elem = null; 2752 } 2753 2754 delete elemData.events; 2755 delete elemData.handle; 2756 2757 if ( jQuery.isEmptyObject( elemData ) ) { 2758 jQuery.removeData( elem, undefined, true ); 2759 } 2760 } 2761 }, 2762 2763 // Events that are safe to short-circuit if no handlers are attached. 2764 // Native DOM events should not be added, they may have inline handlers. 2765 customEvent: { 2766 "getData": true, 2767 "setData": true, 2768 "changeData": true 2769 }, 2770 2771 trigger: function( event, data, elem, onlyHandlers ) { 2772 // Event object or event type 2773 var type = event.type || event, 2774 namespaces = [], 2775 exclusive; 2776 2777 if ( type.indexOf("!") >= 0 ) { 2778 // Exclusive events trigger only for the exact event (no namespaces) 2779 type = type.slice(0, -1); 2780 exclusive = true; 2781 } 2782 2783 if ( type.indexOf(".") >= 0 ) { 2784 // Namespaced trigger; create a regexp to match event type in handle() 2785 namespaces = type.split("."); 2786 type = namespaces.shift(); 2787 namespaces.sort(); 2788 } 2789 2790 if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { 2791 // No jQuery handlers for this event type, and it can't have inline handlers 2792 return; 2793 } 2794 2795 // Caller can pass in an Event, Object, or just an event type string 2796 event = typeof event === "object" ? 2797 // jQuery.Event object 2798 event[ jQuery.expando ] ? event : 2799 // Object literal 2800 new jQuery.Event( type, event ) : 2801 // Just the event type (string) 2802 new jQuery.Event( type ); 2803 2804 event.type = type; 2805 event.exclusive = exclusive; 2806 event.namespace = namespaces.join("."); 2807 event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)"); 2808 2809 // triggerHandler() and global events don't bubble or run the default action 2810 if ( onlyHandlers || !elem ) { 2811 event.preventDefault(); 2812 event.stopPropagation(); 2813 } 2814 2815 // Handle a global trigger 2816 if ( !elem ) { 2817 // TODO: Stop taunting the data cache; remove global events and always attach to document 2818 jQuery.each( jQuery.cache, function() { 2819 // internalKey variable is just used to make it easier to find 2820 // and potentially change this stuff later; currently it just 2821 // points to jQuery.expando 2822 var internalKey = jQuery.expando, 2823 internalCache = this[ internalKey ]; 2824 if ( internalCache && internalCache.events && internalCache.events[ type ] ) { 2825 jQuery.event.trigger( event, data, internalCache.handle.elem ); 2826 } 2827 }); 2828 return; 2829 } 2830 2831 // Don't do events on text and comment nodes 2832 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 2833 return; 2834 } 2835 2836 // Clean up the event in case it is being reused 2837 event.result = undefined; 2838 event.target = elem; 2839 2840 // Clone any incoming data and prepend the event, creating the handler arg list 2841 data = data ? jQuery.makeArray( data ) : []; 2842 data.unshift( event ); 2843 2844 var cur = elem, 2845 // IE doesn't like method names with a colon (#3533, #8272) 2846 ontype = type.indexOf(":") < 0 ? "on" + type : ""; 2847 2848 // Fire event on the current element, then bubble up the DOM tree 2849 do { 2850 var handle = jQuery._data( cur, "handle" ); 2851 2852 event.currentTarget = cur; 2853 if ( handle ) { 2854 handle.apply( cur, data ); 2855 } 2856 2857 // Trigger an inline bound script 2858 if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) { 2859 event.result = false; 2860 event.preventDefault(); 2861 } 2862 2863 // Bubble up to document, then to window 2864 cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window; 2865 } while ( cur && !event.isPropagationStopped() ); 2866 2867 // If nobody prevented the default action, do it now 2868 if ( !event.isDefaultPrevented() ) { 2869 var old, 2870 special = jQuery.event.special[ type ] || {}; 2871 2872 if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) && 2873 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { 2874 2875 // Call a native DOM method on the target with the same name name as the event. 2876 // Can't use an .isFunction)() check here because IE6/7 fails that test. 2877 // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch. 2878 try { 2879 if ( ontype && elem[ type ] ) { 2880 // Don't re-trigger an onFOO event when we call its FOO() method 2881 old = elem[ ontype ]; 2882 2883 if ( old ) { 2884 elem[ ontype ] = null; 2885 } 2886 2887 jQuery.event.triggered = type; 2888 elem[ type ](); 2889 } 2890 } catch ( ieError ) {} 2891 2892 if ( old ) { 2893 elem[ ontype ] = old; 2894 } 2895 2896 jQuery.event.triggered = undefined; 2897 } 2898 } 2899 2900 return event.result; 2901 }, 2902 2903 handle: function( event ) { 2904 event = jQuery.event.fix( event || window.event ); 2905 // Snapshot the handlers list since a called handler may add/remove events. 2906 var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0), 2907 run_all = !event.exclusive && !event.namespace, 2908 args = Array.prototype.slice.call( arguments, 0 ); 2909 2910 // Use the fix-ed Event rather than the (read-only) native event 2911 args[0] = event; 2912 event.currentTarget = this; 2913 2914 for ( var j = 0, l = handlers.length; j < l; j++ ) { 2915 var handleObj = handlers[ j ]; 2916 2917 // Triggered event must 1) be non-exclusive and have no namespace, or 2918 // 2) have namespace(s) a subset or equal to those in the bound event. 2919 if ( run_all || event.namespace_re.test( handleObj.namespace ) ) { 2920 // Pass in a reference to the handler function itself 2921 // So that we can later remove it 2922 event.handler = handleObj.handler; 2923 event.data = handleObj.data; 2924 event.handleObj = handleObj; 2925 2926 var ret = handleObj.handler.apply( this, args ); 2927 2928 if ( ret !== undefined ) { 2929 event.result = ret; 2930 if ( ret === false ) { 2931 event.preventDefault(); 2932 event.stopPropagation(); 2933 } 2934 } 2935 2936 if ( event.isImmediatePropagationStopped() ) { 2937 break; 2938 } 2939 } 2940 } 2941 return event.result; 2942 }, 2943 2944 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), 2945 2946 fix: function( event ) { 2947 if ( event[ jQuery.expando ] ) { 2948 return event; 2949 } 2950 2951 // store a copy of the original event object 2952 // and "clone" to set read-only properties 2953 var originalEvent = event; 2954 event = jQuery.Event( originalEvent ); 2955 2956 for ( var i = this.props.length, prop; i; ) { 2957 prop = this.props[ --i ]; 2958 event[ prop ] = originalEvent[ prop ]; 2959 } 2960 2961 // Fix target property, if necessary 2962 if ( !event.target ) { 2963 // Fixes #1925 where srcElement might not be defined either 2964 event.target = event.srcElement || document; 2965 } 2966 2967 // check if target is a textnode (safari) 2968 if ( event.target.nodeType === 3 ) { 2969 event.target = event.target.parentNode; 2970 } 2971 2972 // Add relatedTarget, if necessary 2973 if ( !event.relatedTarget && event.fromElement ) { 2974 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; 2975 } 2976 2977 // Calculate pageX/Y if missing and clientX/Y available 2978 if ( event.pageX == null && event.clientX != null ) { 2979 var eventDocument = event.target.ownerDocument || document, 2980 doc = eventDocument.documentElement, 2981 body = eventDocument.body; 2982 2983 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); 2984 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); 2985 } 2986 2987 // Add which for key events 2988 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) { 2989 event.which = event.charCode != null ? event.charCode : event.keyCode; 2990 } 2991 2992 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) 2993 if ( !event.metaKey && event.ctrlKey ) { 2994 event.metaKey = event.ctrlKey; 2995 } 2996 2997 // Add which for click: 1 === left; 2 === middle; 3 === right 2998 // Note: button is not normalized, so don't use it 2999 if ( !event.which && event.button !== undefined ) { 3000 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); 3001 } 3002 3003 return event; 3004 }, 3005 3006 // Deprecated, use jQuery.guid instead 3007 guid: 1E8, 3008 3009 // Deprecated, use jQuery.proxy instead 3010 proxy: jQuery.proxy, 3011 3012 special: { 3013 ready: { 3014 // Make sure the ready event is setup 3015 setup: jQuery.bindReady, 3016 teardown: jQuery.noop 3017 }, 3018 3019 live: { 3020 add: function( handleObj ) { 3021 jQuery.event.add( this, 3022 liveConvert( handleObj.origType, handleObj.selector ), 3023 jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) ); 3024 }, 3025 3026 remove: function( handleObj ) { 3027 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj ); 3028 } 3029 }, 3030 3031 beforeunload: { 3032 setup: function( data, namespaces, eventHandle ) { 3033 // We only want to do this special case on windows 3034 if ( jQuery.isWindow( this ) ) { 3035 this.onbeforeunload = eventHandle; 3036 } 3037 }, 3038 3039 teardown: function( namespaces, eventHandle ) { 3040 if ( this.onbeforeunload === eventHandle ) { 3041 this.onbeforeunload = null; 3042 } 3043 } 3044 } 3045 } 3046}; 3047 3048jQuery.removeEvent = document.removeEventListener ? 3049 function( elem, type, handle ) { 3050 if ( elem.removeEventListener ) { 3051 elem.removeEventListener( type, handle, false ); 3052 } 3053 } : 3054 function( elem, type, handle ) { 3055 if ( elem.detachEvent ) { 3056 elem.detachEvent( "on" + type, handle ); 3057 } 3058 }; 3059 3060jQuery.Event = function( src, props ) { 3061 // Allow instantiation without the 'new' keyword 3062 if ( !this.preventDefault ) { 3063 return new jQuery.Event( src, props ); 3064 } 3065 3066 // Event object 3067 if ( src && src.type ) { 3068 this.originalEvent = src; 3069 this.type = src.type; 3070 3071 // Events bubbling up the document may have been marked as prevented 3072 // by a handler lower down the tree; reflect the correct value. 3073 this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false || 3074 src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse; 3075 3076 // Event type 3077 } else { 3078 this.type = src; 3079 } 3080 3081 // Put explicitly provided properties onto the event object 3082 if ( props ) { 3083 jQuery.extend( this, props ); 3084 } 3085 3086 // timeStamp is buggy for some events on Firefox(#3843) 3087 // So we won't rely on the native value 3088 this.timeStamp = jQuery.now(); 3089 3090 // Mark it as fixed 3091 this[ jQuery.expando ] = true; 3092}; 3093 3094function returnFalse() { 3095 return false; 3096} 3097function returnTrue() { 3098 return true; 3099} 3100 3101// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 3102// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 3103jQuery.Event.prototype = { 3104 preventDefault: function() { 3105 this.isDefaultPrevented = returnTrue; 3106 3107 var e = this.originalEvent; 3108 if ( !e ) { 3109 return; 3110 } 3111 3112 // if preventDefault exists run it on the original event 3113 if ( e.preventDefault ) { 3114 e.preventDefault(); 3115 3116 // otherwise set the returnValue property of the original event to false (IE) 3117 } else { 3118 e.returnValue = false; 3119 } 3120 }, 3121 stopPropagation: function() { 3122 this.isPropagationStopped = returnTrue; 3123 3124 var e = this.originalEvent; 3125 if ( !e ) { 3126 return; 3127 } 3128 // if stopPropagation exists run it on the original event 3129 if ( e.stopPropagation ) { 3130 e.stopPropagation(); 3131 } 3132 // otherwise set the cancelBubble property of the original event to true (IE) 3133 e.cancelBubble = true; 3134 }, 3135 stopImmediatePropagation: function() { 3136 this.isImmediatePropagationStopped = returnTrue; 3137 this.stopPropagation(); 3138 }, 3139 isDefaultPrevented: returnFalse, 3140 isPropagationStopped: returnFalse, 3141 isImmediatePropagationStopped: returnFalse 3142}; 3143 3144// Checks if an event happened on an element within another element 3145// Used in jQuery.event.special.mouseenter and mouseleave handlers 3146var withinElement = function( event ) { 3147 // Check if mouse(over|out) are still within the same parent element 3148 var parent = event.relatedTarget; 3149 3150 // set the correct event type 3151 event.type = event.data; 3152 3153 // Firefox sometimes assigns relatedTarget a XUL element 3154 // which we cannot access the parentNode property of 3155 try { 3156 3157 // Chrome does something similar, the parentNode property 3158 // can be accessed but is null. 3159 if ( parent && parent !== document && !parent.parentNode ) { 3160 return; 3161 } 3162 3163 // Traverse up the tree 3164 while ( parent && parent !== this ) { 3165 parent = parent.parentNode; 3166 } 3167 3168 if ( parent !== this ) { 3169 // handle event if we actually just moused on to a non sub-element 3170 jQuery.event.handle.apply( this, arguments ); 3171 } 3172 3173 // assuming we've left the element since we most likely mousedover a xul element 3174 } catch(e) { } 3175}, 3176 3177// In case of event delegation, we only need to rename the event.type, 3178// liveHandler will take care of the rest. 3179delegate = function( event ) { 3180 event.type = event.data; 3181 jQuery.event.handle.apply( this, arguments ); 3182}; 3183 3184// Create mouseenter and mouseleave events 3185jQuery.each({ 3186 mouseenter: "mouseover", 3187 mouseleave: "mouseout" 3188}, function( orig, fix ) { 3189 jQuery.event.special[ orig ] = { 3190 setup: function( data ) { 3191 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig ); 3192 }, 3193 teardown: function( data ) { 3194 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement ); 3195 } 3196 }; 3197}); 3198 3199// submit delegation 3200if ( !jQuery.support.submitBubbles ) { 3201 3202 jQuery.event.special.submit = { 3203 setup: function( data, namespaces ) { 3204 if ( !jQuery.nodeName( this, "form" ) ) { 3205 jQuery.event.add(this, "click.specialSubmit", function( e ) { 3206 var elem = e.target, 3207 type = elem.type; 3208 3209 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) { 3210 trigger( "submit", this, arguments ); 3211 } 3212 }); 3213 3214 jQuery.event.add(this, "keypress.specialSubmit", function( e ) { 3215 var elem = e.target, 3216 type = elem.type; 3217 3218 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) { 3219 trigger( "submit", this, arguments ); 3220 } 3221 }); 3222 3223 } else { 3224 return false; 3225 } 3226 }, 3227 3228 teardown: function( namespaces ) { 3229 jQuery.event.remove( this, ".specialSubmit" ); 3230 } 3231 }; 3232 3233} 3234 3235// change delegation, happens here so we have bind. 3236if ( !jQuery.support.changeBubbles ) { 3237 3238 var changeFilters, 3239 3240 getVal = function( elem ) { 3241 var type = elem.type, val = elem.value; 3242 3243 if ( type === "radio" || type === "checkbox" ) { 3244 val = elem.checked; 3245 3246 } else if ( type === "select-multiple" ) { 3247 val = elem.selectedIndex > -1 ? 3248 jQuery.map( elem.options, function( elem ) { 3249 return elem.selected; 3250 }).join("-") : 3251 ""; 3252 3253 } else if ( jQuery.nodeName( elem, "select" ) ) { 3254 val = elem.selectedIndex; 3255 } 3256 3257 return val; 3258 }, 3259 3260 testChange = function testChange( e ) { 3261 var elem = e.target, data, val; 3262 3263 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) { 3264 return; 3265 } 3266 3267 data = jQuery._data( elem, "_change_data" ); 3268 val = getVal(elem); 3269 3270 // the current data will be also retrieved by beforeactivate 3271 if ( e.type !== "focusout" || elem.type !== "radio" ) { 3272 jQuery._data( elem, "_change_data", val ); 3273 } 3274 3275 if ( data === undefined || val === data ) { 3276 return; 3277 } 3278 3279 if ( data != null || val ) { 3280 e.type = "change"; 3281 e.liveFired = undefined; 3282 jQuery.event.trigger( e, arguments[1], elem ); 3283 } 3284 }; 3285 3286 jQuery.event.special.change = { 3287 filters: { 3288 focusout: testChange, 3289 3290 beforedeactivate: testChange, 3291 3292 click: function( e ) { 3293 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; 3294 3295 if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) { 3296 testChange.call( this, e ); 3297 } 3298 }, 3299 3300 // Change has to be called before submit 3301 // Keydown will be called before keypress, which is used in submit-event delegation 3302 keydown: function( e ) { 3303 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; 3304 3305 if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) || 3306 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || 3307 type === "select-multiple" ) { 3308 testChange.call( this, e ); 3309 } 3310 }, 3311 3312 // Beforeactivate happens also before the previous element is blurred 3313 // with this event you can't trigger a change event, but you can store 3314 // information 3315 beforeactivate: function( e ) { 3316 var elem = e.target; 3317 jQuery._data( elem, "_change_data", getVal(elem) ); 3318 } 3319 }, 3320 3321 setup: function( data, namespaces ) { 3322 if ( this.type === "file" ) { 3323 return false; 3324 } 3325 3326 for ( var type in changeFilters ) { 3327 jQuery.event.add( this, type + ".specialChange", changeFilters[type] ); 3328 } 3329 3330 return rformElems.test( this.nodeName ); 3331 }, 3332 3333 teardown: function( namespaces ) { 3334 jQuery.event.remove( this, ".specialChange" ); 3335 3336 return rformElems.test( this.nodeName ); 3337 } 3338 }; 3339 3340 changeFilters = jQuery.event.special.change.filters; 3341 3342 // Handle when the input is .focus()'d 3343 changeFilters.focus = changeFilters.beforeactivate; 3344} 3345 3346function trigger( type, elem, args ) { 3347 // Piggyback on a donor event to simulate a different one. 3348 // Fake originalEvent to avoid donor's stopPropagation, but if the 3349 // simulated event prevents default then we do the same on the donor. 3350 // Don't pass args or remember liveFired; they apply to the donor event. 3351 var event = jQuery.extend( {}, args[ 0 ] ); 3352 event.type = type; 3353 event.originalEvent = {}; 3354 event.liveFired = undefined; 3355 jQuery.event.handle.call( elem, event ); 3356 if ( event.isDefaultPrevented() ) { 3357 args[ 0 ].preventDefault(); 3358 } 3359} 3360 3361// Create "bubbling" focus and blur events 3362if ( !jQuery.support.focusinBubbles ) { 3363 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { 3364 3365 // Attach a single capturing handler while someone wants focusin/focusout 3366 var attaches = 0; 3367 3368 jQuery.event.special[ fix ] = { 3369 setup: function() { 3370 if ( attaches++ === 0 ) { 3371 document.addEventListener( orig, handler, true ); 3372 } 3373 }, 3374 teardown: function() { 3375 if ( --attaches === 0 ) { 3376 document.removeEventListener( orig, handler, true ); 3377 } 3378 } 3379 }; 3380 3381 function handler( donor ) { 3382 // Donor event is always a native one; fix it and switch its type. 3383 // Let focusin/out handler cancel the donor focus/blur event. 3384 var e = jQuery.event.fix( donor ); 3385 e.type = fix; 3386 e.originalEvent = {}; 3387 jQuery.event.trigger( e, null, e.target ); 3388 if ( e.isDefaultPrevented() ) { 3389 donor.preventDefault(); 3390 } 3391 } 3392 }); 3393} 3394 3395jQuery.each(["bind", "one"], function( i, name ) { 3396 jQuery.fn[ name ] = function( type, data, fn ) { 3397 var handler; 3398 3399 // Handle object literals 3400 if ( typeof type === "object" ) { 3401 for ( var key in type ) { 3402 this[ name ](key, data, type[key], fn); 3403 } 3404 return this; 3405 } 3406 3407 if ( arguments.length === 2 || data === false ) { 3408 fn = data; 3409 data = undefined; 3410 } 3411 3412 if ( name === "one" ) { 3413 handler = function( event ) { 3414 jQuery( this ).unbind( event, handler ); 3415 return fn.apply( this, arguments ); 3416 }; 3417 handler.guid = fn.guid || jQuery.guid++; 3418 } else { 3419 handler = fn; 3420 } 3421 3422 if ( type === "unload" && name !== "one" ) { 3423 this.one( type, data, fn ); 3424 3425 } else { 3426 for ( var i = 0, l = this.length; i < l; i++ ) { 3427 jQuery.event.add( this[i], type, handler, data ); 3428 } 3429 } 3430 3431 return this; 3432 }; 3433}); 3434 3435jQuery.fn.extend({ 3436 unbind: function( type, fn ) { 3437 // Handle object literals 3438 if ( typeof type === "object" && !type.preventDefault ) { 3439 for ( var key in type ) { 3440 this.unbind(key, type[key]); 3441 } 3442 3443 } else { 3444 for ( var i = 0, l = this.length; i < l; i++ ) { 3445 jQuery.event.remove( this[i], type, fn ); 3446 } 3447 } 3448 3449 return this; 3450 }, 3451 3452 delegate: function( selector, types, data, fn ) { 3453 return this.live( types, data, fn, selector ); 3454 }, 3455 3456 undelegate: function( selector, types, fn ) { 3457 if ( arguments.length === 0 ) { 3458 return this.unbind( "live" ); 3459 3460 } else { 3461 return this.die( types, null, fn, selector ); 3462 } 3463 }, 3464 3465 trigger: function( type, data ) { 3466 return this.each(function() { 3467 jQuery.event.trigger( type, data, this ); 3468 }); 3469 }, 3470 3471 triggerHandler: function( type, data ) { 3472 if ( this[0] ) { 3473 return jQuery.event.trigger( type, data, this[0], true ); 3474 } 3475 }, 3476 3477 toggle: function( fn ) { 3478 // Save reference to arguments for access in closure 3479 var args = arguments, 3480 guid = fn.guid || jQuery.guid++, 3481 i = 0, 3482 toggler = function( event ) { 3483 // Figure out which function to execute 3484 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i; 3485 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 ); 3486 3487 // Make sure that clicks stop 3488 event.preventDefault(); 3489 3490 // and execute the function 3491 return args[ lastToggle ].apply( this, arguments ) || false; 3492 }; 3493 3494 // link all the functions, so any of them can unbind this click handler 3495 toggler.guid = guid; 3496 while ( i < args.length ) { 3497 args[ i++ ].guid = guid; 3498 } 3499 3500 return this.click( toggler ); 3501 }, 3502 3503 hover: function( fnOver, fnOut ) { 3504 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 3505 } 3506}); 3507 3508var liveMap = { 3509 focus: "focusin", 3510 blur: "focusout", 3511 mouseenter: "mouseover", 3512 mouseleave: "mouseout" 3513}; 3514 3515jQuery.each(["live", "die"], function( i, name ) { 3516 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) { 3517 var type, i = 0, match, namespaces, preType, 3518 selector = origSelector || this.selector, 3519 context = origSelector ? this : jQuery( this.context ); 3520 3521 if ( typeof types === "object" && !types.preventDefault ) { 3522 for ( var key in types ) { 3523 context[ name ]( key, data, types[key], selector ); 3524 } 3525 3526 return this; 3527 } 3528 3529 if ( name === "die" && !types && 3530 origSelector && origSelector.charAt(0) === "." ) { 3531 3532 context.unbind( origSelector ); 3533 3534 return this; 3535 } 3536 3537 if ( data === false || jQuery.isFunction( data ) ) { 3538 fn = data || returnFalse; 3539 data = undefined; 3540 } 3541 3542 types = (types || "").split(" "); 3543 3544 while ( (type = types[ i++ ]) != null ) { 3545 match = rnamespaces.exec( type ); 3546 namespaces = ""; 3547 3548 if ( match ) { 3549 namespaces = match[0]; 3550 type = type.replace( rnamespaces, "" ); 3551 } 3552 3553 if ( type === "hover" ) { 3554 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces ); 3555 continue; 3556 } 3557 3558 preType = type; 3559 3560 if ( liveMap[ type ] ) { 3561 types.push( liveMap[ type ] + namespaces ); 3562 type = type + namespaces; 3563 3564 } else { 3565 type = (liveMap[ type ] || type) + namespaces; 3566 } 3567 3568 if ( name === "live" ) { 3569 // bind live handler 3570 for ( var j = 0, l = context.length; j < l; j++ ) { 3571 jQuery.event.add( context[j], "live." + liveConvert( type, selector ), 3572 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } ); 3573 } 3574 3575 } else { 3576 // unbind live handler 3577 context.unbind( "live." + liveConvert( type, selector ), fn ); 3578 } 3579 } 3580 3581 return this; 3582 }; 3583}); 3584 3585function liveHandler( event ) { 3586 var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret, 3587 elems = [], 3588 selectors = [], 3589 events = jQuery._data( this, "events" ); 3590 3591 // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911) 3592 if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) { 3593 return; 3594 } 3595 3596 if ( event.namespace ) { 3597 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)"); 3598 } 3599 3600 event.liveFired = this; 3601 3602 var live = events.live.slice(0); 3603 3604 for ( j = 0; j < live.length; j++ ) { 3605 handleObj = live[j]; 3606 3607 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) { 3608 selectors.push( handleObj.selector ); 3609 3610 } else { 3611 live.splice( j--, 1 ); 3612 } 3613 } 3614 3615 match = jQuery( event.target ).closest( selectors, event.currentTarget ); 3616 3617 for ( i = 0, l = match.length; i < l; i++ ) { 3618 close = match[i]; 3619 3620 for ( j = 0; j < live.length; j++ ) { 3621 handleObj = live[j]; 3622 3623 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) { 3624 elem = close.elem; 3625 related = null; 3626 3627 // Those two events require additional checking 3628 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) { 3629 event.type = handleObj.preType; 3630 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0]; 3631 3632 // Make sure not to accidentally match a child element with the same selector 3633 if ( related && jQuery.contains( elem, related ) ) { 3634 related = elem; 3635 } 3636 } 3637 3638 if ( !related || related !== elem ) { 3639 elems.push({ elem: elem, handleObj: handleObj, level: close.level }); 3640 } 3641 } 3642 } 3643 } 3644 3645 for ( i = 0, l = elems.length; i < l; i++ ) { 3646 match = elems[i]; 3647 3648 if ( maxLevel && match.level > maxLevel ) { 3649 break; 3650 } 3651 3652 event.currentTarget = match.elem; 3653 event.data = match.handleObj.data; 3654 event.handleObj = match.handleObj; 3655 3656 ret = match.handleObj.origHandler.apply( match.elem, arguments ); 3657 3658 if ( ret === false || event.isPropagationStopped() ) { 3659 maxLevel = match.level; 3660 3661 if ( ret === false ) { 3662 stop = false; 3663 } 3664 if ( event.isImmediatePropagationStopped() ) { 3665 break; 3666 } 3667 } 3668 } 3669 3670 return stop; 3671} 3672 3673function liveConvert( type, selector ) { 3674 return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&"); 3675} 3676 3677jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + 3678 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 3679 "change select submit keydown keypress keyup error").split(" "), function( i, name ) { 3680 3681 // Handle event binding 3682 jQuery.fn[ name ] = function( data, fn ) { 3683 if ( fn == null ) { 3684 fn = data; 3685 data = null; 3686 } 3687 3688 return arguments.length > 0 ? 3689 this.bind( name, data, fn ) : 3690 this.trigger( name ); 3691 }; 3692 3693 if ( jQuery.attrFn ) { 3694 jQuery.attrFn[ name ] = true; 3695 } 3696}); 3697 3698 3699 3700/*! 3701 * Sizzle CSS Selector Engine 3702 * Copyright 2011, The Dojo Foundation 3703 * Released under the MIT, BSD, and GPL Licenses. 3704 * More information: http://sizzlejs.com/ 3705 */ 3706(function(){ 3707 3708var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, 3709 done = 0, 3710 toString = Object.prototype.toString, 3711 hasDuplicate = false, 3712 baseHasDuplicate = true, 3713 rBackslash = /\\/g, 3714 rNonWord = /\W/; 3715 3716// Here we check if the JavaScript engine is using some sort of 3717// optimization where it does not always call our comparision 3718// function. If that is the case, discard the hasDuplicate value. 3719// Thus far that includes Google Chrome. 3720[0, 0].sort(function() { 3721 baseHasDuplicate = false; 3722 return 0; 3723}); 3724 3725var Sizzle = function( selector, context, results, seed ) { 3726 results = results || []; 3727 context = context || document; 3728 3729 var origContext = context; 3730 3731 if ( context.nodeType !== 1 && context.nodeType !== 9 ) { 3732 return []; 3733 } 3734 3735 if ( !selector || typeof selector !== "string" ) { 3736 return results; 3737 } 3738 3739 var m, set, checkSet, extra, ret, cur, pop, i, 3740 prune = true, 3741 contextXML = Sizzle.isXML( context ), 3742 parts = [], 3743 soFar = selector; 3744 3745 // Reset the position of the chunker regexp (start from head) 3746 do { 3747 chunker.exec( "" ); 3748 m = chunker.exec( soFar ); 3749 3750 if ( m ) { 3751 soFar = m[3]; 3752 3753 parts.push( m[1] ); 3754 3755 if ( m[2] ) { 3756 extra = m[3]; 3757 break; 3758 } 3759 } 3760 } while ( m ); 3761 3762 if ( parts.length > 1 && origPOS.exec( selector ) ) { 3763 3764 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { 3765 set = posProcess( parts[0] + parts[1], context ); 3766 3767 } else { 3768 set = Expr.relative[ parts[0] ] ? 3769 [ context ] : 3770 Sizzle( parts.shift(), context ); 3771 3772 while ( parts.length ) { 3773 selector = parts.shift(); 3774 3775 if ( Expr.relative[ selector ] ) { 3776 selector += parts.shift(); 3777 } 3778 3779 set = posProcess( selector, set ); 3780 } 3781 } 3782 3783 } else { 3784 // Take a shortcut and set the context if the root selector is an ID 3785 // (but not if it'll be faster if the inner selector is an ID) 3786 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && 3787 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { 3788 3789 ret = Sizzle.find( parts.shift(), context, contextXML ); 3790 context = ret.expr ? 3791 Sizzle.filter( ret.expr, ret.set )[0] : 3792 ret.set[0]; 3793 } 3794 3795 if ( context ) { 3796 ret = seed ? 3797 { expr: parts.pop(), set: makeArray(seed) } : 3798 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); 3799 3800 set = ret.expr ? 3801 Sizzle.filter( ret.expr, ret.set ) : 3802 ret.set; 3803 3804 if ( parts.length > 0 ) { 3805 checkSet = makeArray( set ); 3806 3807 } else { 3808 prune = false; 3809 } 3810 3811 while ( parts.length ) { 3812 cur = parts.pop(); 3813 pop = cur; 3814 3815 if ( !Expr.relative[ cur ] ) { 3816 cur = ""; 3817 } else { 3818 pop = parts.pop(); 3819 } 3820 3821 if ( pop == null ) { 3822 pop = context; 3823 } 3824 3825 Expr.relative[ cur ]( checkSet, pop, contextXML ); 3826 } 3827 3828 } else { 3829 checkSet = parts = []; 3830 } 3831 } 3832 3833 if ( !checkSet ) { 3834 checkSet = set; 3835 } 3836 3837 if ( !checkSet ) { 3838 Sizzle.error( cur || selector ); 3839 } 3840 3841 if ( toString.call(checkSet) === "[object Array]" ) { 3842 if ( !prune ) { 3843 results.push.apply( results, checkSet ); 3844 3845 } else if ( context && context.nodeType === 1 ) { 3846 for ( i = 0; checkSet[i] != null; i++ ) { 3847 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { 3848 results.push( set[i] ); 3849 } 3850 } 3851 3852 } else { 3853 for ( i = 0; checkSet[i] != null; i++ ) { 3854 if ( checkSet[i] && checkSet[i].nodeType === 1 ) { 3855 results.push( set[i] ); 3856 } 3857 } 3858 } 3859 3860 } else { 3861 makeArray( checkSet, results ); 3862 } 3863 3864 if ( extra ) { 3865 Sizzle( extra, origContext, results, seed ); 3866 Sizzle.uniqueSort( results ); 3867 } 3868 3869 return results; 3870}; 3871 3872Sizzle.uniqueSort = function( results ) { 3873 if ( sortOrder ) { 3874 hasDuplicate = baseHasDuplicate; 3875 results.sort( sortOrder ); 3876 3877 if ( hasDuplicate ) { 3878 for ( var i = 1; i < results.length; i++ ) { 3879 if ( results[i] === results[ i - 1 ] ) { 3880 results.splice( i--, 1 ); 3881 } 3882 } 3883 } 3884 } 3885 3886 return results; 3887}; 3888 3889Sizzle.matches = function( expr, set ) { 3890 return Sizzle( expr, null, null, set ); 3891}; 3892 3893Sizzle.matchesSelector = function( node, expr ) { 3894 return Sizzle( expr, null, null, [node] ).length > 0; 3895}; 3896 3897Sizzle.find = function( expr, context, isXML ) { 3898 var set; 3899 3900 if ( !expr ) { 3901 return []; 3902 } 3903 3904 for ( var i = 0, l = Expr.order.length; i < l; i++ ) { 3905 var match, 3906 type = Expr.order[i]; 3907 3908 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { 3909 var left = match[1]; 3910 match.splice( 1, 1 ); 3911 3912 if ( left.substr( left.length - 1 ) !== "\\" ) { 3913 match[1] = (match[1] || "").replace( rBackslash, "" ); 3914 set = Expr.find[ type ]( match, context, isXML ); 3915 3916 if ( set != null ) { 3917 expr = expr.replace( Expr.match[ type ], "" ); 3918 break; 3919 } 3920 } 3921 } 3922 } 3923 3924 if ( !set ) { 3925 set = typeof context.getElementsByTagName !== "undefined" ? 3926 context.getElementsByTagName( "*" ) : 3927 []; 3928 } 3929 3930 return { set: set, expr: expr }; 3931}; 3932 3933Sizzle.filter = function( expr, set, inplace, not ) { 3934 var match, anyFound, 3935 old = expr, 3936 result = [], 3937 curLoop = set, 3938 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); 3939 3940 while ( expr && set.length ) { 3941 for ( var type in Expr.filter ) { 3942 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { 3943 var found, item, 3944 filter = Expr.filter[ type ], 3945 left = match[1]; 3946 3947 anyFound = false; 3948 3949 match.splice(1,1); 3950 3951 if ( left.substr( left.length - 1 ) === "\\" ) { 3952 continue; 3953 } 3954 3955 if ( curLoop === result ) { 3956 result = []; 3957 } 3958 3959 if ( Expr.preFilter[ type ] ) { 3960 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); 3961 3962 if ( !match ) { 3963 anyFound = found = true; 3964 3965 } else if ( match === true ) { 3966 continue; 3967 } 3968 } 3969 3970 if ( match ) { 3971 for ( var i = 0; (item = curLoop[i]) != null; i++ ) { 3972 if ( item ) { 3973 found = filter( item, match, i, curLoop ); 3974 var pass = not ^ !!found; 3975 3976 if ( inplace && found != null ) { 3977 if ( pass ) { 3978 anyFound = true; 3979 3980 } else { 3981 curLoop[i] = false; 3982 } 3983 3984 } else if ( pass ) { 3985 result.push( item ); 3986 anyFound = true; 3987 } 3988 } 3989 } 3990 } 3991 3992 if ( found !== undefined ) { 3993 if ( !inplace ) { 3994 curLoop = result; 3995 } 3996 3997 expr = expr.replace( Expr.match[ type ], "" ); 3998 3999 if ( !anyFound ) { 4000 return []; 4001 } 4002 4003 break; 4004 } 4005 } 4006 } 4007 4008 // Improper expression 4009 if ( expr === old ) { 4010 if ( anyFound == null ) { 4011 Sizzle.error( expr ); 4012 4013 } else { 4014 break; 4015 } 4016 } 4017 4018 old = expr; 4019 } 4020 4021 return curLoop; 4022}; 4023 4024Sizzle.error = function( msg ) { 4025 throw "Syntax error, unrecognized expression: " + msg; 4026}; 4027 4028var Expr = Sizzle.selectors = { 4029 order: [ "ID", "NAME", "TAG" ], 4030 4031 match: { 4032 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, 4033 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, 4034 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, 4035 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, 4036 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, 4037 CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, 4038 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, 4039 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ 4040 }, 4041 4042 leftMatch: {}, 4043 4044 attrMap: { 4045 "class": "className", 4046 "for": "htmlFor" 4047 }, 4048 4049 attrHandle: { 4050 href: function( elem ) { 4051 return elem.getAttribute( "href" ); 4052 }, 4053 type: function( elem ) { 4054 return elem.getAttribute( "type" ); 4055 } 4056 }, 4057 4058 relative: { 4059 "+": function(checkSet, part){ 4060 var isPartStr = typeof part === "string", 4061 isTag = isPartStr && !rNonWord.test( part ), 4062 isPartStrNotTag = isPartStr && !isTag; 4063 4064 if ( isTag ) { 4065 part = part.toLowerCase(); 4066 } 4067 4068 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { 4069 if ( (elem = checkSet[i]) ) { 4070 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} 4071 4072 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? 4073 elem || false : 4074 elem === part; 4075 } 4076 } 4077 4078 if ( isPartStrNotTag ) { 4079 Sizzle.filter( part, checkSet, true ); 4080 } 4081 }, 4082 4083 ">": function( checkSet, part ) { 4084 var elem, 4085 isPartStr = typeof part === "string", 4086 i = 0, 4087 l = checkSet.length; 4088 4089 if ( isPartStr && !rNonWord.test( part ) ) { 4090 part = part.toLowerCase(); 4091 4092 for ( ; i < l; i++ ) { 4093 elem = checkSet[i]; 4094 4095 if ( elem ) { 4096 var parent = elem.parentNode; 4097 checkSet[i] = parent.