Première version en Python-Django.
[auf_paf.git] / static / admin / js / jquery.js
1 /*!
2 * jQuery JavaScript Library v1.4.2
3 * http://jquery.com/
4 *
5 * Copyright 2010, 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 2010, The Dojo Foundation
12 * Released under the MIT, BSD, and GPL Licenses.
13 *
14 * Date: Sat Feb 13 22:33:48 2010 -0500
15 */
16 (function( window, undefined ) {
17
18 // Define a local copy of jQuery
19 var jQuery = function( selector, context ) {
20 // The jQuery object is actually just the init constructor 'enhanced'
21 return new jQuery.fn.init( selector, context );
22 },
23
24 // Map over jQuery in case of overwrite
25 _jQuery = window.jQuery,
26
27 // Map over the $ in case of overwrite
28 _$ = window.$,
29
30 // Use the correct document accordingly with window argument (sandbox)
31 document = window.document,
32
33 // A central reference to the root jQuery(document)
34 rootjQuery,
35
36 // A simple way to check for HTML strings or ID strings
37 // (both of which we optimize for)
38 quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,
39
40 // Is it a simple selector
41 isSimple = /^.[^:#\[\.,]*$/,
42
43 // Check if a string has a non-whitespace character in it
44 rnotwhite = /\S/,
45
46 // Used for trimming whitespace
47 rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
48
49 // Match a standalone tag
50 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
51
52 // Keep a UserAgent string for use with jQuery.browser
53 userAgent = navigator.userAgent,
54
55 // For matching the engine and version of the browser
56 browserMatch,
57
58 // Has the ready events already been bound?
59 readyBound = false,
60
61 // The functions to execute on DOM ready
62 readyList = [],
63
64 // The ready event handler
65 DOMContentLoaded,
66
67 // Save a reference to some core methods
68 toString = Object.prototype.toString,
69 hasOwnProperty = Object.prototype.hasOwnProperty,
70 push = Array.prototype.push,
71 slice = Array.prototype.slice,
72 indexOf = Array.prototype.indexOf;
73
74 jQuery.fn = jQuery.prototype = {
75 init: function( selector, context ) {
76 var match, elem, ret, doc;
77
78 // Handle $(""), $(null), or $(undefined)
79 if ( !selector ) {
80 return this;
81 }
82
83 // Handle $(DOMElement)
84 if ( selector.nodeType ) {
85 this.context = this[0] = selector;
86 this.length = 1;
87 return this;
88 }
89
90 // The body element only exists once, optimize finding it
91 if ( selector === "body" && !context ) {
92 this.context = document;
93 this[0] = document.body;
94 this.selector = "body";
95 this.length = 1;
96 return this;
97 }
98
99 // Handle HTML strings
100 if ( typeof selector === "string" ) {
101 // Are we dealing with HTML string or an ID?
102 match = quickExpr.exec( selector );
103
104 // Verify a match, and that no context was specified for #id
105 if ( match && (match[1] || !context) ) {
106
107 // HANDLE: $(html) -> $(array)
108 if ( match[1] ) {
109 doc = (context ? context.ownerDocument || context : document);
110
111 // If a single string is passed in and it's a single tag
112 // just do a createElement and skip the rest
113 ret = rsingleTag.exec( selector );
114
115 if ( ret ) {
116 if ( jQuery.isPlainObject( context ) ) {
117 selector = [ document.createElement( ret[1] ) ];
118 jQuery.fn.attr.call( selector, context, true );
119
120 } else {
121 selector = [ doc.createElement( ret[1] ) ];
122 }
123
124 } else {
125 ret = buildFragment( [ match[1] ], [ doc ] );
126 selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
127 }
128
129 return jQuery.merge( this, selector );
130
131 // HANDLE: $("#id")
132 } else {
133 elem = document.getElementById( match[2] );
134
135 if ( elem ) {
136 // Handle the case where IE and Opera return items
137 // by name instead of ID
138 if ( elem.id !== match[2] ) {
139 return rootjQuery.find( selector );
140 }
141
142 // Otherwise, we inject the element directly into the jQuery object
143 this.length = 1;
144 this[0] = elem;
145 }
146
147 this.context = document;
148 this.selector = selector;
149 return this;
150 }
151
152 // HANDLE: $("TAG")
153 } else if ( !context && /^\w+$/.test( selector ) ) {
154 this.selector = selector;
155 this.context = document;
156 selector = document.getElementsByTagName( selector );
157 return jQuery.merge( this, selector );
158
159 // HANDLE: $(expr, $(...))
160 } else if ( !context || context.jquery ) {
161 return (context || rootjQuery).find( selector );
162
163 // HANDLE: $(expr, context)
164 // (which is just equivalent to: $(context).find(expr)
165 } else {
166 return jQuery( context ).find( selector );
167 }
168
169 // HANDLE: $(function)
170 // Shortcut for document ready
171 } else if ( jQuery.isFunction( selector ) ) {
172 return rootjQuery.ready( selector );
173 }
174
175 if (selector.selector !== undefined) {
176 this.selector = selector.selector;
177 this.context = selector.context;
178 }
179
180 return jQuery.makeArray( selector, this );
181 },
182
183 // Start with an empty selector
184 selector: "",
185
186 // The current version of jQuery being used
187 jquery: "1.4.2",
188
189 // The default length of a jQuery object is 0
190 length: 0,
191
192 // The number of elements contained in the matched element set
193 size: function() {
194 return this.length;
195 },
196
197 toArray: function() {
198 return slice.call( this, 0 );
199 },
200
201 // Get the Nth element in the matched element set OR
202 // Get the whole matched element set as a clean array
203 get: function( num ) {
204 return num == null ?
205
206 // Return a 'clean' array
207 this.toArray() :
208
209 // Return just the object
210 ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
211 },
212
213 // Take an array of elements and push it onto the stack
214 // (returning the new matched element set)
215 pushStack: function( elems, name, selector ) {
216 // Build a new jQuery matched element set
217 var ret = jQuery();
218
219 if ( jQuery.isArray( elems ) ) {
220 push.apply( ret, elems );
221
222 } else {
223 jQuery.merge( ret, elems );
224 }
225
226 // Add the old object onto the stack (as a reference)
227 ret.prevObject = this;
228
229 ret.context = this.context;
230
231 if ( name === "find" ) {
232 ret.selector = this.selector + (this.selector ? " " : "") + selector;
233 } else if ( name ) {
234 ret.selector = this.selector + "." + name + "(" + selector + ")";
235 }
236
237 // Return the newly-formed element set
238 return ret;
239 },
240
241 // Execute a callback for every element in the matched set.
242 // (You can seed the arguments with an array of args, but this is
243 // only used internally.)
244 each: function( callback, args ) {
245 return jQuery.each( this, callback, args );
246 },
247
248 ready: function( fn ) {
249 // Attach the listeners
250 jQuery.bindReady();
251
252 // If the DOM is already ready
253 if ( jQuery.isReady ) {
254 // Execute the function immediately
255 fn.call( document, jQuery );
256
257 // Otherwise, remember the function for later
258 } else if ( readyList ) {
259 // Add the function to the wait list
260 readyList.push( fn );
261 }
262
263 return this;
264 },
265
266 eq: function( i ) {
267 return i === -1 ?
268 this.slice( i ) :
269 this.slice( i, +i + 1 );
270 },
271
272 first: function() {
273 return this.eq( 0 );
274 },
275
276 last: function() {
277 return this.eq( -1 );
278 },
279
280 slice: function() {
281 return this.pushStack( slice.apply( this, arguments ),
282 "slice", slice.call(arguments).join(",") );
283 },
284
285 map: function( callback ) {
286 return this.pushStack( jQuery.map(this, function( elem, i ) {
287 return callback.call( elem, i, elem );
288 }));
289 },
290
291 end: function() {
292 return this.prevObject || jQuery(null);
293 },
294
295 // For internal use only.
296 // Behaves like an Array's method, not like a jQuery method.
297 push: push,
298 sort: [].sort,
299 splice: [].splice
300 };
301
302 // Give the init function the jQuery prototype for later instantiation
303 jQuery.fn.init.prototype = jQuery.fn;
304
305 jQuery.extend = jQuery.fn.extend = function() {
306 // copy reference to target object
307 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
308
309 // Handle a deep copy situation
310 if ( typeof target === "boolean" ) {
311 deep = target;
312 target = arguments[1] || {};
313 // skip the boolean and the target
314 i = 2;
315 }
316
317 // Handle case when target is a string or something (possible in deep copy)
318 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
319 target = {};
320 }
321
322 // extend jQuery itself if only one argument is passed
323 if ( length === i ) {
324 target = this;
325 --i;
326 }
327
328 for ( ; i < length; i++ ) {
329 // Only deal with non-null/undefined values
330 if ( (options = arguments[ i ]) != null ) {
331 // Extend the base object
332 for ( name in options ) {
333 src = target[ name ];
334 copy = options[ name ];
335
336 // Prevent never-ending loop
337 if ( target === copy ) {
338 continue;
339 }
340
341 // Recurse if we're merging object literal values or arrays
342 if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
343 var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
344 : jQuery.isArray(copy) ? [] : {};
345
346 // Never move original objects, clone them
347 target[ name ] = jQuery.extend( deep, clone, copy );
348
349 // Don't bring in undefined values
350 } else if ( copy !== undefined ) {
351 target[ name ] = copy;
352 }
353 }
354 }
355 }
356
357 // Return the modified object
358 return target;
359 };
360
361 jQuery.extend({
362 noConflict: function( deep ) {
363 window.$ = _$;
364
365 if ( deep ) {
366 window.jQuery = _jQuery;
367 }
368
369 return jQuery;
370 },
371
372 // Is the DOM ready to be used? Set to true once it occurs.
373 isReady: false,
374
375 // Handle when the DOM is ready
376 ready: function() {
377 // Make sure that the DOM is not already loaded
378 if ( !jQuery.isReady ) {
379 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
380 if ( !document.body ) {
381 return setTimeout( jQuery.ready, 13 );
382 }
383
384 // Remember that the DOM is ready
385 jQuery.isReady = true;
386
387 // If there are functions bound, to execute
388 if ( readyList ) {
389 // Execute all of them
390 var fn, i = 0;
391 while ( (fn = readyList[ i++ ]) ) {
392 fn.call( document, jQuery );
393 }
394
395 // Reset the list of functions
396 readyList = null;
397 }
398
399 // Trigger any bound ready events
400 if ( jQuery.fn.triggerHandler ) {
401 jQuery( document ).triggerHandler( "ready" );
402 }
403 }
404 },
405
406 bindReady: function() {
407 if ( readyBound ) {
408 return;
409 }
410
411 readyBound = true;
412
413 // Catch cases where $(document).ready() is called after the
414 // browser event has already occurred.
415 if ( document.readyState === "complete" ) {
416 return jQuery.ready();
417 }
418
419 // Mozilla, Opera and webkit nightlies currently support this event
420 if ( document.addEventListener ) {
421 // Use the handy event callback
422 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
423
424 // A fallback to window.onload, that will always work
425 window.addEventListener( "load", jQuery.ready, false );
426
427 // If IE event model is used
428 } else if ( document.attachEvent ) {
429 // ensure firing before onload,
430 // maybe late but safe also for iframes
431 document.attachEvent("onreadystatechange", DOMContentLoaded);
432
433 // A fallback to window.onload, that will always work
434 window.attachEvent( "onload", jQuery.ready );
435
436 // If IE and not a frame
437 // continually check to see if the document is ready
438 var toplevel = false;
439
440 try {
441 toplevel = window.frameElement == null;
442 } catch(e) {}
443
444 if ( document.documentElement.doScroll && toplevel ) {
445 doScrollCheck();
446 }
447 }
448 },
449
450 // See test/unit/core.js for details concerning isFunction.
451 // Since version 1.3, DOM methods and functions like alert
452 // aren't supported. They return false on IE (#2968).
453 isFunction: function( obj ) {
454 return toString.call(obj) === "[object Function]";
455 },
456
457 isArray: function( obj ) {
458 return toString.call(obj) === "[object Array]";
459 },
460
461 isPlainObject: function( obj ) {
462 // Must be an Object.
463 // Because of IE, we also have to check the presence of the constructor property.
464 // Make sure that DOM nodes and window objects don't pass through, as well
465 if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
466 return false;
467 }
468
469 // Not own constructor property must be Object
470 if ( obj.constructor
471 && !hasOwnProperty.call(obj, "constructor")
472 && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
473 return false;
474 }
475
476 // Own properties are enumerated firstly, so to speed up,
477 // if last one is own, then all properties are own.
478
479 var key;
480 for ( key in obj ) {}
481
482 return key === undefined || hasOwnProperty.call( obj, key );
483 },
484
485 isEmptyObject: function( obj ) {
486 for ( var name in obj ) {
487 return false;
488 }
489 return true;
490 },
491
492 error: function( msg ) {
493 throw msg;
494 },
495
496 parseJSON: function( data ) {
497 if ( typeof data !== "string" || !data ) {
498 return null;
499 }
500
501 // Make sure leading/trailing whitespace is removed (IE can't handle it)
502 data = jQuery.trim( data );
503
504 // Make sure the incoming data is actual JSON
505 // Logic borrowed from http://json.org/json2.js
506 if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
507 .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
508 .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
509
510 // Try to use the native JSON parser first
511 return window.JSON && window.JSON.parse ?
512 window.JSON.parse( data ) :
513 (new Function("return " + data))();
514
515 } else {
516 jQuery.error( "Invalid JSON: " + data );
517 }
518 },
519
520 noop: function() {},
521
522 // Evalulates a script in a global context
523 globalEval: function( data ) {
524 if ( data && rnotwhite.test(data) ) {
525 // Inspired by code by Andrea Giammarchi
526 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
527 var head = document.getElementsByTagName("head")[0] || document.documentElement,
528 script = document.createElement("script");
529
530 script.type = "text/javascript";
531
532 if ( jQuery.support.scriptEval ) {
533 script.appendChild( document.createTextNode( data ) );
534 } else {
535 script.text = data;
536 }
537
538 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
539 // This arises when a base node is used (#2709).
540 head.insertBefore( script, head.firstChild );
541 head.removeChild( script );
542 }
543 },
544
545 nodeName: function( elem, name ) {
546 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
547 },
548
549 // args is for internal usage only
550 each: function( object, callback, args ) {
551 var name, i = 0,
552 length = object.length,
553 isObj = length === undefined || jQuery.isFunction(object);
554
555 if ( args ) {
556 if ( isObj ) {
557 for ( name in object ) {
558 if ( callback.apply( object[ name ], args ) === false ) {
559 break;
560 }
561 }
562 } else {
563 for ( ; i < length; ) {
564 if ( callback.apply( object[ i++ ], args ) === false ) {
565 break;
566 }
567 }
568 }
569
570 // A special, fast, case for the most common use of each
571 } else {
572 if ( isObj ) {
573 for ( name in object ) {
574 if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
575 break;
576 }
577 }
578 } else {
579 for ( var value = object[0];
580 i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
581 }
582 }
583
584 return object;
585 },
586
587 trim: function( text ) {
588 return (text || "").replace( rtrim, "" );
589 },
590
591 // results is for internal usage only
592 makeArray: function( array, results ) {
593 var ret = results || [];
594
595 if ( array != null ) {
596 // The window, strings (and functions) also have 'length'
597 // The extra typeof function check is to prevent crashes
598 // in Safari 2 (See: #3039)
599 if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
600 push.call( ret, array );
601 } else {
602 jQuery.merge( ret, array );
603 }
604 }
605
606 return ret;
607 },
608
609 inArray: function( elem, array ) {
610 if ( array.indexOf ) {
611 return array.indexOf( elem );
612 }
613
614 for ( var i = 0, length = array.length; i < length; i++ ) {
615 if ( array[ i ] === elem ) {
616 return i;
617 }
618 }
619
620 return -1;
621 },
622
623 merge: function( first, second ) {
624 var i = first.length, j = 0;
625
626 if ( typeof second.length === "number" ) {
627 for ( var l = second.length; j < l; j++ ) {
628 first[ i++ ] = second[ j ];
629 }
630
631 } else {
632 while ( second[j] !== undefined ) {
633 first[ i++ ] = second[ j++ ];
634 }
635 }
636
637 first.length = i;
638
639 return first;
640 },
641
642 grep: function( elems, callback, inv ) {
643 var ret = [];
644
645 // Go through the array, only saving the items
646 // that pass the validator function
647 for ( var i = 0, length = elems.length; i < length; i++ ) {
648 if ( !inv !== !callback( elems[ i ], i ) ) {
649 ret.push( elems[ i ] );
650 }
651 }
652
653 return ret;
654 },
655
656 // arg is for internal usage only
657 map: function( elems, callback, arg ) {
658 var ret = [], value;
659
660 // Go through the array, translating each of the items to their
661 // new value (or values).
662 for ( var i = 0, length = elems.length; i < length; i++ ) {
663 value = callback( elems[ i ], i, arg );
664
665 if ( value != null ) {
666 ret[ ret.length ] = value;
667 }
668 }
669
670 return ret.concat.apply( [], ret );
671 },
672
673 // A global GUID counter for objects
674 guid: 1,
675
676 proxy: function( fn, proxy, thisObject ) {
677 if ( arguments.length === 2 ) {
678 if ( typeof proxy === "string" ) {
679 thisObject = fn;
680 fn = thisObject[ proxy ];
681 proxy = undefined;
682
683 } else if ( proxy && !jQuery.isFunction( proxy ) ) {
684 thisObject = proxy;
685 proxy = undefined;
686 }
687 }
688
689 if ( !proxy && fn ) {
690 proxy = function() {
691 return fn.apply( thisObject || this, arguments );
692 };
693 }
694
695 // Set the guid of unique handler to the same of original handler, so it can be removed
696 if ( fn ) {
697 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
698 }
699
700 // So proxy can be declared as an argument
701 return proxy;
702 },
703
704 // Use of jQuery.browser is frowned upon.
705 // More details: http://docs.jquery.com/Utilities/jQuery.browser
706 uaMatch: function( ua ) {
707 ua = ua.toLowerCase();
708
709 var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
710 /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||
711 /(msie) ([\w.]+)/.exec( ua ) ||
712 !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) ||
713 [];
714
715 return { browser: match[1] || "", version: match[2] || "0" };
716 },
717
718 browser: {}
719 });
720
721 browserMatch = jQuery.uaMatch( userAgent );
722 if ( browserMatch.browser ) {
723 jQuery.browser[ browserMatch.browser ] = true;
724 jQuery.browser.version = browserMatch.version;
725 }
726
727 // Deprecated, use jQuery.browser.webkit instead
728 if ( jQuery.browser.webkit ) {
729 jQuery.browser.safari = true;
730 }
731
732 if ( indexOf ) {
733 jQuery.inArray = function( elem, array ) {
734 return indexOf.call( array, elem );
735 };
736 }
737
738 // All jQuery objects should point back to these
739 rootjQuery = jQuery(document);
740
741 // Cleanup functions for the document ready method
742 if ( document.addEventListener ) {
743 DOMContentLoaded = function() {
744 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
745 jQuery.ready();
746 };
747
748 } else if ( document.attachEvent ) {
749 DOMContentLoaded = function() {
750 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
751 if ( document.readyState === "complete" ) {
752 document.detachEvent( "onreadystatechange", DOMContentLoaded );
753 jQuery.ready();
754 }
755 };
756 }
757
758 // The DOM ready check for Internet Explorer
759 function doScrollCheck() {
760 if ( jQuery.isReady ) {
761 return;
762 }
763
764 try {
765 // If IE is used, use the trick by Diego Perini
766 // http://javascript.nwbox.com/IEContentLoaded/
767 document.documentElement.doScroll("left");
768 } catch( error ) {
769 setTimeout( doScrollCheck, 1 );
770 return;
771 }
772
773 // and execute any waiting functions
774 jQuery.ready();
775 }
776
777 function evalScript( i, elem ) {
778 if ( elem.src ) {
779 jQuery.ajax({
780 url: elem.src,
781 async: false,
782 dataType: "script"
783 });
784 } else {
785 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
786 }
787
788 if ( elem.parentNode ) {
789 elem.parentNode.removeChild( elem );
790 }
791 }
792
793 // Mutifunctional method to get and set values to a collection
794 // The value/s can be optionally by executed if its a function
795 function access( elems, key, value, exec, fn, pass ) {
796 var length = elems.length;
797
798 // Setting many attributes
799 if ( typeof key === "object" ) {
800 for ( var k in key ) {
801 access( elems, k, key[k], exec, fn, value );
802 }
803 return elems;
804 }
805
806 // Setting one attribute
807 if ( value !== undefined ) {
808 // Optionally, function values get executed if exec is true
809 exec = !pass && exec && jQuery.isFunction(value);
810
811 for ( var i = 0; i < length; i++ ) {
812 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
813 }
814
815 return elems;
816 }
817
818 // Getting an attribute
819 return length ? fn( elems[0], key ) : undefined;
820 }
821
822 function now() {
823 return (new Date).getTime();
824 }
825 (function() {
826
827 jQuery.support = {};
828
829 var root = document.documentElement,
830 script = document.createElement("script"),
831 div = document.createElement("div"),
832 id = "script" + now();
833
834 div.style.display = "none";
835 div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
836
837 var all = div.getElementsByTagName("*"),
838 a = div.getElementsByTagName("a")[0];
839
840 // Can't get basic test support
841 if ( !all || !all.length || !a ) {
842 return;
843 }
844
845 jQuery.support = {
846 // IE strips leading whitespace when .innerHTML is used
847 leadingWhitespace: div.firstChild.nodeType === 3,
848
849 // Make sure that tbody elements aren't automatically inserted
850 // IE will insert them into empty tables
851 tbody: !div.getElementsByTagName("tbody").length,
852
853 // Make sure that link elements get serialized correctly by innerHTML
854 // This requires a wrapper element in IE
855 htmlSerialize: !!div.getElementsByTagName("link").length,
856
857 // Get the style information from getAttribute
858 // (IE uses .cssText insted)
859 style: /red/.test( a.getAttribute("style") ),
860
861 // Make sure that URLs aren't manipulated
862 // (IE normalizes it by default)
863 hrefNormalized: a.getAttribute("href") === "/a",
864
865 // Make sure that element opacity exists
866 // (IE uses filter instead)
867 // Use a regex to work around a WebKit issue. See #5145
868 opacity: /^0.55$/.test( a.style.opacity ),
869
870 // Verify style float existence
871 // (IE uses styleFloat instead of cssFloat)
872 cssFloat: !!a.style.cssFloat,
873
874 // Make sure that if no value is specified for a checkbox
875 // that it defaults to "on".
876 // (WebKit defaults to "" instead)
877 checkOn: div.getElementsByTagName("input")[0].value === "on",
878
879 // Make sure that a selected-by-default option has a working selected property.
880 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
881 optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
882
883 parentNode: div.removeChild( div.appendChild( document.createElement("div") ) ).parentNode === null,
884
885 // Will be defined later
886 deleteExpando: true,
887 checkClone: false,
888 scriptEval: false,
889 noCloneEvent: true,
890 boxModel: null
891 };
892
893 script.type = "text/javascript";
894 try {
895 script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
896 } catch(e) {}
897
898 root.insertBefore( script, root.firstChild );
899
900 // Make sure that the execution of code works by injecting a script
901 // tag with appendChild/createTextNode
902 // (IE doesn't support this, fails, and uses .text instead)
903 if ( window[ id ] ) {
904 jQuery.support.scriptEval = true;
905 delete window[ id ];
906 }
907
908 // Test to see if it's possible to delete an expando from an element
909 // Fails in Internet Explorer
910 try {
911 delete script.test;
912
913 } catch(e) {
914 jQuery.support.deleteExpando = false;
915 }
916
917 root.removeChild( script );
918
919 if ( div.attachEvent && div.fireEvent ) {
920 div.attachEvent("onclick", function click() {
921 // Cloning a node shouldn't copy over any
922 // bound event handlers (IE does this)
923 jQuery.support.noCloneEvent = false;
924 div.detachEvent("onclick", click);
925 });
926 div.cloneNode(true).fireEvent("onclick");
927 }
928
929 div = document.createElement("div");
930 div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
931
932 var fragment = document.createDocumentFragment();
933 fragment.appendChild( div.firstChild );
934
935 // WebKit doesn't clone checked state correctly in fragments
936 jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
937
938 // Figure out if the W3C box model works as expected
939 // document.body must exist before we can do this
940 jQuery(function() {
941 var div = document.createElement("div");
942 div.style.width = div.style.paddingLeft = "1px";
943
944 document.body.appendChild( div );
945 jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
946 document.body.removeChild( div ).style.display = 'none';
947
948 div = null;
949 });
950
951 // Technique from Juriy Zaytsev
952 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
953 var eventSupported = function( eventName ) {
954 var el = document.createElement("div");
955 eventName = "on" + eventName;
956
957 var isSupported = (eventName in el);
958 if ( !isSupported ) {
959 el.setAttribute(eventName, "return;");
960 isSupported = typeof el[eventName] === "function";
961 }
962 el = null;
963
964 return isSupported;
965 };
966
967 jQuery.support.submitBubbles = eventSupported("submit");
968 jQuery.support.changeBubbles = eventSupported("change");
969
970 // release memory in IE
971 root = script = div = all = a = null;
972 })();
973
974 jQuery.props = {
975 "for": "htmlFor",
976 "class": "className",
977 readonly: "readOnly",
978 maxlength: "maxLength",
979 cellspacing: "cellSpacing",
980 rowspan: "rowSpan",
981 colspan: "colSpan",
982 tabindex: "tabIndex",
983 usemap: "useMap",
984 frameborder: "frameBorder"
985 };
986 var expando = "jQuery" + now(), uuid = 0, windowData = {};
987
988 jQuery.extend({
989 cache: {},
990
991 expando:expando,
992
993 // The following elements throw uncatchable exceptions if you
994 // attempt to add expando properties to them.
995 noData: {
996 "embed": true,
997 "object": true,
998 "applet": true
999 },
1000
1001 data: function( elem, name, data ) {
1002 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
1003 return;
1004 }
1005
1006 elem = elem == window ?
1007 windowData :
1008 elem;
1009
1010 var id = elem[ expando ], cache = jQuery.cache, thisCache;
1011
1012 if ( !id && typeof name === "string" && data === undefined ) {
1013 return null;
1014 }
1015
1016 // Compute a unique ID for the element
1017 if ( !id ) {
1018 id = ++uuid;
1019 }
1020
1021 // Avoid generating a new cache unless none exists and we
1022 // want to manipulate it.
1023 if ( typeof name === "object" ) {
1024 elem[ expando ] = id;
1025 thisCache = cache[ id ] = jQuery.extend(true, {}, name);
1026
1027 } else if ( !cache[ id ] ) {
1028 elem[ expando ] = id;
1029 cache[ id ] = {};
1030 }
1031
1032 thisCache = cache[ id ];
1033
1034 // Prevent overriding the named cache with undefined values
1035 if ( data !== undefined ) {
1036 thisCache[ name ] = data;
1037 }
1038
1039 return typeof name === "string" ? thisCache[ name ] : thisCache;
1040 },
1041
1042 removeData: function( elem, name ) {
1043 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
1044 return;
1045 }
1046
1047 elem = elem == window ?
1048 windowData :
1049 elem;
1050
1051 var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];
1052
1053 // If we want to remove a specific section of the element's data
1054 if ( name ) {
1055 if ( thisCache ) {
1056 // Remove the section of cache data
1057 delete thisCache[ name ];
1058
1059 // If we've removed all the data, remove the element's cache
1060 if ( jQuery.isEmptyObject(thisCache) ) {
1061 jQuery.removeData( elem );
1062 }
1063 }
1064
1065 // Otherwise, we want to remove all of the element's data
1066 } else {
1067 if ( jQuery.support.deleteExpando ) {
1068 delete elem[ jQuery.expando ];
1069
1070 } else if ( elem.removeAttribute ) {
1071 elem.removeAttribute( jQuery.expando );
1072 }
1073
1074 // Completely remove the data cache
1075 delete cache[ id ];
1076 }
1077 }
1078 });
1079
1080 jQuery.fn.extend({
1081 data: function( key, value ) {
1082 if ( typeof key === "undefined" && this.length ) {
1083 return jQuery.data( this[0] );
1084
1085 } else if ( typeof key === "object" ) {
1086 return this.each(function() {
1087 jQuery.data( this, key );
1088 });
1089 }
1090
1091 var parts = key.split(".");
1092 parts[1] = parts[1] ? "." + parts[1] : "";
1093
1094 if ( value === undefined ) {
1095 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1096
1097 if ( data === undefined && this.length ) {
1098 data = jQuery.data( this[0], key );
1099 }
1100 return data === undefined && parts[1] ?
1101 this.data( parts[0] ) :
1102 data;
1103 } else {
1104 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
1105 jQuery.data( this, key, value );
1106 });
1107 }
1108 },
1109
1110 removeData: function( key ) {
1111 return this.each(function() {
1112 jQuery.removeData( this, key );
1113 });
1114 }
1115 });
1116 jQuery.extend({
1117 queue: function( elem, type, data ) {
1118 if ( !elem ) {
1119 return;
1120 }
1121
1122 type = (type || "fx") + "queue";
1123 var q = jQuery.data( elem, type );
1124
1125 // Speed up dequeue by getting out quickly if this is just a lookup
1126 if ( !data ) {
1127 return q || [];
1128 }
1129
1130 if ( !q || jQuery.isArray(data) ) {
1131 q = jQuery.data( elem, type, jQuery.makeArray(data) );
1132
1133 } else {
1134 q.push( data );
1135 }
1136
1137 return q;
1138 },
1139
1140 dequeue: function( elem, type ) {
1141 type = type || "fx";
1142
1143 var queue = jQuery.queue( elem, type ), fn = queue.shift();
1144
1145 // If the fx queue is dequeued, always remove the progress sentinel
1146 if ( fn === "inprogress" ) {
1147 fn = queue.shift();
1148 }
1149
1150 if ( fn ) {
1151 // Add a progress sentinel to prevent the fx queue from being
1152 // automatically dequeued
1153 if ( type === "fx" ) {
1154 queue.unshift("inprogress");
1155 }
1156
1157 fn.call(elem, function() {
1158 jQuery.dequeue(elem, type);
1159 });
1160 }
1161 }
1162 });
1163
1164 jQuery.fn.extend({
1165 queue: function( type, data ) {
1166 if ( typeof type !== "string" ) {
1167 data = type;
1168 type = "fx";
1169 }
1170
1171 if ( data === undefined ) {
1172 return jQuery.queue( this[0], type );
1173 }
1174 return this.each(function( i, elem ) {
1175 var queue = jQuery.queue( this, type, data );
1176
1177 if ( type === "fx" && queue[0] !== "inprogress" ) {
1178 jQuery.dequeue( this, type );
1179 }
1180 });
1181 },
1182 dequeue: function( type ) {
1183 return this.each(function() {
1184 jQuery.dequeue( this, type );
1185 });
1186 },
1187
1188 // Based off of the plugin by Clint Helfers, with permission.
1189 // http://blindsignals.com/index.php/2009/07/jquery-delay/
1190 delay: function( time, type ) {
1191 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1192 type = type || "fx";
1193
1194 return this.queue( type, function() {
1195 var elem = this;
1196 setTimeout(function() {
1197 jQuery.dequeue( elem, type );
1198 }, time );
1199 });
1200 },
1201
1202 clearQueue: function( type ) {
1203 return this.queue( type || "fx", [] );
1204 }
1205 });
1206 var rclass = /[\n\t]/g,
1207 rspace = /\s+/,
1208 rreturn = /\r/g,
1209 rspecialurl = /href|src|style/,
1210 rtype = /(button|input)/i,
1211 rfocusable = /(button|input|object|select|textarea)/i,
1212 rclickable = /^(a|area)$/i,
1213 rradiocheck = /radio|checkbox/;
1214
1215 jQuery.fn.extend({
1216 attr: function( name, value ) {
1217 return access( this, name, value, true, jQuery.attr );
1218 },
1219
1220 removeAttr: function( name, fn ) {
1221 return this.each(function(){
1222 jQuery.attr( this, name, "" );
1223 if ( this.nodeType === 1 ) {
1224 this.removeAttribute( name );
1225 }
1226 });
1227 },
1228
1229 addClass: function( value ) {
1230 if ( jQuery.isFunction(value) ) {
1231 return this.each(function(i) {
1232 var self = jQuery(this);
1233 self.addClass( value.call(this, i, self.attr("class")) );
1234 });
1235 }
1236
1237 if ( value && typeof value === "string" ) {
1238 var classNames = (value || "").split( rspace );
1239
1240 for ( var i = 0, l = this.length; i < l; i++ ) {
1241 var elem = this[i];
1242
1243 if ( elem.nodeType === 1 ) {
1244 if ( !elem.className ) {
1245 elem.className = value;
1246
1247 } else {
1248 var className = " " + elem.className + " ", setClass = elem.className;
1249 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1250 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
1251 setClass += " " + classNames[c];
1252 }
1253 }
1254 elem.className = jQuery.trim( setClass );
1255 }
1256 }
1257 }
1258 }
1259
1260 return this;
1261 },
1262
1263 removeClass: function( value ) {
1264 if ( jQuery.isFunction(value) ) {
1265 return this.each(function(i) {
1266 var self = jQuery(this);
1267 self.removeClass( value.call(this, i, self.attr("class")) );
1268 });
1269 }
1270
1271 if ( (value && typeof value === "string") || value === undefined ) {
1272 var classNames = (value || "").split(rspace);
1273
1274 for ( var i = 0, l = this.length; i < l; i++ ) {
1275 var elem = this[i];
1276
1277 if ( elem.nodeType === 1 && elem.className ) {
1278 if ( value ) {
1279 var className = (" " + elem.className + " ").replace(rclass, " ");
1280 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1281 className = className.replace(" " + classNames[c] + " ", " ");
1282 }
1283 elem.className = jQuery.trim( className );
1284
1285 } else {
1286 elem.className = "";
1287 }
1288 }
1289 }
1290 }
1291
1292 return this;
1293 },
1294
1295 toggleClass: function( value, stateVal ) {
1296 var type = typeof value, isBool = typeof stateVal === "boolean";
1297
1298 if ( jQuery.isFunction( value ) ) {
1299 return this.each(function(i) {
1300 var self = jQuery(this);
1301 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
1302 });
1303 }
1304
1305 return this.each(function() {
1306 if ( type === "string" ) {
1307 // toggle individual class names
1308 var className, i = 0, self = jQuery(this),
1309 state = stateVal,
1310 classNames = value.split( rspace );
1311
1312 while ( (className = classNames[ i++ ]) ) {
1313 // check each className given, space seperated list
1314 state = isBool ? state : !self.hasClass( className );
1315 self[ state ? "addClass" : "removeClass" ]( className );
1316 }
1317
1318 } else if ( type === "undefined" || type === "boolean" ) {
1319 if ( this.className ) {
1320 // store className if set
1321 jQuery.data( this, "__className__", this.className );
1322 }
1323
1324 // toggle whole className
1325 this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
1326 }
1327 });
1328 },
1329
1330 hasClass: function( selector ) {
1331 var className = " " + selector + " ";
1332 for ( var i = 0, l = this.length; i < l; i++ ) {
1333 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
1334 return true;
1335 }
1336 }
1337
1338 return false;
1339 },
1340
1341 val: function( value ) {
1342 if ( value === undefined ) {
1343 var elem = this[0];
1344
1345 if ( elem ) {
1346 if ( jQuery.nodeName( elem, "option" ) ) {
1347 return (elem.attributes.value || {}).specified ? elem.value : elem.text;
1348 }
1349
1350 // We need to handle select boxes special
1351 if ( jQuery.nodeName( elem, "select" ) ) {
1352 var index = elem.selectedIndex,
1353 values = [],
1354 options = elem.options,
1355 one = elem.type === "select-one";
1356
1357 // Nothing was selected
1358 if ( index < 0 ) {
1359 return null;
1360 }
1361
1362 // Loop through all the selected options
1363 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
1364 var option = options[ i ];
1365
1366 if ( option.selected ) {
1367 // Get the specifc value for the option
1368 value = jQuery(option).val();
1369
1370 // We don't need an array for one selects
1371 if ( one ) {
1372 return value;
1373 }
1374
1375 // Multi-Selects return an array
1376 values.push( value );
1377 }
1378 }
1379
1380 return values;
1381 }
1382
1383 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
1384 if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
1385 return elem.getAttribute("value") === null ? "on" : elem.value;
1386 }
1387
1388
1389 // Everything else, we just grab the value
1390 return (elem.value || "").replace(rreturn, "");
1391
1392 }
1393
1394 return undefined;
1395 }
1396
1397 var isFunction = jQuery.isFunction(value);
1398
1399 return this.each(function(i) {
1400 var self = jQuery(this), val = value;
1401
1402 if ( this.nodeType !== 1 ) {
1403 return;
1404 }
1405
1406 if ( isFunction ) {
1407 val = value.call(this, i, self.val());
1408 }
1409
1410 // Typecast each time if the value is a Function and the appended
1411 // value is therefore different each time.
1412 if ( typeof val === "number" ) {
1413 val += "";
1414 }
1415
1416 if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
1417 this.checked = jQuery.inArray( self.val(), val ) >= 0;
1418
1419 } else if ( jQuery.nodeName( this, "select" ) ) {
1420 var values = jQuery.makeArray(val);
1421
1422 jQuery( "option", this ).each(function() {
1423 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
1424 });
1425
1426 if ( !values.length ) {
1427 this.selectedIndex = -1;
1428 }
1429
1430 } else {
1431 this.value = val;
1432 }
1433 });
1434 }
1435 });
1436
1437 jQuery.extend({
1438 attrFn: {
1439 val: true,
1440 css: true,
1441 html: true,
1442 text: true,
1443 data: true,
1444 width: true,
1445 height: true,
1446 offset: true
1447 },
1448
1449 attr: function( elem, name, value, pass ) {
1450 // don't set attributes on text and comment nodes
1451 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
1452 return undefined;
1453 }
1454
1455 if ( pass && name in jQuery.attrFn ) {
1456 return jQuery(elem)[name](value);
1457 }
1458
1459 var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
1460 // Whether we are setting (or getting)
1461 set = value !== undefined;
1462
1463 // Try to normalize/fix the name
1464 name = notxml && jQuery.props[ name ] || name;
1465
1466 // Only do all the following if this is a node (faster for style)
1467 if ( elem.nodeType === 1 ) {
1468 // These attributes require special treatment
1469 var special = rspecialurl.test( name );
1470
1471 // Safari mis-reports the default selected property of an option
1472 // Accessing the parent's selectedIndex property fixes it
1473 if ( name === "selected" && !jQuery.support.optSelected ) {
1474 var parent = elem.parentNode;
1475 if ( parent ) {
1476 parent.selectedIndex;
1477
1478 // Make sure that it also works with optgroups, see #5701
1479 if ( parent.parentNode ) {
1480 parent.parentNode.selectedIndex;
1481 }
1482 }
1483 }
1484
1485 // If applicable, access the attribute via the DOM 0 way
1486 if ( name in elem && notxml && !special ) {
1487 if ( set ) {
1488 // We can't allow the type property to be changed (since it causes problems in IE)
1489 if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
1490 jQuery.error( "type property can't be changed" );
1491 }
1492
1493 elem[ name ] = value;
1494 }
1495
1496 // browsers index elements by id/name on forms, give priority to attributes.
1497 if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
1498 return elem.getAttributeNode( name ).nodeValue;
1499 }
1500
1501 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1502 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1503 if ( name === "tabIndex" ) {
1504 var attributeNode = elem.getAttributeNode( "tabIndex" );
1505
1506 return attributeNode && attributeNode.specified ?
1507 attributeNode.value :
1508 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
1509 0 :
1510 undefined;
1511 }
1512
1513 return elem[ name ];
1514 }
1515
1516 if ( !jQuery.support.style && notxml && name === "style" ) {
1517 if ( set ) {
1518 elem.style.cssText = "" + value;
1519 }
1520
1521 return elem.style.cssText;
1522 }
1523
1524 if ( set ) {
1525 // convert the value to a string (all browsers do this but IE) see #1070
1526 elem.setAttribute( name, "" + value );
1527 }
1528
1529 var attr = !jQuery.support.hrefNormalized && notxml && special ?
1530 // Some attributes require a special call on IE
1531 elem.getAttribute( name, 2 ) :
1532 elem.getAttribute( name );
1533
1534 // Non-existent attributes return null, we normalize to undefined
1535 return attr === null ? undefined : attr;
1536 }
1537
1538 // elem is actually elem.style ... set the style
1539 // Using attr for specific style information is now deprecated. Use style instead.
1540 return jQuery.style( elem, name, value );
1541 }
1542 });
1543 var rnamespaces = /\.(.*)$/,
1544 fcleanup = function( nm ) {
1545 return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
1546 return "\\" + ch;
1547 });
1548 };
1549
1550 /*
1551 * A number of helper functions used for managing events.
1552 * Many of the ideas behind this code originated from
1553 * Dean Edwards' addEvent library.
1554 */
1555 jQuery.event = {
1556
1557 // Bind an event to an element
1558 // Original by Dean Edwards
1559 add: function( elem, types, handler, data ) {
1560 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
1561 return;
1562 }
1563
1564 // For whatever reason, IE has trouble passing the window object
1565 // around, causing it to be cloned in the process
1566 if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
1567 elem = window;
1568 }
1569
1570 var handleObjIn, handleObj;
1571
1572 if ( handler.handler ) {
1573 handleObjIn = handler;
1574 handler = handleObjIn.handler;
1575 }
1576
1577 // Make sure that the function being executed has a unique ID
1578 if ( !handler.guid ) {
1579 handler.guid = jQuery.guid++;
1580 }
1581
1582 // Init the element's event structure
1583 var elemData = jQuery.data( elem );
1584
1585 // If no elemData is found then we must be trying to bind to one of the
1586 // banned noData elements
1587 if ( !elemData ) {
1588 return;
1589 }
1590
1591 var events = elemData.events = elemData.events || {},
1592 eventHandle = elemData.handle, eventHandle;
1593
1594 if ( !eventHandle ) {
1595 elemData.handle = eventHandle = function() {
1596 // Handle the second event of a trigger and when
1597 // an event is called after a page has unloaded
1598 return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
1599 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
1600 undefined;
1601 };
1602 }
1603
1604 // Add elem as a property of the handle function
1605 // This is to prevent a memory leak with non-native events in IE.
1606 eventHandle.elem = elem;
1607
1608 // Handle multiple events separated by a space
1609 // jQuery(...).bind("mouseover mouseout", fn);
1610 types = types.split(" ");
1611
1612 var type, i = 0, namespaces;
1613
1614 while ( (type = types[ i++ ]) ) {
1615 handleObj = handleObjIn ?
1616 jQuery.extend({}, handleObjIn) :
1617 { handler: handler, data: data };
1618
1619 // Namespaced event handlers
1620 if ( type.indexOf(".") > -1 ) {
1621 namespaces = type.split(".");
1622 type = namespaces.shift();
1623 handleObj.namespace = namespaces.slice(0).sort().join(".");
1624
1625 } else {
1626 namespaces = [];
1627 handleObj.namespace = "";
1628 }
1629
1630 handleObj.type = type;
1631 handleObj.guid = handler.guid;
1632
1633 // Get the current list of functions bound to this event
1634 var handlers = events[ type ],
1635 special = jQuery.event.special[ type ] || {};
1636
1637 // Init the event handler queue
1638 if ( !handlers ) {
1639 handlers = events[ type ] = [];
1640
1641 // Check for a special event handler
1642 // Only use addEventListener/attachEvent if the special
1643 // events handler returns false
1644 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
1645 // Bind the global event handler to the element
1646 if ( elem.addEventListener ) {
1647 elem.addEventListener( type, eventHandle, false );
1648
1649 } else if ( elem.attachEvent ) {
1650 elem.attachEvent( "on" + type, eventHandle );
1651 }
1652 }
1653 }
1654
1655 if ( special.add ) {
1656 special.add.call( elem, handleObj );
1657
1658 if ( !handleObj.handler.guid ) {
1659 handleObj.handler.guid = handler.guid;
1660 }
1661 }
1662
1663 // Add the function to the element's handler list
1664 handlers.push( handleObj );
1665
1666 // Keep track of which events have been used, for global triggering
1667 jQuery.event.global[ type ] = true;
1668 }
1669
1670 // Nullify elem to prevent memory leaks in IE
1671 elem = null;
1672 },
1673
1674 global: {},
1675
1676 // Detach an event or set of events from an element
1677 remove: function( elem, types, handler, pos ) {
1678 // don't do events on text and comment nodes
1679 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
1680 return;
1681 }
1682
1683 var ret, type, fn, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
1684 elemData = jQuery.data( elem ),
1685 events = elemData && elemData.events;
1686
1687 if ( !elemData || !events ) {
1688 return;
1689 }
1690
1691 // types is actually an event object here
1692 if ( types && types.type ) {
1693 handler = types.handler;
1694 types = types.type;
1695 }
1696
1697 // Unbind all events for the element
1698 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
1699 types = types || "";
1700
1701 for ( type in events ) {
1702 jQuery.event.remove( elem, type + types );
1703 }
1704
1705 return;
1706 }
1707
1708 // Handle multiple events separated by a space
1709 // jQuery(...).unbind("mouseover mouseout", fn);
1710 types = types.split(" ");
1711
1712 while ( (type = types[ i++ ]) ) {
1713 origType = type;
1714 handleObj = null;
1715 all = type.indexOf(".") < 0;
1716 namespaces = [];
1717
1718 if ( !all ) {
1719 // Namespaced event handlers
1720 namespaces = type.split(".");
1721 type = namespaces.shift();
1722
1723 namespace = new RegExp("(^|\\.)" +
1724 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)")
1725 }
1726
1727 eventType = events[ type ];
1728
1729 if ( !eventType ) {
1730 continue;
1731 }
1732
1733 if ( !handler ) {
1734 for ( var j = 0; j < eventType.length; j++ ) {
1735 handleObj = eventType[ j ];
1736
1737 if ( all || namespace.test( handleObj.namespace ) ) {
1738 jQuery.event.remove( elem, origType, handleObj.handler, j );
1739 eventType.splice( j--, 1 );
1740 }
1741 }
1742
1743 continue;
1744 }
1745
1746 special = jQuery.event.special[ type ] || {};
1747
1748 for ( var j = pos || 0; j < eventType.length; j++ ) {
1749 handleObj = eventType[ j ];
1750
1751 if ( handler.guid === handleObj.guid ) {
1752 // remove the given handler for the given type
1753 if ( all || namespace.test( handleObj.namespace ) ) {
1754 if ( pos == null ) {
1755 eventType.splice( j--, 1 );
1756 }
1757
1758 if ( special.remove ) {
1759 special.remove.call( elem, handleObj );
1760 }
1761 }
1762
1763 if ( pos != null ) {
1764 break;
1765 }
1766 }
1767 }
1768
1769 // remove generic event handler if no more handlers exist
1770 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
1771 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
1772 removeEvent( elem, type, elemData.handle );
1773 }
1774
1775 ret = null;
1776 delete events[ type ];
1777 }
1778 }
1779
1780 // Remove the expando if it's no longer used
1781 if ( jQuery.isEmptyObject( events ) ) {
1782 var handle = elemData.handle;
1783 if ( handle ) {
1784 handle.elem = null;
1785 }
1786
1787 delete elemData.events;
1788 delete elemData.handle;
1789
1790 if ( jQuery.isEmptyObject( elemData ) ) {
1791 jQuery.removeData( elem );
1792 }
1793 }
1794 },
1795
1796 // bubbling is internal
1797 trigger: function( event, data, elem /*, bubbling */ ) {
1798 // Event object or event type
1799 var type = event.type || event,
1800 bubbling = arguments[3];
1801
1802 if ( !bubbling ) {
1803 event = typeof event === "object" ?
1804 // jQuery.Event object
1805 event[expando] ? event :
1806 // Object literal
1807 jQuery.extend( jQuery.Event(type), event ) :
1808 // Just the event type (string)
1809 jQuery.Event(type);
1810
1811 if ( type.indexOf("!") >= 0 ) {
1812 event.type = type = type.slice(0, -1);
1813 event.exclusive = true;
1814 }
1815
1816 // Handle a global trigger
1817 if ( !elem ) {
1818 // Don't bubble custom events when global (to avoid too much overhead)
1819 event.stopPropagation();
1820
1821 // Only trigger if we've ever bound an event for it
1822 if ( jQuery.event.global[ type ] ) {
1823 jQuery.each( jQuery.cache, function() {
1824 if ( this.events && this.events[type] ) {
1825 jQuery.event.trigger( event, data, this.handle.elem );
1826 }
1827 });
1828 }
1829 }
1830
1831 // Handle triggering a single element
1832
1833 // don't do events on text and comment nodes
1834 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
1835 return undefined;
1836 }
1837
1838 // Clean up in case it is reused
1839 event.result = undefined;
1840 event.target = elem;
1841
1842 // Clone the incoming data, if any
1843 data = jQuery.makeArray( data );
1844 data.unshift( event );
1845 }
1846
1847 event.currentTarget = elem;
1848
1849 // Trigger the event, it is assumed that "handle" is a function
1850 var handle = jQuery.data( elem, "handle" );
1851 if ( handle ) {
1852 handle.apply( elem, data );
1853 }
1854
1855 var parent = elem.parentNode || elem.ownerDocument;
1856
1857 // Trigger an inline bound script
1858 try {
1859 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
1860 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
1861 event.result = false;
1862 }
1863 }
1864
1865 // prevent IE from throwing an error for some elements with some event types, see #3533
1866 } catch (e) {}
1867
1868 if ( !event.isPropagationStopped() && parent ) {
1869 jQuery.event.trigger( event, data, parent, true );
1870
1871 } else if ( !event.isDefaultPrevented() ) {
1872 var target = event.target, old,
1873 isClick = jQuery.nodeName(target, "a") && type === "click",
1874 special = jQuery.event.special[ type ] || {};
1875
1876 if ( (!special._default || special._default.call( elem, event ) === false) &&
1877 !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
1878
1879 try {
1880 if ( target[ type ] ) {
1881 // Make sure that we don't accidentally re-trigger the onFOO events
1882 old = target[ "on" + type ];
1883
1884 if ( old ) {
1885 target[ "on" + type ] = null;
1886 }
1887
1888 jQuery.event.triggered = true;
1889 target[ type ]();
1890 }
1891
1892 // prevent IE from throwing an error for some elements with some event types, see #3533
1893 } catch (e) {}
1894
1895 if ( old ) {
1896 target[ "on" + type ] = old;
1897 }
1898
1899 jQuery.event.triggered = false;
1900 }
1901 }
1902 },
1903
1904 handle: function( event ) {
1905 var all, handlers, namespaces, namespace, events;
1906
1907 event = arguments[0] = jQuery.event.fix( event || window.event );
1908 event.currentTarget = this;
1909
1910 // Namespaced event handlers
1911 all = event.type.indexOf(".") < 0 && !event.exclusive;
1912
1913 if ( !all ) {
1914 namespaces = event.type.split(".");
1915 event.type = namespaces.shift();
1916 namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
1917 }
1918
1919 var events = jQuery.data(this, "events"), handlers = events[ event.type ];
1920
1921 if ( events && handlers ) {
1922 // Clone the handlers to prevent manipulation
1923 handlers = handlers.slice(0);
1924
1925 for ( var j = 0, l = handlers.length; j < l; j++ ) {
1926 var handleObj = handlers[ j ];
1927
1928 // Filter the functions by class
1929 if ( all || namespace.test( handleObj.namespace ) ) {
1930 // Pass in a reference to the handler function itself
1931 // So that we can later remove it
1932 event.handler = handleObj.handler;
1933 event.data = handleObj.data;
1934 event.handleObj = handleObj;
1935
1936 var ret = handleObj.handler.apply( this, arguments );
1937
1938 if ( ret !== undefined ) {
1939 event.result = ret;
1940 if ( ret === false ) {
1941 event.preventDefault();
1942 event.stopPropagation();
1943 }
1944 }
1945
1946 if ( event.isImmediatePropagationStopped() ) {
1947 break;
1948 }
1949 }
1950 }
1951 }
1952
1953 return event.result;
1954 },
1955
1956 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
1957
1958 fix: function( event ) {
1959 if ( event[ expando ] ) {
1960 return event;
1961 }
1962
1963 // store a copy of the original event object
1964 // and "clone" to set read-only properties
1965 var originalEvent = event;
1966 event = jQuery.Event( originalEvent );
1967
1968 for ( var i = this.props.length, prop; i; ) {
1969 prop = this.props[ --i ];
1970 event[ prop ] = originalEvent[ prop ];
1971 }
1972
1973 // Fix target property, if necessary
1974 if ( !event.target ) {
1975 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
1976 }
1977
1978 // check if target is a textnode (safari)
1979 if ( event.target.nodeType === 3 ) {
1980 event.target = event.target.parentNode;
1981 }
1982
1983 // Add relatedTarget, if necessary
1984 if ( !event.relatedTarget && event.fromElement ) {
1985 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
1986 }
1987
1988 // Calculate pageX/Y if missing and clientX/Y available
1989 if ( event.pageX == null && event.clientX != null ) {
1990 var doc = document.documentElement, body = document.body;
1991 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
1992 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
1993 }
1994
1995 // Add which for key events
1996 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
1997 event.which = event.charCode || event.keyCode;
1998 }
1999
2000 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2001 if ( !event.metaKey && event.ctrlKey ) {
2002 event.metaKey = event.ctrlKey;
2003 }
2004
2005 // Add which for click: 1 === left; 2 === middle; 3 === right
2006 // Note: button is not normalized, so don't use it
2007 if ( !event.which && event.button !== undefined ) {
2008 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2009 }
2010
2011 return event;
2012 },
2013
2014 // Deprecated, use jQuery.guid instead
2015 guid: 1E8,
2016
2017 // Deprecated, use jQuery.proxy instead
2018 proxy: jQuery.proxy,
2019
2020 special: {
2021 ready: {
2022 // Make sure the ready event is setup
2023 setup: jQuery.bindReady,
2024 teardown: jQuery.noop
2025 },
2026
2027 live: {
2028 add: function( handleObj ) {
2029 jQuery.event.add( this, handleObj.origType, jQuery.extend({}, handleObj, {handler: liveHandler}) );
2030 },
2031
2032 remove: function( handleObj ) {
2033 var remove = true,
2034 type = handleObj.origType.replace(rnamespaces, "");
2035
2036 jQuery.each( jQuery.data(this, "events").live || [], function() {
2037 if ( type === this.origType.replace(rnamespaces, "") ) {
2038 remove = false;
2039 return false;
2040 }
2041 });
2042
2043 if ( remove ) {
2044 jQuery.event.remove( this, handleObj.origType, liveHandler );
2045 }
2046 }
2047
2048 },
2049
2050 beforeunload: {
2051 setup: function( data, namespaces, eventHandle ) {
2052 // We only want to do this special case on windows
2053 if ( this.setInterval ) {
2054 this.onbeforeunload = eventHandle;
2055 }
2056
2057 return false;
2058 },
2059 teardown: function( namespaces, eventHandle ) {
2060 if ( this.onbeforeunload === eventHandle ) {
2061 this.onbeforeunload = null;
2062 }
2063 }
2064 }
2065 }
2066 };
2067
2068 var removeEvent = document.removeEventListener ?
2069 function( elem, type, handle ) {
2070 elem.removeEventListener( type, handle, false );
2071 } :
2072 function( elem, type, handle ) {
2073 elem.detachEvent( "on" + type, handle );
2074 };
2075
2076 jQuery.Event = function( src ) {
2077 // Allow instantiation without the 'new' keyword
2078 if ( !this.preventDefault ) {
2079 return new jQuery.Event( src );
2080 }
2081
2082 // Event object
2083 if ( src && src.type ) {
2084 this.originalEvent = src;
2085 this.type = src.type;
2086 // Event type
2087 } else {
2088 this.type = src;
2089 }
2090
2091 // timeStamp is buggy for some events on Firefox(#3843)
2092 // So we won't rely on the native value
2093 this.timeStamp = now();
2094
2095 // Mark it as fixed
2096 this[ expando ] = true;
2097 };
2098
2099 function returnFalse() {
2100 return false;
2101 }
2102 function returnTrue() {
2103 return true;
2104 }
2105
2106 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2107 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2108 jQuery.Event.prototype = {
2109 preventDefault: function() {
2110 this.isDefaultPrevented = returnTrue;
2111
2112 var e = this.originalEvent;
2113 if ( !e ) {
2114 return;
2115 }
2116
2117 // if preventDefault exists run it on the original event
2118 if ( e.preventDefault ) {
2119 e.preventDefault();
2120 }
2121 // otherwise set the returnValue property of the original event to false (IE)
2122 e.returnValue = false;
2123 },
2124 stopPropagation: function() {
2125 this.isPropagationStopped = returnTrue;
2126
2127 var e = this.originalEvent;
2128 if ( !e ) {
2129 return;
2130 }
2131 // if stopPropagation exists run it on the original event
2132 if ( e.stopPropagation ) {
2133 e.stopPropagation();
2134 }
2135 // otherwise set the cancelBubble property of the original event to true (IE)
2136 e.cancelBubble = true;
2137 },
2138 stopImmediatePropagation: function() {
2139 this.isImmediatePropagationStopped = returnTrue;
2140 this.stopPropagation();
2141 },
2142 isDefaultPrevented: returnFalse,
2143 isPropagationStopped: returnFalse,
2144 isImmediatePropagationStopped: returnFalse
2145 };
2146
2147 // Checks if an event happened on an element within another element
2148 // Used in jQuery.event.special.mouseenter and mouseleave handlers
2149 var withinElement = function( event ) {
2150 // Check if mouse(over|out) are still within the same parent element
2151 var parent = event.relatedTarget;
2152
2153 // Firefox sometimes assigns relatedTarget a XUL element
2154 // which we cannot access the parentNode property of
2155 try {
2156 // Traverse up the tree
2157 while ( parent && parent !== this ) {
2158 parent = parent.parentNode;
2159 }
2160
2161 if ( parent !== this ) {
2162 // set the correct event type
2163 event.type = event.data;
2164
2165 // handle event if we actually just moused on to a non sub-element
2166 jQuery.event.handle.apply( this, arguments );
2167 }
2168
2169 // assuming we've left the element since we most likely mousedover a xul element
2170 } catch(e) { }
2171 },
2172
2173 // In case of event delegation, we only need to rename the event.type,
2174 // liveHandler will take care of the rest.
2175 delegate = function( event ) {
2176 event.type = event.data;
2177 jQuery.event.handle.apply( this, arguments );
2178 };
2179
2180 // Create mouseenter and mouseleave events
2181 jQuery.each({
2182 mouseenter: "mouseover",
2183 mouseleave: "mouseout"
2184 }, function( orig, fix ) {
2185 jQuery.event.special[ orig ] = {
2186 setup: function( data ) {
2187 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
2188 },
2189 teardown: function( data ) {
2190 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
2191 }
2192 };
2193 });
2194
2195 // submit delegation
2196 if ( !jQuery.support.submitBubbles ) {
2197
2198 jQuery.event.special.submit = {
2199 setup: function( data, namespaces ) {
2200 if ( this.nodeName.toLowerCase() !== "form" ) {
2201 jQuery.event.add(this, "click.specialSubmit", function( e ) {
2202 var elem = e.target, type = elem.type;
2203
2204 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
2205 return trigger( "submit", this, arguments );
2206 }
2207 });
2208
2209 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
2210 var elem = e.target, type = elem.type;
2211
2212 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
2213 return trigger( "submit", this, arguments );
2214 }
2215 });
2216
2217 } else {
2218 return false;
2219 }
2220 },
2221
2222 teardown: function( namespaces ) {
2223 jQuery.event.remove( this, ".specialSubmit" );
2224 }
2225 };
2226
2227 }
2228
2229 // change delegation, happens here so we have bind.
2230 if ( !jQuery.support.changeBubbles ) {
2231
2232 var formElems = /textarea|input|select/i,
2233
2234 changeFilters,
2235
2236 getVal = function( elem ) {
2237 var type = elem.type, val = elem.value;
2238
2239 if ( type === "radio" || type === "checkbox" ) {
2240 val = elem.checked;
2241
2242 } else if ( type === "select-multiple" ) {
2243 val = elem.selectedIndex > -1 ?
2244 jQuery.map( elem.options, function( elem ) {
2245 return elem.selected;
2246 }).join("-") :
2247 "";
2248
2249 } else if ( elem.nodeName.toLowerCase() === "select" ) {
2250 val = elem.selectedIndex;
2251 }
2252
2253 return val;
2254 },
2255
2256 testChange = function testChange( e ) {
2257 var elem = e.target, data, val;
2258
2259 if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
2260 return;
2261 }
2262
2263 data = jQuery.data( elem, "_change_data" );
2264 val = getVal(elem);
2265
2266 // the current data will be also retrieved by beforeactivate
2267 if ( e.type !== "focusout" || elem.type !== "radio" ) {
2268 jQuery.data( elem, "_change_data", val );
2269 }
2270
2271 if ( data === undefined || val === data ) {
2272 return;
2273 }
2274
2275 if ( data != null || val ) {
2276 e.type = "change";
2277 return jQuery.event.trigger( e, arguments[1], elem );
2278 }
2279 };
2280
2281 jQuery.event.special.change = {
2282 filters: {
2283 focusout: testChange,
2284
2285 click: function( e ) {
2286 var elem = e.target, type = elem.type;
2287
2288 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
2289 return testChange.call( this, e );
2290 }
2291 },
2292
2293 // Change has to be called before submit
2294 // Keydown will be called before keypress, which is used in submit-event delegation
2295 keydown: function( e ) {
2296 var elem = e.target, type = elem.type;
2297
2298 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
2299 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
2300 type === "select-multiple" ) {
2301 return testChange.call( this, e );
2302 }
2303 },
2304
2305 // Beforeactivate happens also before the previous element is blurred
2306 // with this event you can't trigger a change event, but you can store
2307 // information/focus[in] is not needed anymore
2308 beforeactivate: function( e ) {
2309 var elem = e.target;
2310 jQuery.data( elem, "_change_data", getVal(elem) );
2311 }
2312 },
2313
2314 setup: function( data, namespaces ) {
2315 if ( this.type === "file" ) {
2316 return false;
2317 }
2318
2319 for ( var type in changeFilters ) {
2320 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
2321 }
2322
2323 return formElems.test( this.nodeName );
2324 },
2325
2326 teardown: function( namespaces ) {
2327 jQuery.event.remove( this, ".specialChange" );
2328
2329 return formElems.test( this.nodeName );
2330 }
2331 };
2332
2333 changeFilters = jQuery.event.special.change.filters;
2334 }
2335
2336 function trigger( type, elem, args ) {
2337 args[0].type = type;
2338 return jQuery.event.handle.apply( elem, args );
2339 }
2340
2341 // Create "bubbling" focus and blur events
2342 if ( document.addEventListener ) {
2343 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
2344 jQuery.event.special[ fix ] = {
2345 setup: function() {
2346 this.addEventListener( orig, handler, true );
2347 },
2348 teardown: function() {
2349 this.removeEventListener( orig, handler, true );
2350 }
2351 };
2352
2353 function handler( e ) {
2354 e = jQuery.event.fix( e );
2355 e.type = fix;
2356 return jQuery.event.handle.call( this, e );
2357 }
2358 });
2359 }
2360
2361 jQuery.each(["bind", "one"], function( i, name ) {
2362 jQuery.fn[ name ] = function( type, data, fn ) {
2363 // Handle object literals
2364 if ( typeof type === "object" ) {
2365 for ( var key in type ) {
2366 this[ name ](key, data, type[key], fn);
2367 }
2368 return this;
2369 }
2370
2371 if ( jQuery.isFunction( data ) ) {
2372 fn = data;
2373 data = undefined;
2374 }
2375
2376 var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
2377 jQuery( this ).unbind( event, handler );
2378 return fn.apply( this, arguments );
2379 }) : fn;
2380
2381 if ( type === "unload" && name !== "one" ) {
2382 this.one( type, data, fn );
2383
2384 } else {
2385 for ( var i = 0, l = this.length; i < l; i++ ) {
2386 jQuery.event.add( this[i], type, handler, data );
2387 }
2388 }
2389
2390 return this;
2391 };
2392 });
2393
2394 jQuery.fn.extend({
2395 unbind: function( type, fn ) {
2396 // Handle object literals
2397 if ( typeof type === "object" && !type.preventDefault ) {
2398 for ( var key in type ) {
2399 this.unbind(key, type[key]);
2400 }
2401
2402 } else {
2403 for ( var i = 0, l = this.length; i < l; i++ ) {
2404 jQuery.event.remove( this[i], type, fn );
2405 }
2406 }
2407
2408 return this;
2409 },
2410
2411 delegate: function( selector, types, data, fn ) {
2412 return this.live( types, data, fn, selector );
2413 },
2414
2415 undelegate: function( selector, types, fn ) {
2416 if ( arguments.length === 0 ) {
2417 return this.unbind( "live" );
2418
2419 } else {
2420 return this.die( types, null, fn, selector );
2421 }
2422 },
2423
2424 trigger: function( type, data ) {
2425 return this.each(function() {
2426 jQuery.event.trigger( type, data, this );
2427 });
2428 },
2429
2430 triggerHandler: function( type, data ) {
2431 if ( this[0] ) {
2432 var event = jQuery.Event( type );
2433 event.preventDefault();
2434 event.stopPropagation();
2435 jQuery.event.trigger( event, data, this[0] );
2436 return event.result;
2437 }
2438 },
2439
2440 toggle: function( fn ) {
2441 // Save reference to arguments for access in closure
2442 var args = arguments, i = 1;
2443
2444 // link all the functions, so any of them can unbind this click handler
2445 while ( i < args.length ) {
2446 jQuery.proxy( fn, args[ i++ ] );
2447 }
2448
2449 return this.click( jQuery.proxy( fn, function( event ) {
2450 // Figure out which function to execute
2451 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
2452 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
2453
2454 // Make sure that clicks stop
2455 event.preventDefault();
2456
2457 // and execute the function
2458 return args[ lastToggle ].apply( this, arguments ) || false;
2459 }));
2460 },
2461
2462 hover: function( fnOver, fnOut ) {
2463 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
2464 }
2465 });
2466
2467 var liveMap = {
2468 focus: "focusin",
2469 blur: "focusout",
2470 mouseenter: "mouseover",
2471 mouseleave: "mouseout"
2472 };
2473
2474 jQuery.each(["live", "die"], function( i, name ) {
2475 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
2476 var type, i = 0, match, namespaces, preType,
2477 selector = origSelector || this.selector,
2478 context = origSelector ? this : jQuery( this.context );
2479
2480 if ( jQuery.isFunction( data ) ) {
2481 fn = data;
2482 data = undefined;
2483 }
2484
2485 types = (types || "").split(" ");
2486
2487 while ( (type = types[ i++ ]) != null ) {
2488 match = rnamespaces.exec( type );
2489 namespaces = "";
2490
2491 if ( match ) {
2492 namespaces = match[0];
2493 type = type.replace( rnamespaces, "" );
2494 }
2495
2496 if ( type === "hover" ) {
2497 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
2498 continue;
2499 }
2500
2501 preType = type;
2502
2503 if ( type === "focus" || type === "blur" ) {
2504 types.push( liveMap[ type ] + namespaces );
2505 type = type + namespaces;
2506
2507 } else {
2508 type = (liveMap[ type ] || type) + namespaces;
2509 }
2510
2511 if ( name === "live" ) {
2512 // bind live handler
2513 context.each(function(){
2514 jQuery.event.add( this, liveConvert( type, selector ),
2515 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
2516 });
2517
2518 } else {
2519 // unbind live handler
2520 context.unbind( liveConvert( type, selector ), fn );
2521 }
2522 }
2523
2524 return this;
2525 }
2526 });
2527
2528 function liveHandler( event ) {
2529 var stop, elems = [], selectors = [], args = arguments,
2530 related, match, handleObj, elem, j, i, l, data,
2531 events = jQuery.data( this, "events" );
2532
2533 // Make sure we avoid non-left-click bubbling in Firefox (#3861)
2534 if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
2535 return;
2536 }
2537
2538 event.liveFired = this;
2539
2540 var live = events.live.slice(0);
2541
2542 for ( j = 0; j < live.length; j++ ) {
2543 handleObj = live[j];
2544
2545 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
2546 selectors.push( handleObj.selector );
2547
2548 } else {
2549 live.splice( j--, 1 );
2550 }
2551 }
2552
2553 match = jQuery( event.target ).closest( selectors, event.currentTarget );
2554
2555 for ( i = 0, l = match.length; i < l; i++ ) {
2556 for ( j = 0; j < live.length; j++ ) {
2557 handleObj = live[j];
2558
2559 if ( match[i].selector === handleObj.selector ) {
2560 elem = match[i].elem;
2561 related = null;
2562
2563 // Those two events require additional checking
2564 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
2565 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
2566 }
2567
2568 if ( !related || related !== elem ) {
2569 elems.push({ elem: elem, handleObj: handleObj });
2570 }
2571 }
2572 }
2573 }
2574
2575 for ( i = 0, l = elems.length; i < l; i++ ) {
2576 match = elems[i];
2577 event.currentTarget = match.elem;
2578 event.data = match.handleObj.data;
2579 event.handleObj = match.handleObj;
2580
2581 if ( match.handleObj.origHandler.apply( match.elem, args ) === false ) {
2582 stop = false;
2583 break;
2584 }
2585 }
2586
2587 return stop;
2588 }
2589
2590 function liveConvert( type, selector ) {
2591 return "live." + (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
2592 }
2593
2594 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
2595 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
2596 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
2597
2598 // Handle event binding
2599 jQuery.fn[ name ] = function( fn ) {
2600 return fn ? this.bind( name, fn ) : this.trigger( name );
2601 };
2602
2603 if ( jQuery.attrFn ) {
2604 jQuery.attrFn[ name ] = true;
2605 }
2606 });
2607
2608 // Prevent memory leaks in IE
2609 // Window isn't included so as not to unbind existing unload events
2610 // More info:
2611 // - http://isaacschlueter.com/2006/10/msie-memory-leaks/
2612 if ( window.attachEvent && !window.addEventListener ) {
2613 window.attachEvent("onunload", function() {
2614 for ( var id in jQuery.cache ) {
2615 if ( jQuery.cache[ id ].handle ) {
2616 // Try/Catch is to handle iframes being unloaded, see #4280
2617 try {
2618 jQuery.event.remove( jQuery.cache[ id ].handle.elem );
2619 } catch(e) {}
2620 }
2621 }
2622 });
2623 }
2624 /*!
2625 * Sizzle CSS Selector Engine - v1.0
2626 * Copyright 2009, The Dojo Foundation
2627 * Released under the MIT, BSD, and GPL Licenses.
2628 * More information: http://sizzlejs.com/
2629 */
2630 (function(){
2631
2632 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
2633 done = 0,
2634 toString = Object.prototype.toString,
2635 hasDuplicate = false,
2636 baseHasDuplicate = true;
2637
2638 // Here we check if the JavaScript engine is using some sort of
2639 // optimization where it does not always call our comparision
2640 // function. If that is the case, discard the hasDuplicate value.
2641 // Thus far that includes Google Chrome.
2642 [0, 0].sort(function(){
2643 baseHasDuplicate = false;
2644 return 0;
2645 });
2646
2647 var Sizzle = function(selector, context, results, seed) {
2648 results = results || [];
2649 var origContext = context = context || document;
2650
2651 if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
2652 return [];
2653 }
2654
2655 if ( !selector || typeof selector !== "string" ) {
2656 return results;
2657 }
2658
2659 var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context),
2660 soFar = selector;
2661
2662 // Reset the position of the chunker regexp (start from head)
2663 while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
2664 soFar = m[3];
2665
2666 parts.push( m[1] );
2667
2668 if ( m[2] ) {
2669 extra = m[3];
2670 break;
2671 }
2672 }
2673
2674 if ( parts.length > 1 && origPOS.exec( selector ) ) {
2675 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
2676 set = posProcess( parts[0] + parts[1], context );
2677 } else {
2678 set = Expr.relative[ parts[0] ] ?
2679 [ context ] :
2680 Sizzle( parts.shift(), context );
2681
2682 while ( parts.length ) {
2683 selector = parts.shift();
2684
2685 if ( Expr.relative[ selector ] ) {
2686 selector += parts.shift();
2687 }
2688
2689 set = posProcess( selector, set );
2690 }
2691 }
2692 } else {
2693 // Take a shortcut and set the context if the root selector is an ID
2694 // (but not if it'll be faster if the inner selector is an ID)
2695 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
2696 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
2697 var ret = Sizzle.find( parts.shift(), context, contextXML );
2698 context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
2699 }
2700
2701 if ( context ) {
2702 var ret = seed ?
2703 { expr: parts.pop(), set: makeArray(seed) } :
2704 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
2705 set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
2706
2707 if ( parts.length > 0 ) {
2708 checkSet = makeArray(set);
2709 } else {
2710 prune = false;
2711 }
2712
2713 while ( parts.length ) {
2714 var cur = parts.pop(), pop = cur;
2715
2716 if ( !Expr.relative[ cur ] ) {
2717 cur = "";
2718 } else {
2719 pop = parts.pop();
2720 }
2721
2722 if ( pop == null ) {
2723 pop = context;
2724 }
2725
2726 Expr.relative[ cur ]( checkSet, pop, contextXML );
2727 }
2728 } else {
2729 checkSet = parts = [];
2730 }
2731 }
2732
2733 if ( !checkSet ) {
2734 checkSet = set;
2735 }
2736
2737 if ( !checkSet ) {
2738 Sizzle.error( cur || selector );
2739 }
2740
2741 if ( toString.call(checkSet) === "[object Array]" ) {
2742 if ( !prune ) {
2743 results.push.apply( results, checkSet );
2744 } else if ( context && context.nodeType === 1 ) {
2745 for ( var i = 0; checkSet[i] != null; i++ ) {
2746 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
2747 results.push( set[i] );
2748 }
2749 }
2750 } else {
2751 for ( var i = 0; checkSet[i] != null; i++ ) {
2752 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
2753 results.push( set[i] );
2754 }
2755 }
2756 }
2757 } else {
2758 makeArray( checkSet, results );
2759 }
2760
2761 if ( extra ) {
2762 Sizzle( extra, origContext, results, seed );
2763 Sizzle.uniqueSort( results );
2764 }
2765
2766 return results;
2767 };
2768
2769 Sizzle.uniqueSort = function(results){
2770 if ( sortOrder ) {
2771 hasDuplicate = baseHasDuplicate;
2772 results.sort(sortOrder);
2773
2774 if ( hasDuplicate ) {
2775 for ( var i = 1; i < results.length; i++ ) {
2776 if ( results[i] === results[i-1] ) {
2777 results.splice(i--, 1);
2778 }
2779 }
2780 }
2781 }
2782
2783 return results;
2784 };
2785
2786 Sizzle.matches = function(expr, set){
2787 return Sizzle(expr, null, null, set);
2788 };
2789
2790 Sizzle.find = function(expr, context, isXML){
2791 var set, match;
2792
2793 if ( !expr ) {
2794 return [];
2795 }
2796
2797 for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
2798 var type = Expr.order[i], match;
2799
2800 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
2801 var left = match[1];
2802 match.splice(1,1);
2803
2804 if ( left.substr( left.length - 1 ) !== "\\" ) {
2805 match[1] = (match[1] || "").replace(/\\/g, "");
2806 set = Expr.find[ type ]( match, context, isXML );
2807 if ( set != null ) {
2808 expr = expr.replace( Expr.match[ type ], "" );
2809 break;
2810 }
2811 }
2812 }
2813 }
2814
2815 if ( !set ) {
2816 set = context.getElementsByTagName("*");
2817 }
2818
2819 return {set: set, expr: expr};
2820 };
2821
2822 Sizzle.filter = function(expr, set, inplace, not){
2823 var old = expr, result = [], curLoop = set, match, anyFound,
2824 isXMLFilter = set && set[0] && isXML(set[0]);
2825
2826 while ( expr && set.length ) {
2827 for ( var type in Expr.filter ) {
2828 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
2829 var filter = Expr.filter[ type ], found, item, left = match[1];
2830 anyFound = false;
2831
2832 match.splice(1,1);
2833
2834 if ( left.substr( left.length - 1 ) === "\\" ) {
2835 continue;
2836 }
2837
2838 if ( curLoop === result ) {
2839 result = [];
2840 }
2841
2842 if ( Expr.preFilter[ type ] ) {
2843 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
2844
2845 if ( !match ) {
2846 anyFound = found = true;
2847 } else if ( match === true ) {
2848 continue;
2849 }
2850 }
2851
2852 if ( match ) {
2853 for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
2854 if ( item ) {
2855 found = filter( item, match, i, curLoop );
2856 var pass = not ^ !!found;
2857
2858 if ( inplace && found != null ) {
2859 if ( pass ) {
2860 anyFound = true;
2861 } else {
2862 curLoop[i] = false;
2863 }
2864 } else if ( pass ) {
2865 result.push( item );
2866 anyFound = true;
2867 }
2868 }
2869 }
2870 }
2871
2872 if ( found !== undefined ) {
2873 if ( !inplace ) {
2874 curLoop = result;
2875 }
2876
2877 expr = expr.replace( Expr.match[ type ], "" );
2878
2879 if ( !anyFound ) {
2880 return [];
2881 }
2882
2883 break;
2884 }
2885 }
2886 }
2887
2888 // Improper expression
2889 if ( expr === old ) {
2890 if ( anyFound == null ) {
2891 Sizzle.error( expr );
2892 } else {
2893 break;
2894 }
2895 }
2896
2897 old = expr;
2898 }
2899
2900 return curLoop;
2901 };
2902
2903 Sizzle.error = function( msg ) {
2904 throw "Syntax error, unrecognized expression: " + msg;
2905 };
2906
2907 var Expr = Sizzle.selectors = {
2908 order: [ "ID", "NAME", "TAG" ],
2909 match: {
2910 ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
2911 CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
2912 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
2913 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
2914 TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
2915 CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
2916 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
2917 PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
2918 },
2919 leftMatch: {},
2920 attrMap: {
2921 "class": "className",
2922 "for": "htmlFor"
2923 },
2924 attrHandle: {
2925 href: function(elem){
2926 return elem.getAttribute("href");
2927 }
2928 },
2929 relative: {
2930 "+": function(checkSet, part){
2931 var isPartStr = typeof part === "string",
2932 isTag = isPartStr && !/\W/.test(part),
2933 isPartStrNotTag = isPartStr && !isTag;
2934
2935 if ( isTag ) {
2936 part = part.toLowerCase();
2937 }
2938
2939 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
2940 if ( (elem = checkSet[i]) ) {
2941 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
2942
2943 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
2944 elem || false :
2945 elem === part;
2946 }
2947 }
2948
2949 if ( isPartStrNotTag ) {
2950 Sizzle.filter( part, checkSet, true );
2951 }
2952 },
2953 ">": function(checkSet, part){
2954 var isPartStr = typeof part === "string";
2955
2956 if ( isPartStr && !/\W/.test(part) ) {
2957 part = part.toLowerCase();
2958
2959 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2960 var elem = checkSet[i];
2961 if ( elem ) {
2962 var parent = elem.parentNode;
2963 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
2964 }
2965 }
2966 } else {
2967 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2968 var elem = checkSet[i];
2969 if ( elem ) {
2970 checkSet[i] = isPartStr ?
2971 elem.parentNode :
2972 elem.parentNode === part;
2973 }
2974 }
2975
2976 if ( isPartStr ) {
2977 Sizzle.filter( part, checkSet, true );
2978 }
2979 }
2980 },
2981 "": function(checkSet, part, isXML){
2982 var doneName = done++, checkFn = dirCheck;
2983
2984 if ( typeof part === "string" && !/\W/.test(part) ) {
2985 var nodeCheck = part = part.toLowerCase();
2986 checkFn = dirNodeCheck;
2987 }
2988
2989 checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
2990 },
2991 "~": function(checkSet, part, isXML){
2992 var doneName = done++, checkFn = dirCheck;
2993
2994 if ( typeof part === "string" && !/\W/.test(part) ) {
2995 var nodeCheck = part = part.toLowerCase();
2996 checkFn = dirNodeCheck;
2997 }
2998
2999 checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
3000 }
3001 },
3002 find: {
3003 ID: function(match, context, isXML){
3004 if ( typeof context.getElementById !== "undefined" && !isXML ) {
3005 var m = context.getElementById(match[1]);
3006 return m ? [m] : [];
3007 }
3008 },
3009 NAME: function(match, context){
3010 if ( typeof context.getElementsByName !== "undefined" ) {
3011 var ret = [], results = context.getElementsByName(match[1]);
3012
3013 for ( var i = 0, l = results.length; i < l; i++ ) {
3014 if ( results[i].getAttribute("name") === match[1] ) {
3015 ret.push( results[i] );
3016 }
3017 }
3018
3019 return ret.length === 0 ? null : ret;
3020 }
3021 },
3022 TAG: function(match, context){
3023 return context.getElementsByTagName(match[1]);
3024 }
3025 },
3026 preFilter: {
3027 CLASS: function(match, curLoop, inplace, result, not, isXML){
3028 match = " " + match[1].replace(/\\/g, "") + " ";
3029
3030 if ( isXML ) {
3031 return match;
3032 }
3033
3034 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
3035 if ( elem ) {
3036 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
3037 if ( !inplace ) {
3038 result.push( elem );
3039 }
3040 } else if ( inplace ) {
3041 curLoop[i] = false;
3042 }
3043 }
3044 }
3045
3046 return false;
3047 },
3048 ID: function(match){
3049 return match[1].replace(/\\/g, "");
3050 },
3051 TAG: function(match, curLoop){
3052 return match[1].toLowerCase();
3053 },
3054 CHILD: function(match){
3055 if ( match[1] === "nth" ) {
3056 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
3057 var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
3058 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
3059 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
3060
3061 // calculate the numbers (first)n+(last) including if they are negative
3062 match[2] = (test[1] + (test[2] || 1)) - 0;
3063 match[3] = test[3] - 0;
3064 }
3065
3066 // TODO: Move to normal caching system
3067 match[0] = done++;
3068
3069 return match;
3070 },
3071 ATTR: function(match, curLoop, inplace, result, not, isXML){
3072 var name = match[1].replace(/\\/g, "");
3073
3074 if ( !isXML && Expr.attrMap[name] ) {
3075 match[1] = Expr.attrMap[name];
3076 }
3077
3078 if ( match[2] === "~=" ) {
3079 match[4] = " " + match[4] + " ";
3080 }
3081
3082 return match;
3083 },
3084 PSEUDO: function(match, curLoop, inplace, result, not){
3085 if ( match[1] === "not" ) {
3086 // If we're dealing with a complex expression, or a simple one
3087 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
3088 match[3] = Sizzle(match[3], null, null, curLoop);
3089 } else {
3090 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
3091 if ( !inplace ) {
3092 result.push.apply( result, ret );
3093 }
3094 return false;
3095 }
3096 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
3097 return true;
3098 }
3099
3100 return match;
3101 },
3102 POS: function(match){
3103 match.unshift( true );
3104 return match;
3105 }
3106 },
3107 filters: {
3108 enabled: function(elem){
3109 return elem.disabled === false && elem.type !== "hidden";
3110 },
3111 disabled: function(elem){
3112 return elem.disabled === true;
3113 },
3114 checked: function(elem){
3115 return elem.checked === true;
3116 },
3117 selected: function(elem){
3118 // Accessing this property makes selected-by-default
3119 // options in Safari work properly
3120 elem.parentNode.selectedIndex;
3121 return elem.selected === true;
3122 },
3123 parent: function(elem){
3124 return !!elem.firstChild;
3125 },
3126 empty: function(elem){
3127 return !elem.firstChild;
3128 },
3129 has: function(elem, i, match){
3130 return !!Sizzle( match[3], elem ).length;
3131 },
3132 header: function(elem){
3133 return /h\d/i.test( elem.nodeName );
3134 },
3135 text: function(elem){
3136 return "text" === elem.type;
3137 },
3138 radio: function(elem){
3139 return "radio" === elem.type;
3140 },
3141 checkbox: function(elem){
3142 return "checkbox" === elem.type;
3143 },
3144 file: function(elem){
3145 return "file" === elem.type;
3146 },
3147 password: function(elem){
3148 return "password" === elem.type;
3149 },
3150 submit: function(elem){
3151 return "submit" === elem.type;
3152 },
3153 image: function(elem){
3154 return "image" === elem.type;
3155 },
3156 reset: function(elem){
3157 return "reset" === elem.type;
3158 },
3159 button: function(elem){
3160 return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
3161 },
3162 input: function(elem){
3163 return /input|select|textarea|button/i.test(elem.nodeName);
3164 }
3165 },
3166 setFilters: {
3167 first: function(elem, i){
3168 return i === 0;
3169 },
3170 last: function(elem, i, match, array){
3171 return i === array.length - 1;
3172 },
3173 even: function(elem, i){
3174 return i % 2 === 0;
3175 },
3176 odd: function(elem, i){
3177 return i % 2 === 1;
3178 },
3179 lt: function(elem, i, match){
3180 return i < match[3] - 0;
3181 },
3182 gt: function(elem, i, match){
3183 return i > match[3] - 0;
3184 },
3185 nth: function(elem, i, match){
3186 return match[3] - 0 === i;
3187 },
3188 eq: function(elem, i, match){
3189 return match[3] - 0 === i;
3190 }
3191 },
3192 filter: {
3193 PSEUDO: function(elem, match, i, array){
3194 var name = match[1], filter = Expr.filters[ name ];
3195
3196 if ( filter ) {
3197 return filter( elem, i, match, array );
3198 } else if ( name === "contains" ) {
3199 return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
3200 } else if ( name === "not" ) {
3201 var not = match[3];
3202
3203 for ( var i = 0, l = not.length; i < l; i++ ) {
3204 if ( not[i] === elem ) {
3205 return false;
3206 }
3207 }
3208
3209 return true;
3210 } else {
3211 Sizzle.error( "Syntax error, unrecognized expression: " + name );
3212 }
3213 },
3214 CHILD: function(elem, match){
3215 var type = match[1], node = elem;
3216 switch (type) {
3217 case 'only':
3218 case 'first':
3219 while ( (node = node.previousSibling) ) {
3220 if ( node.nodeType === 1 ) {
3221 return false;
3222 }
3223 }
3224 if ( type === "first" ) {
3225 return true;
3226 }
3227 node = elem;
3228 case 'last':
3229 while ( (node = node.nextSibling) ) {
3230 if ( node.nodeType === 1 ) {
3231 return false;
3232 }
3233 }
3234 return true;
3235 case 'nth':
3236 var first = match[2], last = match[3];
3237
3238 if ( first === 1 && last === 0 ) {
3239 return true;
3240 }
3241
3242 var doneName = match[0],
3243 parent = elem.parentNode;
3244
3245 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
3246 var count = 0;
3247 for ( node = parent.firstChild; node; node = node.nextSibling ) {
3248 if ( node.nodeType === 1 ) {
3249 node.nodeIndex = ++count;
3250 }
3251 }
3252 parent.sizcache = doneName;
3253 }
3254
3255 var diff = elem.nodeIndex - last;
3256 if ( first === 0 ) {
3257 return diff === 0;
3258 } else {
3259 return ( diff % first === 0 && diff / first >= 0 );
3260 }
3261 }
3262 },
3263 ID: function(elem, match){
3264 return elem.nodeType === 1 && elem.getAttribute("id") === match;
3265 },
3266 TAG: function(elem, match){
3267 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
3268 },
3269 CLASS: function(elem, match){
3270 return (" " + (elem.className || elem.getAttribute("class")) + " ")
3271 .indexOf( match ) > -1;
3272 },
3273 ATTR: function(elem, match){
3274 var name = match[1],
3275 result = Expr.attrHandle[ name ] ?
3276 Expr.attrHandle[ name ]( elem ) :
3277 elem[ name ] != null ?
3278 elem[ name ] :
3279 elem.getAttribute( name ),
3280 value = result + "",
3281 type = match[2],
3282 check = match[4];
3283
3284 return result == null ?
3285 type === "!=" :
3286 type === "=" ?
3287 value === check :
3288 type === "*=" ?
3289 value.indexOf(check) >= 0 :
3290 type === "~=" ?
3291 (" " + value + " ").indexOf(check) >= 0 :
3292 !check ?
3293 value && result !== false :
3294 type === "!=" ?
3295 value !== check :
3296 type === "^=" ?
3297 value.indexOf(check) === 0 :
3298 type === "$=" ?
3299 value.substr(value.length - check.length) === check :
3300 type === "|=" ?
3301 value === check || value.substr(0, check.length + 1) === check + "-" :
3302 false;
3303 },
3304 POS: function(elem, match, i, array){
3305 var name = match[2], filter = Expr.setFilters[ name ];
3306
3307 if ( filter ) {
3308 return filter( elem, i, match, array );
3309 }
3310 }
3311 }
3312 };
3313
3314 var origPOS = Expr.match.POS;
3315
3316 for ( var type in Expr.match ) {
3317 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
3318 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){
3319 return "\\" + (num - 0 + 1);
3320 }));
3321 }
3322
3323 var makeArray = function(array, results) {
3324 array = Array.prototype.slice.call( array, 0 );
3325
3326 if ( results ) {
3327 results.push.apply( results, array );
3328 return results;
3329 }
3330
3331 return array;
3332 };
3333
3334 // Perform a simple check to determine if the browser is capable of
3335 // converting a NodeList to an array using builtin methods.
3336 // Also verifies that the returned array holds DOM nodes
3337 // (which is not the case in the Blackberry browser)
3338 try {
3339 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
3340
3341 // Provide a fallback method if it does not work
3342 } catch(e){
3343 makeArray = function(array, results) {
3344 var ret = results || [];
3345
3346 if ( toString.call(array) === "[object Array]" ) {
3347 Array.prototype.push.apply( ret, array );
3348 } else {
3349 if ( typeof array.length === "number" ) {
3350 for ( var i = 0, l = array.length; i < l; i++ ) {
3351 ret.push( array[i] );
3352 }
3353 } else {
3354 for ( var i = 0; array[i]; i++ ) {
3355 ret.push( array[i] );
3356 }
3357 }
3358 }
3359
3360 return ret;
3361 };
3362 }
3363
3364 var sortOrder;
3365
3366 if ( document.documentElement.compareDocumentPosition ) {
3367 sortOrder = function( a, b ) {
3368 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
3369 if ( a == b ) {
3370 hasDuplicate = true;
3371 }
3372 return a.compareDocumentPosition ? -1 : 1;
3373 }
3374
3375 var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
3376 if ( ret === 0 ) {
3377 hasDuplicate = true;
3378 }
3379 return ret;
3380 };
3381 } else if ( "sourceIndex" in document.documentElement ) {
3382 sortOrder = function( a, b ) {
3383 if ( !a.sourceIndex || !b.sourceIndex ) {
3384 if ( a == b ) {
3385 hasDuplicate = true;
3386 }
3387 return a.sourceIndex ? -1 : 1;
3388 }
3389
3390 var ret = a.sourceIndex - b.sourceIndex;
3391 if ( ret === 0 ) {
3392 hasDuplicate = true;
3393 }
3394 return ret;
3395 };
3396 } else if ( document.createRange ) {
3397 sortOrder = function( a, b ) {
3398 if ( !a.ownerDocument || !b.ownerDocument ) {
3399 if ( a == b ) {
3400 hasDuplicate = true;
3401 }
3402 return a.ownerDocument ? -1 : 1;
3403 }
3404
3405 var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
3406 aRange.setStart(a, 0);
3407 aRange.setEnd(a, 0);
3408 bRange.setStart(b, 0);
3409 bRange.setEnd(b, 0);
3410 var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
3411 if ( ret === 0 ) {
3412 hasDuplicate = true;
3413 }
3414 return ret;
3415 };
3416 }
3417
3418 // Utility function for retreiving the text value of an array of DOM nodes
3419 function getText( elems ) {
3420 var ret = "", elem;
3421
3422 for ( var i = 0; elems[i]; i++ ) {
3423 elem = elems[i];
3424
3425 // Get the text from text nodes and CDATA nodes
3426 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
3427 ret += elem.nodeValue;
3428
3429 // Traverse everything else, except comment nodes
3430 } else if ( elem.nodeType !== 8 ) {
3431 ret += getText( elem.childNodes );
3432 }
3433 }
3434
3435 return ret;
3436 }
3437
3438 // Check to see if the browser returns elements by name when
3439 // querying by getElementById (and provide a workaround)
3440 (function(){
3441 // We're going to inject a fake input element with a specified name
3442 var form = document.createElement("div"),
3443 id = "script" + (new Date).getTime();
3444 form.innerHTML = "<a name='" + id + "'/>";
3445
3446 // Inject it into the root element, check its status, and remove it quickly
3447 var root = document.documentElement;
3448 root.insertBefore( form, root.firstChild );
3449
3450 // The workaround has to do additional checks after a getElementById
3451 // Which slows things down for other browsers (hence the branching)
3452 if ( document.getElementById( id ) ) {
3453 Expr.find.ID = function(match, context, isXML){
3454 if ( typeof context.getElementById !== "undefined" && !isXML ) {
3455 var m = context.getElementById(match[1]);
3456 return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
3457 }
3458 };
3459
3460 Expr.filter.ID = function(elem, match){
3461 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
3462 return elem.nodeType === 1 && node && node