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