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