blob: fd8c15b024934325881375a93048a507d9a51705 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*!
2 * jQuery JavaScript Library v1.3.2
3 *
4 * Copyright (c) 2009 John Resig, http://jquery.com/
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
26 * Revision: 6246
27 */
28
29
30//jquery.js
31(function(){
32var
33 // Will speed up references to window, and allows munging its name.
34 window = this,
35 // Will speed up references to undefined, and allows munging its name.
36 undefined,
37 // Map over jQuery in case of overwrite
38 _jQuery = window.jQuery,
39 // Map over the $ in case of overwrite
40 _$ = window.$,
41
42 jQuery = window.jQuery = window.$ = function( selector, context ) {
43 // The jQuery object is actually just the init constructor 'enhanced'
44 return new jQuery.fn.init( selector, context );
45 },
46
47 // A simple way to check for HTML strings or ID strings
48 // (both of which we optimize for)
49 quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
50 // Is it a simple selector
51 isSimple = /^.[^:#\[\.,]*$/;
52
53jQuery.fn = jQuery.prototype = {
54 init: function( selector, context ) {
55 // Make sure that a selection was provided
56 selector = selector || document;
57
58 // Handle $(DOMElement)
59 if ( selector.nodeType ) {
60 this[0] = selector;
61 this.length = 1;
62 this.context = selector;
63 return this;
64 }
65 // Handle HTML strings
66 if ( typeof selector === "string" ) {
67 // Are we dealing with HTML string or an ID?
68 var match = quickExpr.exec( selector );
69
70 // Verify a match, and that no context was specified for #id
71 if ( match && (match[1] || !context) ) {
72
73 // HANDLE: $(html) -> $(array)
74 if ( match[1] )
75 selector = jQuery.clean( [ match[1] ], context );
76
77 // HANDLE: $("#id")
78 else {
79 var elem = document.getElementById( match[3] );
80
81 // Handle the case where IE and Opera return items
82 // by name instead of ID
83 if ( elem && elem.id != match[3] )
84 return jQuery().find( selector );
85
86 // Otherwise, we inject the element directly into the jQuery object
87 var ret = jQuery( elem || [] );
88 ret.context = document;
89 ret.selector = selector;
90 return ret;
91 }
92
93 // HANDLE: $(expr, [context])
94 // (which is just equivalent to: $(content).find(expr)
95 } else
96 return jQuery( context ).find( selector );
97
98 // HANDLE: $(function)
99 // Shortcut for document ready
100 } else if ( jQuery.isFunction( selector ) )
101 return jQuery( document ).ready( selector );
102
103 // Make sure that old selector state is passed along
104 if ( selector.selector && selector.context ) {
105 this.selector = selector.selector;
106 this.context = selector.context;
107 }
108
109 return this.setArray(jQuery.isArray( selector ) ?
110 selector :
111 jQuery.makeArray(selector));
112 },
113
114 // Start with an empty selector
115 selector: "",
116
117 // The current version of jQuery being used
118 jquery: "1.3.2",
119
120 // The number of elements contained in the matched element set
121 size: function() {
122 return this.length;
123 },
124
125 // Get the Nth element in the matched element set OR
126 // Get the whole matched element set as a clean array
127 get: function( num ) {
128 return num === undefined ?
129
130 // Return a 'clean' array
131 Array.prototype.slice.call( this ) :
132
133 // Return just the object
134 this[ num ];
135 },
136
137 // Take an array of elements and push it onto the stack
138 // (returning the new matched element set)
139 pushStack: function( elems, name, selector ) {
140 // Build a new jQuery matched element set
141 var ret = jQuery( elems );
142
143 // Add the old object onto the stack (as a reference)
144 ret.prevObject = this;
145
146 ret.context = this.context;
147
148 if ( name === "find" )
149 ret.selector = this.selector + (this.selector ? " " : "") + selector;
150 else if ( name )
151 ret.selector = this.selector + "." + name + "(" + selector + ")";
152
153 // Return the newly-formed element set
154 return ret;
155 },
156
157 // Force the current matched set of elements to become
158 // the specified array of elements (destroying the stack in the process)
159 // You should use pushStack() in order to do this, but maintain the stack
160 setArray: function( elems ) {
161 // Resetting the length to 0, then using the native Array push
162 // is a super-fast way to populate an object with array-like properties
163 this.length = 0;
164 Array.prototype.push.apply( this, elems );
165
166 return this;
167 },
168
169 // Execute a callback for every element in the matched set.
170 // (You can seed the arguments with an array of args, but this is
171 // only used internally.)
172 each: function( callback, args ) {
173 return jQuery.each( this, callback, args );
174 },
175
176 // Determine the position of an element within
177 // the matched set of elements
178 index: function( elem ) {
179 // Locate the position of the desired element
180 return jQuery.inArray(
181 // If it receives a jQuery object, the first element is used
182 elem && elem.jquery ? elem[0] : elem
183 , this );
184 },
185
186 attr: function( name, value, type ) {
187 var options = name;
188
189 // Look for the case where we're accessing a style value
190 if ( typeof name === "string" )
191 if ( value === undefined )
192 return this[0] && jQuery[ type || "attr" ]( this[0], name );
193
194 else {
195 options = {};
196 options[ name ] = value;
197 }
198
199 // Check to see if we're setting style values
200 return this.each(function(i){
201 // Set all the styles
202 for ( name in options )
203 jQuery.attr(
204 type ?
205 this.style :
206 this,
207 name, jQuery.prop( this, options[ name ], type, i, name )
208 );
209 });
210 },
211
212 css: function( key, value ) {
213 // ignore negative width and height values
214 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
215 value = undefined;
216 return this.attr( key, value, "curCSS" );
217 },
218
219 text: function( text ) {
220 if ( typeof text !== "object" && text != null )
221 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
222
223 var ret = "";
224
225 jQuery.each( text || this, function(){
226 jQuery.each( this.childNodes, function(){
227 if ( this.nodeType != 8 )
228 ret += this.nodeType != 1 ?
229 this.nodeValue :
230 jQuery.fn.text( [ this ] );
231 });
232 });
233
234 return ret;
235 },
236
237 wrapAll: function( html ) {
238 if ( this[0] ) {
239 // The elements to wrap the target around
240 var wrap = jQuery( html, this[0].ownerDocument ).clone();
241
242 if ( this[0].parentNode )
243 wrap.insertBefore( this[0] );
244
245 wrap.map(function(){
246 var elem = this;
247
248 while ( elem.firstChild )
249 elem = elem.firstChild;
250
251 return elem;
252 }).append(this);
253 }
254
255 return this;
256 },
257
258 wrapInner: function( html ) {
259 return this.each(function(){
260 jQuery( this ).contents().wrapAll( html );
261 });
262 },
263
264 wrap: function( html ) {
265 return this.each(function(){
266 jQuery( this ).wrapAll( html );
267 });
268 },
269
270 append: function() {
271 return this.domManip(arguments, true, function(elem){
272 if (this.nodeType == 1)
273 this.appendChild( elem );
274 });
275 },
276
277 prepend: function() {
278 return this.domManip(arguments, true, function(elem){
279 if (this.nodeType == 1)
280 this.insertBefore( elem, this.firstChild );
281 });
282 },
283
284 before: function() {
285 return this.domManip(arguments, false, function(elem){
286 this.parentNode.insertBefore( elem, this );
287 });
288 },
289
290 after: function() {
291 return this.domManip(arguments, false, function(elem){
292 this.parentNode.insertBefore( elem, this.nextSibling );
293 });
294 },
295
296 end: function() {
297 return this.prevObject || jQuery( [] );
298 },
299
300 // For internal use only.
301 // Behaves like an Array's method, not like a jQuery method.
302 push: [].push,
303 sort: [].sort,
304 splice: [].splice,
305
306 find: function( selector ) {
307 if ( this.length === 1 ) {
308 var ret = this.pushStack( [], "find", selector );
309 ret.length = 0;
310 jQuery.find( selector, this[0], ret );
311 return ret;
312 } else {
313 return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
314 return jQuery.find( selector, elem );
315 })), "find", selector );
316 }
317 },
318
319 clone: function( events ) {
320 // Do the clone
321 var ret = this.map(function(){
322 if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
323 // IE copies events bound via attachEvent when
324 // using cloneNode. Calling detachEvent on the
325 // clone will also remove the events from the orignal
326 // In order to get around this, we use innerHTML.
327 // Unfortunately, this means some modifications to
328 // attributes in IE that are actually only stored
329 // as properties will not be copied (such as the
330 // the name attribute on an input).
331 var html = this.outerHTML;
332 if ( !html ) {
333 var div = this.ownerDocument.createElement("div");
334 div.appendChild( this.cloneNode(true) );
335 html = div.innerHTML;
336 }
337
338 return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
339 } else
340 return this.cloneNode(true);
341 });
342
343 // Copy the events from the original to the clone
344 if ( events === true ) {
345 var orig = this.find("*").andSelf(), i = 0;
346
347 ret.find("*").andSelf().each(function(){
348 if ( this.nodeName !== orig[i].nodeName )
349 return;
350
351 var events = jQuery.data( orig[i], "events" );
352
353 for ( var type in events ) {
354 for ( var handler in events[ type ] ) {
355 jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
356 }
357 }
358
359 i++;
360 });
361 }
362
363 // Return the cloned set
364 return ret;
365 },
366
367 filter: function( selector ) {
368 return this.pushStack(
369 jQuery.isFunction( selector ) &&
370 jQuery.grep(this, function(elem, i){
371 return selector.call( elem, i );
372 }) ||
373
374 jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
375 return elem.nodeType === 1;
376 }) ), "filter", selector );
377 },
378
379 closest: function( selector ) {
380 var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
381 closer = 0;
382
383 return this.map(function(){
384 var cur = this;
385 while ( cur && cur.ownerDocument ) {
386 if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
387 jQuery.data(cur, "closest", closer);
388 return cur;
389 }
390 cur = cur.parentNode;
391 closer++;
392 }
393 });
394 },
395
396 not: function( selector ) {
397 if ( typeof selector === "string" )
398 // test special case where just one selector is passed in
399 if ( isSimple.test( selector ) )
400 return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
401 else
402 selector = jQuery.multiFilter( selector, this );
403
404 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
405 return this.filter(function() {
406 return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
407 });
408 },
409
410 add: function( selector ) {
411 return this.pushStack( jQuery.unique( jQuery.merge(
412 this.get(),
413 typeof selector === "string" ?
414 jQuery( selector ) :
415 jQuery.makeArray( selector )
416 )));
417 },
418
419 is: function( selector ) {
420 return !!selector && jQuery.multiFilter( selector, this ).length > 0;
421 },
422
423 hasClass: function( selector ) {
424 return !!selector && this.is( "." + selector );
425 },
426
427 val: function( value ) {
428 if ( value === undefined ) {
429 var elem = this[0];
430
431 if ( elem ) {
432 if( jQuery.nodeName( elem, 'option' ) )
433 return (elem.attributes.value || {}).specified ? elem.value : elem.text;
434
435 // We need to handle select boxes special
436 if ( jQuery.nodeName( elem, "select" ) ) {
437 var index = elem.selectedIndex,
438 values = [],
439 options = elem.options,
440 one = elem.type == "select-one";
441
442 // Nothing was selected
443 if ( index < 0 )
444 return null;
445
446 // Loop through all the selected options
447 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
448 var option = options[ i ];
449
450 if ( option.selected ) {
451 // Get the specifc value for the option
452 value = jQuery(option).val();
453
454 // We don't need an array for one selects
455 if ( one )
456 return value;
457
458 // Multi-Selects return an array
459 values.push( value );
460 }
461 }
462
463 return values;
464 }
465
466 // Everything else, we just grab the value
467 return (elem.value || "").replace(/\r/g, "");
468
469 }
470
471 return undefined;
472 }
473
474 if ( typeof value === "number" )
475 value += '';
476
477 return this.each(function(){
478 if ( this.nodeType != 1 )
479 return;
480
481 if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
482 this.checked = (jQuery.inArray(this.value, value) >= 0 ||
483 jQuery.inArray(this.name, value) >= 0);
484
485 else if ( jQuery.nodeName( this, "select" ) ) {
486 var values = jQuery.makeArray(value);
487
488 jQuery( "option", this ).each(function(){
489 this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
490 jQuery.inArray( this.text, values ) >= 0);
491 });
492
493 if ( !values.length )
494 this.selectedIndex = -1;
495
496 } else
497 this.value = value;
498 });
499 },
500
501 html: function( value ) {
502 return value === undefined ?
503 (this[0] ?
504 this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
505 null) :
506 this.empty().append( value );
507 },
508
509 replaceWith: function( value ) {
510 return this.after( value ).remove();
511 },
512
513 eq: function( i ) {
514 return this.slice( i, +i + 1 );
515 },
516
517 slice: function() {
518 return this.pushStack( Array.prototype.slice.apply( this, arguments ),
519 "slice", Array.prototype.slice.call(arguments).join(",") );
520 },
521
522 map: function( callback ) {
523 return this.pushStack( jQuery.map(this, function(elem, i){
524 return callback.call( elem, i, elem );
525 }));
526 },
527
528 andSelf: function() {
529 return this.add( this.prevObject );
530 },
531
532 domManip: function( args, table, callback ) {
533 if ( this[0] ) {
534 var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
535 scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
536 first = fragment.firstChild;
537
538 if ( first )
539 for ( var i = 0, l = this.length; i < l; i++ )
540 callback.call( root(this[i], first), this.length > 1 || i > 0 ?
541 fragment.cloneNode(true) : fragment );
542
543 if ( scripts )
544 jQuery.each( scripts, evalScript );
545 }
546
547 return this;
548
549 function root( elem, cur ) {
550 return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
551 (elem.getElementsByTagName("tbody")[0] ||
552 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
553 elem;
554 }
555 }
556};
557
558// Give the init function the jQuery prototype for later instantiation
559jQuery.fn.init.prototype = jQuery.fn;
560
561function evalScript( i, elem ) {
562 if ( elem.src )
563 jQuery.ajax({
564 url: elem.src,
565 async: false,
566 dataType: "script"
567 });
568
569 else
570 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
571
572 if ( elem.parentNode )
573 elem.parentNode.removeChild( elem );
574}
575
576function now(){
577 return +new Date;
578}
579
580jQuery.extend = jQuery.fn.extend = function() {
581 // copy reference to target object
582 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
583
584 // Handle a deep copy situation
585 if ( typeof target === "boolean" ) {
586 deep = target;
587 target = arguments[1] || {};
588 // skip the boolean and the target
589 i = 2;
590 }
591
592 // Handle case when target is a string or something (possible in deep copy)
593 if ( typeof target !== "object" && !jQuery.isFunction(target) )
594 target = {};
595
596 // extend jQuery itself if only one argument is passed
597 if ( length == i ) {
598 target = this;
599 --i;
600 }
601
602 for ( ; i < length; i++ )
603 // Only deal with non-null/undefined values
604 if ( (options = arguments[ i ]) != null )
605 // Extend the base object
606 for ( var name in options ) {
607 var src = target[ name ], copy = options[ name ];
608
609 // Prevent never-ending loop
610 if ( target === copy )
611 continue;
612
613 // Recurse if we're merging object values
614 if ( deep && copy && typeof copy === "object" && !copy.nodeType )
615 target[ name ] = jQuery.extend( deep,
616 // Never move original objects, clone them
617 src || ( copy.length != null ? [ ] : { } )
618 , copy );
619
620 // Don't bring in undefined values
621 else if ( copy !== undefined )
622 target[ name ] = copy;
623
624 }
625
626 // Return the modified object
627 return target;
628};
629
630// exclude the following css properties to add px
631var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
632 // cache defaultView
633 defaultView = document.defaultView || {},
634 toString = Object.prototype.toString;
635
636jQuery.extend({
637 noConflict: function( deep ) {
638 window.$ = _$;
639
640 if ( deep )
641 window.jQuery = _jQuery;
642
643 return jQuery;
644 },
645
646 // See test/unit/core.js for details concerning isFunction.
647 // Since version 1.3, DOM methods and functions like alert
648 // aren't supported. They return false on IE (#2968).
649 isFunction: function( obj ) {
650 return toString.call(obj) === "[object Function]";
651 },
652
653 isArray: function( obj ) {
654 return toString.call(obj) === "[object Array]";
655 },
656
657 // check if an element is in a (or is an) XML document
658 isXMLDoc: function( elem ) {
659 return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
660 !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
661 },
662
663 // Evalulates a script in a global context
664 globalEval: function( data ) {
665 if ( data && /\S/.test(data) ) {
666 // Inspired by code by Andrea Giammarchi
667 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
668 var head = document.getElementsByTagName("head")[0] || document.documentElement,
669 script = document.createElement("script");
670
671 script.type = "text/javascript";
672 if ( jQuery.support.scriptEval )
673 script.appendChild( document.createTextNode( data ) );
674 else
675 script.text = data;
676
677 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
678 // This arises when a base node is used (#2709).
679 head.insertBefore( script, head.firstChild );
680 head.removeChild( script );
681 }
682 },
683
684 nodeName: function( elem, name ) {
685 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
686 },
687
688 // args is for internal usage only
689 each: function( object, callback, args ) {
690 var name, i = 0, length = object.length;
691
692 if ( args ) {
693 if ( length === undefined ) {
694 for ( name in object )
695 if ( callback.apply( object[ name ], args ) === false )
696 break;
697 } else
698 for ( ; i < length; )
699 if ( callback.apply( object[ i++ ], args ) === false )
700 break;
701
702 // A special, fast, case for the most common use of each
703 } else {
704 if ( length === undefined ) {
705 for ( name in object )
706 if ( callback.call( object[ name ], name, object[ name ] ) === false )
707 break;
708 } else
709 for ( var value = object[0];
710 i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
711 }
712
713 return object;
714 },
715
716 prop: function( elem, value, type, i, name ) {
717 // Handle executable functions
718 if ( jQuery.isFunction( value ) )
719 value = value.call( elem, i );
720
721 // Handle passing in a number to a CSS property
722 return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
723 value + "px" :
724 value;
725 },
726
727 className: {
728 // internal only, use addClass("class")
729 add: function( elem, classNames ) {
730 jQuery.each((classNames || "").split(/\s+/), function(i, className){
731 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
732 elem.className += (elem.className ? " " : "") + className;
733 });
734 },
735
736 // internal only, use removeClass("class")
737 remove: function( elem, classNames ) {
738 if (elem.nodeType == 1)
739 elem.className = classNames !== undefined ?
740 jQuery.grep(elem.className.split(/\s+/), function(className){
741 return !jQuery.className.has( classNames, className );
742 }).join(" ") :
743 "";
744 },
745
746 // internal only, use hasClass("class")
747 has: function( elem, className ) {
748 return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
749 }
750 },
751
752 // A method for quickly swapping in/out CSS properties to get correct calculations
753 swap: function( elem, options, callback ) {
754 var old = {};
755 // Remember the old values, and insert the new ones
756 for ( var name in options ) {
757 old[ name ] = elem.style[ name ];
758 elem.style[ name ] = options[ name ];
759 }
760
761 callback.call( elem );
762
763 // Revert the old values
764 for ( var name in options )
765 elem.style[ name ] = old[ name ];
766 },
767
768 css: function( elem, name, force, extra ) {
769 if ( name == "width" || name == "height" ) {
770 var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
771
772 function getWH() {
773 val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
774
775 if ( extra === "border" )
776 return;
777
778 jQuery.each( which, function() {
779 if ( !extra )
780 val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
781 if ( extra === "margin" )
782 val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
783 else
784 val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
785 });
786 }
787
788 if ( elem.offsetWidth !== 0 )
789 getWH();
790 else
791 jQuery.swap( elem, props, getWH );
792
793 return Math.max(0, Math.round(val));
794 }
795
796 return jQuery.curCSS( elem, name, force );
797 },
798
799 curCSS: function( elem, name, force ) {
800 var ret, style = elem.style;
801
802 // We need to handle opacity special in IE
803 if ( name == "opacity" && !jQuery.support.opacity ) {
804 ret = jQuery.attr( style, "opacity" );
805
806 return ret == "" ?
807 "1" :
808 ret;
809 }
810
811 // Make sure we're using the right name for getting the float value
812 if ( name.match( /float/i ) )
813 name = styleFloat;
814
815 if ( !force && style && style[ name ] )
816 ret = style[ name ];
817
818 else if ( defaultView.getComputedStyle ) {
819
820 // Only "float" is needed here
821 if ( name.match( /float/i ) )
822 name = "float";
823
824 name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
825
826 var computedStyle = defaultView.getComputedStyle( elem, null );
827
828 if ( computedStyle )
829 ret = computedStyle.getPropertyValue( name );
830
831 // We should always get a number back from opacity
832 if ( name == "opacity" && ret == "" )
833 ret = "1";
834
835 } else if ( elem.currentStyle ) {
836 var camelCase = name.replace(/\-(\w)/g, function(all, letter){
837 return letter.toUpperCase();
838 });
839
840 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
841
842 // From the awesome hack by Dean Edwards
843 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
844
845 // If we're not dealing with a regular pixel number
846 // but a number that has a weird ending, we need to convert it to pixels
847 if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
848 // Remember the original values
849 var left = style.left, rsLeft = elem.runtimeStyle.left;
850
851 // Put in the new values to get a computed value out
852 elem.runtimeStyle.left = elem.currentStyle.left;
853 style.left = ret || 0;
854 ret = style.pixelLeft + "px";
855
856 // Revert the changed values
857 style.left = left;
858 elem.runtimeStyle.left = rsLeft;
859 }
860 }
861
862 return ret;
863 },
864
865 clean: function( elems, context, fragment ) {
866 context = context || document;
867
868 // !context.createElement fails in IE with an error but returns typeof 'object'
869 if ( typeof context.createElement === "undefined" )
870 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
871
872 // If a single string is passed in and it's a single tag
873 // just do a createElement and skip the rest
874 if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
875 var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
876 if ( match )
877 return [ context.createElement( match[1] ) ];
878 }
879
880 var ret = [], scripts = [], div = context.createElement("div");
881
882 jQuery.each(elems, function(i, elem){
883 if ( typeof elem === "number" )
884 elem += '';
885
886 if ( !elem )
887 return;
888
889 // Convert html string into DOM nodes
890 if ( typeof elem === "string" ) {
891 // Fix "XHTML"-style tags in all browsers
892 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
893 return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
894 all :
895 front + "></" + tag + ">";
896 });
897
898 // Trim whitespace, otherwise indexOf won't work as expected
899 var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
900
901 var wrap =
902 // option or optgroup
903 !tags.indexOf("<opt") &&
904 [ 1, "<select multiple='multiple'>", "</select>" ] ||
905
906 !tags.indexOf("<leg") &&
907 [ 1, "<fieldset>", "</fieldset>" ] ||
908
909 tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
910 [ 1, "<table>", "</table>" ] ||
911
912 !tags.indexOf("<tr") &&
913 [ 2, "<table><tbody>", "</tbody></table>" ] ||
914
915 // <thead> matched above
916 (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
917 [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
918
919 !tags.indexOf("<col") &&
920 [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
921
922 // IE can't serialize <link> and <script> tags normally
923 !jQuery.support.htmlSerialize &&
924 [ 1, "div<div>", "</div>" ] ||
925
926 [ 0, "", "" ];
927
928 // Go to html and back, then peel off extra wrappers
929 div.innerHTML = wrap[1] + elem + wrap[2];
930
931 // Move to the right depth
932 while ( wrap[0]-- )
933 div = div.lastChild;
934
935 // Remove IE's autoinserted <tbody> from table fragments
936 if ( !jQuery.support.tbody ) {
937
938 // String was a <table>, *may* have spurious <tbody>
939 var hasBody = /<tbody/i.test(elem),
940 tbody = !tags.indexOf("<table") && !hasBody ?
941 div.firstChild && div.firstChild.childNodes :
942
943 // String was a bare <thead> or <tfoot>
944 wrap[1] == "<table>" && !hasBody ?
945 div.childNodes :
946 [];
947
948 for ( var j = tbody.length - 1; j >= 0 ; --j )
949 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
950 tbody[ j ].parentNode.removeChild( tbody[ j ] );
951
952 }
953
954 // IE completely kills leading whitespace when innerHTML is used
955 if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
956 div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
957
958 elem = jQuery.makeArray( div.childNodes );
959 }
960
961 if ( elem.nodeType )
962 ret.push( elem );
963 else
964 ret = jQuery.merge( ret, elem );
965
966 });
967
968 if ( fragment ) {
969 for ( var i = 0; ret[i]; i++ ) {
970 if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
971 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
972 } else {
973 if ( ret[i].nodeType === 1 )
974 ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
975 fragment.appendChild( ret[i] );
976 }
977 }
978
979 return scripts;
980 }
981
982 return ret;
983 },
984
985 attr: function( elem, name, value ) {
986 // don't set attributes on text and comment nodes
987 if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
988 return undefined;
989
990 var notxml = !jQuery.isXMLDoc( elem ),
991 // Whether we are setting (or getting)
992 set = value !== undefined;
993
994 // Try to normalize/fix the name
995 name = notxml && jQuery.props[ name ] || name;
996
997 // Only do all the following if this is a node (faster for style)
998 // IE elem.getAttribute passes even for style
999 if ( elem.tagName ) {
1000
1001 // These attributes require special treatment
1002 var special = /href|src|style/.test( name );
1003
1004 // Safari mis-reports the default selected property of a hidden option
1005 // Accessing the parent's selectedIndex property fixes it
1006 if ( name == "selected" && elem.parentNode )
1007 elem.parentNode.selectedIndex;
1008
1009 // If applicable, access the attribute via the DOM 0 way
1010 if ( name in elem && notxml && !special ) {
1011 if ( set ){
1012 // We can't allow the type property to be changed (since it causes problems in IE)
1013 if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
1014 throw "type property can't be changed";
1015
1016 elem[ name ] = value;
1017 }
1018
1019 // browsers index elements by id/name on forms, give priority to attributes.
1020 if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
1021 return elem.getAttributeNode( name ).nodeValue;
1022
1023 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1024 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1025 if ( name == "tabIndex" ) {
1026 var attributeNode = elem.getAttributeNode( "tabIndex" );
1027 return attributeNode && attributeNode.specified
1028 ? attributeNode.value
1029 : elem.nodeName.match(/(button|input|object|select|textarea)/i)
1030 ? 0
1031 : elem.nodeName.match(/^(a|area)$/i) && elem.href
1032 ? 0
1033 : undefined;
1034 }
1035
1036 return elem[ name ];
1037 }
1038
1039 if ( !jQuery.support.style && notxml && name == "style" )
1040 return jQuery.attr( elem.style, "cssText", value );
1041
1042 if ( set )
1043 // convert the value to a string (all browsers do this but IE) see #1070
1044 elem.setAttribute( name, "" + value );
1045
1046 var attr = !jQuery.support.hrefNormalized && notxml && special
1047 // Some attributes require a special call on IE
1048 ? elem.getAttribute( name, 2 )
1049 : elem.getAttribute( name );
1050
1051 // Non-existent attributes return null, we normalize to undefined
1052 return attr === null ? undefined : attr;
1053 }
1054
1055 // elem is actually elem.style ... set the style
1056
1057 // IE uses filters for opacity
1058 if ( !jQuery.support.opacity && name == "opacity" ) {
1059 if ( set ) {
1060 // IE has trouble with opacity if it does not have layout
1061 // Force it by setting the zoom level
1062 elem.zoom = 1;
1063
1064 // Set the alpha filter to set the opacity
1065 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
1066 (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
1067 }
1068
1069 return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
1070 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
1071 "";
1072 }
1073
1074 name = name.replace(/-([a-z])/ig, function(all, letter){
1075 return letter.toUpperCase();
1076 });
1077
1078 if ( set )
1079 elem[ name ] = value;
1080
1081 return elem[ name ];
1082 },
1083
1084 trim: function( text ) {
1085 return (text || "").replace( /^\s+|\s+$/g, "" );
1086 },
1087
1088 makeArray: function( array ) {
1089 var ret = [];
1090
1091 if( array != null ){
1092 var i = array.length;
1093 // The window, strings (and functions) also have 'length'
1094 if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
1095 ret[0] = array;
1096 else
1097 while( i )
1098 ret[--i] = array[i];
1099 }
1100
1101 return ret;
1102 },
1103
1104 inArray: function( elem, array ) {
1105 for ( var i = 0, length = array.length; i < length; i++ )
1106 // Use === because on IE, window == document
1107 if ( array[ i ] === elem )
1108 return i;
1109
1110 return -1;
1111 },
1112
1113 merge: function( first, second ) {
1114 // We have to loop this way because IE & Opera overwrite the length
1115 // expando of getElementsByTagName
1116 var i = 0, elem, pos = first.length;
1117 // Also, we need to make sure that the correct elements are being returned
1118 // (IE returns comment nodes in a '*' query)
1119 if ( !jQuery.support.getAll ) {
1120 while ( (elem = second[ i++ ]) != null )
1121 if ( elem.nodeType != 8 )
1122 first[ pos++ ] = elem;
1123
1124 } else
1125 while ( (elem = second[ i++ ]) != null )
1126 first[ pos++ ] = elem;
1127
1128 return first;
1129 },
1130
1131 unique: function( array ) {
1132 var ret = [], done = {};
1133
1134 try {
1135
1136 for ( var i = 0, length = array.length; i < length; i++ ) {
1137 var id = jQuery.data( array[ i ] );
1138
1139 if ( !done[ id ] ) {
1140 done[ id ] = true;
1141 ret.push( array[ i ] );
1142 }
1143 }
1144
1145 } catch( e ) {
1146 ret = array;
1147 }
1148
1149 return ret;
1150 },
1151
1152 grep: function( elems, callback, inv ) {
1153 var ret = [];
1154
1155 // Go through the array, only saving the items
1156 // that pass the validator function
1157 for ( var i = 0, length = elems.length; i < length; i++ )
1158 if ( !inv != !callback( elems[ i ], i ) )
1159 ret.push( elems[ i ] );
1160
1161 return ret;
1162 },
1163
1164 map: function( elems, callback ) {
1165 var ret = [];
1166
1167 // Go through the array, translating each of the items to their
1168 // new value (or values).
1169 for ( var i = 0, length = elems.length; i < length; i++ ) {
1170 var value = callback( elems[ i ], i );
1171
1172 if ( value != null )
1173 ret[ ret.length ] = value;
1174 }
1175
1176 return ret.concat.apply( [], ret );
1177 }
1178});
1179
1180// Use of jQuery.browser is deprecated.
1181// It's included for backwards compatibility and plugins,
1182// although they should work to migrate away.
1183
1184var userAgent = navigator.userAgent.toLowerCase();
1185
1186// Figure out what browser is being used
1187jQuery.browser = {
1188 version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
1189 safari: /webkit/.test( userAgent ),
1190 opera: /opera/.test( userAgent ),
1191 msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
1192 mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
1193};
1194
1195jQuery.each({
1196 parent: function(elem){return elem.parentNode;},
1197 parents: function(elem){return jQuery.dir(elem,"parentNode");},
1198 next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
1199 prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
1200 nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
1201 prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
1202 siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
1203 children: function(elem){return jQuery.sibling(elem.firstChild);},
1204 contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
1205}, function(name, fn){
1206 jQuery.fn[ name ] = function( selector ) {
1207 var ret = jQuery.map( this, fn );
1208
1209 if ( selector && typeof selector == "string" )
1210 ret = jQuery.multiFilter( selector, ret );
1211
1212 return this.pushStack( jQuery.unique( ret ), name, selector );
1213 };
1214});
1215
1216jQuery.each({
1217 appendTo: "append",
1218 prependTo: "prepend",
1219 insertBefore: "before",
1220 insertAfter: "after",
1221 replaceAll: "replaceWith"
1222}, function(name, original){
1223 jQuery.fn[ name ] = function( selector ) {
1224 var ret = [], insert = jQuery( selector );
1225
1226 for ( var i = 0, l = insert.length; i < l; i++ ) {
1227 var elems = (i > 0 ? this.clone(true) : this).get();
1228 jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
1229 ret = ret.concat( elems );
1230 }
1231
1232 return this.pushStack( ret, name, selector );
1233 };
1234});
1235
1236jQuery.each({
1237 removeAttr: function( name ) {
1238 jQuery.attr( this, name, "" );
1239 if (this.nodeType == 1)
1240 this.removeAttribute( name );
1241 },
1242
1243 addClass: function( classNames ) {
1244 jQuery.className.add( this, classNames );
1245 },
1246
1247 removeClass: function( classNames ) {
1248 jQuery.className.remove( this, classNames );
1249 },
1250
1251 toggleClass: function( classNames, state ) {
1252 if( typeof state !== "boolean" )
1253 state = !jQuery.className.has( this, classNames );
1254 jQuery.className[ state ? "add" : "remove" ]( this, classNames );
1255 },
1256
1257 remove: function( selector ) {
1258 if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
1259 // Prevent memory leaks
1260 jQuery( "*", this ).add([this]).each(function(){
1261 jQuery.event.remove(this);
1262 jQuery.removeData(this);
1263 });
1264 if (this.parentNode)
1265 this.parentNode.removeChild( this );
1266 }
1267 },
1268
1269 empty: function() {
1270 // Remove element nodes and prevent memory leaks
1271 jQuery(this).children().remove();
1272
1273 // Remove any remaining nodes
1274 while ( this.firstChild )
1275 this.removeChild( this.firstChild );
1276 }
1277}, function(name, fn){
1278 jQuery.fn[ name ] = function(){
1279 return this.each( fn, arguments );
1280 };
1281});
1282
1283// Helper function used by the dimensions and offset modules
1284function num(elem, prop) {
1285 return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
1286}
1287var expando = "jQuery" + now(), uuid = 0, windowData = {};
1288
1289jQuery.extend({
1290 cache: {},
1291
1292 data: function( elem, name, data ) {
1293 elem = elem == window ?
1294 windowData :
1295 elem;
1296
1297 var id = elem[ expando ];
1298
1299 // Compute a unique ID for the element
1300 if ( !id )
1301 id = elem[ expando ] = ++uuid;
1302
1303 // Only generate the data cache if we're
1304 // trying to access or manipulate it
1305 if ( name && !jQuery.cache[ id ] )
1306 jQuery.cache[ id ] = {};
1307
1308 // Prevent overriding the named cache with undefined values
1309 if ( data !== undefined )
1310 jQuery.cache[ id ][ name ] = data;
1311
1312 // Return the named cache data, or the ID for the element
1313 return name ?
1314 jQuery.cache[ id ][ name ] :
1315 id;
1316 },
1317
1318 removeData: function( elem, name ) {
1319 elem = elem == window ?
1320 windowData :
1321 elem;
1322
1323 var id = elem[ expando ];
1324
1325 // If we want to remove a specific section of the element's data
1326 if ( name ) {
1327 if ( jQuery.cache[ id ] ) {
1328 // Remove the section of cache data
1329 delete jQuery.cache[ id ][ name ];
1330
1331 // If we've removed all the data, remove the element's cache
1332 name = "";
1333
1334 for ( name in jQuery.cache[ id ] )
1335 break;
1336
1337 if ( !name )
1338 jQuery.removeData( elem );
1339 }
1340
1341 // Otherwise, we want to remove all of the element's data
1342 } else {
1343 // Clean up the element expando
1344 try {
1345 delete elem[ expando ];
1346 } catch(e){
1347 // IE has trouble directly removing the expando
1348 // but it's ok with using removeAttribute
1349 if ( elem.removeAttribute )
1350 elem.removeAttribute( expando );
1351 }
1352
1353 // Completely remove the data cache
1354 delete jQuery.cache[ id ];
1355 }
1356 },
1357 queue: function( elem, type, data ) {
1358 if ( elem ){
1359
1360 type = (type || "fx") + "queue";
1361
1362 var q = jQuery.data( elem, type );
1363
1364 if ( !q || jQuery.isArray(data) )
1365 q = jQuery.data( elem, type, jQuery.makeArray(data) );
1366 else if( data )
1367 q.push( data );
1368
1369 }
1370 return q;
1371 },
1372
1373 dequeue: function( elem, type ){
1374 var queue = jQuery.queue( elem, type ),
1375 fn = queue.shift();
1376
1377 if( !type || type === "fx" )
1378 fn = queue[0];
1379
1380 if( fn !== undefined )
1381 fn.call(elem);
1382 }
1383});
1384
1385jQuery.fn.extend({
1386 data: function( key, value ){
1387 var parts = key.split(".");
1388 parts[1] = parts[1] ? "." + parts[1] : "";
1389
1390 if ( value === undefined ) {
1391 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1392
1393 if ( data === undefined && this.length )
1394 data = jQuery.data( this[0], key );
1395
1396 return data === undefined && parts[1] ?
1397 this.data( parts[0] ) :
1398 data;
1399 } else
1400 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
1401 jQuery.data( this, key, value );
1402 });
1403 },
1404
1405 removeData: function( key ){
1406 return this.each(function(){
1407 jQuery.removeData( this, key );
1408 });
1409 },
1410 queue: function(type, data){
1411 if ( typeof type !== "string" ) {
1412 data = type;
1413 type = "fx";
1414 }
1415
1416 if ( data === undefined )
1417 return jQuery.queue( this[0], type );
1418
1419 return this.each(function(){
1420 var queue = jQuery.queue( this, type, data );
1421
1422 if( type == "fx" && queue.length == 1 )
1423 queue[0].call(this);
1424 });
1425 },
1426 dequeue: function(type){
1427 return this.each(function(){
1428 jQuery.dequeue( this, type );
1429 });
1430 }
1431});/*!
1432 * Sizzle CSS Selector Engine - v0.9.3
1433 * Copyright 2009, The Dojo Foundation
1434 * Released under the MIT, BSD, and GPL Licenses.
1435 * More information: http://sizzlejs.com/
1436 */
1437(function(){
1438
1439var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
1440 done = 0,
1441 toString = Object.prototype.toString;
1442
1443var Sizzle = function(selector, context, results, seed) {
1444 results = results || [];
1445 context = context || document;
1446
1447 if ( context.nodeType !== 1 && context.nodeType !== 9 )
1448 return [];
1449
1450 if ( !selector || typeof selector !== "string" ) {
1451 return results;
1452 }
1453
1454 var parts = [], m, set, checkSet, check, mode, extra, prune = true;
1455
1456 // Reset the position of the chunker regexp (start from head)
1457 chunker.lastIndex = 0;
1458
1459 while ( (m = chunker.exec(selector)) !== null ) {
1460 parts.push( m[1] );
1461
1462 if ( m[2] ) {
1463 extra = RegExp.rightContext;
1464 break;
1465 }
1466 }
1467
1468 if ( parts.length > 1 && origPOS.exec( selector ) ) {
1469 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
1470 set = posProcess( parts[0] + parts[1], context );
1471 } else {
1472 set = Expr.relative[ parts[0] ] ?
1473 [ context ] :
1474 Sizzle( parts.shift(), context );
1475
1476 while ( parts.length ) {
1477 selector = parts.shift();
1478
1479 if ( Expr.relative[ selector ] )
1480 selector += parts.shift();
1481
1482 set = posProcess( selector, set );
1483 }
1484 }
1485 } else {
1486 var ret = seed ?
1487 { expr: parts.pop(), set: makeArray(seed) } :
1488 Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context, isXML(context) );
1489 set = Sizzle.filter( ret.expr, ret.set );
1490
1491 if ( parts.length > 0 ) {
1492 checkSet = makeArray(set);
1493 } else {
1494 prune = false;
1495 }
1496
1497 while ( parts.length ) {
1498 var cur = parts.pop(), pop = cur;
1499
1500 if ( !Expr.relative[ cur ] ) {
1501 cur = "";
1502 } else {
1503 pop = parts.pop();
1504 }
1505
1506 if ( pop == null ) {
1507 pop = context;
1508 }
1509
1510 Expr.relative[ cur ]( checkSet, pop, isXML(context) );
1511 }
1512 }
1513
1514 if ( !checkSet ) {
1515 checkSet = set;
1516 }
1517
1518 if ( !checkSet ) {
1519 throw "Syntax error, unrecognized expression: " + (cur || selector);
1520 }
1521
1522 if ( toString.call(checkSet) === "[object Array]" ) {
1523 if ( !prune ) {
1524 results.push.apply( results, checkSet );
1525 } else if ( context.nodeType === 1 ) {
1526 for ( var i = 0; checkSet[i] != null; i++ ) {
1527 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
1528 results.push( set[i] );
1529 }
1530 }
1531 } else {
1532 for ( var i = 0; checkSet[i] != null; i++ ) {
1533 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
1534 results.push( set[i] );
1535 }
1536 }
1537 }
1538 } else {
1539 makeArray( checkSet, results );
1540 }
1541
1542 if ( extra ) {
1543 Sizzle( extra, context, results, seed );
1544
1545 if ( sortOrder ) {
1546 hasDuplicate = false;
1547 results.sort(sortOrder);
1548
1549 if ( hasDuplicate ) {
1550 for ( var i = 1; i < results.length; i++ ) {
1551 if ( results[i] === results[i-1] ) {
1552 results.splice(i--, 1);
1553 }
1554 }
1555 }
1556 }
1557 }
1558
1559 return results;
1560};
1561
1562Sizzle.matches = function(expr, set){
1563 return Sizzle(expr, null, null, set);
1564};
1565
1566Sizzle.find = function(expr, context, isXML){
1567 var set, match;
1568
1569 if ( !expr ) {
1570 return [];
1571 }
1572
1573 for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
1574 var type = Expr.order[i], match;
1575
1576 if ( (match = Expr.match[ type ].exec( expr )) ) {
1577 var left = RegExp.leftContext;
1578
1579 if ( left.substr( left.length - 1 ) !== "\\" ) {
1580 match[1] = (match[1] || "").replace(/\\/g, "");
1581 set = Expr.find[ type ]( match, context, isXML );
1582 if ( set != null ) {
1583 expr = expr.replace( Expr.match[ type ], "" );
1584 break;
1585 }
1586 }
1587 }
1588 }
1589
1590 if ( !set ) {
1591 set = context.getElementsByTagName("*");
1592 }
1593
1594 return {set: set, expr: expr};
1595};
1596
1597Sizzle.filter = function(expr, set, inplace, not){
1598 var old = expr, result = [], curLoop = set, match, anyFound,
1599 isXMLFilter = set && set[0] && isXML(set[0]);
1600
1601 while ( expr && set.length ) {
1602 for ( var type in Expr.filter ) {
1603 if ( (match = Expr.match[ type ].exec( expr )) != null ) {
1604 var filter = Expr.filter[ type ], found, item;
1605 anyFound = false;
1606
1607 if ( curLoop == result ) {
1608 result = [];
1609 }
1610
1611 if ( Expr.preFilter[ type ] ) {
1612 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
1613
1614 if ( !match ) {
1615 anyFound = found = true;
1616 } else if ( match === true ) {
1617 continue;
1618 }
1619 }
1620
1621 if ( match ) {
1622 for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
1623 if ( item ) {
1624 found = filter( item, match, i, curLoop );
1625 var pass = not ^ !!found;
1626
1627 if ( inplace && found != null ) {
1628 if ( pass ) {
1629 anyFound = true;
1630 } else {
1631 curLoop[i] = false;
1632 }
1633 } else if ( pass ) {
1634 result.push( item );
1635 anyFound = true;
1636 }
1637 }
1638 }
1639 }
1640
1641 if ( found !== undefined ) {
1642 if ( !inplace ) {
1643 curLoop = result;
1644 }
1645
1646 expr = expr.replace( Expr.match[ type ], "" );
1647
1648 if ( !anyFound ) {
1649 return [];
1650 }
1651
1652 break;
1653 }
1654 }
1655 }
1656
1657 // Improper expression
1658 if ( expr == old ) {
1659 if ( anyFound == null ) {
1660 throw "Syntax error, unrecognized expression: " + expr;
1661 } else {
1662 break;
1663 }
1664 }
1665
1666 old = expr;
1667 }
1668
1669 return curLoop;
1670};
1671
1672var Expr = Sizzle.selectors = {
1673 order: [ "ID", "NAME", "TAG" ],
1674 match: {
1675 ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1676 CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1677 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
1678 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
1679 TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
1680 CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
1681 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
1682 PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
1683 },
1684 attrMap: {
1685 "class": "className",
1686 "for": "htmlFor"
1687 },
1688 attrHandle: {
1689 href: function(elem){
1690 return elem.getAttribute("href");
1691 }
1692 },
1693 relative: {
1694 "+": function(checkSet, part, isXML){
1695 var isPartStr = typeof part === "string",
1696 isTag = isPartStr && !/\W/.test(part),
1697 isPartStrNotTag = isPartStr && !isTag;
1698
1699 if ( isTag && !isXML ) {
1700 part = part.toUpperCase();
1701 }
1702
1703 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
1704 if ( (elem = checkSet[i]) ) {
1705 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
1706
1707 checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
1708 elem || false :
1709 elem === part;
1710 }
1711 }
1712
1713 if ( isPartStrNotTag ) {
1714 Sizzle.filter( part, checkSet, true );
1715 }
1716 },
1717 ">": function(checkSet, part, isXML){
1718 var isPartStr = typeof part === "string";
1719
1720 if ( isPartStr && !/\W/.test(part) ) {
1721 part = isXML ? part : part.toUpperCase();
1722
1723 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1724 var elem = checkSet[i];
1725 if ( elem ) {
1726 var parent = elem.parentNode;
1727 checkSet[i] = parent.nodeName === part ? parent : false;
1728 }
1729 }
1730 } else {
1731 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1732 var elem = checkSet[i];
1733 if ( elem ) {
1734 checkSet[i] = isPartStr ?
1735 elem.parentNode :
1736 elem.parentNode === part;
1737 }
1738 }
1739
1740 if ( isPartStr ) {
1741 Sizzle.filter( part, checkSet, true );
1742 }
1743 }
1744 },
1745 "": function(checkSet, part, isXML){
1746 var doneName = done++, checkFn = dirCheck;
1747
1748 if ( !part.match(/\W/) ) {
1749 var nodeCheck = part = isXML ? part : part.toUpperCase();
1750 checkFn = dirNodeCheck;
1751 }
1752
1753 checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
1754 },
1755 "~": function(checkSet, part, isXML){
1756 var doneName = done++, checkFn = dirCheck;
1757
1758 if ( typeof part === "string" && !part.match(/\W/) ) {
1759 var nodeCheck = part = isXML ? part : part.toUpperCase();
1760 checkFn = dirNodeCheck;
1761 }
1762
1763 checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
1764 }
1765 },
1766 find: {
1767 ID: function(match, context, isXML){
1768 if ( typeof context.getElementById !== "undefined" && !isXML ) {
1769 var m = context.getElementById(match[1]);
1770 return m ? [m] : [];
1771 }
1772 },
1773 NAME: function(match, context, isXML){
1774 if ( typeof context.getElementsByName !== "undefined" ) {
1775 var ret = [], results = context.getElementsByName(match[1]);
1776
1777 for ( var i = 0, l = results.length; i < l; i++ ) {
1778 if ( results[i].getAttribute("name") === match[1] ) {
1779 ret.push( results[i] );
1780 }
1781 }
1782
1783 return ret.length === 0 ? null : ret;
1784 }
1785 },
1786 TAG: function(match, context){
1787 return context.getElementsByTagName(match[1]);
1788 }
1789 },
1790 preFilter: {
1791 CLASS: function(match, curLoop, inplace, result, not, isXML){
1792 match = " " + match[1].replace(/\\/g, "") + " ";
1793
1794 if ( isXML ) {
1795 return match;
1796 }
1797
1798 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
1799 if ( elem ) {
1800 if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
1801 if ( !inplace )
1802 result.push( elem );
1803 } else if ( inplace ) {
1804 curLoop[i] = false;
1805 }
1806 }
1807 }
1808
1809 return false;
1810 },
1811 ID: function(match){
1812 return match[1].replace(/\\/g, "");
1813 },
1814 TAG: function(match, curLoop){
1815 for ( var i = 0; curLoop[i] === false; i++ ){}
1816 return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
1817 },
1818 CHILD: function(match){
1819 if ( match[1] == "nth" ) {
1820 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
1821 var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
1822 match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
1823 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
1824
1825 // calculate the numbers (first)n+(last) including if they are negative
1826 match[2] = (test[1] + (test[2] || 1)) - 0;
1827 match[3] = test[3] - 0;
1828 }
1829
1830 // TODO: Move to normal caching system
1831 match[0] = done++;
1832
1833 return match;
1834 },
1835 ATTR: function(match, curLoop, inplace, result, not, isXML){
1836 var name = match[1].replace(/\\/g, "");
1837
1838 if ( !isXML && Expr.attrMap[name] ) {
1839 match[1] = Expr.attrMap[name];
1840 }
1841
1842 if ( match[2] === "~=" ) {
1843 match[4] = " " + match[4] + " ";
1844 }
1845
1846 return match;
1847 },
1848 PSEUDO: function(match, curLoop, inplace, result, not){
1849 if ( match[1] === "not" ) {
1850 // If we're dealing with a complex expression, or a simple one
1851 if ( match[3].match(chunker).length > 1 || /^\w/.test(match[3]) ) {
1852 match[3] = Sizzle(match[3], null, null, curLoop);
1853 } else {
1854 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
1855 if ( !inplace ) {
1856 result.push.apply( result, ret );
1857 }
1858 return false;
1859 }
1860 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
1861 return true;
1862 }
1863
1864 return match;
1865 },
1866 POS: function(match){
1867 match.unshift( true );
1868 return match;
1869 }
1870 },
1871 filters: {
1872 enabled: function(elem){
1873 return elem.disabled === false && elem.type !== "hidden";
1874 },
1875 disabled: function(elem){
1876 return elem.disabled === true;
1877 },
1878 checked: function(elem){
1879 return elem.checked === true;
1880 },
1881 selected: function(elem){
1882 // Accessing this property makes selected-by-default
1883 // options in Safari work properly
1884 elem.parentNode.selectedIndex;
1885 return elem.selected === true;
1886 },
1887 parent: function(elem){
1888 return !!elem.firstChild;
1889 },
1890 empty: function(elem){
1891 return !elem.firstChild;
1892 },
1893 has: function(elem, i, match){
1894 return !!Sizzle( match[3], elem ).length;
1895 },
1896 header: function(elem){
1897 return /h\d/i.test( elem.nodeName );
1898 },
1899 text: function(elem){
1900 return "text" === elem.type;
1901 },
1902 radio: function(elem){
1903 return "radio" === elem.type;
1904 },
1905 checkbox: function(elem){
1906 return "checkbox" === elem.type;
1907 },
1908 file: function(elem){
1909 return "file" === elem.type;
1910 },
1911 password: function(elem){
1912 return "password" === elem.type;
1913 },
1914 submit: function(elem){
1915 return "submit" === elem.type;
1916 },
1917 image: function(elem){
1918 return "image" === elem.type;
1919 },
1920 reset: function(elem){
1921 return "reset" === elem.type;
1922 },
1923 button: function(elem){
1924 return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
1925 },
1926 input: function(elem){
1927 return /input|select|textarea|button/i.test(elem.nodeName);
1928 }
1929 },
1930 setFilters: {
1931 first: function(elem, i){
1932 return i === 0;
1933 },
1934 last: function(elem, i, match, array){
1935 return i === array.length - 1;
1936 },
1937 even: function(elem, i){
1938 return i % 2 === 0;
1939 },
1940 odd: function(elem, i){
1941 return i % 2 === 1;
1942 },
1943 lt: function(elem, i, match){
1944 return i < match[3] - 0;
1945 },
1946 gt: function(elem, i, match){
1947 return i > match[3] - 0;
1948 },
1949 nth: function(elem, i, match){
1950 return match[3] - 0 == i;
1951 },
1952 eq: function(elem, i, match){
1953 return match[3] - 0 == i;
1954 }
1955 },
1956 filter: {
1957 PSEUDO: function(elem, match, i, array){
1958 var name = match[1], filter = Expr.filters[ name ];
1959
1960 if ( filter ) {
1961 return filter( elem, i, match, array );
1962 } else if ( name === "contains" ) {
1963 return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
1964 } else if ( name === "not" ) {
1965 var not = match[3];
1966
1967 for ( var i = 0, l = not.length; i < l; i++ ) {
1968 if ( not[i] === elem ) {
1969 return false;
1970 }
1971 }
1972
1973 return true;
1974 }
1975 },
1976 CHILD: function(elem, match){
1977 var type = match[1], node = elem;
1978 switch (type) {
1979 case 'only':
1980 case 'first':
1981 while (node = node.previousSibling) {
1982 if ( node.nodeType === 1 ) return false;
1983 }
1984 if ( type == 'first') return true;
1985 node = elem;
1986 case 'last':
1987 while (node = node.nextSibling) {
1988 if ( node.nodeType === 1 ) return false;
1989 }
1990 return true;
1991 case 'nth':
1992 var first = match[2], last = match[3];
1993
1994 if ( first == 1 && last == 0 ) {
1995 return true;
1996 }
1997
1998 var doneName = match[0],
1999 parent = elem.parentNode;
2000
2001 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
2002 var count = 0;
2003 for ( node = parent.firstChild; node; node = node.nextSibling ) {
2004 if ( node.nodeType === 1 ) {
2005 node.nodeIndex = ++count;
2006 }
2007 }
2008 parent.sizcache = doneName;
2009 }
2010
2011 var diff = elem.nodeIndex - last;
2012 if ( first == 0 ) {
2013 return diff == 0;
2014 } else {
2015 return ( diff % first == 0 && diff / first >= 0 );
2016 }
2017 }
2018 },
2019 ID: function(elem, match){
2020 return elem.nodeType === 1 && elem.getAttribute("id") === match;
2021 },
2022 TAG: function(elem, match){
2023 return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
2024 },
2025 CLASS: function(elem, match){
2026 return (" " + (elem.className || elem.getAttribute("class")) + " ")
2027 .indexOf( match ) > -1;
2028 },
2029 ATTR: function(elem, match){
2030 var name = match[1],
2031 result = Expr.attrHandle[ name ] ?
2032 Expr.attrHandle[ name ]( elem ) :
2033 elem[ name ] != null ?
2034 elem[ name ] :
2035 elem.getAttribute( name ),
2036 value = result + "",
2037 type = match[2],
2038 check = match[4];
2039
2040 return result == null ?
2041 type === "!=" :
2042 type === "=" ?
2043 value === check :
2044 type === "*=" ?
2045 value.indexOf(check) >= 0 :
2046 type === "~=" ?
2047 (" " + value + " ").indexOf(check) >= 0 :
2048 !check ?
2049 value && result !== false :
2050 type === "!=" ?
2051 value != check :
2052 type === "^=" ?
2053 value.indexOf(check) === 0 :
2054 type === "$=" ?
2055 value.substr(value.length - check.length) === check :
2056 type === "|=" ?
2057 value === check || value.substr(0, check.length + 1) === check + "-" :
2058 false;
2059 },
2060 POS: function(elem, match, i, array){
2061 var name = match[2], filter = Expr.setFilters[ name ];
2062
2063 if ( filter ) {
2064 return filter( elem, i, match, array );
2065 }
2066 }
2067 }
2068};
2069
2070var origPOS = Expr.match.POS;
2071
2072for ( var type in Expr.match ) {
2073 Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
2074}
2075
2076var makeArray = function(array, results) {
2077 array = Array.prototype.slice.call( array );
2078
2079 if ( results ) {
2080 results.push.apply( results, array );
2081 return results;
2082 }
2083
2084 return array;
2085};
2086
2087// Perform a simple check to determine if the browser is capable of
2088// converting a NodeList to an array using builtin methods.
2089try {
2090 Array.prototype.slice.call( document.documentElement.childNodes );
2091
2092// Provide a fallback method if it does not work
2093} catch(e){
2094 makeArray = function(array, results) {
2095 var ret = results || [];
2096
2097 if ( toString.call(array) === "[object Array]" ) {
2098 Array.prototype.push.apply( ret, array );
2099 } else {
2100 if ( typeof array.length === "number" ) {
2101 for ( var i = 0, l = array.length; i < l; i++ ) {
2102 ret.push( array[i] );
2103 }
2104 } else {
2105 for ( var i = 0; array[i]; i++ ) {
2106 ret.push( array[i] );
2107 }
2108 }
2109 }
2110
2111 return ret;
2112 };
2113}
2114
2115var sortOrder;
2116
2117if ( document.documentElement.compareDocumentPosition ) {
2118 sortOrder = function( a, b ) {
2119 var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
2120 if ( ret === 0 ) {
2121 hasDuplicate = true;
2122 }
2123 return ret;
2124 };
2125} else if ( "sourceIndex" in document.documentElement ) {
2126 sortOrder = function( a, b ) {
2127 var ret = a.sourceIndex - b.sourceIndex;
2128 if ( ret === 0 ) {
2129 hasDuplicate = true;
2130 }
2131 return ret;
2132 };
2133} else if ( document.createRange ) {
2134 sortOrder = function( a, b ) {
2135 var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
2136 aRange.selectNode(a);
2137 aRange.collapse(true);
2138 bRange.selectNode(b);
2139 bRange.collapse(true);
2140 var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
2141 if ( ret === 0 ) {
2142 hasDuplicate = true;
2143 }
2144 return ret;
2145 };
2146}
2147
2148// Check to see if the browser returns elements by name when
2149// querying by getElementById (and provide a workaround)
2150(function(){
2151 // We're going to inject a fake input element with a specified name
2152 var form = document.createElement("form"),
2153 id = "script" + (new Date).getTime();
2154 form.innerHTML = "<input name='" + id + "'/>";
2155
2156 // Inject it into the root element, check its status, and remove it quickly
2157 var root = document.documentElement;
2158 root.insertBefore( form, root.firstChild );
2159
2160 // The workaround has to do additional checks after a getElementById
2161 // Which slows things down for other browsers (hence the branching)
2162 if ( !!document.getElementById( id ) ) {
2163 Expr.find.ID = function(match, context, isXML){
2164 if ( typeof context.getElementById !== "undefined" && !isXML ) {
2165 var m = context.getElementById(match[1]);
2166 return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
2167 }
2168 };
2169
2170 Expr.filter.ID = function(elem, match){
2171 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
2172 return elem.nodeType === 1 && node && node.nodeValue === match;
2173 };
2174 }
2175
2176 root.removeChild( form );
2177})();
2178
2179(function(){
2180 // Check to see if the browser returns only elements
2181 // when doing getElementsByTagName("*")
2182
2183 // Create a fake element
2184 var div = document.createElement("div");
2185 div.appendChild( document.createComment("") );
2186
2187 // Make sure no comments are found
2188 if ( div.getElementsByTagName("*").length > 0 ) {
2189 Expr.find.TAG = function(match, context){
2190 var results = context.getElementsByTagName(match[1]);
2191
2192 // Filter out possible comments
2193 if ( match[1] === "*" ) {
2194 var tmp = [];
2195
2196 for ( var i = 0; results[i]; i++ ) {
2197 if ( results[i].nodeType === 1 ) {
2198 tmp.push( results[i] );
2199 }
2200 }
2201
2202 results = tmp;
2203 }
2204
2205 return results;
2206 };
2207 }
2208
2209 // Check to see if an attribute returns normalized href attributes
2210 div.innerHTML = "<a href='#'></a>";
2211 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
2212 div.firstChild.getAttribute("href") !== "#" ) {
2213 Expr.attrHandle.href = function(elem){
2214 return elem.getAttribute("href", 2);
2215 };
2216 }
2217})();
2218
2219if ( document.querySelectorAll ) (function(){
2220 var oldSizzle = Sizzle, div = document.createElement("div");
2221 div.innerHTML = "<p class='TEST'></p>";
2222
2223 // Safari can't handle uppercase or unicode characters when
2224 // in quirks mode.
2225 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
2226 return;
2227 }
2228
2229 Sizzle = function(query, context, extra, seed){
2230 context = context || document;
2231
2232 // Only use querySelectorAll on non-XML documents
2233 // (ID selectors don't work in non-HTML documents)
2234 if ( !seed && context.nodeType === 9 && !isXML(context) ) {
2235 try {
2236 return makeArray( context.querySelectorAll(query), extra );
2237 } catch(e){}
2238 }
2239
2240 return oldSizzle(query, context, extra, seed);
2241 };
2242
2243 Sizzle.find = oldSizzle.find;
2244 Sizzle.filter = oldSizzle.filter;
2245 Sizzle.selectors = oldSizzle.selectors;
2246 Sizzle.matches = oldSizzle.matches;
2247})();
2248
2249if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
2250 var div = document.createElement("div");
2251 div.innerHTML = "<div class='test e'></div><div class='test'></div>";
2252
2253 // Opera can't find a second classname (in 9.6)
2254 if ( div.getElementsByClassName("e").length === 0 )
2255 return;
2256
2257 // Safari caches class attributes, doesn't catch changes (in 3.2)
2258 div.lastChild.className = "e";
2259
2260 if ( div.getElementsByClassName("e").length === 1 )
2261 return;
2262
2263 Expr.order.splice(1, 0, "CLASS");
2264 Expr.find.CLASS = function(match, context, isXML) {
2265 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
2266 return context.getElementsByClassName(match[1]);
2267 }
2268 };
2269})();
2270
2271function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2272 var sibDir = dir == "previousSibling" && !isXML;
2273 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2274 var elem = checkSet[i];
2275 if ( elem ) {
2276 if ( sibDir && elem.nodeType === 1 ){
2277 elem.sizcache = doneName;
2278 elem.sizset = i;
2279 }
2280 elem = elem[dir];
2281 var match = false;
2282
2283 while ( elem ) {
2284 if ( elem.sizcache === doneName ) {
2285 match = checkSet[elem.sizset];
2286 break;
2287 }
2288
2289 if ( elem.nodeType === 1 && !isXML ){
2290 elem.sizcache = doneName;
2291 elem.sizset = i;
2292 }
2293
2294 if ( elem.nodeName === cur ) {
2295 match = elem;
2296 break;
2297 }
2298
2299 elem = elem[dir];
2300 }
2301
2302 checkSet[i] = match;
2303 }
2304 }
2305}
2306
2307function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2308 var sibDir = dir == "previousSibling" && !isXML;
2309 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2310 var elem = checkSet[i];
2311 if ( elem ) {
2312 if ( sibDir && elem.nodeType === 1 ) {
2313 elem.sizcache = doneName;
2314 elem.sizset = i;
2315 }
2316 elem = elem[dir];
2317 var match = false;
2318
2319 while ( elem ) {
2320 if ( elem.sizcache === doneName ) {
2321 match = checkSet[elem.sizset];
2322 break;
2323 }
2324
2325 if ( elem.nodeType === 1 ) {
2326 if ( !isXML ) {
2327 elem.sizcache = doneName;
2328 elem.sizset = i;
2329 }
2330 if ( typeof cur !== "string" ) {
2331 if ( elem === cur ) {
2332 match = true;
2333 break;
2334 }
2335
2336 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
2337 match = elem;
2338 break;
2339 }
2340 }
2341
2342 elem = elem[dir];
2343 }
2344
2345 checkSet[i] = match;
2346 }
2347 }
2348}
2349
2350var contains = document.compareDocumentPosition ? function(a, b){
2351 return a.compareDocumentPosition(b) & 16;
2352} : function(a, b){
2353 return a !== b && (a.contains ? a.contains(b) : true);
2354};
2355
2356var isXML = function(elem){
2357 return elem.nodeType === 9 && elem.documentElement && elem.documentElement.nodeName !== "HTML" ||
2358 !!elem.ownerDocument && isXML( elem.ownerDocument );
2359};
2360
2361var posProcess = function(selector, context){
2362 var tmpSet = [], later = "", match,
2363 root = context.nodeType ? [context] : context;
2364
2365 // Position selectors must be done after the filter
2366 // And so must :not(positional) so we move all PSEUDOs to the end
2367 while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
2368 later += match[0];
2369 selector = selector.replace( Expr.match.PSEUDO, "" );
2370 }
2371
2372 selector = Expr.relative[selector] ? selector + "*" : selector;
2373
2374 for ( var i = 0, l = root.length; i < l; i++ ) {
2375 Sizzle( selector, root[i], tmpSet );
2376 }
2377
2378 return Sizzle.filter( later, tmpSet );
2379};
2380
2381// EXPOSE
2382jQuery.find = Sizzle;
2383jQuery.filter = Sizzle.filter;
2384jQuery.expr = Sizzle.selectors;
2385jQuery.expr[":"] = jQuery.expr.filters;
2386
2387Sizzle.selectors.filters.hidden = function(elem){
2388 return elem.offsetWidth === 0 || elem.offsetHeight === 0;
2389};
2390
2391Sizzle.selectors.filters.visible = function(elem){
2392 return elem.offsetWidth > 0 || elem.offsetHeight > 0;
2393};
2394
2395Sizzle.selectors.filters.animated = function(elem){
2396 return jQuery.grep(jQuery.timers, function(fn){
2397 return elem === fn.elem;
2398 }).length;
2399};
2400
2401jQuery.multiFilter = function( expr, elems, not ) {
2402 if ( not ) {
2403 expr = ":not(" + expr + ")";
2404 }
2405
2406 return Sizzle.matches(expr, elems);
2407};
2408
2409jQuery.dir = function( elem, dir ){
2410 var matched = [], cur = elem[dir];
2411 while ( cur && cur != document ) {
2412 if ( cur.nodeType == 1 )
2413 matched.push( cur );
2414 cur = cur[dir];
2415 }
2416 return matched;
2417};
2418
2419jQuery.nth = function(cur, result, dir, elem){
2420 result = result || 1;
2421 var num = 0;
2422
2423 for ( ; cur; cur = cur[dir] )
2424 if ( cur.nodeType == 1 && ++num == result )
2425 break;
2426
2427 return cur;
2428};
2429
2430jQuery.sibling = function(n, elem){
2431 var r = [];
2432
2433 for ( ; n; n = n.nextSibling ) {
2434 if ( n.nodeType == 1 && n != elem )
2435 r.push( n );
2436 }
2437
2438 return r;
2439};
2440
2441return;
2442
2443window.Sizzle = Sizzle;
2444
2445})();
2446/*
2447 * A number of helper functions used for managing events.
2448 * Many of the ideas behind this code originated from
2449 * Dean Edwards' addEvent library.
2450 */
2451jQuery.event = {
2452
2453 // Bind an event to an element
2454 // Original by Dean Edwards
2455 add: function(elem, types, handler, data) {
2456 if ( elem.nodeType == 3 || elem.nodeType == 8 )
2457 return;
2458
2459 // For whatever reason, IE has trouble passing the window object
2460 // around, causing it to be cloned in the process
2461 if ( elem.setInterval && elem != window )
2462 elem = window;
2463
2464 // Make sure that the function being executed has a unique ID
2465 if ( !handler.guid )
2466 handler.guid = this.guid++;
2467
2468 // if data is passed, bind to handler
2469 if ( data !== undefined ) {
2470 // Create temporary function pointer to original handler
2471 var fn = handler;
2472
2473 // Create unique handler function, wrapped around original handler
2474 handler = this.proxy( fn );
2475
2476 // Store data in unique handler
2477 handler.data = data;
2478 }
2479
2480 // Init the element's event structure
2481 var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
2482 handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
2483 // Handle the second event of a trigger and when
2484 // an event is called after a page has unloaded
2485 return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
2486 jQuery.event.handle.apply(arguments.callee.elem, arguments) :
2487 undefined;
2488 });
2489 // Add elem as a property of the handle function
2490 // This is to prevent a memory leak with non-native
2491 // event in IE.
2492 handle.elem = elem;
2493
2494 // Handle multiple events separated by a space
2495 // jQuery(...).bind("mouseover mouseout", fn);
2496 jQuery.each(types.split(/\s+/), function(index, type) {
2497 // Namespaced event handlers
2498 var namespaces = type.split(".");
2499 type = namespaces.shift();
2500 handler.type = namespaces.slice().sort().join(".");
2501
2502 // Get the current list of functions bound to this event
2503 var handlers = events[type];
2504
2505 if ( jQuery.event.specialAll[type] )
2506 jQuery.event.specialAll[type].setup.call(elem, data, namespaces);
2507
2508 // Init the event handler queue
2509 if (!handlers) {
2510 handlers = events[type] = {};
2511
2512 // Check for a special event handler
2513 // Only use addEventListener/attachEvent if the special
2514 // events handler returns false
2515 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) {
2516 // Bind the global event handler to the element
2517 if (elem.addEventListener)
2518 elem.addEventListener(type, handle, false);
2519 else if (elem.attachEvent)
2520 elem.attachEvent("on" + type, handle);
2521 }
2522 }
2523
2524 // Add the function to the element's handler list
2525 handlers[handler.guid] = handler;
2526
2527 // Keep track of which events have been used, for global triggering
2528 jQuery.event.global[type] = true;
2529 });
2530
2531 // Nullify elem to prevent memory leaks in IE
2532 elem = null;
2533 },
2534
2535 guid: 1,
2536 global: {},
2537
2538 // Detach an event or set of events from an element
2539 remove: function(elem, types, handler) {
2540 // don't do events on text and comment nodes
2541 if ( elem.nodeType == 3 || elem.nodeType == 8 )
2542 return;
2543
2544 var events = jQuery.data(elem, "events"), ret, index;
2545
2546 if ( events ) {
2547 // Unbind all events for the element
2548 if ( types === undefined || (typeof types === "string" && types.charAt(0) == ".") )
2549 for ( var type in events )
2550 this.remove( elem, type + (types || "") );
2551 else {
2552 // types is actually an event object here
2553 if ( types.type ) {
2554 handler = types.handler;
2555 types = types.type;
2556 }
2557
2558 // Handle multiple events seperated by a space
2559 // jQuery(...).unbind("mouseover mouseout", fn);
2560 jQuery.each(types.split(/\s+/), function(index, type){
2561 // Namespaced event handlers
2562 var namespaces = type.split(".");
2563 type = namespaces.shift();
2564 var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
2565
2566 if ( events[type] ) {
2567 // remove the given handler for the given type
2568 if ( handler )
2569 delete events[type][handler.guid];
2570
2571 // remove all handlers for the given type
2572 else
2573 for ( var handle in events[type] )
2574 // Handle the removal of namespaced events
2575 if ( namespace.test(events[type][handle].type) )
2576 delete events[type][handle];
2577
2578 if ( jQuery.event.specialAll[type] )
2579 jQuery.event.specialAll[type].teardown.call(elem, namespaces);
2580
2581 // remove generic event handler if no more handlers exist
2582 for ( ret in events[type] ) break;
2583 if ( !ret ) {
2584 if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {
2585 if (elem.removeEventListener)
2586 elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
2587 else if (elem.detachEvent)
2588 elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
2589 }
2590 ret = null;
2591 delete events[type];
2592 }
2593 }
2594 });
2595 }
2596
2597 // Remove the expando if it's no longer used
2598 for ( ret in events ) break;
2599 if ( !ret ) {
2600 var handle = jQuery.data( elem, "handle" );
2601 if ( handle ) handle.elem = null;
2602 jQuery.removeData( elem, "events" );
2603 jQuery.removeData( elem, "handle" );
2604 }
2605 }
2606 },
2607
2608 // bubbling is internal
2609 trigger: function( event, data, elem, bubbling ) {
2610 // Event object or event type
2611 var type = event.type || event;
2612
2613 if( !bubbling ){
2614 event = typeof event === "object" ?
2615 // jQuery.Event object
2616 event[expando] ? event :
2617 // Object literal
2618 jQuery.extend( jQuery.Event(type), event ) :
2619 // Just the event type (string)
2620 jQuery.Event(type);
2621
2622 if ( type.indexOf("!") >= 0 ) {
2623 event.type = type = type.slice(0, -1);
2624 event.exclusive = true;
2625 }
2626
2627 // Handle a global trigger
2628 if ( !elem ) {
2629 // Don't bubble custom events when global (to avoid too much overhead)
2630 event.stopPropagation();
2631 // Only trigger if we've ever bound an event for it
2632 if ( this.global[type] )
2633 jQuery.each( jQuery.cache, function(){
2634 if ( this.events && this.events[type] )
2635 jQuery.event.trigger( event, data, this.handle.elem );
2636 });
2637 }
2638
2639 // Handle triggering a single element
2640
2641 // don't do events on text and comment nodes
2642 if ( !elem || elem.nodeType == 3 || elem.nodeType == 8 )
2643 return undefined;
2644
2645 // Clean up in case it is reused
2646 event.result = undefined;
2647 event.target = elem;
2648
2649 // Clone the incoming data, if any
2650 data = jQuery.makeArray(data);
2651 data.unshift( event );
2652 }
2653
2654 event.currentTarget = elem;
2655
2656 // Trigger the event, it is assumed that "handle" is a function
2657 var handle = jQuery.data(elem, "handle");
2658 if ( handle )
2659 handle.apply( elem, data );
2660
2661 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
2662 if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
2663 event.result = false;
2664
2665 // Trigger the native events (except for clicks on links)
2666 if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
2667 this.triggered = true;
2668 try {
2669 elem[ type ]();
2670 // prevent IE from throwing an error for some hidden elements
2671 } catch (e) {}
2672 }
2673
2674 this.triggered = false;
2675
2676 if ( !event.isPropagationStopped() ) {
2677 var parent = elem.parentNode || elem.ownerDocument;
2678 if ( parent )
2679 jQuery.event.trigger(event, data, parent, true);
2680 }
2681 },
2682
2683 handle: function(event) {
2684 // returned undefined or false
2685 var all, handlers;
2686
2687 event = arguments[0] = jQuery.event.fix( event || window.event );
2688 event.currentTarget = this;
2689
2690 // Namespaced event handlers
2691 var namespaces = event.type.split(".");
2692 event.type = namespaces.shift();
2693
2694 // Cache this now, all = true means, any handler
2695 all = !namespaces.length && !event.exclusive;
2696
2697 var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
2698
2699 handlers = ( jQuery.data(this, "events") || {} )[event.type];
2700
2701 for ( var j in handlers ) {
2702 var handler = handlers[j];
2703
2704 // Filter the functions by class
2705 if ( all || namespace.test(handler.type) ) {
2706 // Pass in a reference to the handler function itself
2707 // So that we can later remove it
2708 event.handler = handler;
2709 event.data = handler.data;
2710
2711 var ret = handler.apply(this, arguments);
2712
2713 if( ret !== undefined ){
2714 event.result = ret;
2715 if ( ret === false ) {
2716 event.preventDefault();
2717 event.stopPropagation();
2718 }
2719 }
2720
2721 if( event.isImmediatePropagationStopped() )
2722 break;
2723
2724 }
2725 }
2726 },
2727
2728 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
2729
2730 fix: function(event) {
2731 if ( event[expando] )
2732 return event;
2733
2734 // store a copy of the original event object
2735 // and "clone" to set read-only properties
2736 var originalEvent = event;
2737 event = jQuery.Event( originalEvent );
2738
2739 for ( var i = this.props.length, prop; i; ){
2740 prop = this.props[ --i ];
2741 event[ prop ] = originalEvent[ prop ];
2742 }
2743
2744 // Fix target property, if necessary
2745 if ( !event.target )
2746 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
2747
2748 // check if target is a textnode (safari)
2749 if ( event.target.nodeType == 3 )
2750 event.target = event.target.parentNode;
2751
2752 // Add relatedTarget, if necessary
2753 if ( !event.relatedTarget && event.fromElement )
2754 event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
2755
2756 // Calculate pageX/Y if missing and clientX/Y available
2757 if ( event.pageX == null && event.clientX != null ) {
2758 var doc = document.documentElement, body = document.body;
2759 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
2760 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
2761 }
2762
2763 // Add which for key events
2764 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
2765 event.which = event.charCode || event.keyCode;
2766
2767 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2768 if ( !event.metaKey && event.ctrlKey )
2769 event.metaKey = event.ctrlKey;
2770
2771 // Add which for click: 1 == left; 2 == middle; 3 == right
2772 // Note: button is not normalized, so don't use it
2773 if ( !event.which && event.button )
2774 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2775
2776 return event;
2777 },
2778
2779 proxy: function( fn, proxy ){
2780 proxy = proxy || function(){ return fn.apply(this, arguments); };
2781 // Set the guid of unique handler to the same of original handler, so it can be removed
2782 proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
2783 // So proxy can be declared as an argument
2784 return proxy;
2785 },
2786
2787 special: {
2788 ready: {
2789 // Make sure the ready event is setup
2790 setup: bindReady,
2791 teardown: function() {}
2792 }
2793 },
2794
2795 specialAll: {
2796 live: {
2797 setup: function( selector, namespaces ){
2798 jQuery.event.add( this, namespaces[0], liveHandler );
2799 },
2800 teardown: function( namespaces ){
2801 if ( namespaces.length ) {
2802 var remove = 0, name = RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
2803
2804 jQuery.each( (jQuery.data(this, "events").live || {}), function(){
2805 if ( name.test(this.type) )
2806 remove++;
2807 });
2808
2809 if ( remove < 1 )
2810 jQuery.event.remove( this, namespaces[0], liveHandler );
2811 }
2812 }
2813 }
2814 }
2815};
2816
2817jQuery.Event = function( src ){
2818 // Allow instantiation without the 'new' keyword
2819 if( !this.preventDefault )
2820 return new jQuery.Event(src);
2821
2822 // Event object
2823 if( src && src.type ){
2824 this.originalEvent = src;
2825 this.type = src.type;
2826 // Event type
2827 }else
2828 this.type = src;
2829
2830 // timeStamp is buggy for some events on Firefox(#3843)
2831 // So we won't rely on the native value
2832 this.timeStamp = now();
2833
2834 // Mark it as fixed
2835 this[expando] = true;
2836};
2837
2838function returnFalse(){
2839 return false;
2840}
2841function returnTrue(){
2842 return true;
2843}
2844
2845// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2846// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2847jQuery.Event.prototype = {
2848 preventDefault: function() {
2849 this.isDefaultPrevented = returnTrue;
2850
2851 var e = this.originalEvent;
2852 if( !e )
2853 return;
2854 // if preventDefault exists run it on the original event
2855 if (e.preventDefault)
2856 e.preventDefault();
2857 // otherwise set the returnValue property of the original event to false (IE)
2858 e.returnValue = false;
2859 },
2860 stopPropagation: function() {
2861 this.isPropagationStopped = returnTrue;
2862
2863 var e = this.originalEvent;
2864 if( !e )
2865 return;
2866 // if stopPropagation exists run it on the original event
2867 if (e.stopPropagation)
2868 e.stopPropagation();
2869 // otherwise set the cancelBubble property of the original event to true (IE)
2870 e.cancelBubble = true;
2871 },
2872 stopImmediatePropagation:function(){
2873 this.isImmediatePropagationStopped = returnTrue;
2874 this.stopPropagation();
2875 },
2876 isDefaultPrevented: returnFalse,
2877 isPropagationStopped: returnFalse,
2878 isImmediatePropagationStopped: returnFalse
2879};
2880// Checks if an event happened on an element within another element
2881// Used in jQuery.event.special.mouseenter and mouseleave handlers
2882var withinElement = function(event) {
2883 // Check if mouse(over|out) are still within the same parent element
2884 var parent = event.relatedTarget;
2885 // Traverse up the tree
2886 while ( parent && parent != this )
2887 try { parent = parent.parentNode; }
2888 catch(e) { parent = this; }
2889
2890 if( parent != this ){
2891 // set the correct event type
2892 event.type = event.data;
2893 // handle event if we actually just moused on to a non sub-element
2894 jQuery.event.handle.apply( this, arguments );
2895 }
2896};
2897
2898jQuery.each({
2899 mouseover: 'mouseenter',
2900 mouseout: 'mouseleave'
2901}, function( orig, fix ){
2902 jQuery.event.special[ fix ] = {
2903 setup: function(){
2904 jQuery.event.add( this, orig, withinElement, fix );
2905 },
2906 teardown: function(){
2907 jQuery.event.remove( this, orig, withinElement );
2908 }
2909 };
2910});
2911
2912jQuery.fn.extend({
2913 bind: function( type, data, fn ) {
2914 return type == "unload" ? this.one(type, data, fn) : this.each(function(){
2915 jQuery.event.add( this, type, fn || data, fn && data );
2916 });
2917 },
2918
2919 one: function( type, data, fn ) {
2920 var one = jQuery.event.proxy( fn || data, function(event) {
2921 jQuery(this).unbind(event, one);
2922 return (fn || data).apply( this, arguments );
2923 });
2924 return this.each(function(){
2925 jQuery.event.add( this, type, one, fn && data);
2926 });
2927 },
2928
2929 unbind: function( type, fn ) {
2930 return this.each(function(){
2931 jQuery.event.remove( this, type, fn );
2932 });
2933 },
2934
2935 trigger: function( type, data ) {
2936 return this.each(function(){
2937 jQuery.event.trigger( type, data, this );
2938 });
2939 },
2940
2941 triggerHandler: function( type, data ) {
2942 if( this[0] ){
2943 var event = jQuery.Event(type);
2944 event.preventDefault();
2945 event.stopPropagation();
2946 jQuery.event.trigger( event, data, this[0] );
2947 return event.result;
2948 }
2949 },
2950
2951 toggle: function( fn ) {
2952 // Save reference to arguments for access in closure
2953 var args = arguments, i = 1;
2954
2955 // link all the functions, so any of them can unbind this click handler
2956 while( i < args.length )
2957 jQuery.event.proxy( fn, args[i++] );
2958
2959 return this.click( jQuery.event.proxy( fn, function(event) {
2960 // Figure out which function to execute
2961 this.lastToggle = ( this.lastToggle || 0 ) % i;
2962
2963 // Make sure that clicks stop
2964 event.preventDefault();
2965
2966 // and execute the function
2967 return args[ this.lastToggle++ ].apply( this, arguments ) || false;
2968 }));
2969 },
2970
2971 hover: function(fnOver, fnOut) {
2972 return this.mouseenter(fnOver).mouseleave(fnOut);
2973 },
2974
2975 ready: function(fn) {
2976 // Attach the listeners
2977 bindReady();
2978
2979 // If the DOM is already ready
2980 if ( jQuery.isReady )
2981 // Execute the function immediately
2982 fn.call( document, jQuery );
2983
2984 // Otherwise, remember the function for later
2985 else
2986 // Add the function to the wait list
2987 jQuery.readyList.push( fn );
2988
2989 return this;
2990 },
2991
2992 live: function( type, fn ){
2993 var proxy = jQuery.event.proxy( fn );
2994 proxy.guid += this.selector + type;
2995
2996 jQuery(document).bind( liveConvert(type, this.selector), this.selector, proxy );
2997
2998 return this;
2999 },
3000
3001 die: function( type, fn ){
3002 jQuery(document).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type } : null );
3003 return this;
3004 }
3005});
3006
3007function liveHandler( event ){
3008 var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"),
3009 stop = true,
3010 elems = [];
3011
3012 jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){
3013 if ( check.test(fn.type) ) {
3014 var elem = jQuery(event.target).closest(fn.data)[0];
3015 if ( elem )
3016 elems.push({ elem: elem, fn: fn });
3017 }
3018 });
3019
3020 elems.sort(function(a,b) {
3021 return jQuery.data(a.elem, "closest") - jQuery.data(b.elem, "closest");
3022 });
3023
3024 jQuery.each(elems, function(){
3025 if ( this.fn.call(this.elem, event, this.fn.data) === false )
3026 return (stop = false);
3027 });
3028
3029 return stop;
3030}
3031
3032function liveConvert(type, selector){
3033 return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "|")].join(".");
3034}
3035
3036jQuery.extend({
3037 isReady: false,
3038 readyList: [],
3039 // Handle when the DOM is ready
3040 ready: function() {
3041 // Make sure that the DOM is not already loaded
3042 if ( !jQuery.isReady ) {
3043 // Remember that the DOM is ready
3044 jQuery.isReady = true;
3045
3046 // If there are functions bound, to execute
3047 if ( jQuery.readyList ) {
3048 // Execute all of them
3049 jQuery.each( jQuery.readyList, function(){
3050 this.call( document, jQuery );
3051 });
3052
3053 // Reset the list of functions
3054 jQuery.readyList = null;
3055 }
3056
3057 // Trigger any bound ready events
3058 jQuery(document).triggerHandler("ready");
3059 }
3060 }
3061});
3062
3063var readyBound = false;
3064
3065function bindReady(){
3066 if ( readyBound ) return;
3067 readyBound = true;
3068
3069 // Mozilla, Opera and webkit nightlies currently support this event
3070 if ( document.addEventListener ) {
3071 // Use the handy event callback
3072 document.addEventListener( "DOMContentLoaded", function(){
3073 document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
3074 jQuery.ready();
3075 }, false );
3076
3077 // If IE event model is used
3078 } else if ( document.attachEvent ) {
3079 // ensure firing before onload,
3080 // maybe late but safe also for iframes
3081 document.attachEvent("onreadystatechange", function(){
3082 if ( document.readyState === "complete" ) {
3083 document.detachEvent( "onreadystatechange", arguments.callee );
3084 jQuery.ready();
3085 }
3086 });
3087
3088 // If IE and not an iframe
3089 // continually check to see if the document is ready
3090 if ( document.documentElement.doScroll && window == window.top ) (function(){
3091 if ( jQuery.isReady ) return;
3092
3093 try {
3094 // If IE is used, use the trick by Diego Perini
3095 // http://javascript.nwbox.com/IEContentLoaded/
3096 document.documentElement.doScroll("left");
3097 } catch( error ) {
3098 setTimeout( arguments.callee, 0 );
3099 return;
3100 }
3101
3102 // and execute any waiting functions
3103 jQuery.ready();
3104 })();
3105 }
3106
3107 // A fallback to window.onload, that will always work
3108 jQuery.event.add( window, "load", jQuery.ready );
3109}
3110
3111jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
3112 "mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave," +
3113 "change,select,submit,keydown,keypress,keyup,error").split(","), function(i, name){
3114
3115 // Handle event binding
3116 jQuery.fn[name] = function(fn){
3117 return fn ? this.bind(name, fn) : this.trigger(name);
3118 };
3119});
3120
3121// Prevent memory leaks in IE
3122// And prevent errors on refresh with events like mouseover in other browsers
3123// Window isn't included so as not to unbind existing unload events
3124jQuery( window ).bind( 'unload', function(){
3125 for ( var id in jQuery.cache )
3126 // Skip the window
3127 if ( id != 1 && jQuery.cache[ id ].handle )
3128 jQuery.event.remove( jQuery.cache[ id ].handle.elem );
3129});
3130(function(){
3131
3132 jQuery.support = {};
3133
3134 var root = document.documentElement,
3135 script = document.createElement("script"),
3136 div = document.createElement("div"),
3137 id = "script" + (new Date).getTime();
3138
3139 div.style.display = "none";
3140 div.innerHTML = ' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';
3141
3142 var all = div.getElementsByTagName("*"),
3143 a = div.getElementsByTagName("a")[0];
3144
3145 // Can't get basic test support
3146 if ( !all || !all.length || !a ) {
3147 return;
3148 }
3149
3150 jQuery.support = {
3151 // IE strips leading whitespace when .innerHTML is used
3152 leadingWhitespace: div.firstChild.nodeType == 3,
3153
3154 // Make sure that tbody elements aren't automatically inserted
3155 // IE will insert them into empty tables
3156 tbody: !div.getElementsByTagName("tbody").length,
3157
3158 // Make sure that you can get all elements in an <object> element
3159 // IE 7 always returns no results
3160 objectAll: !!div.getElementsByTagName("object")[0]
3161 .getElementsByTagName("*").length,
3162
3163 // Make sure that link elements get serialized correctly by innerHTML
3164 // This requires a wrapper element in IE
3165 htmlSerialize: !!div.getElementsByTagName("link").length,
3166
3167 // Get the style information from getAttribute
3168 // (IE uses .cssText insted)
3169 style: /red/.test( a.getAttribute("style") ),
3170
3171 // Make sure that URLs aren't manipulated
3172 // (IE normalizes it by default)
3173 hrefNormalized: a.getAttribute("href") === "/a",
3174
3175 // Make sure that element opacity exists
3176 // (IE uses filter instead)
3177 opacity: a.style.opacity === "0.5",
3178
3179 // Verify style float existence
3180 // (IE uses styleFloat instead of cssFloat)
3181 cssFloat: !!a.style.cssFloat,
3182
3183 // Will be defined later
3184 scriptEval: false,
3185 noCloneEvent: true,
3186 boxModel: null
3187 };
3188
3189 script.type = "text/javascript";
3190 try {
3191 script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
3192 } catch(e){}
3193
3194 root.insertBefore( script, root.firstChild );
3195
3196 // Make sure that the execution of code works by injecting a script
3197 // tag with appendChild/createTextNode
3198 // (IE doesn't support this, fails, and uses .text instead)
3199 if ( window[ id ] ) {
3200 jQuery.support.scriptEval = true;
3201 delete window[ id ];
3202 }
3203
3204 root.removeChild( script );
3205
3206 if ( div.attachEvent && div.fireEvent ) {
3207 div.attachEvent("onclick", function(){
3208 // Cloning a node shouldn't copy over any
3209 // bound event handlers (IE does this)
3210 jQuery.support.noCloneEvent = false;
3211 div.detachEvent("onclick", arguments.callee);
3212 });
3213 div.cloneNode(true).fireEvent("onclick");
3214 }
3215
3216 // Figure out if the W3C box model works as expected
3217 // document.body must exist before we can do this
3218 jQuery(function(){
3219 var div = document.createElement("div");
3220 div.style.width = div.style.paddingLeft = "1px";
3221
3222 document.body.appendChild( div );
3223 jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
3224 document.body.removeChild( div ).style.display = 'none';
3225 });
3226})();
3227
3228var styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat";
3229
3230jQuery.props = {
3231 "for": "htmlFor",
3232 "class": "className",
3233 "float": styleFloat,
3234 cssFloat: styleFloat,
3235 styleFloat: styleFloat,
3236 readonly: "readOnly",
3237 maxlength: "maxLength",
3238 cellspacing: "cellSpacing",
3239 rowspan: "rowSpan",
3240 tabindex: "tabIndex"
3241};
3242jQuery.fn.extend({
3243 // Keep a copy of the old load
3244 _load: jQuery.fn.load,
3245
3246 load: function( url, params, callback ) {
3247 if ( typeof url !== "string" )
3248 return this._load( url );
3249
3250 var off = url.indexOf(" ");
3251 if ( off >= 0 ) {
3252 var selector = url.slice(off, url.length);
3253 url = url.slice(0, off);
3254 }
3255
3256 // Default to a GET request
3257 var type = "GET";
3258
3259 // If the second parameter was provided
3260 if ( params )
3261 // If it's a function
3262 if ( jQuery.isFunction( params ) ) {
3263 // We assume that it's the callback
3264 callback = params;
3265 params = null;
3266
3267 // Otherwise, build a param string
3268 } else if( typeof params === "object" ) {
3269 params = jQuery.param( params );
3270 type = "POST";
3271 }
3272
3273 var self = this;
3274
3275 // Request the remote document
3276 jQuery.ajax({
3277 url: url,
3278 type: type,
3279 dataType: "html",
3280 data: params,
3281 complete: function(res, status){
3282 // If successful, inject the HTML into all the matched elements
3283 if ( status == "success" || status == "notmodified" )
3284 // See if a selector was specified
3285 self.html( selector ?
3286 // Create a dummy div to hold the results
3287 jQuery("<div/>")
3288 // inject the contents of the document in, removing the scripts
3289 // to avoid any 'Permission Denied' errors in IE
3290 .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
3291
3292 // Locate the specified elements
3293 .find(selector) :
3294
3295 // If not, just inject the full result
3296 res.responseText );
3297
3298 if( callback )
3299 self.each( callback, [res.responseText, status, res] );
3300 }
3301 });
3302 return this;
3303 },
3304
3305 serialize: function() {
3306 return jQuery.param(this.serializeArray());
3307 },
3308 serializeArray: function() {
3309 return this.map(function(){
3310 return this.elements ? jQuery.makeArray(this.elements) : this;
3311 })
3312 .filter(function(){
3313 return this.name && !this.disabled &&
3314 (this.checked || /select|textarea/i.test(this.nodeName) ||
3315 /text|hidden|password|search/i.test(this.type));
3316 })
3317 .map(function(i, elem){
3318 var val = jQuery(this).val();
3319 return val == null ? null :
3320 jQuery.isArray(val) ?
3321 jQuery.map( val, function(val, i){
3322 return {name: elem.name, value: val};
3323 }) :
3324 {name: elem.name, value: val};
3325 }).get();
3326 }
3327});
3328
3329// Attach a bunch of functions for handling common AJAX events
3330jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
3331 jQuery.fn[o] = function(f){
3332 return this.bind(o, f);
3333 };
3334});
3335
3336var jsc = now();
3337
3338jQuery.extend({
3339
3340 get: function( url, data, callback, type ) {
3341 // shift arguments if data argument was ommited
3342 if ( jQuery.isFunction( data ) ) {
3343 callback = data;
3344 data = null;
3345 }
3346
3347 return jQuery.ajax({
3348 type: "GET",
3349 url: url,
3350 data: data,
3351 success: callback,
3352 dataType: type
3353 });
3354 },
3355
3356 getScript: function( url, callback ) {
3357 return jQuery.get(url, null, callback, "script");
3358 },
3359
3360 getJSON: function( url, data, callback ) {
3361 return jQuery.get(url, data, callback, "json");
3362 },
3363
3364 post: function( url, data, callback, type ) {
3365 if ( jQuery.isFunction( data ) ) {
3366 callback = data;
3367 data = {};
3368 }
3369
3370 return jQuery.ajax({
3371 type: "POST",
3372 url: url,
3373 data: data,
3374 success: callback,
3375 dataType: type
3376 });
3377 },
3378
3379 ajaxSetup: function( settings ) {
3380 jQuery.extend( jQuery.ajaxSettings, settings );
3381 },
3382
3383 ajaxSettings: {
3384 url: location.href,
3385 global: true,
3386 type: "GET",
3387 contentType: "application/x-www-form-urlencoded",
3388 processData: true,
3389 async: true,
3390 /*
3391 timeout: 0,
3392 data: null,
3393 username: null,
3394 password: null,
3395 */
3396 // Create the request object; Microsoft failed to properly
3397 // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
3398 // This function can be overriden by calling jQuery.ajaxSetup
3399 xhr:function(){
3400 return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
3401 },
3402 accepts: {
3403 xml: "application/xml, text/xml",
3404 html: "text/html",
3405 script: "text/javascript, application/javascript",
3406 json: "application/json, text/javascript",
3407 text: "text/plain",
3408 _default: "*/*"
3409 }
3410 },
3411
3412 // Last-Modified header cache for next request
3413 lastModified: {},
3414
3415 ajax: function( s ) {
3416 // Extend the settings, but re-extend 's' so that it can be
3417 // checked again later (in the test suite, specifically)
3418 s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
3419
3420 var jsonp, jsre = /=\?(&|$)/g, status, data,
3421 type = s.type.toUpperCase();
3422
3423 // convert data if not already a string
3424 if ( s.data && s.processData && typeof s.data !== "string" )
3425 s.data = jQuery.param(s.data);
3426
3427 // Handle JSONP Parameter Callbacks
3428 if ( s.dataType == "jsonp" ) {
3429 if ( type == "GET" ) {
3430 if ( !s.url.match(jsre) )
3431 s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
3432 } else if ( !s.data || !s.data.match(jsre) )
3433 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
3434 s.dataType = "json";
3435 }
3436
3437 // Build temporary JSONP function
3438 if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
3439 jsonp = "jsonp" + jsc++;
3440
3441 // Replace the =? sequence both in the query string and the data
3442 if ( s.data )
3443 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
3444 s.url = s.url.replace(jsre, "=" + jsonp + "$1");
3445
3446 // We need to make sure
3447 // that a JSONP style response is executed properly
3448 s.dataType = "script";
3449
3450 // Handle JSONP-style loading
3451 window[ jsonp ] = function(tmp){
3452 data = tmp;
3453 success();
3454 complete();
3455 // Garbage collect
3456 window[ jsonp ] = undefined;
3457 try{ delete window[ jsonp ]; } catch(e){}
3458 if ( head )
3459 head.removeChild( script );
3460 };
3461 }
3462
3463 if ( s.dataType == "script" && s.cache == null )
3464 s.cache = false;
3465
3466 if ( s.cache === false && type == "GET" ) {
3467 var ts = now();
3468 // try replacing _= if it is there
3469 var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
3470 // if nothing was replaced, add timestamp to the end
3471 s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
3472 }
3473
3474 // If data is available, append data to url for get requests
3475 if ( s.data && type == "GET" ) {
3476 s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
3477
3478 // IE likes to send both get and post data, prevent this
3479 s.data = null;
3480 }
3481
3482 // Watch for a new set of requests
3483 if ( s.global && ! jQuery.active++ )
3484 jQuery.event.trigger( "ajaxStart" );
3485
3486 // Matches an absolute URL, and saves the domain
3487 var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec( s.url );
3488
3489 // If we're requesting a remote document
3490 // and trying to load JSON or Script with a GET
3491 if ( s.dataType == "script" && type == "GET" && parts
3492 && ( parts[1] && parts[1] != location.protocol || parts[2] != location.host )){
3493
3494 var head = document.getElementsByTagName("head")[0];
3495 var script = document.createElement("script");
3496 script.src = s.url;
3497 if (s.scriptCharset)
3498 script.charset = s.scriptCharset;
3499
3500 // Handle Script loading
3501 if ( !jsonp ) {
3502 var done = false;
3503
3504 // Attach handlers for all browsers
3505 script.onload = script.onreadystatechange = function(){
3506 if ( !done && (!this.readyState ||
3507 this.readyState == "loaded" || this.readyState == "complete") ) {
3508 done = true;
3509 success();
3510 complete();
3511
3512 // Handle memory leak in IE
3513 script.onload = script.onreadystatechange = null;
3514 head.removeChild( script );
3515 }
3516 };
3517 }
3518
3519 head.appendChild(script);
3520
3521 // We handle everything using the script element injection
3522 return undefined;
3523 }
3524
3525 var requestDone = false;
3526
3527 // Create the request object
3528 var xhr = s.xhr();
3529
3530 // Open the socket
3531 // Passing null username, generates a login popup on Opera (#2865)
3532 if( s.username )
3533 xhr.open(type, s.url, s.async, s.username, s.password);
3534 else
3535 xhr.open(type, s.url, s.async);
3536
3537 // Need an extra try/catch for cross domain requests in Firefox 3
3538 try {
3539 // Set the correct header, if data is being sent
3540 if ( s.data )
3541 xhr.setRequestHeader("Content-Type", s.contentType);
3542
3543 // Set the If-Modified-Since header, if ifModified mode.
3544 if ( s.ifModified )
3545 xhr.setRequestHeader("If-Modified-Since",
3546 jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
3547
3548 // Set header so the called script knows that it's an XMLHttpRequest
3549 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
3550
3551 // Set the Accepts header for the server, depending on the dataType
3552 xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
3553 s.accepts[ s.dataType ] + ", */*" :
3554 s.accepts._default );
3555 } catch(e){}
3556
3557 // Allow custom headers/mimetypes and early abort
3558 if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
3559 // Handle the global AJAX counter
3560 if ( s.global && ! --jQuery.active )
3561 jQuery.event.trigger( "ajaxStop" );
3562 // close opended socket
3563 xhr.abort();
3564 return false;
3565 }
3566
3567 if ( s.global )
3568 jQuery.event.trigger("ajaxSend", [xhr, s]);
3569
3570 // Wait for a response to come back
3571 var onreadystatechange = function(isTimeout){
3572 // The request was aborted, clear the interval and decrement jQuery.active
3573 if (xhr.readyState == 0) {
3574 if (ival) {
3575 // clear poll interval
3576 clearInterval(ival);
3577 ival = null;
3578 // Handle the global AJAX counter
3579 if ( s.global && ! --jQuery.active )
3580 jQuery.event.trigger( "ajaxStop" );
3581 }
3582 // The transfer is complete and the data is available, or the request timed out
3583 } else if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
3584 requestDone = true;
3585
3586 // clear poll interval
3587 if (ival) {
3588 clearInterval(ival);
3589 ival = null;
3590 }
3591
3592 status = isTimeout == "timeout" ? "timeout" :
3593 !jQuery.httpSuccess( xhr ) ? "error" :
3594 s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" :
3595 "success";
3596
3597 if ( status == "success" ) {
3598 // Watch for, and catch, XML document parse errors
3599 try {
3600 // process the data (runs the xml through httpData regardless of callback)
3601 data = jQuery.httpData( xhr, s.dataType, s );
3602 } catch(e) {
3603 status = "parsererror";
3604 }
3605 }
3606
3607 // Make sure that the request was successful or notmodified
3608 if ( status == "success" ) {
3609 // Cache Last-Modified header, if ifModified mode.
3610 var modRes;
3611 try {
3612 modRes = xhr.getResponseHeader("Last-Modified");
3613 } catch(e) {} // swallow exception thrown by FF if header is not available
3614
3615 if ( s.ifModified && modRes )
3616 jQuery.lastModified[s.url] = modRes;
3617
3618 // JSONP handles its own success callback
3619 if ( !jsonp )
3620 success();
3621 } else
3622 jQuery.handleError(s, xhr, status);
3623
3624 // Fire the complete handlers
3625 complete();
3626
3627 if ( isTimeout )
3628 xhr.abort();
3629
3630 // Stop memory leaks
3631 if ( s.async )
3632 xhr = null;
3633 }
3634 };
3635
3636 if ( s.async ) {
3637 // don't attach the handler to the request, just poll it instead
3638 var ival = setInterval(onreadystatechange, 13);
3639
3640 // Timeout checker
3641 if ( s.timeout > 0 )
3642 setTimeout(function(){
3643 // Check to see if the request is still happening
3644 if ( xhr && !requestDone )
3645 onreadystatechange( "timeout" );
3646 }, s.timeout);
3647 }
3648
3649 // Send the data
3650 try {
3651 xhr.send(s.data);
3652 } catch(e) {
3653 jQuery.handleError(s, xhr, null, e);
3654 }
3655
3656 // firefox 1.5 doesn't fire statechange for sync requests
3657 if ( !s.async )
3658 onreadystatechange();
3659
3660 function success(){
3661 // If a local callback was specified, fire it and pass it the data
3662 if ( s.success )
3663 s.success( data, status );
3664
3665 // Fire the global callback
3666 if ( s.global )
3667 jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
3668 }
3669
3670 function complete(){
3671 // Process result
3672 if ( s.complete )
3673 s.complete(xhr, status);
3674
3675 // The request was completed
3676 if ( s.global )
3677 jQuery.event.trigger( "ajaxComplete", [xhr, s] );
3678
3679 // Handle the global AJAX counter
3680 if ( s.global && ! --jQuery.active )
3681 jQuery.event.trigger( "ajaxStop" );
3682 }
3683
3684 // return XMLHttpRequest to allow aborting the request etc.
3685 return xhr;
3686 },
3687
3688 handleError: function( s, xhr, status, e ) {
3689 // If a local callback was specified, fire it
3690 if ( s.error ) s.error( xhr, status, e );
3691
3692 // Fire the global callback
3693 if ( s.global )
3694 jQuery.event.trigger( "ajaxError", [xhr, s, e] );
3695 },
3696
3697 // Counter for holding the number of active queries
3698 active: 0,
3699
3700 // Determines if an XMLHttpRequest was successful or not
3701 httpSuccess: function( xhr ) {
3702 try {
3703 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
3704 return !xhr.status && location.protocol == "file:" ||
3705 ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223;
3706 } catch(e){}
3707 return false;
3708 },
3709
3710 // Determines if an XMLHttpRequest returns NotModified
3711 httpNotModified: function( xhr, url ) {
3712 try {
3713 var xhrRes = xhr.getResponseHeader("Last-Modified");
3714
3715 // Firefox always returns 200. check Last-Modified date
3716 return xhr.status == 304 || xhrRes == jQuery.lastModified[url];
3717 } catch(e){}
3718 return false;
3719 },
3720
3721 httpData: function( xhr, type, s ) {
3722 var ct = xhr.getResponseHeader("content-type"),
3723 xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
3724 data = xml ? xhr.responseXML : xhr.responseText;
3725
3726 if ( xml && data.documentElement.tagName == "parsererror" )
3727 throw "parsererror";
3728
3729 // Allow a pre-filtering function to sanitize the response
3730 // s != null is checked to keep backwards compatibility
3731 if( s && s.dataFilter )
3732 data = s.dataFilter( data, type );
3733
3734 // The filter can actually parse the response
3735 if( typeof data === "string" ){
3736
3737 // If the type is "script", eval it in global context
3738 if ( type == "script" )
3739 jQuery.globalEval( data );
3740
3741 // Get the JavaScript object, if JSON is used.
3742 if ( type == "json" )
3743 data = window["eval"]("(" + data + ")");
3744 }
3745
3746 return data;
3747 },
3748
3749 // Serialize an array of form elements or a set of
3750 // key/values into a query string
3751 param: function( a ) {
3752 var s = [ ];
3753
3754 function add( key, value ){
3755 s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
3756 };
3757
3758 // If an array was passed in, assume that it is an array
3759 // of form elements
3760 if ( jQuery.isArray(a) || a.jquery )
3761 // Serialize the form elements
3762 jQuery.each( a, function(){
3763 add( this.name, this.value );
3764 });
3765
3766 // Otherwise, assume that it's an object of key/value pairs
3767 else
3768 // Serialize the key/values
3769 for ( var j in a )
3770 // If the value is an array then the key names need to be repeated
3771 if ( jQuery.isArray(a[j]) )
3772 jQuery.each( a[j], function(){
3773 add( j, this );
3774 });
3775 else
3776 add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
3777
3778 // Return the resulting serialization
3779 return s.join("&").replace(/%20/g, "+");
3780 }
3781
3782});
3783var elemdisplay = {},
3784 timerId,
3785 fxAttrs = [
3786 // height animations
3787 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
3788 // width animations
3789 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
3790 // opacity animations
3791 [ "opacity" ]
3792 ];
3793
3794function genFx( type, num ){
3795 var obj = {};
3796 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function(){
3797 obj[ this ] = type;
3798 });
3799 return obj;
3800}
3801
3802jQuery.fn.extend({
3803 show: function(speed,callback){
3804 if ( speed ) {
3805 return this.animate( genFx("show", 3), speed, callback);
3806 } else {
3807 for ( var i = 0, l = this.length; i < l; i++ ){
3808 var old = jQuery.data(this[i], "olddisplay");
3809
3810 this[i].style.display = old || "";
3811
3812 if ( jQuery.css(this[i], "display") === "none" ) {
3813 var tagName = this[i].tagName, display;
3814
3815 if ( elemdisplay[ tagName ] ) {
3816 display = elemdisplay[ tagName ];
3817 } else {
3818 var elem = jQuery("<" + tagName + " />").appendTo("body");
3819
3820 display = elem.css("display");
3821 if ( display === "none" )
3822 display = "block";
3823
3824 elem.remove();
3825
3826 elemdisplay[ tagName ] = display;
3827 }
3828
3829 jQuery.data(this[i], "olddisplay", display);
3830 }
3831 }
3832
3833 // Set the display of the elements in a second loop
3834 // to avoid the constant reflow
3835 for ( var i = 0, l = this.length; i < l; i++ ){
3836 this[i].style.display = jQuery.data(this[i], "olddisplay") || "";
3837 }
3838
3839 return this;
3840 }
3841 },
3842
3843 hide: function(speed,callback){
3844 if ( speed ) {
3845 return this.animate( genFx("hide", 3), speed, callback);
3846 } else {
3847 for ( var i = 0, l = this.length; i < l; i++ ){
3848 var old = jQuery.data(this[i], "olddisplay");
3849 if ( !old && old !== "none" )
3850 jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
3851 }
3852
3853 // Set the display of the elements in a second loop
3854 // to avoid the constant reflow
3855 for ( var i = 0, l = this.length; i < l; i++ ){
3856 this[i].style.display = "none";
3857 }
3858
3859 return this;
3860 }
3861 },
3862
3863 // Save the old toggle function
3864 _toggle: jQuery.fn.toggle,
3865
3866 toggle: function( fn, fn2 ){
3867 var bool = typeof fn === "boolean";
3868
3869 return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
3870 this._toggle.apply( this, arguments ) :
3871 fn == null || bool ?
3872 this.each(function(){
3873 var state = bool ? fn : jQuery(this).is(":hidden");
3874 jQuery(this)[ state ? "show" : "hide" ]();
3875 }) :
3876 this.animate(genFx("toggle", 3), fn, fn2);
3877 },
3878
3879 fadeTo: function(speed,to,callback){
3880 return this.animate({opacity: to}, speed, callback);
3881 },
3882
3883 animate: function( prop, speed, easing, callback ) {
3884 var optall = jQuery.speed(speed, easing, callback);
3885
3886 return this[ optall.queue === false ? "each" : "queue" ](function(){
3887
3888 var opt = jQuery.extend({}, optall), p,
3889 hidden = this.nodeType == 1 && jQuery(this).is(":hidden"),
3890 self = this;
3891
3892 for ( p in prop ) {
3893 if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
3894 return opt.complete.call(this);
3895
3896 if ( ( p == "height" || p == "width" ) && this.style ) {
3897 // Store display property
3898 opt.display = jQuery.css(this, "display");
3899
3900 // Make sure that nothing sneaks out
3901 opt.overflow = this.style.overflow;
3902 }
3903 }
3904
3905 if ( opt.overflow != null )
3906 this.style.overflow = "hidden";
3907
3908 opt.curAnim = jQuery.extend({}, prop);
3909
3910 jQuery.each( prop, function(name, val){
3911 var e = new jQuery.fx( self, opt, name );
3912
3913 if ( /toggle|show|hide/.test(val) )
3914 e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
3915 else {
3916 var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
3917 start = e.cur(true) || 0;
3918
3919 if ( parts ) {
3920 var end = parseFloat(parts[2]),
3921 unit = parts[3] || "px";
3922
3923 // We need to compute starting value
3924 if ( unit != "px" ) {
3925 self.style[ name ] = (end || 1) + unit;
3926 start = ((end || 1) / e.cur(true)) * start;
3927 self.style[ name ] = start + unit;
3928 }
3929
3930 // If a +=/-= token was provided, we're doing a relative animation
3931 if ( parts[1] )
3932 end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
3933
3934 e.custom( start, end, unit );
3935 } else
3936 e.custom( start, val, "" );
3937 }
3938 });
3939
3940 // For JS strict compliance
3941 return true;
3942 });
3943 },
3944
3945 stop: function(clearQueue, gotoEnd){
3946 var timers = jQuery.timers;
3947
3948 if (clearQueue)
3949 this.queue([]);
3950
3951 this.each(function(){
3952 // go in reverse order so anything added to the queue during the loop is ignored
3953 for ( var i = timers.length - 1; i >= 0; i-- )
3954 if ( timers[i].elem == this ) {
3955 if (gotoEnd)
3956 // force the next step to be the last
3957 timers[i](true);
3958 timers.splice(i, 1);
3959 }
3960 });
3961
3962 // start the next in the queue if the last step wasn't forced
3963 if (!gotoEnd)
3964 this.dequeue();
3965
3966 return this;
3967 }
3968
3969});
3970
3971// Generate shortcuts for custom animations
3972jQuery.each({
3973 slideDown: genFx("show", 1),
3974 slideUp: genFx("hide", 1),
3975 slideToggle: genFx("toggle", 1),
3976 fadeIn: { opacity: "show" },
3977 fadeOut: { opacity: "hide" }
3978}, function( name, props ){
3979 jQuery.fn[ name ] = function( speed, callback ){
3980 return this.animate( props, speed, callback );
3981 };
3982});
3983
3984jQuery.extend({
3985
3986 speed: function(speed, easing, fn) {
3987 var opt = typeof speed === "object" ? speed : {
3988 complete: fn || !fn && easing ||
3989 jQuery.isFunction( speed ) && speed,
3990 duration: speed,
3991 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
3992 };
3993
3994 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
3995 jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
3996
3997 // Queueing
3998 opt.old = opt.complete;
3999 opt.complete = function(){
4000 if ( opt.queue !== false )
4001 jQuery(this).dequeue();
4002 if ( jQuery.isFunction( opt.old ) )
4003 opt.old.call( this );
4004 };
4005
4006 return opt;
4007 },
4008
4009 easing: {
4010 linear: function( p, n, firstNum, diff ) {
4011 return firstNum + diff * p;
4012 },
4013 swing: function( p, n, firstNum, diff ) {
4014 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
4015 }
4016 },
4017
4018 timers: [],
4019
4020 fx: function( elem, options, prop ){
4021 this.options = options;
4022 this.elem = elem;
4023 this.prop = prop;
4024
4025 if ( !options.orig )
4026 options.orig = {};
4027 }
4028
4029});
4030
4031jQuery.fx.prototype = {
4032
4033 // Simple function for setting a style value
4034 update: function(){
4035 if ( this.options.step )
4036 this.options.step.call( this.elem, this.now, this );
4037
4038 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
4039
4040 // Set display property to block for height/width animations
4041 if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style )
4042 this.elem.style.display = "block";
4043 },
4044
4045 // Get the current size
4046 cur: function(force){
4047 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) )
4048 return this.elem[ this.prop ];
4049
4050 var r = parseFloat(jQuery.css(this.elem, this.prop, force));
4051 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
4052 },
4053
4054 // Start an animation from one number to another
4055 custom: function(from, to, unit){
4056 this.startTime = now();
4057 this.start = from;
4058 this.end = to;
4059 this.unit = unit || this.unit || "px";
4060 this.now = this.start;
4061 this.pos = this.state = 0;
4062
4063 var self = this;
4064 function t(gotoEnd){
4065 return self.step(gotoEnd);
4066 }
4067
4068 t.elem = this.elem;
4069
4070 if ( t() && jQuery.timers.push(t) && !timerId ) {
4071 timerId = setInterval(function(){
4072 var timers = jQuery.timers;
4073
4074 for ( var i = 0; i < timers.length; i++ )
4075 if ( !timers[i]() )
4076 timers.splice(i--, 1);
4077
4078 if ( !timers.length ) {
4079 clearInterval( timerId );
4080 timerId = undefined;
4081 }
4082 }, 13);
4083 }
4084 },
4085
4086 // Simple 'show' function
4087 show: function(){
4088 // Remember where we started, so that we can go back to it later
4089 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
4090 this.options.show = true;
4091
4092 // Begin the animation
4093 // Make sure that we start at a small width/height to avoid any
4094 // flash of content
4095 this.custom(this.prop == "width" || this.prop == "height" ? 1 : 0, this.cur());
4096
4097 // Start by showing the element
4098 jQuery(this.elem).show();
4099 },
4100
4101 // Simple 'hide' function
4102 hide: function(){
4103 // Remember where we started, so that we can go back to it later
4104 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
4105 this.options.hide = true;
4106
4107 // Begin the animation
4108 this.custom(this.cur(), 0);
4109 },
4110
4111 // Each step of an animation
4112 step: function(gotoEnd){
4113 var t = now();
4114
4115 if ( gotoEnd || t >= this.options.duration + this.startTime ) {
4116 this.now = this.end;
4117 this.pos = this.state = 1;
4118 this.update();
4119
4120 this.options.curAnim[ this.prop ] = true;
4121
4122 var done = true;
4123 for ( var i in this.options.curAnim )
4124 if ( this.options.curAnim[i] !== true )
4125 done = false;
4126
4127 if ( done ) {
4128 if ( this.options.display != null ) {
4129 // Reset the overflow
4130 this.elem.style.overflow = this.options.overflow;
4131
4132 // Reset the display
4133 this.elem.style.display = this.options.display;
4134 if ( jQuery.css(this.elem, "display") == "none" )
4135 this.elem.style.display = "block";
4136 }
4137
4138 // Hide the element if the "hide" operation was done
4139 if ( this.options.hide )
4140 jQuery(this.elem).hide();
4141
4142 // Reset the properties, if the item has been hidden or shown
4143 if ( this.options.hide || this.options.show )
4144 for ( var p in this.options.curAnim )
4145 jQuery.attr(this.elem.style, p, this.options.orig[p]);
4146
4147 // Execute the complete function
4148 this.options.complete.call( this.elem );
4149 }
4150
4151 return false;
4152 } else {
4153 var n = t - this.startTime;
4154 this.state = n / this.options.duration;
4155
4156 // Perform the easing function, defaults to swing
4157 this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
4158 this.now = this.start + ((this.end - this.start) * this.pos);
4159
4160 // Perform the next step of the animation
4161 this.update();
4162 }
4163
4164 return true;
4165 }
4166
4167};
4168
4169jQuery.extend( jQuery.fx, {
4170 speeds:{
4171 slow: 600,
4172 fast: 200,
4173 // Default speed
4174 _default: 400
4175 },
4176 step: {
4177
4178 opacity: function(fx){
4179 jQuery.attr(fx.elem.style, "opacity", fx.now);
4180 },
4181
4182 _default: function(fx){
4183 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null )
4184 fx.elem.style[ fx.prop ] = fx.now + fx.unit;
4185 else
4186 fx.elem[ fx.prop ] = fx.now;
4187 }
4188 }
4189});
4190if ( document.documentElement["getBoundingClientRect"] )
4191 jQuery.fn.offset = function() {
4192 if ( !this[0] ) return { top: 0, left: 0 };
4193 if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
4194 var box = this[0].getBoundingClientRect(), doc = this[0].ownerDocument, body = doc.body, docElem = doc.documentElement,
4195 clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
4196 top = box.top + (self.pageYOffset || jQuery.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
4197 left = box.left + (self.pageXOffset || jQuery.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
4198 return { top: top, left: left };
4199 };
4200else
4201 jQuery.fn.offset = function() {
4202 if ( !this[0] ) return { top: 0, left: 0 };
4203 if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
4204 jQuery.offset.initialized || jQuery.offset.initialize();
4205
4206 var elem = this[0], offsetParent = elem.offsetParent, prevOffsetParent = elem,
4207 doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
4208 body = doc.body, defaultView = doc.defaultView,
4209 prevComputedStyle = defaultView.getComputedStyle(elem, null),
4210 top = elem.offsetTop, left = elem.offsetLeft;
4211
4212 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
4213 computedStyle = defaultView.getComputedStyle(elem, null);
4214 top -= elem.scrollTop, left -= elem.scrollLeft;
4215 if ( elem === offsetParent ) {
4216 top += elem.offsetTop, left += elem.offsetLeft;
4217 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.tagName)) )
4218 top += parseInt( computedStyle.borderTopWidth, 10) || 0,
4219 left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
4220 prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
4221 }
4222 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" )
4223 top += parseInt( computedStyle.borderTopWidth, 10) || 0,
4224 left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
4225 prevComputedStyle = computedStyle;
4226 }
4227
4228 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" )
4229 top += body.offsetTop,
4230 left += body.offsetLeft;
4231
4232 if ( prevComputedStyle.position === "fixed" )
4233 top += Math.max(docElem.scrollTop, body.scrollTop),
4234 left += Math.max(docElem.scrollLeft, body.scrollLeft);
4235
4236 return { top: top, left: left };
4237 };
4238
4239jQuery.offset = {
4240 initialize: function() {
4241 if ( this.initialized ) return;
4242 var body = document.body, container = document.createElement('div'), innerDiv, checkDiv, table, td, rules, prop, bodyMarginTop = body.style.marginTop,
4243 html = '<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';
4244
4245 rules = { position: 'absolute', top: 0, left: 0, margin: 0, border: 0, width: '1px', height: '1px', visibility: 'hidden' };
4246 for ( prop in rules ) container.style[prop] = rules[prop];
4247
4248 container.innerHTML = html;
4249 body.insertBefore(container, body.firstChild);
4250 innerDiv = container.firstChild, checkDiv = innerDiv.firstChild, td = innerDiv.nextSibling.firstChild.firstChild;
4251
4252 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
4253 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
4254
4255 innerDiv.style.overflow = 'hidden', innerDiv.style.position = 'relative';
4256 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
4257
4258 body.style.marginTop = '1px';
4259 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop === 0);
4260 body.style.marginTop = bodyMarginTop;
4261
4262 body.removeChild(container);
4263 this.initialized = true;
4264 },
4265
4266 bodyOffset: function(body) {
4267 jQuery.offset.initialized || jQuery.offset.initialize();
4268 var top = body.offsetTop, left = body.offsetLeft;
4269 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset )
4270 top += parseInt( jQuery.curCSS(body, 'marginTop', true), 10 ) || 0,
4271 left += parseInt( jQuery.curCSS(body, 'marginLeft', true), 10 ) || 0;
4272 return { top: top, left: left };
4273 }
4274};
4275
4276
4277jQuery.fn.extend({
4278 position: function() {
4279 var left = 0, top = 0, results;
4280
4281 if ( this[0] ) {
4282 // Get *real* offsetParent
4283 var offsetParent = this.offsetParent(),
4284
4285 // Get correct offsets
4286 offset = this.offset(),
4287 parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
4288
4289 // Subtract element margins
4290 // note: when an element has margin: auto the offsetLeft and marginLeft
4291 // are the same in Safari causing offset.left to incorrectly be 0
4292 offset.top -= num( this, 'marginTop' );
4293 offset.left -= num( this, 'marginLeft' );
4294
4295 // Add offsetParent borders
4296 parentOffset.top += num( offsetParent, 'borderTopWidth' );
4297 parentOffset.left += num( offsetParent, 'borderLeftWidth' );
4298
4299 // Subtract the two offsets
4300 results = {
4301 top: offset.top - parentOffset.top,
4302 left: offset.left - parentOffset.left
4303 };
4304 }
4305
4306 return results;
4307 },
4308
4309 offsetParent: function() {
4310 var offsetParent = this[0].offsetParent || document.body;
4311 while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
4312 offsetParent = offsetParent.offsetParent;
4313 return jQuery(offsetParent);
4314 }
4315});
4316
4317
4318// Create scrollLeft and scrollTop methods
4319jQuery.each( ['Left', 'Top'], function(i, name) {
4320 var method = 'scroll' + name;
4321
4322 jQuery.fn[ method ] = function(val) {
4323 if (!this[0]) return null;
4324
4325 return val !== undefined ?
4326
4327 // Set the scroll offset
4328 this.each(function() {
4329 this == window || this == document ?
4330 window.scrollTo(
4331 !i ? val : jQuery(window).scrollLeft(),
4332 i ? val : jQuery(window).scrollTop()
4333 ) :
4334 this[ method ] = val;
4335 }) :
4336
4337 // Return the scroll offset
4338 this[0] == window || this[0] == document ?
4339 self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
4340 jQuery.boxModel && document.documentElement[ method ] ||
4341 document.body[ method ] :
4342 this[0][ method ];
4343 };
4344});
4345// Create innerHeight, innerWidth, outerHeight and outerWidth methods
4346jQuery.each([ "Height", "Width" ], function(i, name){
4347
4348 var tl = i ? "Left" : "Top", // top or left
4349 br = i ? "Right" : "Bottom", // bottom or right
4350 lower = name.toLowerCase();
4351
4352 // innerHeight and innerWidth
4353 jQuery.fn["inner" + name] = function(){
4354 return this[0] ?
4355 jQuery.css( this[0], lower, false, "padding" ) :
4356 null;
4357 };
4358
4359 // outerHeight and outerWidth
4360 jQuery.fn["outer" + name] = function(margin) {
4361 return this[0] ?
4362 jQuery.css( this[0], lower, false, margin ? "margin" : "border" ) :
4363 null;
4364 };
4365
4366 var type = name.toLowerCase();
4367
4368 jQuery.fn[ type ] = function( size ) {
4369 // Get window width or height
4370 return this[0] == window ?
4371 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
4372 document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] ||
4373 document.body[ "client" + name ] :
4374
4375 // Get document width or height
4376 this[0] == document ?
4377 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
4378 Math.max(
4379 document.documentElement["client" + name],
4380 document.body["scroll" + name], document.documentElement["scroll" + name],
4381 document.body["offset" + name], document.documentElement["offset" + name]
4382 ) :
4383
4384 // Get or set width or height on the element
4385 size === undefined ?
4386 // Get width or height on the element
4387 (this.length ? jQuery.css( this[0], type ) : null) :
4388
4389 // Set the width or height on the element (default to pixels if value is unitless)
4390 this.css( type, typeof size === "string" ? size : size + "px" );
4391 };
4392
4393});
4394})();