1 (function(){2 /*3 * jQuery 1.2.6 - New Wave Javascript4 *5 * Copyright (c) 2008 John Resig (jquery.com)6 * Dual licensed under the MIT (MIT-LICENSE.txt)7 * and GPL (GPL-LICENSE.txt) licenses.8 *9 * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $10 * $Rev: 5685 $11 */1213 // Map over jQuery in case of overwrite14 var _jQuery = window.jQuery,15 // Map over the $ in case of overwrite16 _$ = window.$;1718 var jQuery = window.jQuery = window.$ = function( selector, context ) {19 // The jQuery object is actually just the init constructor 'enhanced'20 return new jQuery.fn.init( selector, context );21 };2223 // A simple way to check for HTML strings or ID strings24 // (both of which we optimize for)25 var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,2627 // Is it a simple selector28 isSimple = /^.[^:#\[\.]*$/,2930 // Will speed up references to undefined, and allows munging its name.31 undefined;3233 jQuery.fn = jQuery.prototype = {34 init: function( selector, context ) {35 // Make sure that a selection was provided36 selector = selector || document;3738 // Handle $(DOMElement)39 if ( selector.nodeType ) {40 this[0] = selector;41 this.length = 1;42 return this;43 }44 // Handle HTML strings45 if ( typeof selector == "string" ) {46 // Are we dealing with HTML string or an ID?47 var match = quickExpr.exec( selector );4849 // Verify a match, and that no context was specified for #id50 if ( match && (match[1] || !context) ) {5152 // HANDLE: $(html) -> $(array)53 if ( match[1] )54 selector = jQuery.clean( [ match[1] ], context );5556 // HANDLE: $("#id")57 else {58 var elem = document.getElementById( match[3] );5960 // Make sure an element was located61 if ( elem ){62 // Handle the case where IE and Opera return items63 // by name instead of ID64 if ( elem.id != match[3] )65 return jQuery().find( selector );6667 // Otherwise, we inject the element directly into the jQuery object68 return jQuery( elem );69 }70 selector = [];71 }7273 // HANDLE: $(expr, [context])74 // (which is just equivalent to: $(content).find(expr)75 } else76 return jQuery( context ).find( selector );7778 // HANDLE: $(function)79 // Shortcut for document ready80 } else if ( jQuery.isFunction( selector ) )81 return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );8283 return this.setArray(jQuery.makeArray(selector));84 },8586 // The current version of jQuery being used87 jquery: "1.2.6",8889 // The number of elements contained in the matched element set90 size: function() {91 return this.length;92 },9394 // The number of elements contained in the matched element set95 length: 0,9697 // Get the Nth element in the matched element set OR98 // Get the whole matched element set as a clean array99 get: function( num ) {100 return num == undefined ?101102 // Return a 'clean' array103 jQuery.makeArray( this ) :104105 // Return just the object106 this[ num ];107 },108109 // Take an array of elements and push it onto the stack110 // (returning the new matched element set)111 pushStack: function( elems ) {112 // Build a new jQuery matched element set113 var ret = jQuery( elems );114115 // Add the old object onto the stack (as a reference)116 ret.prevObject = this;117118 // Return the newly-formed element set119 return ret;120 },121122 // Force the current matched set of elements to become123 // the specified array of elements (destroying the stack in the process)124 // You should use pushStack() in order to do this, but maintain the stack125 setArray: function( elems ) {126 // Resetting the length to 0, then using the native Array push127 // is a super-fast way to populate an object with array-like properties128 this.length = 0;129 Array.prototype.push.apply( this, elems );130131 return this;132 },133134 // Execute a callback for every element in the matched set.135 // (You can seed the arguments with an array of args, but this is136 // only used internally.)137 each: function( callback, args ) {138 return jQuery.each( this, callback, args );139 },140141 // Determine the position of an element within142 // the matched set of elements143 index: function( elem ) {144 var ret = -1;145146 // Locate the position of the desired element147 return jQuery.inArray(148 // If it receives a jQuery object, the first element is used149 elem && elem.jquery ? elem[0] : elem150 , this );151 },152153 attr: function( name, value, type ) {154 var options = name;155156 // Look for the case where we're accessing a style value157 if ( name.constructor == String )158 if ( value === undefined )159 return this[0] && jQuery[ type || "attr" ]( this[0], name );160161 else {162 options = {};163 options[ name ] = value;164 }165166 // Check to see if we're setting style values167 return this.each(function(i){168 // Set all the styles169 for ( name in options )170 jQuery.attr(171 type ?172 this.style :173 this,174 name, jQuery.prop( this, options[ name ], type, i, name )175 );176 });177 },178179 css: function( key, value ) {180 // ignore negative width and height values181 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )182 value = undefined;183 return this.attr( key, value, "curCSS" );184 },185186 text: function( text ) {187 if ( typeof text != "object" && text != null )188 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );189190 var ret = "";191192 jQuery.each( text || this, function(){193 jQuery.each( this.childNodes, function(){194 if ( this.nodeType != 8 )195 ret += this.nodeType != 1 ?196 this.nodeValue :197 jQuery.fn.text( [ this ] );198 });199 });200201 return ret;202 },203204 wrapAll: function( html ) {205 if ( this[0] )206 // The elements to wrap the target around207 jQuery( html, this[0].ownerDocument )208 .clone()209 .insertBefore( this[0] )210 .map(function(){211 var elem = this;212213 while ( elem.firstChild )214 elem = elem.firstChild;215216 return elem;217 })218 .append(this);219220 return this;221 },222223 wrapInner: function( html ) {224 return this.each(function(){225 jQuery( this ).contents().wrapAll( html );226 });227 },228229 wrap: function( html ) {230 return this.each(function(){231 jQuery( this ).wrapAll( html );232 });233 },234235 append: function() {236 return this.domManip(arguments, true, false, function(elem){237 if (this.nodeType == 1)238 this.appendChild( elem );239 });240 },241242 prepend: function() {243 return this.domManip(arguments, true, true, function(elem){244 if (this.nodeType == 1)245 this.insertBefore( elem, this.firstChild );246 });247 },248249 before: function() {250 return this.domManip(arguments, false, false, function(elem){251 this.parentNode.insertBefore( elem, this );252 });253 },254255 after: function() {256 return this.domManip(arguments, false, true, function(elem){257 this.parentNode.insertBefore( elem, this.nextSibling );258 });259 },260261 end: function() {262 return this.prevObject || jQuery( [] );263 },264265 find: function( selector ) {266 var elems = jQuery.map(this, function(elem){267 return jQuery.find( selector, elem );268 });269270 return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?271 jQuery.unique( elems ) :272 elems );273 },274275 clone: function( events ) {276 // Do the clone277 var ret = this.map(function(){278 if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {279 // IE copies events bound via attachEvent when280 // using cloneNode. Calling detachEvent on the281 // clone will also remove the events from the orignal282 // In order to get around this, we use innerHTML.283 // Unfortunately, this means some modifications to284 // attributes in IE that are actually only stored285 // as properties will not be copied (such as the286 // the name attribute on an input).287 var clone = this.cloneNode(true),288 container = document.createElement("div");289 container.appendChild(clone);290 return jQuery.clean([container.innerHTML])[0];291 } else292 return this.cloneNode(true);293 });294295 // Need to set the expando to null on the cloned set if it exists296 // removeData doesn't work here, IE removes it from the original as well297 // this is primarily for IE but the data expando shouldn't be copied over in any browser298 var clone = ret.find("*").andSelf().each(function(){299 if ( this[ expando ] != undefined )300 this[ expando ] = null;301 });302303 // Copy the events from the original to the clone304 if ( events === true )305 this.find("*").andSelf().each(function(i){306 if (this.nodeType == 3)307 return;308 var events = jQuery.data( this, "events" );309310 for ( var type in events )311 for ( var handler in events[ type ] )312 jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );313 });314315 // Return the cloned set316 return ret;317 },318319 filter: function( selector ) {320 return this.pushStack(321 jQuery.isFunction( selector ) &&322 jQuery.grep(this, function(elem, i){323 return selector.call( elem, i );324 }) ||325326 jQuery.multiFilter( selector, this ) );327 },328329 not: function( selector ) {330 if ( selector.constructor == String )331 // test special case where just one selector is passed in332 if ( isSimple.test( selector ) )333 return this.pushStack( jQuery.multiFilter( selector, this, true ) );334 else335 selector = jQuery.multiFilter( selector, this );336337 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;338 return this.filter(function() {339 return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;340 });341 },342343 add: function( selector ) {344 return this.pushStack( jQuery.unique( jQuery.merge(345 this.get(),346 typeof selector == 'string' ?347 jQuery( selector ) :348 jQuery.makeArray( selector )349 )));350 },351352 is: function( selector ) {353 return !!selector && jQuery.multiFilter( selector, this ).length > 0;354 },355356 hasClass: function( selector ) {357 return this.is( "." + selector );358 },359360 val: function( value ) {361 if ( value == undefined ) {362363 if ( this.length ) {364 var elem = this[0];365366 // We need to handle select boxes special367 if ( jQuery.nodeName( elem, "select" ) ) {368 var index = elem.selectedIndex,369 values = [],370 options = elem.options,371 one = elem.type == "select-one";372373 // Nothing was selected374 if ( index < 0 )375 return null;376377 // Loop through all the selected options378 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {379 var option = options[ i ];380381 if ( option.selected ) {382 // Get the specifc value for the option383 value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;384385 // We don't need an array for one selects386 if ( one )387 return value;388389 // Multi-Selects return an array390 values.push( value );391 }392 }393394 return values;395396 // Everything else, we just grab the value397 } else398 return (this[0].value || "").replace(/\r/g, "");399400 }401402 return undefined;403 }404405 if( value.constructor == Number )406 value += '';407408 return this.each(function(){409 if ( this.nodeType != 1 )410 return;411412 if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )413 this.checked = (jQuery.inArray(this.value, value) >= 0 ||414 jQuery.inArray(this.name, value) >= 0);415416 else if ( jQuery.nodeName( this, "select" ) ) {417 var values = jQuery.makeArray(value);418419 jQuery( "option", this ).each(function(){420 this.selected = (jQuery.inArray( this.value, values ) >= 0 ||421 jQuery.inArray( this.text, values ) >= 0);422 });423424 if ( !values.length )425 this.selectedIndex = -1;426427 } else428 this.value = value;429 });430 },431432 html: function( value ) {433 return value == undefined ?434 (this[0] ?435 this[0].innerHTML :436 null) :437 this.empty().append( value );438 },439440 replaceWith: function( value ) {441 return this.after( value ).remove();442 },443444 eq: function( i ) {445 return this.slice( i, i + 1 );446 },447448 slice: function() {449 return this.pushStack( Array.prototype.slice.apply( this, arguments ) );450 },451452 map: function( callback ) {453 return this.pushStack( jQuery.map(this, function(elem, i){454 return callback.call( elem, i, elem );455 }));456 },457458 andSelf: function() {459 return this.add( this.prevObject );460 },461462 data: function( key, value ){463 var parts = key.split(".");464 parts[1] = parts[1] ? "." + parts[1] : "";465466 if ( value === undefined ) {467 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);468469 if ( data === undefined && this.length )470 data = jQuery.data( this[0], key );471472 return data === undefined && parts[1] ?473 this.data( parts[0] ) :474 data;475 } else476 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){477 jQuery.data( this, key, value );478 });479 },480481 removeData: function( key ){482 return this.each(function(){483 jQuery.removeData( this, key );484 });485 },486487 domManip: function( args, table, reverse, callback ) {488 var clone = this.length > 1, elems;489490 return this.each(function(){491 if ( !elems ) {492 elems = jQuery.clean( args, this.ownerDocument );493494 if ( reverse )495 elems.reverse();496 }497498 var obj = this;499500 if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )501 obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );502503 var scripts = jQuery( [] );504505 jQuery.each(elems, function(){506 var elem = clone ?507 jQuery( this ).clone( true )[0] :508 this;509510 // execute all scripts after the elements have been injected511 if ( jQuery.nodeName( elem, "script" ) )512 scripts = scripts.add( elem );513 else {514 // Remove any inner scripts for later evaluation515 if ( elem.nodeType == 1 )516 scripts = scripts.add( jQuery( "script", elem ).remove() );517518 // Inject the elements into the document519 callback.call( obj, elem );520 }521 });522523 scripts.each( evalScript );524 });525 }526 };527528 // Give the init function the jQuery prototype for later instantiation529 jQuery.fn.init.prototype = jQuery.fn;530531 function evalScript( i, elem ) {532 if ( elem.src )533 jQuery.ajax({534 url: elem.src,535 async: false,536 dataType: "script"537 });538539 else540 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );541542 if ( elem.parentNode )543 elem.parentNode.removeChild( elem );544 }545546 function now(){547 return +new Date;548 }549550 jQuery.extend = jQuery.fn.extend = function() {551 // copy reference to target object552 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;553554 // Handle a deep copy situation555 if ( target.constructor == Boolean ) {556 deep = target;557 target = arguments[1] || {};558 // skip the boolean and the target559 i = 2;560 }561562 // Handle case when target is a string or something (possible in deep copy)563 if ( typeof target != "object" && typeof target != "function" )564 target = {};565566 // extend jQuery itself if only one argument is passed567 if ( length == i ) {568 target = this;569 --i;570 }571572 for ( ; i < length; i++ )573 // Only deal with non-null/undefined values574 if ( (options = arguments[ i ]) != null )575 // Extend the base object576 for ( var name in options ) {577 var src = target[ name ], copy = options[ name ];578579 // Prevent never-ending loop580 if ( target === copy )581 continue;582583 // Recurse if we're merging object values584 if ( deep && copy && typeof copy == "object" && !copy.nodeType )585 target[ name ] = jQuery.extend( deep,586 // Never move original objects, clone them587 src || ( copy.length != null ? [ ] : { } )588 , copy );589590 // Don't bring in undefined values591 else if ( copy !== undefined )592 target[ name ] = copy;593594 }595596 // Return the modified object597 return target;598 };599600 var expando = "jQuery" + now(), uuid = 0, windowData = {},601 // exclude the following css properties to add px602 exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,603 // cache defaultView604 defaultView = document.defaultView || {};605606 jQuery.extend({607 noConflict: function( deep ) {608 window.$ = _$;609610 if ( deep )611 window.jQuery = _jQuery;612613 return jQuery;614 },615616 // See test/unit/core.js for details concerning this function.617 isFunction: function( fn ) {618 return !!fn && typeof fn != "string" && !fn.nodeName &&619 fn.constructor != Array && /^[\s[]?function/.test( fn + "" );620 },621622 // check if an element is in a (or is an) XML document623 isXMLDoc: function( elem ) {624 return elem.documentElement && !elem.body ||625 elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;626 },627628 // Evalulates a script in a global context629 globalEval: function( data ) {630 data = jQuery.trim( data );631632 if ( data ) {633 // Inspired by code by Andrea Giammarchi634 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html635 var head = document.getElementsByTagName("head")[0] || document.documentElement,636 script = document.createElement("script");637638 script.type = "text/javascript";639 if ( jQuery.browser.msie )640 script.text = data;641 else642 script.appendChild( document.createTextNode( data ) );643644 // Use insertBefore instead of appendChild to circumvent an IE6 bug.645 // This arises when a base node is used (#2709).646 head.insertBefore( script, head.firstChild );647 head.removeChild( script );648 }649 },650651 nodeName: function( elem, name ) {652 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();653 },654655 cache: {},656657 data: function( elem, name, data ) {658 elem = elem == window ?659 windowData :660 elem;661662 var id = elem[ expando ];663664 // Compute a unique ID for the element665 if ( !id )666 id = elem[ expando ] = ++uuid;667668 // Only generate the data cache if we're669 // trying to access or manipulate it670 if ( name && !jQuery.cache[ id ] )671 jQuery.cache[ id ] = {};672673 // Prevent overriding the named cache with undefined values674 if ( data !== undefined )675 jQuery.cache[ id ][ name ] = data;676677 // Return the named cache data, or the ID for the element678 return name ?679 jQuery.cache[ id ][ name ] :680 id;681 },682683 removeData: function( elem, name ) {684 elem = elem == window ?685 windowData :686 elem;687688 var id = elem[ expando ];689690 // If we want to remove a specific section of the element's data691 if ( name ) {692 if ( jQuery.cache[ id ] ) {693 // Remove the section of cache data694 delete jQuery.cache[ id ][ name ];695696 // If we've removed all the data, remove the element's cache697 name = "";698699 for ( name in jQuery.cache[ id ] )700 break;701702 if ( !name )703 jQuery.removeData( elem );704 }705706 // Otherwise, we want to remove all of the element's data707 } else {708 // Clean up the element expando709 try {710 delete elem[ expando ];711 } catch(e){712 // IE has trouble directly removing the expando713 // but it's ok with using removeAttribute714 if ( elem.removeAttribute )715 elem.removeAttribute( expando );716 }717718 // Completely remove the data cache719 delete jQuery.cache[ id ];720 }721 },722723 // args is for internal usage only724 each: function( object, callback, args ) {725 var name, i = 0, length = object.length;726727 if ( args ) {728 if ( length == undefined ) {729 for ( name in object )730 if ( callback.apply( object[ name ], args ) === false )731 break;732 } else733 for ( ; i < length; )734 if ( callback.apply( object[ i++ ], args ) === false )735 break;736737 // A special, fast, case for the most common use of each738 } else {739 if ( length == undefined ) {740 for ( name in object )741 if ( callback.call( object[ name ], name, object[ name ] ) === false )742 break;743 } else744 for ( var value = object[0];745 i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}746 }747748 return object;749 },750751 prop: function( elem, value, type, i, name ) {752 // Handle executable functions753 if ( jQuery.isFunction( value ) )754 value = value.call( elem, i );755756 // Handle passing in a number to a CSS property757 return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?758 value + "px" :759 value;760 },761762 className: {763 // internal only, use addClass("class")764 add: function( elem, classNames ) {765 jQuery.each((classNames || "").split(/\s+/), function(i, className){766 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )767 elem.className += (elem.className ? " " : "") + className;768 });769 },770771 // internal only, use removeClass("class")772 remove: function( elem, classNames ) {773 if (elem.nodeType == 1)774 elem.className = classNames != undefined ?775 jQuery.grep(elem.className.split(/\s+/), function(className){776 return !jQuery.className.has( classNames, className );777 }).join(" ") :778 "";779 },780781 // internal only, use hasClass("class")782 has: function( elem, className ) {783 return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;784 }785 },786787 // A method for quickly swapping in/out CSS properties to get correct calculations788 swap: function( elem, options, callback ) {789 var old = {};790 // Remember the old values, and insert the new ones791 for ( var name in options ) {792 old[ name ] = elem.style[ name ];793 elem.style[ name ] = options[ name ];794 }795796 callback.call( elem );797798 // Revert the old values799 for ( var name in options )800 elem.style[ name ] = old[ name ];801 },802803 css: function( elem, name, force ) {804 if ( name == "width" || name == "height" ) {805 var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];806807 function getWH() {808 val = name == "width" ? elem.offsetWidth : elem.offsetHeight;809 var padding = 0, border = 0;810 jQuery.each( which, function() {811 padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;812 border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;813 });814 val -= Math.round(padding + border);815 }816817 if ( jQuery(elem).is(":visible") )818 getWH();819 else820 jQuery.swap( elem, props, getWH );821822 return Math.max(0, val);823 }824825 return jQuery.curCSS( elem, name, force );826 },827828 curCSS: function( elem, name, force ) {829 var ret, style = elem.style;830831 // A helper method for determining if an element's values are broken832 function color( elem ) {833 if ( !jQuery.browser.safari )834 return false;835836 // defaultView is cached837 var ret = defaultView.getComputedStyle( elem, null );838 return !ret || ret.getPropertyValue("color") == "";839 }840841 // We need to handle opacity special in IE842 if ( name == "opacity" && jQuery.browser.msie ) {843 ret = jQuery.attr( style, "opacity" );844845 return ret == "" ?846 "1" :847 ret;848 }849 // Opera sometimes will give the wrong display answer, this fixes it, see #2037850 if ( jQuery.browser.opera && name == "display" ) {851 var save = style.outline;852 style.outline = "0 solid black";853 style.outline = save;854 }855856 // Make sure we're using the right name for getting the float value857 if ( name.match( /float/i ) )858 name = styleFloat;859860 if ( !force && style && style[ name ] )861 ret = style[ name ];862863 else if ( defaultView.getComputedStyle ) {864865 // Only "float" is needed here866 if ( name.match( /float/i ) )867 name = "float";868869 name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();870871 var computedStyle = defaultView.getComputedStyle( elem, null );872873 if ( computedStyle && !color( elem ) )874 ret = computedStyle.getPropertyValue( name );875876 // If the element isn't reporting its values properly in Safari877 // then some display: none elements are involved878 else {879 var swap = [], stack = [], a = elem, i = 0;880881 // Locate all of the parent display: none elements882 for ( ; a && color(a); a = a.parentNode )883 stack.unshift(a);884885 // Go through and make them visible, but in reverse886 // (It would be better if we knew the exact display type that they had)887 for ( ; i < stack.length; i++ )888 if ( color( stack[ i ] ) ) {889 swap[ i ] = stack[ i ].style.display;890 stack[ i ].style.display = "block";891 }892893 // Since we flip the display style, we have to handle that894 // one special, otherwise get the value895 ret = name == "display" && swap[ stack.length - 1 ] != null ?896 "none" :897 ( computedStyle && computedStyle.getPropertyValue( name ) ) || "";898899 // Finally, revert the display styles back900 for ( i = 0; i < swap.length; i++ )901 if ( swap[ i ] != null )902 stack[ i ].style.display = swap[ i ];903 }904905 // We should always get a number back from opacity906 if ( name == "opacity" && ret == "" )907 ret = "1";908909 } else if ( elem.currentStyle ) {910 var camelCase = name.replace(/\-(\w)/g, function(all, letter){911 return letter.toUpperCase();912 });913914 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];915916 // From the awesome hack by Dean Edwards917 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291918919 // If we're not dealing with a regular pixel number920 // but a number that has a weird ending, we need to convert it to pixels921 if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {922 // Remember the original values923 var left = style.left, rsLeft = elem.runtimeStyle.left;924925 // Put in the new values to get a computed value out926 elem.runtimeStyle.left = elem.currentStyle.left;927 style.left = ret || 0;928 ret = style.pixelLeft + "px";929930 // Revert the changed values931 style.left = left;932 elem.runtimeStyle.left = rsLeft;933 }934 }935936 return ret;937 },938939 clean: function( elems, context ) {940 var ret = [];941 context = context || document;942 // !context.createElement fails in IE with an error but returns typeof 'object'943 if (typeof context.createElement == 'undefined')944 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;945946 jQuery.each(elems, function(i, elem){947 if ( !elem )948 return;949950 if ( elem.constructor == Number )951 elem += '';952953 // Convert html string into DOM nodes954 if ( typeof elem == "string" ) {955 // Fix "XHTML"-style tags in all browsers956 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){957 return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?958 all :959 front + "></" + tag + ">";960 });961962 // Trim whitespace, otherwise indexOf won't work as expected963 var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");964965 var wrap =966 // option or optgroup967 !tags.indexOf("<opt") &&968 [ 1, "<select multiple='multiple'>", "</select>" ] ||969970 !tags.indexOf("<leg") &&971 [ 1, "<fieldset>", "</fieldset>" ] ||972973 tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&974 [ 1, "<table>", "</table>" ] ||975976 !tags.indexOf("<tr") &&977 [ 2, "<table><tbody>", "</tbody></table>" ] ||978979 // <thead> matched above980 (!tags.indexOf("<td") || !tags.indexOf("<th")) &&981 [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||982983 !tags.indexOf("<col") &&984 [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||985986 // IE can't serialize <link> and <script> tags normally987 jQuery.browser.msie &&988 [ 1, "div<div>", "</div>" ] ||989990 [ 0, "", "" ];991992 // Go to html and back, then peel off extra wrappers993 div.innerHTML = wrap[1] + elem + wrap[2];994995 // Move to the right depth996 while ( wrap[0]-- )997 div = div.lastChild;998999 // Remove IE's autoinserted <tbody> from table fragments1000 if ( jQuery.browser.msie ) {10011002 // String was a <table>, *may* have spurious <tbody>1003 var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?1004 div.firstChild && div.firstChild.childNodes :10051006 // String was a bare <thead> or <tfoot>1007 wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?1008 div.childNodes :1009 [];10101011 for ( var j = tbody.length - 1; j >= 0 ; --j )1012 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )1013 tbody[ j ].parentNode.removeChild( tbody[ j ] );10141015 // IE completely kills leading whitespace when innerHTML is used1016 if ( /^\s/.test( elem ) )1017 div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );10181019 }10201021 elem = jQuery.makeArray( div.childNodes );1022 }10231024 if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )1025 return;10261027 if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )1028 ret.push( elem );10291030 else1031 ret = jQuery.merge( ret, elem );10321033 });10341035 return ret;1036 },10371038 attr: function( elem, name, value ) {1039 // don't set attributes on text and comment nodes1040 if (!elem || elem.nodeType == 3 || elem.nodeType == 8)1041 return undefined;10421043 var notxml = !jQuery.isXMLDoc( elem ),1044 // Whether we are setting (or getting)1045 set = value !== undefined,1046 msie = jQuery.browser.msie;10471048 // Try to normalize/fix the name1049 name = notxml && jQuery.props[ name ] || name;10501051 // Only do all the following if this is a node (faster for style)1052 // IE elem.getAttribute passes even for style1053 if ( elem.tagName ) {10541055 // These attributes require special treatment1056 var special = /href|src|style/.test( name );10571058 // Safari mis-reports the default selected property of a hidden option1059 // Accessing the parent's selectedIndex property fixes it1060 if ( name == "selected" && jQuery.browser.safari )1061 elem.parentNode.selectedIndex;10621063 // If applicable, access the attribute via the DOM 0 way1064 if ( name in elem && notxml && !special ) {1065 if ( set ){1066 // We can't allow the type property to be changed (since it causes problems in IE)1067 if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )1068 throw "type property can't be changed";10691070 elem[ name ] = value;1071 }10721073 // browsers index elements by id/name on forms, give priority to attributes.1074 if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )1075 return elem.getAttributeNode( name ).nodeValue;10761077 return elem[ name ];1078 }10791080 if ( msie && notxml && name == "style" )1081 return jQuery.attr( elem.style, "cssText", value );10821083 if ( set )1084 // convert the value to a string (all browsers do this but IE) see #10701085 elem.setAttribute( name, "" + value );10861087 var attr = msie && notxml && special1088 // Some attributes require a special call on IE1089 ? elem.getAttribute( name, 2 )1090 : elem.getAttribute( name );10911092 // Non-existent attributes return null, we normalize to undefined1093 return attr === null ? undefined : attr;1094 }10951096 // elem is actually elem.style ... set the style10971098 // IE uses filters for opacity1099 if ( msie && name == "opacity" ) {1100 if ( set ) {1101 // IE has trouble with opacity if it does not have layout1102 // Force it by setting the zoom level1103 elem.zoom = 1;11041105 // Set the alpha filter to set the opacity1106 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +1107 (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");1108 }11091110 return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?1111 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':1112 "";1113 }11141115 name = name.replace(/-([a-z])/ig, function(all, letter){1116 return letter.toUpperCase();1117 });11181119 if ( set )1120 elem[ name ] = value;11211122 return elem[ name ];1123 },11241125 trim: function( text ) {1126 return (text || "").replace( /^\s+|\s+$/g, "" );1127 },11281129 makeArray: function( array ) {1130 var ret = [];11311132 if( array != null ){1133 var i = array.length;1134 //the window, strings and functions also have 'length'1135 if( i == null || array.split || array.setInterval || array.call )1136 ret[0] = array;1137 else1138 while( i )1139 ret[--i] = array[i];1140 }11411142 return ret;1143 },11441145 inArray: function( elem, array ) {1146 for ( var i = 0, length = array.length; i < length; i++ )1147 // Use === because on IE, window == document1148 if ( array[ i ] === elem )1149 return i;11501151 return -1;1152 },11531154 merge: function( first, second ) {1155 // We have to loop this way because IE & Opera overwrite the length1156 // expando of getElementsByTagName1157 var i = 0, elem, pos = first.length;1158 // Also, we need to make sure that the correct elements are being returned1159 // (IE returns comment nodes in a '*' query)1160 if ( jQuery.browser.msie ) {1161 while ( elem = second[ i++ ] )1162 if ( elem.nodeType != 8 )1163 first[ pos++ ] = elem;11641165 } else1166 while ( elem = second[ i++ ] )1167 first[ pos++ ] = elem;11681169 return first;1170 },11711172 unique: function( array ) {1173 var ret = [], done = {};11741175 try {11761177 for ( var i = 0, length = array.length; i < length; i++ ) {1178 var id = jQuery.data( array[ i ] );11791180 if ( !done[ id ] ) {1181 done[ id ] = true;1182 ret.push( array[ i ] );1183 }1184 }11851186 } catch( e ) {1187 ret = array;1188 }11891190 return ret;1191 },11921193 grep: function( elems, callback, inv ) {1194 var ret = [];11951196 // Go through the array, only saving the items1197 // that pass the validator function1198 for ( var i = 0, length = elems.length; i < length; i++ )1199 if ( !inv != !callback( elems[ i ], i ) )1200 ret.push( elems[ i ] );12011202 return ret;1203 },12041205 map: function( elems, callback ) {1206 var ret = [];12071208 // Go through the array, translating each of the items to their1209 // new value (or values).1210 for ( var i = 0, length = elems.length; i < length; i++ ) {1211 var value = callback( elems[ i ], i );12121213 if ( value != null )1214 ret[ ret.length ] = value;1215 }12161217 return ret.concat.apply( [], ret );1218 }1219 });12201221 var userAgent = navigator.userAgent.toLowerCase();12221223 // Figure out what browser is being used1224 jQuery.browser = {1225 version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],1226 safari: /webkit/.test( userAgent ),1227 opera: /opera/.test( userAgent ),1228 msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),1229 mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )1230 };12311232 var styleFloat = jQuery.browser.msie ?1233 "styleFloat" :1234 "cssFloat";12351236 jQuery.extend({1237 // Check to see if the W3C box model is being used1238 boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",12391240 props: {1241 "for": "htmlFor",1242 "class": "className",1243 "float": styleFloat,1244 cssFloat: styleFloat,1245 styleFloat: styleFloat,1246 readonly: "readOnly",1247 maxlength: "maxLength",1248 cellspacing: "cellSpacing"1249 }1250 });12511252 jQuery.each({1253 parent: function(elem){return elem.parentNode;},1254 parents: function(elem){return jQuery.dir(elem,"parentNode");},1255 next: function(elem){return jQuery.nth(elem,2,"nextSibling");},1256 prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},1257 nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},1258 prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},1259 siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},1260 children: function(elem){return jQuery.sibling(elem.firstChild);},1261 contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}1262 }, function(name, fn){1263 jQuery.fn[ name ] = function( selector ) {1264 var ret = jQuery.map( this, fn );12651266 if ( selector && typeof selector == "string" )1267 ret = jQuery.multiFilter( selector, ret );12681269 return this.pushStack( jQuery.unique( ret ) );1270 };1271 });12721273 jQuery.each({1274 appendTo: "append",1275 prependTo: "prepend",1276 insertBefore: "before",1277 insertAfter: "after",1278 replaceAll: "replaceWith"1279 }, function(name, original){1280 jQuery.fn[ name ] = function() {1281 var args = arguments;12821283 return this.each(function(){1284 for ( var i = 0, length = args.length; i < length; i++ )1285 jQuery( args[ i ] )[ original ]( this );1286 });1287 };1288 });12891290 jQuery.each({1291 removeAttr: function( name ) {1292 jQuery.attr( this, name, "" );1293 if (this.nodeType == 1)1294 this.removeAttribute( name );1295 },12961297 addClass: function( classNames ) {1298 jQuery.className.add( this, classNames );1299 },13001301 removeClass: function( classNames ) {1302 jQuery.className.remove( this, classNames );1303 },13041305 toggleClass: function( classNames ) {1306 jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );1307 },13081309 remove: function( selector ) {1310 if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {1311 // Prevent memory leaks1312 jQuery( "*", this ).add(this).each(function(){1313 jQuery.event.remove(this);1314 jQuery.removeData(this);1315 });1316 if (this.parentNode)1317 this.parentNode.removeChild( this );1318 }1319 },13201321 empty: function() {1322 // Remove element nodes and prevent memory leaks1323 jQuery( ">*", this ).remove();13241325 // Remove any remaining nodes1326 while ( this.firstChild )1327 this.removeChild( this.firstChild );1328 }1329 }, function(name, fn){1330 jQuery.fn[ name ] = function(){1331 return this.each( fn, arguments );1332 };1333 });13341335 jQuery.each([ "Height", "Width" ], function(i, name){1336 var type = name.toLowerCase();13371338 jQuery.fn[ type ] = function( size ) {1339 // Get window width or height1340 return this[0] == window ?1341 // Opera reports document.body.client[Width/Height] properly in both quirks and standards1342 jQuery.browser.opera && document.body[ "client" + name ] ||13431344 // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)1345 jQuery.browser.safari && window[ "inner" + name ] ||13461347 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode1348 document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :13491350 // Get document width or height1351 this[0] == document ?1352 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater1353 Math.max(1354 Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),1355 Math.max(document.body["offset" + name], document.documentElement["offset" + name])1356 ) :13571358 // Get or set width or height on the element1359 size == undefined ?1360 // Get width or height on the element1361 (this.length ? jQuery.css( this[0], type ) : null) :13621363 // Set the width or height on the element (default to pixels if value is unitless)1364 this.css( type, size.constructor == String ? size : size + "px" );1365 };1366 });13671368 // Helper function used by the dimensions and offset modules1369 function num(elem, prop) {1370 return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;1371 }var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?1372 "(?:[\\w*_-]|\\\\.)" :1373 "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",1374 quickChild = new RegExp("^>\\s*(" + chars + "+)"),1375 quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),1376 quickClass = new RegExp("^([#.]?)(" + chars + "*)");13771378 jQuery.extend({1379 expr: {1380 "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},1381 "#": function(a,i,m){return a.getAttribute("id")==m[2];},1382 ":": {1383 // Position Checks1384 lt: function(a,i,m){return i<m[3]-0;},1385 gt: function(a,i,m){return i>m[3]-0;},1386 nth: function(a,i,m){return m[3]-0==i;},1387 eq: function(a,i,m){return m[3]-0==i;},1388 first: function(a,i){return i==0;},1389 last: function(a,i,m,r){return i==r.length-1;},1390 even: function(a,i){return i%2==0;},1391 odd: function(a,i){return i%2;},13921393 // Child Checks1394 "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},1395 "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},1396 "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},13971398 // Parent Checks1399 parent: function(a){return a.firstChild;},1400 empty: function(a){return !a.firstChild;},14011402 // Text Check1403 contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},14041405 // Visibility1406 visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},1407 hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},14081409 // Form attributes1410 enabled: function(a){return !a.disabled;},1411 disabled: function(a){return a.disabled;},1412 checked: function(a){return a.checked;},1413 selected: function(a){return a.selected||jQuery.attr(a,"selected");},14141415 // Form elements1416 text: function(a){return "text"==a.type;},1417 radio: function(a){return "radio"==a.type;},1418 checkbox: function(a){return "checkbox"==a.type;},1419 file: function(a){return "file"==a.type;},1420 password: function(a){return "password"==a.type;},1421 submit: function(a){return "submit"==a.type;},1422 image: function(a){return "image"==a.type;},1423 reset: function(a){return "reset"==a.type;},1424 button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},1425 input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},14261427 // :has()1428 has: function(a,i,m){return jQuery.find(m[3],a).length;},14291430 // :header1431 header: function(a){return /h\d/i.test(a.nodeName);},14321433 // :animated1434 animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}1435 }1436 },14371438 // The regular expressions that power the parsing engine1439 parse: [1440 // Match: [@value='test'], [@foo]1441 /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,14421443 // Match: :contains('foo')1444 /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,14451446 // Match: :even, :last-child, #id, .class1447 new RegExp("^([:.#]*)(" + chars + "+)")1448 ],14491450 multiFilter: function( expr, elems, not ) {1451 var old, cur = [];14521453 while ( expr && expr != old ) {1454 old = expr;1455 var f = jQuery.filter( expr, elems, not );1456 expr = f.t.replace(/^\s*,\s*/, "" );1457 cur = not ? elems = f.r : jQuery.merge( cur, f.r );1458 }14591460 return cur;1461 },14621463 find: function( t, context ) {1464 // Quickly handle non-string expressions1465 if ( typeof t != "string" )1466 return [ t ];14671468 // check to make sure context is a DOM element or a document1469 if ( context && context.nodeType != 1 && context.nodeType != 9)1470 return [ ];14711472 // Set the correct context (if none is provided)1473 context = context || document;14741475 // Initialize the search1476 var ret = [context], done = [], last, nodeName;14771478 // Continue while a selector expression exists, and while1479 // we're no longer looping upon ourselves1480 while ( t && last != t ) {1481 var r = [];1482 last = t;14831484 t = jQuery.trim(t);14851486 var foundToken = false,14871488 // An attempt at speeding up child selectors that1489 // point to a specific element tag1490 re = quickChild,14911492 m = re.exec(t);14931494 if ( m ) {1495 nodeName = m[1].toUpperCase();14961497 // Perform our own iteration and filter1498 for ( var i = 0; ret[i]; i++ )1499 for ( var c = ret[i].firstChild; c; c = c.nextSibling )1500 if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )1501 r.push( c );15021503 ret = r;1504 t = t.replace( re, "" );1505 if ( t.indexOf(" ") == 0 ) continue;1506 foundToken = true;1507 } else {1508 re = /^([>+~])\s*(\w*)/i;15091510 if ( (m = re.exec(t)) != null ) {1511 r = [];15121513 var merge = {};1514 nodeName = m[2].toUpperCase();1515 m = m[1];15161517 for ( var j = 0, rl = ret.length; j < rl; j++ ) {1518 var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;1519 for ( ; n; n = n.nextSibling )1520 if ( n.nodeType == 1 ) {1521 var id = jQuery.data(n);15221523 if ( m == "~" && merge[id] ) break;15241525 if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {1526 if ( m == "~" ) merge[id] = true;1527 r.push( n );1528 }15291530 if ( m == "+" ) break;1531 }1532 }15331534 ret = r;15351536 // And remove the token1537 t = jQuery.trim( t.replace( re, "" ) );1538 foundToken = true;1539 }1540 }15411542 // See if there's still an expression, and that we haven't already1543 // matched a token1544 if ( t && !foundToken ) {1545 // Handle multiple expressions1546 if ( !t.indexOf(",") ) {1547 // Clean the result set1548 if ( context == ret[0] ) ret.shift();15491550 // Merge the result sets1551 done = jQuery.merge( done, ret );15521553 // Reset the context1554 r = ret = [context];15551556 // Touch up the selector string1557 t = " " + t.substr(1,t.length);15581559 } else {1560 // Optimize for the case nodeName#idName1561 var re2 = quickID;1562 var m = re2.exec(t);15631564 // Re-organize the results, so that they're consistent1565 if ( m ) {1566 m = [ 0, m[2], m[3], m[1] ];15671568 } else {1569 // Otherwise, do a traditional filter check for1570 // ID, class, and element selectors1571 re2 = quickClass;1572 m = re2.exec(t);1573 }15741575 m[2] = m[2].replace(/\\/g, "");15761577 var elem = ret[ret.length-1];15781579 // Try to do a global search by ID, where we can1580 if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {1581 // Optimization for HTML document case1582 var oid = elem.getElementById(m[2]);15831584 // Do a quick check for the existence of the actual ID attribute1585 // to avoid selecting by the name attribute in IE1586 // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form1587 if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )1588 oid = jQuery('[@id="'+m[2]+'"]', elem)[0];15891590 // Do a quick check for node name (where applicable) so1591 // that div#foo searches will be really fast1592 ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];1593 } else {1594 // We need to find all descendant elements1595 for ( var i = 0; ret[i]; i++ ) {1596 // Grab the tag name being searched for1597 var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];15981599 // Handle IE7 being really dumb about <object>s1600 if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )1601 tag = "param";16021603 r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));1604 }16051606 // It's faster to filter by class and be done with it1607 if ( m[1] == "." )1608 r = jQuery.classFilter( r, m[2] );16091610 // Same with ID filtering1611 if ( m[1] == "#" ) {1612 var tmp = [];16131614 // Try to find the element with the ID1615 for ( var i = 0; r[i]; i++ )1616 if ( r[i].getAttribute("id") == m[2] ) {1617 tmp = [ r[i] ];1618 break;1619 }16201621 r = tmp;1622 }16231624 ret = r;1625 }16261627 t = t.replace( re2, "" );1628 }16291630 }16311632 // If a selector string still exists1633 if ( t ) {1634 // Attempt to filter it1635 var val = jQuery.filter(t,r);1636 ret = r = val.r;1637 t = jQuery.trim(val.t);1638 }1639 }16401641 // An error occurred with the selector;1642 // just return an empty set instead1643 if ( t )1644 ret = [];16451646 // Remove the root context1647 if ( ret && context == ret[0] )1648 ret.shift();16491650 // And combine the results1651 done = jQuery.merge( done, ret );16521653 return done;1654 },16551656 classFilter: function(r,m,not){1657 m = " " + m + " ";1658 var tmp = [];1659 for ( var i = 0; r[i]; i++ ) {1660 var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;1661 if ( !not && pass || not && !pass )1662 tmp.push( r[i] );1663 }1664 return tmp;1665 },16661667 filter: function(t,r,not) {1668 var last;16691670 // Look for common filter expressions1671 while ( t && t != last ) {1672 last = t;16731674 var p = jQuery.parse, m;16751676 for ( var i = 0; p[i]; i++ ) {1677 m = p[i].exec( t );16781679 if ( m ) {1680 // Remove what we just matched1681 t = t.substring( m[0].length );16821683 m[2] = m[2].replace(/\\/g, "");1684 break;1685 }1686 }16871688 if ( !m )1689 break;16901691 // :not() is a special case that can be optimized by1692 // keeping it out of the expression list1693 if ( m[1] == ":" && m[2] == "not" )1694 // optimize if only one selector found (most common case)1695 r = isSimple.test( m[3] ) ?1696 jQuery.filter(m[3], r, true).r :1697 jQuery( r ).not( m[3] );16981699 // We can get a big speed boost by filtering by class here1700 else if ( m[1] == "." )1701 r = jQuery.classFilter(r, m[2], not);17021703 else if ( m[1] == "[" ) {1704 var tmp = [], type = m[3];17051706 for ( var i = 0, rl = r.length; i < rl; i++ ) {1707 var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];17081709 if ( z == null || /href|src|selected/.test(m[2]) )1710 z = jQuery.attr(a,m[2]) || '';17111712 if ( (type == "" && !!z ||1713 type == "=" && z == m[5] ||1714 type == "!=" && z != m[5] ||1715 type == "^=" && z && !z.indexOf(m[5]) ||1716 type == "$=" && z.substr(z.length - m[5].length) == m[5] ||1717 (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )1718 tmp.push( a );1719 }17201721 r = tmp;17221723 // We can get a speed boost by handling nth-child here1724 } else if ( m[1] == ":" && m[2] == "nth-child" ) {1725 var merge = {}, tmp = [],1726 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'1727 test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(1728 m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||1729 !/\D/.test(m[3]) && "0n+" + m[3] || m[3]),1730 // calculate the numbers (first)n+(last) including if they are negative1731 first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;17321733 // loop through all the elements left in the jQuery object1734 for ( var i = 0, rl = r.length; i < rl; i++ ) {1735 var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);17361737 if ( !merge[id] ) {1738 var c = 1;17391740 for ( var n = parentNode.firstChild; n; n = n.nextSibling )1741 if ( n.nodeType == 1 )1742 n.nodeIndex = c++;17431744 merge[id] = true;1745 }17461747 var add = false;17481749 if ( first == 0 ) {1750 if ( node.nodeIndex == last )1751 add = true;1752 } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )1753 add = true;17541755 if ( add ^ not )1756 tmp.push( node );1757 }17581759 r = tmp;17601761 // Otherwise, find the expression to execute1762 } else {1763 var fn = jQuery.expr[ m[1] ];1764 if ( typeof fn == "object" )1765 fn = fn[ m[2] ];17661767 if ( typeof fn == "string" )1768 fn = eval("false||function(a,i){return " + fn + ";}");17691770 // Execute it against the current filter1771 r = jQuery.grep( r, function(elem, i){1772 return fn(elem, i, m, r);1773 }, not );1774 }1775 }17761777 // Return an array of filtered elements (r)1778 // and the modified expression string (t)1779 return { r: r, t: t };1780 },17811782 dir: function( elem, dir ){1783 var matched = [],1784 cur = elem[dir];1785 while ( cur && cur != document ) {1786 if ( cur.nodeType == 1 )1787 matched.push( cur );1788 cur = cur[dir];1789 }1790 return matched;1791 },17921793 nth: function(cur,result,dir,elem){1794 result = result || 1;1795 var num = 0;17961797 for ( ; cur; cur = cur[dir] )1798 if ( cur.nodeType == 1 && ++num == result )1799 break;18001801 return cur;1802 },18031804 sibling: function( n, elem ) {1805 var r = [];18061807 for ( ; n; n = n.nextSibling ) {1808 if ( n.nodeType == 1 && n != elem )1809 r.push( n );1810 }18111812 return r;1813 }1814 });1815 /*1816 * A number of helper functions used for managing events.1817 * Many of the ideas behind this code orignated from1818 * Dean Edwards' addEvent library.1819 */1820 jQuery.event = {18211822 // Bind an event to an element1823 // Original by Dean Edwards1824 add: function(elem, types, handler, data) {1825 if ( elem.nodeType == 3 || elem.nodeType == 8 )1826 return;18271828 // For whatever reason, IE has trouble passing the window object1829 // around, causing it to be cloned in the process1830 if ( jQuery.browser.msie && elem.setInterval )1831 elem = window;18321833 // Make sure that the function being executed has a unique ID1834 if ( !handler.guid )1835 handler.guid = this.guid++;18361837 // if data is passed, bind to handler1838 if( data != undefined ) {1839 // Create temporary function pointer to original handler1840 var fn = handler;18411842 // Create unique handler function, wrapped around original handler1843 handler = this.proxy( fn, function() {1844 // Pass arguments and context to original handler1845 return fn.apply(this, arguments);1846 });18471848 // Store data in unique handler1849 handler.data = data;1850 }18511852 // Init the element's event structure1853 var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),1854 handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){1855 // Handle the second event of a trigger and when1856 // an event is called after a page has unloaded1857 if ( typeof jQuery != "undefined" && !jQuery.event.triggered )1858 return jQuery.event.handle.apply(arguments.callee.elem, arguments);1859 });1860 // Add elem as a property of the handle function1861 // This is to prevent a memory leak with non-native1862 // event in IE.1863 handle.elem = elem;18641865 // Handle multiple events separated by a space1866 // jQuery(...).bind("mouseover mouseout", fn);1867 jQuery.each(types.split(/\s+/), function(index, type) {1868 // Namespaced event handlers1869 var parts = type.split(".");1870 type = parts[0];1871 handler.type = parts[1];18721873 // Get the current list of functions bound to this event1874 var handlers = events[type];18751876 // Init the event handler queue1877 if (!handlers) {1878 handlers = events[type] = {};18791880 // Check for a special event handler1881 // Only use addEventListener/attachEvent if the special1882 // events handler returns false1883 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {1884 // Bind the global event handler to the element1885 if (elem.addEventListener)1886 elem.addEventListener(type, handle, false);1887 else if (elem.attachEvent)1888 elem.attachEvent("on" + type, handle);1889 }1890 }18911892 // Add the function to the element's handler list1893 handlers[handler.guid] = handler;18941895 // Keep track of which events have been used, for global triggering1896 jQuery.event.global[type] = true;1897 });18981899 // Nullify elem to prevent memory leaks in IE1900 elem = null;1901 },19021903 guid: 1,1904 global: {},19051906 // Detach an event or set of events from an element1907 remove: function(elem, types, handler) {1908 // don't do events on text and comment nodes1909 if ( elem.nodeType == 3 || elem.nodeType == 8 )1910 return;19111912 var events = jQuery.data(elem, "events"), ret, index;19131914 if ( events ) {1915 // Unbind all events for the element1916 if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )1917 for ( var type in events )1918 this.remove( elem, type + (types || "") );1919 else {1920 // types is actually an event object here1921 if ( types.type ) {1922 handler = types.handler;1923 types = types.type;1924 }19251926 // Handle multiple events seperated by a space1927 // jQuery(...).unbind("mouseover mouseout", fn);1928 jQuery.each(types.split(/\s+/), function(index, type){1929 // Namespaced event handlers1930 var parts = type.split(".");1931 type = parts[0];19321933 if ( events[type] ) {1934 // remove the given handler for the given type1935 if ( handler )1936 delete events[type][handler.guid];19371938 // remove all handlers for the given type1939 else1940 for ( handler in events[type] )1941 // Handle the removal of namespaced events1942 if ( !parts[1] || events[type][handler].type == parts[1] )1943 delete events[type][handler];19441945 // remove generic event handler if no more handlers exist1946 for ( ret in events[type] ) break;1947 if ( !ret ) {1948 if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {1949 if (elem.removeEventListener)1950 elem.removeEventListener(type, jQuery.data(elem, "handle"), false);1951 else if (elem.detachEvent)1952 elem.detachEvent("on" + type, jQuery.data(elem, "handle"));1953 }1954 ret = null;1955 delete events[type];1956 }1957 }1958 });1959 }19601961 // Remove the expando if it's no longer used1962 for ( ret in events ) break;1963 if ( !ret ) {1964 var handle = jQuery.data( elem, "handle" );1965 if ( handle ) handle.elem = null;1966 jQuery.removeData( elem, "events" );1967 jQuery.removeData( elem, "handle" );1968 }1969 }1970 },19711972 trigger: function(type, data, elem, donative, extra) {1973 // Clone the incoming data, if any1974 data = jQuery.makeArray(data);19751976 if ( type.indexOf("!") >= 0 ) {1977 type = type.slice(0, -1);1978 var exclusive = true;1979 }19801981 // Handle a global trigger1982 if ( !elem ) {1983 // Only trigger if we've ever bound an event for it1984 if ( this.global[type] )1985 jQuery("*").add([window, document]).trigger(type, data);19861987 // Handle triggering a single element1988 } else {1989 // don't do events on text and comment nodes1990 if ( elem.nodeType == 3 || elem.nodeType == 8 )1991 return undefined;19921993 var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),1994 // Check to see if we need to provide a fake event, or not1995 event = !data[0] || !data[0].preventDefault;19961997 // Pass along a fake event1998 if ( event ) {1999 data.unshift({2000 type: type,2001 target: elem,2002 preventDefault: function(){},2003 stopPropagation: function(){},2004 timeStamp: now()2005 });2006 data[0][expando] = true; // no need to fix fake event2007 }20082009 // Enforce the right trigger type2010 data[0].type = type;2011 if ( exclusive )2012 data[0].exclusive = true;20132014 // Trigger the event, it is assumed that "handle" is a function2015 var handle = jQuery.data(elem, "handle");2016 if ( handle )2017 val = handle.apply( elem, data );20182019 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)2020 if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )2021 val = false;20222023 // Extra functions don't get the custom event object2024 if ( event )2025 data.shift();20262027 // Handle triggering of extra function2028 if ( extra && jQuery.isFunction( extra ) ) {2029 // call the extra function and tack the current return value on the end for possible inspection2030 ret = extra.apply( elem, val == null ? data : data.concat( val ) );2031 // if anything is returned, give it precedence and have it overwrite the previous value2032 if (ret !== undefined)2033 val = ret;2034 }20352036 // Trigger the native events (except for clicks on links)2037 if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {2038 this.triggered = true;2039 try {2040 elem[ type ]();2041 // prevent IE from throwing an error for some hidden elements2042 } catch (e) {}2043 }20442045 this.triggered = false;2046 }20472048 return val;2049 },20502051 handle: function(event) {2052 // returned undefined or false2053 var val, ret, namespace, all, handlers;20542055 event = arguments[0] = jQuery.event.fix( event || window.event );20562057 // Namespaced event handlers2058 namespace = event.type.split(".");2059 event.type = namespace[0];2060 namespace = namespace[1];2061 // Cache this now, all = true means, any handler2062 all = !namespace && !event.exclusive;20632064 handlers = ( jQuery.data(this, "events") || {} )[event.type];20652066 for ( var j in handlers ) {2067 var handler = handlers[j];20682069 // Filter the functions by class2070 if ( all || handler.type == namespace ) {2071 // Pass in a reference to the handler function itself2072 // So that we can later remove it2073 event.handler = handler;2074 event.data = handler.data;20752076 ret = handler.apply( this, arguments );20772078 if ( val !== false )2079 val = ret;20802081 if ( ret === false ) {2082 event.preventDefault();2083 event.stopPropagation();2084 }2085 }2086 }20872088 return val;2089 },20902091 fix: function(event) {2092 if ( event[expando] == true )2093 return event;20942095 // store a copy of the original event object2096 // and "clone" to set read-only properties2097 var originalEvent = event;2098 event = { originalEvent: originalEvent };2099 var 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 timeStamp toElement type view wheelDelta which".split(" ");2100 for ( var i=props.length; i; i-- )2101 event[ props[i] ] = originalEvent[ props[i] ];21022103 // Mark it as fixed2104 event[expando] = true;21052106 // add preventDefault and stopPropagation since2107 // they will not work on the clone2108 event.preventDefault = function() {2109 // if preventDefault exists run it on the original event2110 if (originalEvent.preventDefault)2111 originalEvent.preventDefault();2112 // otherwise set the returnValue property of the original event to false (IE)2113 originalEvent.returnValue = false;2114 };2115 event.stopPropagation = function() {2116 // if stopPropagation exists run it on the original event2117 if (originalEvent.stopPropagation)2118 originalEvent.stopPropagation();2119 // otherwise set the cancelBubble property of the original event to true (IE)2120 originalEvent.cancelBubble = true;2121 };21222123 // Fix timeStamp2124 event.timeStamp = event.timeStamp || now();21252126 // Fix target property, if necessary2127 if ( !event.target )2128 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either21292130 // check if target is a textnode (safari)2131 if ( event.target.nodeType == 3 )2132 event.target = event.target.parentNode;21332134 // Add relatedTarget, if necessary2135 if ( !event.relatedTarget && event.fromElement )2136 event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;21372138 // Calculate pageX/Y if missing and clientX/Y available2139 if ( event.pageX == null && event.clientX != null ) {2140 var doc = document.documentElement, body = document.body;2141 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);2142 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);2143 }21442145 // Add which for key events2146 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )2147 event.which = event.charCode || event.keyCode;21482149 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)2150 if ( !event.metaKey && event.ctrlKey )2151 event.metaKey = event.ctrlKey;21522153 // Add which for click: 1 == left; 2 == middle; 3 == right2154 // Note: button is not normalized, so don't use it2155 if ( !event.which && event.button )2156 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));21572158 return event;2159 },21602161 proxy: function( fn, proxy ){2162 // Set the guid of unique handler to the same of original handler, so it can be removed2163 proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;2164 // So proxy can be declared as an argument2165 return proxy;2166 },21672168 special: {2169 ready: {2170 setup: function() {2171 // Make sure the ready event is setup2172 bindReady();2173 return;2174 },21752176 teardown: function() { return; }2177 },21782179 mouseenter: {2180 setup: function() {2181 if ( jQuery.browser.msie ) return false;2182 jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);2183 return true;2184 },21852186 teardown: function() {2187 if ( jQuery.browser.msie ) return false;2188 jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);2189 return true;2190 },21912192 handler: function(event) {2193 // If we actually just moused on to a sub-element, ignore it2194 if ( withinElement(event, this) ) return true;2195 // Execute the right handlers by setting the event type to mouseenter2196 event.type = "mouseenter";2197 return jQuery.event.handle.apply(this, arguments);2198 }2199 },22002201 mouseleave: {2202 setup: function() {2203 if ( jQuery.browser.msie ) return false;2204 jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);2205 return true;2206 },22072208 teardown: function() {2209 if ( jQuery.browser.msie ) return false;2210 jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);2211 return true;2212 },22132214 handler: function(event) {2215 // If we actually just moused on to a sub-element, ignore it2216 if ( withinElement(event, this) ) return true;2217 // Execute the right handlers by setting the event type to mouseleave2218 event.type = "mouseleave";2219 return jQuery.event.handle.apply(this, arguments);2220 }2221 }2222 }2223 };22242225 jQuery.fn.extend({2226 bind: function( type, data, fn ) {2227 return type == "unload" ? this.one(type, data, fn) : this.each(function(){2228 jQuery.event.add( this, type, fn || data, fn && data );2229 });2230 },22312232 one: function( type, data, fn ) {2233 var one = jQuery.event.proxy( fn || data, function(event) {2234 jQuery(this).unbind(event, one);2235 return (fn || data).apply( this, arguments );2236 });2237 return this.each(function(){2238 jQuery.event.add( this, type, one, fn && data);2239 });2240 },22412242 unbind: function( type, fn ) {2243 return this.each(function(){2244 jQuery.event.remove( this, type, fn );2245 });2246 },22472248 trigger: function( type, data, fn ) {2249 return this.each(function(){2250 jQuery.event.trigger( type, data, this, true, fn );2251 });2252 },22532254 triggerHandler: function( type, data, fn ) {2255 return this[0] && jQuery.event.trigger( type, data, this[0], false, fn );2256 },22572258 toggle: function( fn ) {2259 // Save reference to arguments for access in closure2260 var args = arguments, i = 1;22612262 // link all the functions, so any of them can unbind this click handler2263 while( i < args.length )2264 jQuery.event.proxy( fn, args[i++] );22652266 return this.click( jQuery.event.proxy( fn, function(event) {2267 // Figure out which function to execute2268 this.lastToggle = ( this.lastToggle || 0 ) % i;22692270 // Make sure that clicks stop2271 event.preventDefault();22722273 // and execute the function2274 return args[ this.lastToggle++ ].apply( this, arguments ) || false;2275 }));2276 },22772278 hover: function(fnOver, fnOut) {2279 return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);2280 },22812282 ready: function(fn) {2283 // Attach the listeners2284 bindReady();22852286 // If the DOM is already ready2287 if ( jQuery.isReady )2288 // Execute the function immediately2289 fn.call( document, jQuery );22902291 // Otherwise, remember the function for later2292 else2293 // Add the function to the wait list2294 jQuery.readyList.push( function() { return fn.call(this, jQuery); } );22952296 return this;2297 }2298 });22992300 jQuery.extend({2301 isReady: false,2302 readyList: [],2303 // Handle when the DOM is ready2304 ready: function() {2305 // Make sure that the DOM is not already loaded2306 if ( !jQuery.isReady ) {2307 // Remember that the DOM is ready2308 jQuery.isReady = true;23092310 // If there are functions bound, to execute2311 if ( jQuery.readyList ) {2312 // Execute all of them2313 jQuery.each( jQuery.readyList, function(){2314 this.call( document );2315 });23162317 // Reset the list of functions2318 jQuery.readyList = null;2319 }23202321 // Trigger any bound ready events2322 jQuery(document).triggerHandler("ready");2323 }2324 }2325 });23262327 var readyBound = false;23282329 function bindReady(){2330 if ( readyBound ) return;2331 readyBound = true;23322333 // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event2334 if ( document.addEventListener && !jQuery.browser.opera)2335 // Use the handy event callback2336 document.addEventListener( "DOMContentLoaded", jQuery.ready, false );23372338 // If IE is used and is not in a frame2339 // Continually check to see if the document is ready2340 if ( jQuery.browser.msie && window == top ) (function(){2341 if (jQuery.isReady) return;2342 try {2343 // If IE is used, use the trick by Diego Perini2344 // http://javascript.nwbox.com/IEContentLoaded/2345 document.documentElement.doScroll("left");2346 } catch( error ) {2347 setTimeout( arguments.callee, 0 );2348 return;2349 }2350 // and execute any waiting functions2351 jQuery.ready();2352 })();23532354 if ( jQuery.browser.opera )2355 document.addEventListener( "DOMContentLoaded", function () {2356 if (jQuery.isReady) return;2357 for (var i = 0; i < document.styleSheets.length; i++)2358 if (document.styleSheets[i].disabled) {2359 setTimeout( arguments.callee, 0 );2360 return;2361 }2362 // and execute any waiting functions2363 jQuery.ready();2364 }, false);23652366 if ( jQuery.browser.safari ) {2367 var numStyles;2368 (function(){2369 if (jQuery.isReady) return;2370 if ( document.readyState != "loaded" && document.readyState != "complete" ) {2371 setTimeout( arguments.callee, 0 );2372 return;2373 }2374 if ( numStyles === undefined )2375 numStyles = jQuery("style, link[rel=stylesheet]").length;2376 if ( document.styleSheets.length != numStyles ) {2377 setTimeout( arguments.callee, 0 );2378 return;2379 }2380 // and execute any waiting functions2381 jQuery.ready();2382 })();2383 }23842385 // A fallback to window.onload, that will always work2386 jQuery.event.add( window, "load", jQuery.ready );2387 }23882389 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +2390 "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +2391 "submit,keydown,keypress,keyup,error").split(","), function(i, name){23922393 // Handle event binding2394 jQuery.fn[name] = function(fn){2395 return fn ? this.bind(name, fn) : this.trigger(name);2396 };2397 });23982399 // Checks if an event happened on an element within another element2400 // Used in jQuery.event.special.mouseenter and mouseleave handlers2401 var withinElement = function(event, elem) {2402 // Check if mouse(over|out) are still within the same parent element2403 var parent = event.relatedTarget;2404 // Traverse up the tree2405 while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }2406 // Return true if we actually just moused on to a sub-element2407 return parent == elem;2408 };24092410 // Prevent memory leaks in IE2411 // And prevent errors on refresh with events like mouseover in other browsers2412 // Window isn't included so as not to unbind existing unload events2413 jQuery(window).bind("unload", function() {2414 jQuery("*").add(document).unbind();2415 });2416 jQuery.fn.extend({2417 // Keep a copy of the old load2418 _load: jQuery.fn.load,24192420 load: function( url, params, callback ) {2421 if ( typeof url != 'string' )2422 return this._load( url );24232424 var off = url.indexOf(" ");2425 if ( off >= 0 ) {2426 var selector = url.slice(off, url.length);2427 url = url.slice(0, off);2428 }24292430 callback = callback || function(){};24312432 // Default to a GET request2433 var type = "GET";24342435 // If the second parameter was provided2436 if ( params )2437 // If it's a function2438 if ( jQuery.isFunction( params ) ) {2439 // We assume that it's the callback2440 callback = params;2441 params = null;24422443 // Otherwise, build a param string2444 } else {2445 params = jQuery.param( params );2446 type = "POST";2447 }24482449 var self = this;24502451 // Request the remote document2452 jQuery.ajax({2453 url: url,2454 type: type,2455 dataType: "html",2456 data: params,2457 complete: function(res, status){2458 // If successful, inject the HTML into all the matched elements2459 if ( status == "success" || status == "notmodified" )2460 // See if a selector was specified2461 self.html( selector ?2462 // Create a dummy div to hold the results2463 jQuery("<div/>")2464 // inject the contents of the document in, removing the scripts2465 // to avoid any 'Permission Denied' errors in IE2466 .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))24672468 // Locate the specified elements2469 .find(selector) :24702471 // If not, just inject the full result2472 res.responseText );24732474 self.each( callback, [res.responseText, status, res] );2475 }2476 });2477 return this;2478 },24792480 serialize: function() {2481 return jQuery.param(this.serializeArray());2482 },2483 serializeArray: function() {2484 return this.map(function(){2485 return jQuery.nodeName(this, "form") ?2486 jQuery.makeArray(this.elements) : this;2487 })2488 .filter(function(){2489 return this.name && !this.disabled &&2490 (this.checked || /select|textarea/i.test(this.nodeName) ||2491 /text|hidden|password/i.test(this.type));2492 })2493 .map(function(i, elem){2494 var val = jQuery(this).val();2495 return val == null ? null :2496 val.constructor == Array ?2497 jQuery.map( val, function(val, i){2498 return {name: elem.name, value: val};2499 }) :2500 {name: elem.name, value: val};2501 }).get();2502 }2503 });25042505 // Attach a bunch of functions for handling common AJAX events2506 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){2507 jQuery.fn[o] = function(f){2508 return this.bind(o, f);2509 };2510 });25112512 var jsc = now();25132514 jQuery.extend({2515 get: function( url, data, callback, type ) {2516 // shift arguments if data argument was ommited2517 if ( jQuery.isFunction( data ) ) {2518 callback = data;2519 data = null;2520 }25212522 return jQuery.ajax({2523 type: "GET",2524 url: url,2525 data: data,2526 success: callback,2527 dataType: type2528 });2529 },25302531 getScript: function( url, callback ) {2532 return jQuery.get(url, null, callback, "script");2533 },25342535 getJSON: function( url, data, callback ) {2536 return jQuery.get(url, data, callback, "json");2537 },25382539 post: function( url, data, callback, type ) {2540 if ( jQuery.isFunction( data ) ) {2541 callback = data;2542 data = {};2543 }25442545 return jQuery.ajax({2546 type: "POST",2547 url: url,2548 data: data,2549 success: callback,2550 dataType: type2551 });2552 },25532554 ajaxSetup: function( settings ) {2555 jQuery.extend( jQuery.ajaxSettings, settings );2556 },25572558 ajaxSettings: {2559 url: location.href,2560 global: true,2561 type: "GET",2562 timeout: 0,2563 contentType: "application/x-www-form-urlencoded",2564 processData: true,2565 async: true,2566 data: null,2567 username: null,2568 password: null,2569 accepts: {2570 xml: "application/xml, text/xml",2571 html: "text/html",2572 script: "text/javascript, application/javascript",2573 json: "application/json, text/javascript",2574 text: "text/plain",2575 _default: "*/*"2576 }2577 },25782579 // Last-Modified header cache for next request2580 lastModified: {},25812582 ajax: function( s ) {2583 // Extend the settings, but re-extend 's' so that it can be2584 // checked again later (in the test suite, specifically)2585 s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));25862587 var jsonp, jsre = /=\?(&|$)/g, status, data,2588 type = s.type.toUpperCase();25892590 // convert data if not already a string2591 if ( s.data && s.processData && typeof s.data != "string" )2592 s.data = jQuery.param(s.data);25932594 // Handle JSONP Parameter Callbacks2595 if ( s.dataType == "jsonp" ) {2596 if ( type == "GET" ) {2597 if ( !s.url.match(jsre) )2598 s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";2599 } else if ( !s.data || !s.data.match(jsre) )2600 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";2601 s.dataType = "json";2602 }26032604 // Build temporary JSONP function2605 if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {2606 jsonp = "jsonp" + jsc++;26072608 // Replace the =? sequence both in the query string and the data2609 if ( s.data )2610 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");2611 s.url = s.url.replace(jsre, "=" + jsonp + "$1");26122613 // We need to make sure2614 // that a JSONP style response is executed properly2615 s.dataType = "script";26162617 // Handle JSONP-style loading2618 window[ jsonp ] = function(tmp){2619 data = tmp;2620 success();2621 complete();2622 // Garbage collect2623 window[ jsonp ] = undefined;2624 try{ delete window[ jsonp ]; } catch(e){}2625 if ( head )2626 head.removeChild( script );2627 };2628 }26292630 if ( s.dataType == "script" && s.cache == null )2631 s.cache = false;26322633 if ( s.cache === false && type == "GET" ) {2634 var ts = now();2635 // try replacing _= if it is there2636 var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");2637 // if nothing was replaced, add timestamp to the end2638 s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");2639 }26402641 // If data is available, append data to url for get requests2642 if ( s.data && type == "GET" ) {2643 s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;26442645 // IE likes to send both get and post data, prevent this2646 s.data = null;2647 }26482649 // Watch for a new set of requests2650 if ( s.global && ! jQuery.active++ )2651 jQuery.event.trigger( "ajaxStart" );26522653 // Matches an absolute URL, and saves the domain2654 var remote = /^(?:\w+:)?\/\/([^\/?#]+)/;26552656 // If we're requesting a remote document2657 // and trying to load JSON or Script with a GET2658 if ( s.dataType == "script" && type == "GET"2659 && remote.test(s.url) && remote.exec(s.url)[1] != location.host ){2660 var head = document.getElementsByTagName("head")[0];2661 var script = document.createElement("script");2662 script.src = s.url;2663 if (s.scriptCharset)2664 script.charset = s.scriptCharset;26652666 // Handle Script loading2667 if ( !jsonp ) {2668 var done = false;26692670 // Attach handlers for all browsers2671 script.onload = script.onreadystatechange = function(){2672 if ( !done && (!this.readyState ||2673 this.readyState == "loaded" || this.readyState == "complete") ) {2674 done = true;2675 success();2676 complete();2677 head.removeChild( script );2678 }2679 };2680 }26812682 head.appendChild(script);26832684 // We handle everything using the script element injection2685 return undefined;2686 }26872688 var requestDone = false;26892690 // Create the request object; Microsoft failed to properly2691 // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available2692 var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();26932694 // Open the socket2695 // Passing null username, generates a login popup on Opera (#2865)2696 if( s.username )2697 xhr.open(type, s.url, s.async, s.username, s.password);2698 else2699 xhr.open(type, s.url, s.async);27002701 // Need an extra try/catch for cross domain requests in Firefox 32702 try {2703 // Set the correct header, if data is being sent2704 if ( s.data )2705 xhr.setRequestHeader("Content-Type", s.contentType);27062707 // Set the If-Modified-Since header, if ifModified mode.2708 if ( s.ifModified )2709 xhr.setRequestHeader("If-Modified-Since",2710 jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );27112712 // Set header so the called script knows that it's an XMLHttpRequest2713 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");27142715 // Set the Accepts header for the server, depending on the dataType2716 xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?2717 s.accepts[ s.dataType ] + ", */*" :2718 s.accepts._default );2719 } catch(e){}27202721 // Allow custom headers/mimetypes2722 if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {2723 // cleanup active request counter2724 s.global && jQuery.active--;2725 // close opended socket2726 xhr.abort();2727 return false;2728 }27292730 if ( s.global )2731 jQuery.event.trigger("ajaxSend", [xhr, s]);27322733 // Wait for a response to come back2734 var onreadystatechange = function(isTimeout){2735 // The transfer is complete and the data is available, or the request timed out2736 if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {2737 requestDone = true;27382739 // clear poll interval2740 if (ival) {2741 clearInterval(ival);2742 ival = null;2743 }27442745 status = isTimeout == "timeout" && "timeout" ||2746 !jQuery.httpSuccess( xhr ) && "error" ||2747 s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" ||2748 "success";27492750 if ( status == "success" ) {2751 // Watch for, and catch, XML document parse errors2752 try {2753 // process the data (runs the xml through httpData regardless of callback)2754 data = jQuery.httpData( xhr, s.dataType, s.dataFilter );2755 } catch(e) {2756 status = "parsererror";2757 }2758 }27592760 // Make sure that the request was successful or notmodified2761 if ( status == "success" ) {2762 // Cache Last-Modified header, if ifModified mode.2763 var modRes;2764 try {2765 modRes = xhr.getResponseHeader("Last-Modified");2766 } catch(e) {} // swallow exception thrown by FF if header is not available27672768 if ( s.ifModified && modRes )2769 jQuery.lastModified[s.url] = modRes;27702771 // JSONP handles its own success callback2772 if ( !jsonp )2773 success();2774 } else2775 jQuery.handleError(s, xhr, status);27762777 // Fire the complete handlers2778 complete();27792780 // Stop memory leaks2781 if ( s.async )2782 xhr = null;2783 }2784 };27852786 if ( s.async ) {2787 // don't attach the handler to the request, just poll it instead2788 var ival = setInterval(onreadystatechange, 13);27892790 // Timeout checker2791 if ( s.timeout > 0 )2792 setTimeout(function(){2793 // Check to see if the request is still happening2794 if ( xhr ) {2795 // Cancel the request2796 xhr.abort();27972798 if( !requestDone )2799 onreadystatechange( "timeout" );2800 }2801 }, s.timeout);2802 }28032804 // Send the data2805 try {2806 xhr.send(s.data);2807 } catch(e) {2808 jQuery.handleError(s, xhr, null, e);2809 }28102811 // firefox 1.5 doesn't fire statechange for sync requests2812 if ( !s.async )2813 onreadystatechange();28142815 function success(){2816 // If a local callback was specified, fire it and pass it the data2817 if ( s.success )2818 s.success( data, status );28192820 // Fire the global callback2821 if ( s.global )2822 jQuery.event.trigger( "ajaxSuccess", [xhr, s] );2823 }28242825 function complete(){2826 // Process result2827 if ( s.complete )2828 s.complete(xhr, status);28292830 // The request was completed2831 if ( s.global )2832 jQuery.event.trigger( "ajaxComplete", [xhr, s] );28332834 // Handle the global AJAX counter2835 if ( s.global && ! --jQuery.active )2836 jQuery.event.trigger( "ajaxStop" );2837 }28382839 // return XMLHttpRequest to allow aborting the request etc.2840 return xhr;2841 },28422843 handleError: function( s, xhr, status, e ) {2844 // If a local callback was specified, fire it2845 if ( s.error ) s.error( xhr, status, e );28462847 // Fire the global callback2848 if ( s.global )2849 jQuery.event.trigger( "ajaxError", [xhr, s, e] );2850 },28512852 // Counter for holding the number of active queries2853 active: 0,28542855 // Determines if an XMLHttpRequest was successful or not2856 httpSuccess: function( xhr ) {2857 try {2858 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #14502859 return !xhr.status && location.protocol == "file:" ||2860 ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 ||2861 jQuery.browser.safari && xhr.status == undefined;2862 } catch(e){}2863 return false;2864 },28652866 // Determines if an XMLHttpRequest returns NotModified2867 httpNotModified: function( xhr, url ) {2868 try {2869 var xhrRes = xhr.getResponseHeader("Last-Modified");28702871 // Firefox always returns 200. check Last-Modified date2872 return xhr.status == 304 || xhrRes == jQuery.lastModified[url] ||2873 jQuery.browser.safari && xhr.status == undefined;2874 } catch(e){}2875 return false;2876 },28772878 httpData: function( xhr, type, filter ) {2879 var ct = xhr.getResponseHeader("content-type"),2880 xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,2881 data = xml ? xhr.responseXML : xhr.responseText;28822883 if ( xml && data.documentElement.tagName == "parsererror" )2884 throw "parsererror";28852886 // Allow a pre-filtering function to sanitize the response2887 if( filter )2888 data = filter( data, type );28892890 // If the type is "script", eval it in global context2891 if ( type == "script" )2892 jQuery.globalEval( data );28932894 // Get the JavaScript object, if JSON is used.2895 if ( type == "json" )2896 data = eval("(" + data + ")");28972898 return data;2899 },29002901 // Serialize an array of form elements or a set of2902 // key/values into a query string2903 param: function( a ) {2904 var s = [];29052906 // If an array was passed in, assume that it is an array2907 // of form elements2908 if ( a.constructor == Array || a.jquery )2909 // Serialize the form elements2910 jQuery.each( a, function(){2911 s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );2912 });29132914 // Otherwise, assume that it's an object of key/value pairs2915 else2916 // Serialize the key/values2917 for ( var j in a )2918 // If the value is an array then the key names need to be repeated2919 if ( a[j] && a[j].constructor == Array )2920 jQuery.each( a[j], function(){2921 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );2922 });2923 else2924 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( jQuery.isFunction(a[j]) ? a[j]() : a[j] ) );29252926 // Return the resulting serialization2927 return s.join("&").replace(/%20/g, "+");2928 }29292930 });2931 jQuery.fn.extend({2932 show: function(speed,callback){2933 return speed ?2934 this.animate({2935 height: "show", width: "show", opacity: "show"2936 }, speed, callback) :29372938 this.filter(":hidden").each(function(){2939 this.style.display = this.oldblock || "";2940 if ( jQuery.css(this,"display") == "none" ) {2941 var elem = jQuery("<" + this.tagName + " />").appendTo("body");2942 this.style.display = elem.css("display");2943 // handle an edge condition where css is - div { display:none; } or similar2944 if (this.style.display == "none")2945 this.style.display = "block";2946 elem.remove();2947 }2948 }).end();2949 },29502951 hide: function(speed,callback){2952 return speed ?2953 this.animate({2954 height: "hide", width: "hide", opacity: "hide"2955 }, speed, callback) :29562957 this.filter(":visible").each(function(){2958 this.oldblock = this.oldblock || jQuery.css(this,"display");2959 this.style.display = "none";2960 }).end();2961 },29622963 // Save the old toggle function2964 _toggle: jQuery.fn.toggle,29652966 toggle: function( fn, fn2 ){2967 return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?2968 this._toggle.apply( this, arguments ) :2969 fn ?2970 this.animate({2971 height: "toggle", width: "toggle", opacity: "toggle"2972 }, fn, fn2) :2973 this.each(function(){2974 jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();2975 });2976 },29772978 slideDown: function(speed,callback){2979 return this.animate({height: "show"}, speed, callback);2980 },29812982 slideUp: function(speed,callback){2983 return this.animate({height: "hide"}, speed, callback);2984 },29852986 slideToggle: function(speed, callback){2987 return this.animate({height: "toggle"}, speed, callback);2988 },29892990 fadeIn: function(speed, callback){2991 return this.animate({opacity: "show"}, speed, callback);2992 },29932994 fadeOut: function(speed, callback){2995 return this.animate({opacity: "hide"}, speed, callback);2996 },29972998 fadeTo: function(speed,to,callback){2999 return this.animate({opacity: to}, speed, callback);3000 },30013002 animate: function( prop, speed, easing, callback ) {3003 var optall = jQuery.speed(speed, easing, callback);30043005 return this[ optall.queue === false ? "each" : "queue" ](function(){3006 if ( this.nodeType != 1)3007 return false;30083009 var opt = jQuery.extend({}, optall), p,3010 hidden = jQuery(this).is(":hidden"), self = this;30113012 for ( p in prop ) {3013 if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )3014 return opt.complete.call(this);30153016 if ( p == "height" || p == "width" ) {3017 // Store display property3018 opt.display = jQuery.css(this, "display");30193020 // Make sure that nothing sneaks out3021 opt.overflow = this.style.overflow;3022 }3023 }30243025 if ( opt.overflow != null )3026 this.style.overflow = "hidden";30273028 opt.curAnim = jQuery.extend({}, prop);30293030 jQuery.each( prop, function(name, val){3031 var e = new jQuery.fx( self, opt, name );30323033 if ( /toggle|show|hide/.test(val) )3034 e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );3035 else {3036 var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),3037 start = e.cur(true) || 0;30383039 if ( parts ) {3040 var end = parseFloat(parts[2]),3041 unit = parts[3] || "px";30423043 // We need to compute starting value3044 if ( unit != "px" ) {3045 self.style[ name ] = (end || 1) + unit;3046 start = ((end || 1) / e.cur(true)) * start;3047 self.style[ name ] = start + unit;3048 }30493050 // If a +=/-= token was provided, we're doing a relative animation3051 if ( parts[1] )3052 end = ((parts[1] == "-=" ? -1 : 1) * end) + start;30533054 e.custom( start, end, unit );3055 } else3056 e.custom( start, val, "" );3057 }3058 });30593060 // For JS strict compliance3061 return true;3062 });3063 },30643065 queue: function(type, fn){3066 if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {3067 fn = type;3068 type = "fx";3069 }30703071 if ( !type || (typeof type == "string" && !fn) )3072 return queue( this[0], type );30733074 return this.each(function(){3075 if ( fn.constructor == Array )3076 queue(this, type, fn);3077 else {3078 queue(this, type).push( fn );30793080 if ( queue(this, type).length == 1 )3081 fn.call(this);3082 }3083 });3084 },30853086 stop: function(clearQueue, gotoEnd){3087 var timers = jQuery.timers;30883089 if (clearQueue)3090 this.queue([]);30913092 this.each(function(){3093 // go in reverse order so anything added to the queue during the loop is ignored3094 for ( var i = timers.length - 1; i >= 0; i-- )3095 if ( timers[i].elem == this ) {3096 if (gotoEnd)3097 // force the next step to be the last3098 timers[i](true);3099 timers.splice(i, 1);3100 }3101 });31023103 // start the next in the queue if the last step wasn't forced3104 if (!gotoEnd)3105 this.dequeue();31063107 return this;3108 }31093110 });31113112 var queue = function( elem, type, array ) {3113 if ( elem ){31143115 type = type || "fx";31163117 var q = jQuery.data( elem, type + "queue" );31183119 if ( !q || array )3120 q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) );31213122 }3123 return q;3124 };31253126 jQuery.fn.dequeue = function(type){3127 type = type || "fx";31283129 return this.each(function(){3130 var q = queue(this, type);31313132 q.shift();31333134 if ( q.length )3135 q[0].call( this );3136 });3137 };31383139 jQuery.extend({31403141 speed: function(speed, easing, fn) {3142 var opt = speed && speed.constructor == Object ? speed : {3143 complete: fn || !fn && easing ||3144 jQuery.isFunction( speed ) && speed,3145 duration: speed,3146 easing: fn && easing || easing && easing.constructor != Function && easing3147 };31483149 opt.duration = (opt.duration && opt.duration.constructor == Number ?3150 opt.duration :3151 jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def;31523153 // Queueing3154 opt.old = opt.complete;3155 opt.complete = function(){3156 if ( opt.queue !== false )3157 jQuery(this).dequeue();3158 if ( jQuery.isFunction( opt.old ) )3159 opt.old.call( this );3160 };31613162 return opt;3163 },31643165 easing: {3166 linear: function( p, n, firstNum, diff ) {3167 return firstNum + diff * p;3168 },3169 swing: function( p, n, firstNum, diff ) {3170 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;3171 }3172 },31733174 timers: [],3175 timerId: null,31763177 fx: function( elem, options, prop ){3178 this.options = options;3179 this.elem = elem;3180 this.prop = prop;31813182 if ( !options.orig )3183 options.orig = {};3184 }31853186 });31873188 jQuery.fx.prototype = {31893190 // Simple function for setting a style value3191 update: function(){3192 if ( this.options.step )3193 this.options.step.call( this.elem, this.now, this );31943195 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );31963197 // Set display property to block for height/width animations3198 if ( this.prop == "height" || this.prop == "width" )3199 this.elem.style.display = "block";3200 },32013202 // Get the current size3203 cur: function(force){3204 if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )3205 return this.elem[ this.prop ];32063207 var r = parseFloat(jQuery.css(this.elem, this.prop, force));3208 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;3209 },32103211 // Start an animation from one number to another3212 custom: function(from, to, unit){3213 this.startTime = now();3214 this.start = from;3215 this.end = to;3216 this.unit = unit || this.unit || "px";3217 this.now = this.start;3218 this.pos = this.state = 0;3219 this.update();32203221 var self = this;3222 function t(gotoEnd){3223 return self.step(gotoEnd);3224 }32253226 t.elem = this.elem;32273228 jQuery.timers.push(t);32293230 if ( jQuery.timerId == null ) {3231 jQuery.timerId = setInterval(function(){3232 var timers = jQuery.timers;32333234 for ( var i = 0; i < timers.length; i++ )3235 if ( !timers[i]() )3236 timers.splice(i--, 1);32373238 if ( !timers.length ) {3239 clearInterval( jQuery.timerId );3240 jQuery.timerId = null;3241 }3242 }, 13);3243 }3244 },32453246 // Simple 'show' function3247 show: function(){3248 // Remember where we started, so that we can go back to it later3249 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );3250 this.options.show = true;32513252 // Begin the animation3253 this.custom(0, this.cur());32543255 // Make sure that we start at a small width/height to avoid any3256 // flash of content3257 if ( this.prop == "width" || this.prop == "height" )3258 this.elem.style[this.prop] = "1px";32593260 // Start by showing the element3261 jQuery(this.elem).show();3262 },32633264 // Simple 'hide' function3265 hide: function(){3266 // Remember where we started, so that we can go back to it later3267 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );3268 this.options.hide = true;32693270 // Begin the animation3271 this.custom(this.cur(), 0);3272 },32733274 // Each step of an animation3275 step: function(gotoEnd){3276 var t = now();32773278 if ( gotoEnd || t > this.options.duration + this.startTime ) {3279 this.now = this.end;3280 this.pos = this.state = 1;3281 this.update();32823283 this.options.curAnim[ this.prop ] = true;32843285 var done = true;3286 for ( var i in this.options.curAnim )3287 if ( this.options.curAnim[i] !== true )3288 done = false;32893290 if ( done ) {3291 if ( this.options.display != null ) {3292 // Reset the overflow3293 this.elem.style.overflow = this.options.overflow;32943295 // Reset the display3296 this.elem.style.display = this.options.display;3297 if ( jQuery.css(this.elem, "display") == "none" )3298 this.elem.style.display = "block";3299 }33003301 // Hide the element if the "hide" operation was done3302 if ( this.options.hide )3303 this.elem.style.display = "none";33043305 // Reset the properties, if the item has been hidden or shown3306 if ( this.options.hide || this.options.show )3307 for ( var p in this.options.curAnim )3308 jQuery.attr(this.elem.style, p, this.options.orig[p]);3309 }33103311 if ( done )3312 // Execute the complete function3313 this.options.complete.call( this.elem );33143315 return false;3316 } else {3317 var n = t - this.startTime;3318 this.state = n / this.options.duration;33193320 // Perform the easing function, defaults to swing3321 this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);3322 this.now = this.start + ((this.end - this.start) * this.pos);33233324 // Perform the next step of the animation3325 this.update();3326 }33273328 return true;3329 }33303331 };33323333 jQuery.extend( jQuery.fx, {3334 speeds:{3335 slow: 600,3336 fast: 200,3337 // Default speed3338 def: 4003339 },3340 step: {3341 scrollLeft: function(fx){3342 fx.elem.scrollLeft = fx.now;3343 },33443345 scrollTop: function(fx){3346 fx.elem.scrollTop = fx.now;3347 },33483349 opacity: function(fx){3350 jQuery.attr(fx.elem.style, "opacity", fx.now);3351 },33523353 _default: function(fx){3354 fx.elem.style[ fx.prop ] = fx.now + fx.unit;3355 }3356 }3357 });3358 // The Offset Method3359 // Originally By Brandon Aaron, part of the Dimension Plugin3360 // http://jquery.com/plugins/project/dimensions3361 jQuery.fn.offset = function() {3362 var left = 0, top = 0, elem = this[0], results;33633364 if ( elem ) with ( jQuery.browser ) {3365 var parent = elem.parentNode,3366 offsetChild = elem,3367 offsetParent = elem.offsetParent,3368 doc = elem.ownerDocument,3369 safari2 = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),3370 css = jQuery.curCSS,3371 fixed = css(elem, "position") == "fixed";33723373 // Use getBoundingClientRect if available3374 if ( elem.getBoundingClientRect ) {3375 var box = elem.getBoundingClientRect();33763377 // Add the document scroll offsets3378 add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),3379 box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));33803381 // IE adds the HTML element's border, by default it is medium which is 2px3382 // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }3383 // IE 7 standards mode, the border is always 2px3384 // This border/offset is typically represented by the clientLeft and clientTop properties3385 // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS3386 // Therefore this method will be off by 2px in IE while in quirksmode3387 add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );33883389 // Otherwise loop through the offsetParents and parentNodes3390 } else {33913392 // Initial element offsets3393 add( elem.offsetLeft, elem.offsetTop );33943395 // Get parent offsets3396 while ( offsetParent ) {3397 // Add offsetParent offsets3398 add( offsetParent.offsetLeft, offsetParent.offsetTop );33993400 // Mozilla and Safari > 2 does not include the border on offset parents3401 // However Mozilla adds the border for table or table cells3402 if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )3403 border( offsetParent );34043405 // Add the document scroll offsets if position is fixed on any offsetParent3406 if ( !fixed && css(offsetParent, "position") == "fixed" )3407 fixed = true;34083409 // Set offsetChild to previous offsetParent unless it is the body element3410 offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;3411 // Get next offsetParent3412 offsetParent = offsetParent.offsetParent;3413 }34143415 // Get parent scroll offsets3416 while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {3417 // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug3418 if ( !/^inline|table.*$/i.test(css(parent, "display")) )3419 // Subtract parent scroll offsets3420 add( -parent.scrollLeft, -parent.scrollTop );34213422 // Mozilla does not add the border for a parent that has overflow != visible3423 if ( mozilla && css(parent, "overflow") != "visible" )3424 border( parent );34253426 // Get next parent3427 parent = parent.parentNode;3428 }34293430 // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild3431 // Mozilla doubles body offsets with a non-absolutely positioned offsetChild3432 if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) ||3433 (mozilla && css(offsetChild, "position") != "absolute") )3434 add( -doc.body.offsetLeft, -doc.body.offsetTop );34353436 // Add the document scroll offsets if position is fixed3437 if ( fixed )3438 add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),3439 Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));3440 }34413442 // Return an object with top and left properties3443 results = { top: top, left: left };3444 }34453446 function border(elem) {3447 add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );3448 }34493450 function add(l, t) {3451 left += parseInt(l, 10) || 0;3452 top += parseInt(t, 10) || 0;3453 }34543455 return results;3456 };345734583459 jQuery.fn.extend({3460 position: function() {3461 var left = 0, top = 0, results;34623463 if ( this[0] ) {3464 // Get *real* offsetParent3465 var offsetParent = this.offsetParent(),34663467 // Get correct offsets3468 offset = this.offset(),3469 parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();34703471 // Subtract element margins3472 // note: when an element has margin: auto the offsetLeft and marginLeft3473 // are the same in Safari causing offset.left to incorrectly be 03474 offset.top -= num( this, 'marginTop' );3475 offset.left -= num( this, 'marginLeft' );34763477 // Add offsetParent borders3478 parentOffset.top += num( offsetParent, 'borderTopWidth' );3479 parentOffset.left += num( offsetParent, 'borderLeftWidth' );34803481 // Subtract the two offsets3482 results = {3483 top: offset.top - parentOffset.top,3484 left: offset.left - parentOffset.left3485 };3486 }34873488 return results;3489 },34903491 offsetParent: function() {3492 var offsetParent = this[0].offsetParent;3493 while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )3494 offsetParent = offsetParent.offsetParent;3495 return jQuery(offsetParent);3496 }3497 });349834993500 // Create scrollLeft and scrollTop methods3501 jQuery.each( ['Left', 'Top'], function(i, name) {3502 var method = 'scroll' + name;35033504 jQuery.fn[ method ] = function(val) {3505 if (!this[0]) return;35063507 return val != undefined ?35083509 // Set the scroll offset3510 this.each(function() {3511 this == window || this == document ?3512 window.scrollTo(3513 !i ? val : jQuery(window).scrollLeft(),3514 i ? val : jQuery(window).scrollTop()3515 ) :3516 this[ method ] = val;3517 }) :35183519 // Return the scroll offset3520 this[0] == window || this[0] == document ?3521 self[ i ? 'pageYOffset' : 'pageXOffset' ] ||3522 jQuery.boxModel && document.documentElement[ method ] ||3523 document.body[ method ] :3524 this[0][ method ];3525 };3526 });3527 // Create innerHeight, innerWidth, outerHeight and outerWidth methods3528 jQuery.each([ "Height", "Width" ], function(i, name){35293530 var tl = i ? "Left" : "Top", // top or left3531 br = i ? "Right" : "Bottom"; // bottom or right35323533 // innerHeight and innerWidth3534 jQuery.fn["inner" + name] = function(){3535 return this[ name.toLowerCase() ]() +3536 num(this, "padding" + tl) +3537 num(this, "padding" + br);3538 };35393540 // outerHeight and outerWidth3541 jQuery.fn["outer" + name] = function(margin) {3542 return this["inner" + name]() +3543 num(this, "border" + tl + "Width") +3544 num(this, "border" + br + "Width") +3545 (margin ?3546 num(this, "margin" + tl) + num(this, "margin" + br) : 0);3547 };35483549 });})();1 (function(){ 2 /* 3 * jQuery 1.2.6 - New Wave Javascript 4 * 5 * Copyright (c) 2008 John Resig (jquery.com) 6 * Dual licensed under the MIT (MIT-LICENSE.txt) 7 * and GPL (GPL-LICENSE.txt) licenses. 8 * 9 * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $ 10 * $Rev: 5685 $ 11 */ 12 13 // Map over jQuery in case of overwrite 14 var _jQuery = window.jQuery, 15 // Map over the $ in case of overwrite 16 _$ = window.$; 17 18 var jQuery = window.jQuery = window.$ = function( selector, context ) { 19 // The jQuery object is actually just the init constructor 'enhanced' 20 return new jQuery.fn.init( selector, context ); 21 }; 22 23 // A simple way to check for HTML strings or ID strings 24 // (both of which we optimize for) 25 var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/, 26 27 // Is it a simple selector 28 isSimple = /^.[^:#\[\.]*$/, 29 30 // Will speed up references to undefined, and allows munging its name. 31 undefined; 32 33 jQuery.fn = jQuery.prototype = { 34 init: function( selector, context ) { 35 // Make sure that a selection was provided 36 selector = selector || document; 37 38 // Handle $(DOMElement) 39 if ( selector.nodeType ) { 40 this[0] = selector; 41 this.length = 1; 42 return this; 43 } 44 // Handle HTML strings 45 if ( typeof selector == "string" ) { 46 // Are we dealing with HTML string or an ID? 47 var match = quickExpr.exec( selector ); 48 49 // Verify a match, and that no context was specified for #id 50 if ( match && (match[1] || !context) ) { 51 52 // HANDLE: $(html) -> $(array) 53 if ( match[1] ) 54 selector = jQuery.clean( [ match[1] ], context ); 55 56 // HANDLE: $("#id") 57 else { 58 var elem = document.getElementById( match[3] ); 59 60 // Make sure an element was located 61 if ( elem ){ 62 // Handle the case where IE and Opera return items 63 // by name instead of ID 64 if ( elem.id != match[3] ) 65 return jQuery().find( selector ); 66 67 // Otherwise, we inject the element directly into the jQuery object 68 return jQuery( elem ); 69 } 70 selector = []; 71 } 72 73 // HANDLE: $(expr, [context]) 74 // (which is just equivalent to: $(content).find(expr) 75 } else 76 return jQuery( context ).find( selector ); 77 78 // HANDLE: $(function) 79 // Shortcut for document ready 80 } else if ( jQuery.isFunction( selector ) ) 81 return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector ); 82 83 return this.setArray(jQuery.makeArray(selector)); 84 }, 85 86 // The current version of jQuery being used 87 jquery: "1.2.6", 88 89 // The number of elements contained in the matched element set 90 size: function() { 91 return this.length; 92 }, 93 94 // The number of elements contained in the matched element set 95 length: 0, 96 97 // Get the Nth element in the matched element set OR 98 // Get the whole matched element set as a clean array 99 get: function( num ) { 100 return num == undefined ? 101 102 // Return a 'clean' array 103 jQuery.makeArray( this ) : 104 105 // Return just the object 106 this[ num ]; 107 }, 108 109 // Take an array of elements and push it onto the stack 110 // (returning the new matched element set) 111 pushStack: function( elems ) { 112 // Build a new jQuery matched element set 113 var ret = jQuery( elems ); 114 115 // Add the old object onto the stack (as a reference) 116 ret.prevObject = this; 117 118 // Return the newly-formed element set 119 return ret; 120 }, 121 122 // Force the current matched set of elements to become 123 // the specified array of elements (destroying the stack in the process) 124 // You should use pushStack() in order to do this, but maintain the stack 125 setArray: function( elems ) { 126 // Resetting the length to 0, then using the native Array push 127 // is a super-fast way to populate an object with array-like properties 128 this.length = 0; 129 Array.prototype.push.apply( this, elems ); 130 131 return this; 132 }, 133 134 // Execute a callback for every element in the matched set. 135 // (You can seed the arguments with an array of args, but this is 136 // only used internally.) 137 each: function( callback, args ) { 138 return jQuery.each( this, callback, args ); 139 }, 140 141 // Determine the position of an element within 142 // the matched set of elements 143 index: function( elem ) { 144 var ret = -1; 145 146 // Locate the position of the desired element 147 return jQuery.inArray( 148 // If it receives a jQuery object, the first element is used 149 elem && elem.jquery ? elem[0] : elem 150 , this ); 151 }, 152 153 attr: function( name, value, type ) { 154 var options = name; 155 156 // Look for the case where we're accessing a style value 157 if ( name.constructor == String ) 158 if ( value === undefined ) 159 return this[0] && jQuery[ type || "attr" ]( this[0], name ); 160 161 else { 162 options = {}; 163 options[ name ] = value; 164 } 165 166 // Check to see if we're setting style values 167 return this.each(function(i){ 168 // Set all the styles 169 for ( name in options ) 170 jQuery.attr( 171 type ? 172 this.style : 173 this, 174 name, jQuery.prop( this, options[ name ], type, i, name ) 175 ); 176 }); 177 }, 178 179 css: function( key, value ) { 180 // ignore negative width and height values 181 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) 182 value = undefined; 183 return this.attr( key, value, "curCSS" ); 184 }, 185 186 text: function( text ) { 187 if ( typeof text != "object" && text != null ) 188 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); 189 190 var ret = ""; 191 192 jQuery.each( text || this, function(){ 193 jQuery.each( this.childNodes, function(){ 194 if ( this.nodeType != 8 ) 195 ret += this.nodeType != 1 ? 196 this.nodeValue : 197 jQuery.fn.text( [ this ] ); 198 }); 199 }); 200 201 return ret; 202 }, 203 204 wrapAll: function( html ) { 205 if ( this[0] ) 206 // The elements to wrap the target around 207 jQuery( html, this[0].ownerDocument ) 208 .clone() 209 .insertBefore( this[0] ) 210 .map(function(){ 211 var elem = this; 212 213 while ( elem.firstChild ) 214 elem = elem.firstChild; 215 216 return elem; 217 }) 218 .append(this); 219 220 return this; 221 }, 222 223 wrapInner: function( html ) { 224 return this.each(function(){ 225 jQuery( this ).contents().wrapAll( html ); 226 }); 227 }, 228 229 wrap: function( html ) { 230 return this.each(function(){ 231 jQuery( this ).wrapAll( html ); 232 }); 233 }, 234 235 append: function() { 236 return this.domManip(arguments, true, false, function(elem){ 237 if (this.nodeType == 1) 238 this.appendChild( elem ); 239 }); 240 }, 241 242 prepend: function() { 243 return this.domManip(arguments, true, true, function(elem){ 244 if (this.nodeType == 1) 245 this.insertBefore( elem, this.firstChild ); 246 }); 247 }, 248 249 before: function() { 250 return this.domManip(arguments, false, false, function(elem){ 251 this.parentNode.insertBefore( elem, this ); 252 }); 253 }, 254 255 after: function() { 256 return this.domManip(arguments, false, true, function(elem){ 257 this.parentNode.insertBefore( elem, this.nextSibling ); 258 }); 259 }, 260 261 end: function() { 262 return this.prevObject || jQuery( [] ); 263 }, 264 265 find: function( selector ) { 266 var elems = jQuery.map(this, function(elem){ 267 return jQuery.find( selector, elem ); 268 }); 269 270 return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ? 271 jQuery.unique( elems ) : 272 elems ); 273 }, 274 275 clone: function( events ) { 276 // Do the clone 277 var ret = this.map(function(){ 278 if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) { 279 // IE copies events bound via attachEvent when 280 // using cloneNode. Calling detachEvent on the 281 // clone will also remove the events from the orignal 282 // In order to get around this, we use innerHTML. 283 // Unfortunately, this means some modifications to 284 // attributes in IE that are actually only stored 285 // as properties will not be copied (such as the 286 // the name attribute on an input). 287 var clone = this.cloneNode(true), 288 container = document.createElement("div"); 289 container.appendChild(clone); 290 return jQuery.clean([container.innerHTML])[0]; 291 } else 292 return this.cloneNode(true); 293 }); 294 295 // Need to set the expando to null on the cloned set if it exists 296 // removeData doesn't work here, IE removes it from the original as well 297 // this is primarily for IE but the data expando shouldn't be copied over in any browser 298 var clone = ret.find("*").andSelf().each(function(){ 299 if ( this[ expando ] != undefined ) 300 this[ expando ] = null; 301 }); 302 303 // Copy the events from the original to the clone 304 if ( events === true ) 305 this.find("*").andSelf().each(function(i){ 306 if (this.nodeType == 3) 307 return; 308 var events = jQuery.data( this, "events" ); 309 310 for ( var type in events ) 311 for ( var handler in events[ type ] ) 312 jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data ); 313 }); 314 315 // Return the cloned set 316 return ret; 317 }, 318 319 filter: function( selector ) { 320 return this.pushStack( 321 jQuery.isFunction( selector ) && 322 jQuery.grep(this, function(elem, i){ 323 return selector.call( elem, i ); 324 }) || 325 326 jQuery.multiFilter( selector, this ) ); 327 }, 328 329 not: function( selector ) { 330 if ( selector.constructor == String ) 331 // test special case where just one selector is passed in 332 if ( isSimple.test( selector ) ) 333 return this.pushStack( jQuery.multiFilter( selector, this, true ) ); 334 else 335 selector = jQuery.multiFilter( selector, this ); 336 337 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; 338 return this.filter(function() { 339 return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; 340 }); 341 }, 342 343 add: function( selector ) { 344 return this.pushStack( jQuery.unique( jQuery.merge( 345 this.get(), 346 typeof selector == 'string' ? 347 jQuery( selector ) : 348 jQuery.makeArray( selector ) 349 ))); 350 }, 351 352 is: function( selector ) { 353 return !!selector && jQuery.multiFilter( selector, this ).length > 0; 354 }, 355 356 hasClass: function( selector ) { 357 return this.is( "." + selector ); 358 }, 359 360 val: function( value ) { 361 if ( value == undefined ) { 362 363 if ( this.length ) { 364 var elem = this[0]; 365 366 // We need to handle select boxes special 367 if ( jQuery.nodeName( elem, "select" ) ) { 368 var index = elem.selectedIndex, 369 values = [], 370 options = elem.options, 371 one = elem.type == "select-one"; 372 373 // Nothing was selected 374 if ( index < 0 ) 375 return null; 376 377 // Loop through all the selected options 378 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { 379 var option = options[ i ]; 380 381 if ( option.selected ) { 382 // Get the specifc value for the option 383 value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value; 384 385 // We don't need an array for one selects 386 if ( one ) 387 return value; 388 389 // Multi-Selects return an array 390 values.push( value ); 391 } 392 } 393 394 return values; 395 396 // Everything else, we just grab the value 397 } else 398 return (this[0].value || "").replace(/\r/g, ""); 399 400 } 401 402 return undefined; 403 } 404 405 if( value.constructor == Number ) 406 value += ''; 407 408 return this.each(function(){ 409 if ( this.nodeType != 1 ) 410 return; 411 412 if ( value.constructor == Array && /radio|checkbox/.test( this.type ) ) 413 this.checked = (jQuery.inArray(this.value, value) >= 0 || 414 jQuery.inArray(this.name, value) >= 0); 415 416 else if ( jQuery.nodeName( this, "select" ) ) { 417 var values = jQuery.makeArray(value); 418 419 jQuery( "option", this ).each(function(){ 420 this.selected = (jQuery.inArray( this.value, values ) >= 0 || 421 jQuery.inArray( this.text, values ) >= 0); 422 }); 423 424 if ( !values.length ) 425 this.selectedIndex = -1; 426 427 } else 428 this.value = value; 429 }); 430 }, 431 432 html: function( value ) { 433 return value == undefined ? 434 (this[0] ? 435 this[0].innerHTML : 436 null) : 437 this.empty().append( value ); 438 }, 439 440 replaceWith: function( value ) { 441 return this.after( value ).remove(); 442 }, 443 444 eq: function( i ) { 445 return this.slice( i, i + 1 ); 446 }, 447 448 slice: function() { 449 return this.pushStack( Array.prototype.slice.apply( this, arguments ) ); 450 }, 451 452 map: function( callback ) { 453 return this.pushStack( jQuery.map(this, function(elem, i){ 454 return callback.call( elem, i, elem ); 455 })); 456 }, 457 458 andSelf: function() { 459 return this.add( this.prevObject ); 460 }, 461 462 data: function( key, value ){ 463 var parts = key.split("."); 464 parts[1] = parts[1] ? "." + parts[1] : ""; 465 466 if ( value === undefined ) { 467 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); 468 469 if ( data === undefined && this.length ) 470 data = jQuery.data( this[0], key ); 471 472 return data === undefined && parts[1] ? 473 this.data( parts[0] ) : 474 data; 475 } else 476 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){ 477 jQuery.data( this, key, value ); 478 }); 479 }, 480 481 removeData: function( key ){ 482 return this.each(function(){ 483 jQuery.removeData( this, key ); 484 }); 485 }, 486 487 domManip: function( args, table, reverse, callback ) { 488 var clone = this.length > 1, elems; 489 490 return this.each(function(){ 491 if ( !elems ) { 492 elems = jQuery.clean( args, this.ownerDocument ); 493 494 if ( reverse ) 495 elems.reverse(); 496 } 497 498 var obj = this; 499 500 if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) ) 501 obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") ); 502 503 var scripts = jQuery( [] ); 504 505 jQuery.each(elems, function(){ 506 var elem = clone ? 507 jQuery( this ).clone( true )[0] : 508 this; 509 510 // execute all scripts after the elements have been injected 511 if ( jQuery.nodeName( elem, "script" ) ) 512 scripts = scripts.add( elem ); 513 else { 514 // Remove any inner scripts for later evaluation 515 if ( elem.nodeType == 1 ) 516 scripts = scripts.add( jQuery( "script", elem ).remove() ); 517 518 // Inject the elements into the document 519 callback.call( obj, elem ); 520 } 521 }); 522 523 scripts.each( evalScript ); 524 }); 525 } 526 }; 527 528 // Give the init function the jQuery prototype for later instantiation 529 jQuery.fn.init.prototype = jQuery.fn; 530 531 function evalScript( i, elem ) { 532 if ( elem.src ) 533 jQuery.ajax({ 534 url: elem.src, 535 async: false, 536 dataType: "script" 537 }); 538 539 else 540 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); 541 542 if ( elem.parentNode ) 543 elem.parentNode.removeChild( elem ); 544 } 545 546 function now(){ 547 return +new Date; 548 } 549 550 jQuery.extend = jQuery.fn.extend = function() { 551 // copy reference to target object 552 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; 553 554 // Handle a deep copy situation 555 if ( target.constructor == Boolean ) { 556 deep = target; 557 target = arguments[1] || {}; 558 // skip the boolean and the target 559 i = 2; 560 } 561 562 // Handle case when target is a string or something (possible in deep copy) 563 if ( typeof target != "object" && typeof target != "function" ) 564 target = {}; 565 566 // extend jQuery itself if only one argument is passed 567 if ( length == i ) { 568 target = this; 569 --i; 570 } 571 572 for ( ; i < length; i++ ) 573 // Only deal with non-null/undefined values 574 if ( (options = arguments[ i ]) != null ) 575 // Extend the base object 576 for ( var name in options ) { 577 var src = target[ name ], copy = options[ name ]; 578 579 // Prevent never-ending loop 580 if ( target === copy ) 581 continue; 582 583 // Recurse if we're merging object values 584 if ( deep && copy && typeof copy == "object" && !copy.nodeType ) 585 target[ name ] = jQuery.extend( deep, 586 // Never move original objects, clone them 587 src || ( copy.length != null ? [ ] : { } ) 588 , copy ); 589 590 // Don't bring in undefined values 591 else if ( copy !== undefined ) 592 target[ name ] = copy; 593 594 } 595 596 // Return the modified object 597 return target; 598 }; 599 600 var expando = "jQuery" + now(), uuid = 0, windowData = {}, 601 // exclude the following css properties to add px 602 exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, 603 // cache defaultView 604 defaultView = document.defaultView || {}; 605 606 jQuery.extend({ 607 noConflict: function( deep ) { 608 window.$ = _$; 609 610 if ( deep ) 611 window.jQuery = _jQuery; 612 613 return jQuery; 614 }, 615 616 // See test/unit/core.js for details concerning this function. 617 isFunction: function( fn ) { 618 return !!fn && typeof fn != "string" && !fn.nodeName && 619 fn.constructor != Array && /^[\s[]?function/.test( fn + "" ); 620 }, 621 622 // check if an element is in a (or is an) XML document 623 isXMLDoc: function( elem ) { 624 return elem.documentElement && !elem.body || 625 elem.tagName && elem.ownerDocument && !elem.ownerDocument.body; 626 }, 627 628 // Evalulates a script in a global context 629 globalEval: function( data ) { 630 data = jQuery.trim( data ); 631 632 if ( data ) { 633 // Inspired by code by Andrea Giammarchi 634 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html 635 var head = document.getElementsByTagName("head")[0] || document.documentElement, 636 script = document.createElement("script"); 637 638 script.type = "text/javascript"; 639 if ( jQuery.browser.msie ) 640 script.text = data; 641 else 642 script.appendChild( document.createTextNode( data ) ); 643 644 // Use insertBefore instead of appendChild to circumvent an IE6 bug. 645 // This arises when a base node is used (#2709). 646 head.insertBefore( script, head.firstChild ); 647 head.removeChild( script ); 648 } 649 }, 650 651 nodeName: function( elem, name ) { 652 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); 653 }, 654 655 cache: {}, 656 657 data: function( elem, name, data ) { 658 elem = elem == window ? 659 windowData : 660 elem; 661 662 var id = elem[ expando ]; 663 664 // Compute a unique ID for the element 665 if ( !id ) 666 id = elem[ expando ] = ++uuid; 667 668 // Only generate the data cache if we're 669 // trying to access or manipulate it 670 if ( name && !jQuery.cache[ id ] ) 671 jQuery.cache[ id ] = {}; 672 673 // Prevent overriding the named cache with undefined values 674 if ( data !== undefined ) 675 jQuery.cache[ id ][ name ] = data; 676 677 // Return the named cache data, or the ID for the element 678 return name ? 679 jQuery.cache[ id ][ name ] : 680 id; 681 }, 682 683 removeData: function( elem, name ) { 684 elem = elem == window ? 685 windowData : 686 elem; 687 688 var id = elem[ expando ]; 689 690 // If we want to remove a specific section of the element's data 691 if ( name ) { 692 if ( jQuery.cache[ id ] ) { 693 // Remove the section of cache data 694 delete jQuery.cache[ id ][ name ]; 695 696 // If we've removed all the data, remove the element's cache 697 name = ""; 698 699 for ( name in jQuery.cache[ id ] ) 700 break; 701 702 if ( !name ) 703 jQuery.removeData( elem ); 704 } 705 706 // Otherwise, we want to remove all of the element's data 707 } else { 708 // Clean up the element expando 709 try { 710 delete elem[ expando ]; 711 } catch(e){ 712 // IE has trouble directly removing the expando 713 // but it's ok with using removeAttribute 714 if ( elem.removeAttribute ) 715 elem.removeAttribute( expando ); 716 } 717 718 // Completely remove the data cache 719 delete jQuery.cache[ id ]; 720 } 721 }, 722 723 // args is for internal usage only 724 each: function( object, callback, args ) { 725 var name, i = 0, length = object.length; 726 727 if ( args ) { 728 if ( length == undefined ) { 729 for ( name in object ) 730 if ( callback.apply( object[ name ], args ) === false ) 731 break; 732 } else 733 for ( ; i < length; ) 734 if ( callback.apply( object[ i++ ], args ) === false ) 735 break; 736 737 // A special, fast, case for the most common use of each 738 } else { 739 if ( length == undefined ) { 740 for ( name in object ) 741 if ( callback.call( object[ name ], name, object[ name ] ) === false ) 742 break; 743 } else 744 for ( var value = object[0]; 745 i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} 746 } 747 748 return object; 749 }, 750 751 prop: function( elem, value, type, i, name ) { 752 // Handle executable functions 753 if ( jQuery.isFunction( value ) ) 754 value = value.call( elem, i ); 755 756 // Handle passing in a number to a CSS property 757 return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ? 758 value + "px" : 759 value; 760 }, 761 762 className: { 763 // internal only, use addClass("class") 764 add: function( elem, classNames ) { 765 jQuery.each((classNames || "").split(/\s+/), function(i, className){ 766 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) 767 elem.className += (elem.className ? " " : "") + className; 768 }); 769 }, 770 771 // internal only, use removeClass("class") 772 remove: function( elem, classNames ) { 773 if (elem.nodeType == 1) 774 elem.className = classNames != undefined ? 775 jQuery.grep(elem.className.split(/\s+/), function(className){ 776 return !jQuery.className.has( classNames, className ); 777 }).join(" ") : 778 ""; 779 }, 780 781 // internal only, use hasClass("class") 782 has: function( elem, className ) { 783 return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; 784 } 785 }, 786 787 // A method for quickly swapping in/out CSS properties to get correct calculations 788 swap: function( elem, options, callback ) { 789 var old = {}; 790 // Remember the old values, and insert the new ones 791 for ( var name in options ) { 792 old[ name ] = elem.style[ name ]; 793 elem.style[ name ] = options[ name ]; 794 } 795 796 callback.call( elem ); 797 798 // Revert the old values 799 for ( var name in options ) 800 elem.style[ name ] = old[ name ]; 801 }, 802 803 css: function( elem, name, force ) { 804 if ( name == "width" || name == "height" ) { 805 var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; 806 807 function getWH() { 808 val = name == "width" ? elem.offsetWidth : elem.offsetHeight; 809 var padding = 0, border = 0; 810 jQuery.each( which, function() { 811 padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; 812 border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; 813 }); 814 val -= Math.round(padding + border); 815 } 816 817 if ( jQuery(elem).is(":visible") ) 818 getWH(); 819 else 820 jQuery.swap( elem, props, getWH ); 821 822 return Math.max(0, val); 823 } 824 825 return jQuery.curCSS( elem, name, force ); 826 }, 827 828 curCSS: function( elem, name, force ) { 829 var ret, style = elem.style; 830 831 // A helper method for determining if an element's values are broken 832 function color( elem ) { 833 if ( !jQuery.browser.safari ) 834 return false; 835 836 // defaultView is cached 837 var ret = defaultView.getComputedStyle( elem, null ); 838 return !ret || ret.getPropertyValue("color") == ""; 839 } 840 841 // We need to handle opacity special in IE 842 if ( name == "opacity" && jQuery.browser.msie ) { 843 ret = jQuery.attr( style, "opacity" ); 844 845 return ret == "" ? 846 "1" : 847 ret; 848 } 849 // Opera sometimes will give the wrong display answer, this fixes it, see #2037 850 if ( jQuery.browser.opera && name == "display" ) { 851 var save = style.outline; 852 style.outline = "0 solid black"; 853 style.outline = save; 854 } 855 856 // Make sure we're using the right name for getting the float value 857 if ( name.match( /float/i ) ) 858 name = styleFloat; 859 860 if ( !force && style && style[ name ] ) 861 ret = style[ name ]; 862 863 else if ( defaultView.getComputedStyle ) { 864 865 // Only "float" is needed here 866 if ( name.match( /float/i ) ) 867 name = "float"; 868 869 name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); 870 871 var computedStyle = defaultView.getComputedStyle( elem, null ); 872 873 if ( computedStyle && !color( elem ) ) 874 ret = computedStyle.getPropertyValue( name ); 875 876 // If the element isn't reporting its values properly in Safari 877 // then some display: none elements are involved 878 else { 879 var swap = [], stack = [], a = elem, i = 0; 880 881 // Locate all of the parent display: none elements 882 for ( ; a && color(a); a = a.parentNode ) 883 stack.unshift(a); 884 885 // Go through and make them visible, but in reverse 886 // (It would be better if we knew the exact display type that they had) 887 for ( ; i < stack.length; i++ ) 888 if ( color( stack[ i ] ) ) { 889 swap[ i ] = stack[ i ].style.display; 890 stack[ i ].style.display = "block"; 891 } 892 893 // Since we flip the display style, we have to handle that 894 // one special, otherwise get the value 895 ret = name == "display" && swap[ stack.length - 1 ] != null ? 896 "none" : 897 ( computedStyle && computedStyle.getPropertyValue( name ) ) || ""; 898 899 // Finally, revert the display styles back 900 for ( i = 0; i < swap.length; i++ ) 901 if ( swap[ i ] != null ) 902 stack[ i ].style.display = swap[ i ]; 903 } 904 905 // We should always get a number back from opacity 906 if ( name == "opacity" && ret == "" ) 907 ret = "1"; 908 909 } else if ( elem.currentStyle ) { 910 var camelCase = name.replace(/\-(\w)/g, function(all, letter){ 911 return letter.toUpperCase(); 912 }); 913 914 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; 915 916 // From the awesome hack by Dean Edwards 917 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 918 919 // If we're not dealing with a regular pixel number 920 // but a number that has a weird ending, we need to convert it to pixels 921 if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { 922 // Remember the original values 923 var left = style.left, rsLeft = elem.runtimeStyle.left; 924 925 // Put in the new values to get a computed value out 926 elem.runtimeStyle.left = elem.currentStyle.left; 927 style.left = ret || 0; 928 ret = style.pixelLeft + "px"; 929 930 // Revert the changed values 931 style.left = left; 932 elem.runtimeStyle.left = rsLeft; 933 } 934 } 935 936 return ret; 937 }, 938 939 clean: function( elems, context ) { 940 var ret = []; 941 context = context || document; 942 // !context.createElement fails in IE with an error but returns typeof 'object' 943 if (typeof context.createElement == 'undefined') 944 context = context.ownerDocument || context[0] && context[0].ownerDocument || document; 945 946 jQuery.each(elems, function(i, elem){ 947 if ( !elem ) 948 return; 949 950 if ( elem.constructor == Number ) 951 elem += ''; 952 953 // Convert html string into DOM nodes 954 if ( typeof elem == "string" ) { 955 // Fix "XHTML"-style tags in all browsers 956 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ 957 return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? 958 all : 959 front + "></" + tag + ">"; 960 }); 961 962 // Trim whitespace, otherwise indexOf won't work as expected 963 var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div"); 964 965 var wrap = 966 // option or optgroup 967 !tags.indexOf("<opt") && 968 [ 1, "<select multiple='multiple'>", "</select>" ] || 969 970 !tags.indexOf("<leg") && 971 [ 1, "<fieldset>", "</fieldset>" ] || 972 973 tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && 974 [ 1, "<table>", "</table>" ] || 975 976 !tags.indexOf("<tr") && 977 [ 2, "<table><tbody>", "</tbody></table>" ] || 978 979 // <thead> matched above 980 (!tags.indexOf("<td") || !tags.indexOf("<th")) && 981 [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] || 982 983 !tags.indexOf("<col") && 984 [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] || 985 986 // IE can't serialize <link> and <script> tags normally 987 jQuery.browser.msie && 988 [ 1, "div<div>", "</div>" ] || 989 990 [ 0, "", "" ]; 991 992 // Go to html and back, then peel off extra wrappers 993 div.innerHTML = wrap[1] + elem + wrap[2]; 994 995 // Move to the right depth 996 while ( wrap[0]-- ) 997 div = div.lastChild; 998 999 // Remove IE's autoinserted <tbody> from table fragments 1000 if ( jQuery.browser.msie ) { 1001 1002 // String was a <table>, *may* have spurious <tbody> 1003 var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ? 1004 div.firstChild && div.firstChild.childNodes : 1005 1006 // String was a bare <thead> or <tfoot> 1007 wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ? 1008 div.childNodes : 1009 []; 1010 1011 for ( var j = tbody.length - 1; j >= 0 ; --j ) 1012 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) 1013 tbody[ j ].parentNode.removeChild( tbody[ j ] ); 1014 1015 // IE completely kills leading whitespace when innerHTML is used 1016 if ( /^\s/.test( elem ) ) 1017 div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild ); 1018 1019 } 1020 1021 elem = jQuery.makeArray( div.childNodes ); 1022 } 1023 1024 if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) ) 1025 return; 1026 1027 if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options ) 1028 ret.push( elem ); 1029 1030 else 1031 ret = jQuery.merge( ret, elem ); 1032 1033 }); 1034 1035 return ret; 1036 }, 1037 1038 attr: function( elem, name, value ) { 1039 // don't set attributes on text and comment nodes 1040 if (!elem || elem.nodeType == 3 || elem.nodeType == 8) 1041 return undefined; 1042 1043 var notxml = !jQuery.isXMLDoc( elem ), 1044 // Whether we are setting (or getting) 1045 set = value !== undefined, 1046 msie = jQuery.browser.msie; 1047 1048 // Try to normalize/fix the name 1049 name = notxml && jQuery.props[ name ] || name; 1050 1051 // Only do all the following if this is a node (faster for style) 1052 // IE elem.getAttribute passes even for style 1053 if ( elem.tagName ) { 1054 1055 // These attributes require special treatment 1056 var special = /href|src|style/.test( name ); 1057 1058 // Safari mis-reports the default selected property of a hidden option 1059 // Accessing the parent's selectedIndex property fixes it 1060 if ( name == "selected" && jQuery.browser.safari ) 1061 elem.parentNode.selectedIndex; 1062 1063 // If applicable, access the attribute via the DOM 0 way 1064 if ( name in elem && notxml && !special ) { 1065 if ( set ){ 1066 // We can't allow the type property to be changed (since it causes problems in IE) 1067 if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode ) 1068 throw "type property can't be changed"; 1069 1070 elem[ name ] = value; 1071 } 1072 1073 // browsers index elements by id/name on forms, give priority to attributes. 1074 if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) 1075 return elem.getAttributeNode( name ).nodeValue; 1076 1077 return elem[ name ]; 1078 } 1079 1080 if ( msie && notxml && name == "style" ) 1081 return jQuery.attr( elem.style, "cssText", value ); 1082 1083 if ( set ) 1084 // convert the value to a string (all browsers do this but IE) see #1070 1085 elem.setAttribute( name, "" + value ); 1086 1087 var attr = msie && notxml && special 1088 // Some attributes require a special call on IE 1089 ? elem.getAttribute( name, 2 ) 1090 : elem.getAttribute( name ); 1091 1092 // Non-existent attributes return null, we normalize to undefined 1093 return attr === null ? undefined : attr; 1094 } 1095 1096 // elem is actually elem.style ... set the style 1097 1098 // IE uses filters for opacity 1099 if ( msie && name == "opacity" ) { 1100 if ( set ) { 1101 // IE has trouble with opacity if it does not have layout 1102 // Force it by setting the zoom level 1103 elem.zoom = 1; 1104 1105 // Set the alpha filter to set the opacity 1106 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) + 1107 (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")"); 1108 } 1109 1110 return elem.filter && elem.filter.indexOf("opacity=") >= 0 ? 1111 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '': 1112 ""; 1113 } 1114 1115 name = name.replace(/-([a-z])/ig, function(all, letter){ 1116 return letter.toUpperCase(); 1117 }); 1118 1119 if ( set ) 1120 elem[ name ] = value; 1121 1122 return elem[ name ]; 1123 }, 1124 1125 trim: function( text ) { 1126 return (text || "").replace( /^\s+|\s+$/g, "" ); 1127 }, 1128 1129 makeArray: function( array ) { 1130 var ret = []; 1131 1132 if( array != null ){ 1133 var i = array.length; 1134 //the window, strings and functions also have 'length' 1135 if( i == null || array.split || array.setInterval || array.call ) 1136 ret[0] = array; 1137 else 1138 while( i ) 1139 ret[--i] = array[i]; 1140 } 1141 1142 return ret; 1143 }, 1144 1145 inArray: function( elem, array ) { 1146 for ( var i = 0, length = array.length; i < length; i++ ) 1147 // Use === because on IE, window == document 1148 if ( array[ i ] === elem ) 1149 return i; 1150 1151 return -1; 1152 }, 1153 1154 merge: function( first, second ) { 1155 // We have to loop this way because IE & Opera overwrite the length 1156 // expando of getElementsByTagName 1157 var i = 0, elem, pos = first.length; 1158 // Also, we need to make sure that the correct elements are being returned 1159 // (IE returns comment nodes in a '*' query) 1160 if ( jQuery.browser.msie ) { 1161 while ( elem = second[ i++ ] ) 1162 if ( elem.nodeType != 8 ) 1163 first[ pos++ ] = elem; 1164 1165 } else 1166 while ( elem = second[ i++ ] ) 1167 first[ pos++ ] = elem; 1168 1169 return first; 1170 }, 1171 1172 unique: function( array ) { 1173 var ret = [], done = {}; 1174 1175 try { 1176 1177 for ( var i = 0, length = array.length; i < length; i++ ) { 1178 var id = jQuery.data( array[ i ] ); 1179 1180 if ( !done[ id ] ) { 1181 done[ id ] = true; 1182 ret.push( array[ i ] ); 1183 } 1184 } 1185 1186 } catch( e ) { 1187 ret = array; 1188 } 1189 1190 return ret; 1191 }, 1192 1193 grep: function( elems, callback, inv ) { 1194 var ret = []; 1195 1196 // Go through the array, only saving the items 1197 // that pass the validator function 1198 for ( var i = 0, length = elems.length; i < length; i++ ) 1199 if ( !inv != !callback( elems[ i ], i ) ) 1200 ret.push( elems[ i ] ); 1201 1202 return ret; 1203 }, 1204 1205 map: function( elems, callback ) { 1206 var ret = []; 1207 1208 // Go through the array, translating each of the items to their 1209 // new value (or values). 1210 for ( var i = 0, length = elems.length; i < length; i++ ) { 1211 var value = callback( elems[ i ], i ); 1212 1213 if ( value != null ) 1214 ret[ ret.length ] = value; 1215 } 1216 1217 return ret.concat.apply( [], ret ); 1218 } 1219 }); 1220 1221 var userAgent = navigator.userAgent.toLowerCase(); 1222 1223 // Figure out what browser is being used 1224 jQuery.browser = { 1225 version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1], 1226 safari: /webkit/.test( userAgent ), 1227 opera: /opera/.test( userAgent ), 1228 msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ), 1229 mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent ) 1230 }; 1231 1232 var styleFloat = jQuery.browser.msie ? 1233 "styleFloat" : 1234 "cssFloat"; 1235 1236 jQuery.extend({ 1237 // Check to see if the W3C box model is being used 1238 boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat", 1239 1240 props: { 1241 "for": "htmlFor", 1242 "class": "className", 1243 "float": styleFloat, 1244 cssFloat: styleFloat, 1245 styleFloat: styleFloat, 1246 readonly: "readOnly", 1247 maxlength: "maxLength", 1248 cellspacing: "cellSpacing" 1249 } 1250 }); 1251 1252 jQuery.each({ 1253 parent: function(elem){return elem.parentNode;}, 1254 parents: function(elem){return jQuery.dir(elem,"parentNode");}, 1255 next: function(elem){return jQuery.nth(elem,2,"nextSibling");}, 1256 prev: function(elem){return jQuery.nth(elem,2,"previousSibling");}, 1257 nextAll: function(elem){return jQuery.dir(elem,"nextSibling");}, 1258 prevAll: function(elem){return jQuery.dir(elem,"previousSibling");}, 1259 siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);}, 1260 children: function(elem){return jQuery.sibling(elem.firstChild);}, 1261 contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);} 1262 }, function(name, fn){ 1263 jQuery.fn[ name ] = function( selector ) { 1264 var ret = jQuery.map( this, fn ); 1265 1266 if ( selector && typeof selector == "string" ) 1267 ret = jQuery.multiFilter( selector, ret ); 1268 1269 return this.pushStack( jQuery.unique( ret ) ); 1270 }; 1271 }); 1272 1273 jQuery.each({ 1274 appendTo: "append", 1275 prependTo: "prepend", 1276 insertBefore: "before", 1277 insertAfter: "after", 1278 replaceAll: "replaceWith" 1279 }, function(name, original){ 1280 jQuery.fn[ name ] = function() { 1281 var args = arguments; 1282 1283 return this.each(function(){ 1284 for ( var i = 0, length = args.length; i < length; i++ ) 1285 jQuery( args[ i ] )[ original ]( this ); 1286 }); 1287 }; 1288 }); 1289 1290 jQuery.each({ 1291 removeAttr: function( name ) { 1292 jQuery.attr( this, name, "" ); 1293 if (this.nodeType == 1) 1294 this.removeAttribute( name ); 1295 }, 1296 1297 addClass: function( classNames ) { 1298 jQuery.className.add( this, classNames ); 1299 }, 1300 1301 removeClass: function( classNames ) { 1302 jQuery.className.remove( this, classNames ); 1303 }, 1304 1305 toggleClass: function( classNames ) { 1306 jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames ); 1307 }, 1308 1309 remove: function( selector ) { 1310 if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) { 1311 // Prevent memory leaks 1312 jQuery( "*", this ).add(this).each(function(){ 1313 jQuery.event.remove(this); 1314 jQuery.removeData(this); 1315 }); 1316 if (this.parentNode) 1317 this.parentNode.removeChild( this ); 1318 } 1319 }, 1320 1321 empty: function() { 1322 // Remove element nodes and prevent memory leaks 1323 jQuery( ">*", this ).remove(); 1324 1325 // Remove any remaining nodes 1326 while ( this.firstChild ) 1327 this.removeChild( this.firstChild ); 1328 } 1329 }, function(name, fn){ 1330 jQuery.fn[ name ] = function(){ 1331 return this.each( fn, arguments ); 1332 }; 1333 }); 1334 1335 jQuery.each([ "Height", "Width" ], function(i, name){ 1336 var type = name.toLowerCase(); 1337 1338 jQuery.fn[ type ] = function( size ) { 1339 // Get window width or height 1340 return this[0] == window ? 1341 // Opera reports document.body.client[Width/Height] properly in both quirks and standards 1342 jQuery.browser.opera && document.body[ "client" + name ] || 1343 1344 // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths) 1345 jQuery.browser.safari && window[ "inner" + name ] || 1346 1347 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode 1348 document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] : 1349 1350 // Get document width or height 1351 this[0] == document ? 1352 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater 1353 Math.max( 1354 Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]), 1355 Math.max(document.body["offset" + name], document.documentElement["offset" + name]) 1356 ) : 1357 1358 // Get or set width or height on the element 1359 size == undefined ? 1360 // Get width or height on the element 1361 (this.length ? jQuery.css( this[0], type ) : null) : 1362 1363 // Set the width or height on the element (default to pixels if value is unitless) 1364 this.css( type, size.constructor == String ? size : size + "px" ); 1365 }; 1366 }); 1367 1368 // Helper function used by the dimensions and offset modules 1369 function num(elem, prop) { 1370 return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0; 1371 }var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ? 1372 "(?:[\\w*_-]|\\\\.)" : 1373 "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)", 1374 quickChild = new RegExp("^>\\s*(" + chars + "+)"), 1375 quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"), 1376 quickClass = new RegExp("^([#.]?)(" + chars + "*)"); 1377 1378 jQuery.extend({ 1379 expr: { 1380 "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);}, 1381 "#": function(a,i,m){return a.getAttribute("id")==m[2];}, 1382 ":": { 1383 // Position Checks 1384 lt: function(a,i,m){return i<m[3]-0;}, 1385 gt: function(a,i,m){return i>m[3]-0;}, 1386 nth: function(a,i,m){return m[3]-0==i;}, 1387 eq: function(a,i,m){return m[3]-0==i;}, 1388 first: function(a,i){return i==0;}, 1389 last: function(a,i,m,r){return i==r.length-1;}, 1390 even: function(a,i){return i%2==0;}, 1391 odd: function(a,i){return i%2;}, 1392 1393 // Child Checks 1394 "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;}, 1395 "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;}, 1396 "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");}, 1397 1398 // Parent Checks 1399 parent: function(a){return a.firstChild;}, 1400 empty: function(a){return !a.firstChild;}, 1401 1402 // Text Check 1403 contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;}, 1404 1405 // Visibility 1406 visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";}, 1407 hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";}, 1408 1409 // Form attributes 1410 enabled: function(a){return !a.disabled;}, 1411 disabled: function(a){return a.disabled;}, 1412 checked: function(a){return a.checked;}, 1413 selected: function(a){return a.selected||jQuery.attr(a,"selected");}, 1414 1415 // Form elements 1416 text: function(a){return "text"==a.type;}, 1417 radio: function(a){return "radio"==a.type;}, 1418 checkbox: function(a){return "checkbox"==a.type;}, 1419 file: function(a){return "file"==a.type;}, 1420 password: function(a){return "password"==a.type;}, 1421 submit: function(a){return "submit"==a.type;}, 1422 image: function(a){return "image"==a.type;}, 1423 reset: function(a){return "reset"==a.type;}, 1424 button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");}, 1425 input: function(a){return /input|select|textarea|button/i.test(a.nodeName);}, 1426 1427 // :has() 1428 has: function(a,i,m){return jQuery.find(m[3],a).length;}, 1429 1430 // :header 1431 header: function(a){return /h\d/i.test(a.nodeName);}, 1432 1433 // :animated 1434 animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;} 1435 } 1436 }, 1437 1438 // The regular expressions that power the parsing engine 1439 parse: [ 1440 // Match: [@value='test'], [@foo] 1441 /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/, 1442 1443 // Match: :contains('foo') 1444 /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/, 1445 1446 // Match: :even, :last-child, #id, .class 1447 new RegExp("^([:.#]*)(" + chars + "+)") 1448 ], 1449 1450 multiFilter: function( expr, elems, not ) { 1451 var old, cur = []; 1452 1453 while ( expr && expr != old ) { 1454 old = expr; 1455 var f = jQuery.filter( expr, elems, not ); 1456 expr = f.t.replace(/^\s*,\s*/, "" ); 1457 cur = not ? elems = f.r : jQuery.merge( cur, f.r ); 1458 } 1459 1460 return cur; 1461 }, 1462 1463 find: function( t, context ) { 1464 // Quickly handle non-string expressions 1465 if ( typeof t != "string" ) 1466 return [ t ]; 1467 1468 // check to make sure context is a DOM element or a document 1469 if ( context && context.nodeType != 1 && context.nodeType != 9) 1470 return [ ]; 1471 1472 // Set the correct context (if none is provided) 1473 context = context || document; 1474 1475 // Initialize the search 1476 var ret = [context], done = [], last, nodeName; 1477 1478 // Continue while a selector expression exists, and while 1479 // we're no longer looping upon ourselves 1480 while ( t && last != t ) { 1481 var r = []; 1482 last = t; 1483 1484 t = jQuery.trim(t); 1485 1486 var foundToken = false, 1487 1488 // An attempt at speeding up child selectors that 1489 // point to a specific element tag 1490 re = quickChild, 1491 1492 m = re.exec(t); 1493 1494 if ( m ) { 1495 nodeName = m[1].toUpperCase(); 1496 1497 // Perform our own iteration and filter 1498 for ( var i = 0; ret[i]; i++ ) 1499 for ( var c = ret[i].firstChild; c; c = c.nextSibling ) 1500 if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) ) 1501 r.push( c ); 1502 1503 ret = r; 1504 t = t.replace( re, "" ); 1505 if ( t.indexOf(" ") == 0 ) continue; 1506 foundToken = true; 1507 } else { 1508 re = /^([>+~])\s*(\w*)/i; 1509 1510 if ( (m = re.exec(t)) != null ) { 1511 r = []; 1512 1513 var merge = {}; 1514 nodeName = m[2].toUpperCase(); 1515 m = m[1]; 1516 1517 for ( var j = 0, rl = ret.length; j < rl; j++ ) { 1518 var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild; 1519 for ( ; n; n = n.nextSibling ) 1520 if ( n.nodeType == 1 ) { 1521 var id = jQuery.data(n); 1522 1523 if ( m == "~" && merge[id] ) break; 1524 1525 if (!nodeName || n.nodeName.toUpperCase() == nodeName ) { 1526 if ( m == "~" ) merge[id] = true; 1527 r.push( n ); 1528 } 1529 1530 if ( m == "+" ) break; 1531 } 1532 } 1533 1534 ret = r; 1535 1536 // And remove the token 1537 t = jQuery.trim( t.replace( re, "" ) ); 1538 foundToken = true; 1539 } 1540 } 1541 1542 // See if there's still an expression, and that we haven't already 1543 // matched a token 1544 if ( t && !foundToken ) { 1545 // Handle multiple expressions 1546 if ( !t.indexOf(",") ) { 1547 // Clean the result set 1548 if ( context == ret[0] ) ret.shift(); 1549 1550 // Merge the result sets 1551 done = jQuery.merge( done, ret ); 1552 1553 // Reset the context 1554 r = ret = [context]; 1555 1556 // Touch up the selector string 1557 t = " " + t.substr(1,t.length); 1558 1559 } else { 1560 // Optimize for the case nodeName#idName 1561 var re2 = quickID; 1562 var m = re2.exec(t); 1563 1564 // Re-organize the results, so that they're consistent 1565 if ( m ) { 1566 m = [ 0, m[2], m[3], m[1] ]; 1567 1568 } else { 1569 // Otherwise, do a traditional filter check for 1570 // ID, class, and element selectors 1571 re2 = quickClass; 1572 m = re2.exec(t); 1573 } 1574 1575 m[2] = m[2].replace(/\\/g, ""); 1576 1577 var elem = ret[ret.length-1]; 1578 1579 // Try to do a global search by ID, where we can 1580 if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) { 1581 // Optimization for HTML document case 1582 var oid = elem.getElementById(m[2]); 1583 1584 // Do a quick check for the existence of the actual ID attribute 1585 // to avoid selecting by the name attribute in IE 1586 // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form 1587 if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] ) 1588 oid = jQuery('[@id="'+m[2]+'"]', elem)[0]; 1589 1590 // Do a quick check for node name (where applicable) so 1591 // that div#foo searches will be really fast 1592 ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : []; 1593 } else { 1594 // We need to find all descendant elements 1595 for ( var i = 0; ret[i]; i++ ) { 1596 // Grab the tag name being searched for 1597 var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2]; 1598 1599 // Handle IE7 being really dumb about <object>s 1600 if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" ) 1601 tag = "param"; 1602 1603 r = jQuery.merge( r, ret[i].getElementsByTagName( tag )); 1604 } 1605 1606 // It's faster to filter by class and be done with it 1607 if ( m[1] == "." ) 1608 r = jQuery.classFilter( r, m[2] ); 1609 1610 // Same with ID filtering 1611 if ( m[1] == "#" ) { 1612 var tmp = []; 1613 1614 // Try to find the element with the ID 1615 for ( var i = 0; r[i]; i++ ) 1616 if ( r[i].getAttribute("id") == m[2] ) { 1617 tmp = [ r[i] ]; 1618 break; 1619 } 1620 1621 r = tmp; 1622 } 1623 1624 ret = r; 1625 } 1626 1627 t = t.replace( re2, "" ); 1628 } 1629 1630 } 1631 1632 // If a selector string still exists 1633 if ( t ) { 1634 // Attempt to filter it 1635 var val = jQuery.filter(t,r); 1636 ret = r = val.r; 1637 t = jQuery.trim(val.t); 1638 } 1639 } 1640 1641 // An error occurred with the selector; 1642 // just return an empty set instead 1643 if ( t ) 1644 ret = []; 1645 1646 // Remove the root context 1647 if ( ret && context == ret[0] ) 1648 ret.shift(); 1649 1650 // And combine the results 1651 done = jQuery.merge( done, ret ); 1652 1653 return done; 1654 }, 1655 1656 classFilter: function(r,m,not){ 1657 m = " " + m + " "; 1658 var tmp = []; 1659 for ( var i = 0; r[i]; i++ ) { 1660 var pass = (" " + r[i].className + " ").indexOf( m ) >= 0; 1661 if ( !not && pass || not && !pass ) 1662 tmp.push( r[i] ); 1663 } 1664 return tmp; 1665 }, 1666 1667 filter: function(t,r,not) { 1668 var last; 1669 1670 // Look for common filter expressions 1671 while ( t && t != last ) { 1672 last = t; 1673 1674 var p = jQuery.parse, m; 1675 1676 for ( var i = 0; p[i]; i++ ) { 1677 m = p[i].exec( t ); 1678 1679 if ( m ) { 1680 // Remove what we just matched 1681 t = t.substring( m[0].length ); 1682 1683 m[2] = m[2].replace(/\\/g, ""); 1684 break; 1685 } 1686 } 1687 1688 if ( !m ) 1689 break; 1690 1691 // :not() is a special case that can be optimized by 1692 // keeping it out of the expression list 1693 if ( m[1] == ":" && m[2] == "not" ) 1694 // optimize if only one selector found (most common case) 1695 r = isSimple.test( m[3] ) ? 1696 jQuery.filter(m[3], r, true).r : 1697 jQuery( r ).not( m[3] ); 1698 1699 // We can get a big speed boost by filtering by class here 1700 else if ( m[1] == "." ) 1701 r = jQuery.classFilter(r, m[2], not); 1702 1703 else if ( m[1] == "[" ) { 1704 var tmp = [], type = m[3]; 1705 1706 for ( var i = 0, rl = r.length; i < rl; i++ ) { 1707 var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ]; 1708 1709 if ( z == null || /href|src|selected/.test(m[2]) ) 1710 z = jQuery.attr(a,m[2]) || ''; 1711 1712 if ( (type == "" && !!z || 1713 type == "=" && z == m[5] || 1714 type == "!=" && z != m[5] || 1715 type == "^=" && z && !z.indexOf(m[5]) || 1716 type == "$=" && z.substr(z.length - m[5].length) == m[5] || 1717 (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not ) 1718 tmp.push( a ); 1719 } 1720 1721 r = tmp; 1722 1723 // We can get a speed boost by handling nth-child here 1724 } else if ( m[1] == ":" && m[2] == "nth-child" ) { 1725 var merge = {}, tmp = [], 1726 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' 1727 test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( 1728 m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" || 1729 !/\D/.test(m[3]) && "0n+" + m[3] || m[3]), 1730 // calculate the numbers (first)n+(last) including if they are negative 1731 first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0; 1732 1733 // loop through all the elements left in the jQuery object 1734 for ( var i = 0, rl = r.length; i < rl; i++ ) { 1735 var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode); 1736 1737 if ( !merge[id] ) { 1738 var c = 1; 1739 1740 for ( var n = parentNode.firstChild; n; n = n.nextSibling ) 1741 if ( n.nodeType == 1 ) 1742 n.nodeIndex = c++; 1743 1744 merge[id] = true; 1745 } 1746 1747 var add = false; 1748 1749 if ( first == 0 ) { 1750 if ( node.nodeIndex == last ) 1751 add = true; 1752 } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 ) 1753 add = true; 1754 1755 if ( add ^ not ) 1756 tmp.push( node ); 1757 } 1758 1759 r = tmp; 1760 1761 // Otherwise, find the expression to execute 1762 } else { 1763 var fn = jQuery.expr[ m[1] ]; 1764 if ( typeof fn == "object" ) 1765 fn = fn[ m[2] ]; 1766 1767 if ( typeof fn == "string" ) 1768 fn = eval("false||function(a,i){return " + fn + ";}"); 1769 1770 // Execute it against the current filter 1771 r = jQuery.grep( r, function(elem, i){ 1772 return fn(elem, i, m, r); 1773 }, not ); 1774 } 1775 } 1776 1777 // Return an array of filtered elements (r) 1778 // and the modified expression string (t) 1779 return { r: r, t: t }; 1780 }, 1781 1782 dir: function( elem, dir ){ 1783 var matched = [], 1784 cur = elem[dir]; 1785 while ( cur && cur != document ) { 1786 if ( cur.nodeType == 1 ) 1787 matched.push( cur ); 1788 cur = cur[dir]; 1789 } 1790 return matched; 1791 }, 1792 1793 nth: function(cur,result,dir,elem){ 1794 result = result || 1; 1795 var num = 0; 1796 1797 for ( ; cur; cur = cur[dir] ) 1798 if ( cur.nodeType == 1 && ++num == result ) 1799 break; 1800 1801 return cur; 1802 }, 1803 1804 sibling: function( n, elem ) { 1805 var r = []; 1806 1807 for ( ; n; n = n.nextSibling ) { 1808 if ( n.nodeType == 1 && n != elem ) 1809 r.push( n ); 1810 } 1811 1812 return r; 1813 } 1814 }); 1815 /* 1816 * A number of helper functions used for managing events. 1817 * Many of the ideas behind this code orignated from 1818 * Dean Edwards' addEvent library. 1819 */ 1820 jQuery.event = { 1821 1822 // Bind an event to an element 1823 // Original by Dean Edwards 1824 add: function(elem, types, handler, data) { 1825 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1826 return; 1827 1828 // For whatever reason, IE has trouble passing the window object 1829 // around, causing it to be cloned in the process 1830 if ( jQuery.browser.msie && elem.setInterval ) 1831 elem = window; 1832 1833 // Make sure that the function being executed has a unique ID 1834 if ( !handler.guid ) 1835 handler.guid = this.guid++; 1836 1837 // if data is passed, bind to handler 1838 if( data != undefined ) { 1839 // Create temporary function pointer to original handler 1840 var fn = handler; 1841 1842 // Create unique handler function, wrapped around original handler 1843 handler = this.proxy( fn, function() { 1844 // Pass arguments and context to original handler 1845 return fn.apply(this, arguments); 1846 }); 1847 1848 // Store data in unique handler 1849 handler.data = data; 1850 } 1851 1852 // Init the element's event structure 1853 var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}), 1854 handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){ 1855 // Handle the second event of a trigger and when 1856 // an event is called after a page has unloaded 1857 if ( typeof jQuery != "undefined" && !jQuery.event.triggered ) 1858 return jQuery.event.handle.apply(arguments.callee.elem, arguments); 1859 }); 1860 // Add elem as a property of the handle function 1861 // This is to prevent a memory leak with non-native 1862 // event in IE. 1863 handle.elem = elem; 1864 1865 // Handle multiple events separated by a space 1866 // jQuery(...).bind("mouseover mouseout", fn); 1867 jQuery.each(types.split(/\s+/), function(index, type) { 1868 // Namespaced event handlers 1869 var parts = type.split("."); 1870 type = parts[0]; 1871 handler.type = parts[1]; 1872 1873 // Get the current list of functions bound to this event 1874 var handlers = events[type]; 1875 1876 // Init the event handler queue 1877 if (!handlers) { 1878 handlers = events[type] = {}; 1879 1880 // Check for a special event handler 1881 // Only use addEventListener/attachEvent if the special 1882 // events handler returns false 1883 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) { 1884 // Bind the global event handler to the element 1885 if (elem.addEventListener) 1886 elem.addEventListener(type, handle, false); 1887 else if (elem.attachEvent) 1888 elem.attachEvent("on" + type, handle); 1889 } 1890 } 1891 1892 // Add the function to the element's handler list 1893 handlers[handler.guid] = handler; 1894 1895 // Keep track of which events have been used, for global triggering 1896 jQuery.event.global[type] = true; 1897 }); 1898 1899 // Nullify elem to prevent memory leaks in IE 1900 elem = null; 1901 }, 1902 1903 guid: 1, 1904 global: {}, 1905 1906 // Detach an event or set of events from an element 1907 remove: function(elem, types, handler) { 1908 // don't do events on text and comment nodes 1909 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1910 return; 1911 1912 var events = jQuery.data(elem, "events"), ret, index; 1913 1914 if ( events ) { 1915 // Unbind all events for the element 1916 if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") ) 1917 for ( var type in events ) 1918 this.remove( elem, type + (types || "") ); 1919 else { 1920 // types is actually an event object here 1921 if ( types.type ) { 1922 handler = types.handler; 1923 types = types.type; 1924 } 1925 1926 // Handle multiple events seperated by a space 1927 // jQuery(...).unbind("mouseover mouseout", fn); 1928 jQuery.each(types.split(/\s+/), function(index, type){ 1929 // Namespaced event handlers 1930 var parts = type.split("."); 1931 type = parts[0]; 1932 1933 if ( events[type] ) { 1934 // remove the given handler for the given type 1935 if ( handler ) 1936 delete events[type][handler.guid]; 1937 1938 // remove all handlers for the given type 1939 else 1940 for ( handler in events[type] ) 1941 // Handle the removal of namespaced events 1942 if ( !parts[1] || events[type][handler].type == parts[1] ) 1943 delete events[type][handler]; 1944 1945 // remove generic event handler if no more handlers exist 1946 for ( ret in events[type] ) break; 1947 if ( !ret ) { 1948 if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) { 1949 if (elem.removeEventListener) 1950 elem.removeEventListener(type, jQuery.data(elem, "handle"), false); 1951 else if (elem.detachEvent) 1952 elem.detachEvent("on" + type, jQuery.data(elem, "handle")); 1953 } 1954 ret = null; 1955 delete events[type]; 1956 } 1957 } 1958 }); 1959 } 1960 1961 // Remove the expando if it's no longer used 1962 for ( ret in events ) break; 1963 if ( !ret ) { 1964 var handle = jQuery.data( elem, "handle" ); 1965 if ( handle ) handle.elem = null; 1966 jQuery.removeData( elem, "events" ); 1967 jQuery.removeData( elem, "handle" ); 1968 } 1969 } 1970 }, 1971 1972 trigger: function(type, data, elem, donative, extra) { 1973 // Clone the incoming data, if any 1974 data = jQuery.makeArray(data); 1975 1976 if ( type.indexOf("!") >= 0 ) { 1977 type = type.slice(0, -1); 1978 var exclusive = true; 1979 } 1980 1981 // Handle a global trigger 1982 if ( !elem ) { 1983 // Only trigger if we've ever bound an event for it 1984 if ( this.global[type] ) 1985 jQuery("*").add([window, document]).trigger(type, data); 1986 1987 // Handle triggering a single element 1988 } else { 1989 // don't do events on text and comment nodes 1990 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1991 return undefined; 1992 1993 var val, ret, fn = jQuery.isFunction( elem[ type ] || null ), 1994 // Check to see if we need to provide a fake event, or not 1995 event = !data[0] || !data[0].preventDefault; 1996 1997 // Pass along a fake event 1998 if ( event ) { 1999 data.unshift({ 2000 type: type, 2001 target: elem, 2002 preventDefault: function(){}, 2003 stopPropagation: function(){}, 2004 timeStamp: now() 2005 }); 2006 data[0][expando] = true; // no need to fix fake event 2007 } 2008 2009 // Enforce the right trigger type 2010 data[0].type = type; 2011 if ( exclusive ) 2012 data[0].exclusive = true; 2013 2014 // Trigger the event, it is assumed that "handle" is a function 2015 var handle = jQuery.data(elem, "handle"); 2016 if ( handle ) 2017 val = handle.apply( elem, data ); 2018 2019 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links) 2020 if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false ) 2021 val = false; 2022 2023 // Extra functions don't get the custom event object 2024 if ( event ) 2025 data.shift(); 2026 2027 // Handle triggering of extra function 2028 if ( extra && jQuery.isFunction( extra ) ) { 2029 // call the extra function and tack the current return value on the end for possible inspection 2030 ret = extra.apply( elem, val == null ? data : data.concat( val ) ); 2031 // if anything is returned, give it precedence and have it overwrite the previous value 2032 if (ret !== undefined) 2033 val = ret; 2034 } 2035 2036 // Trigger the native events (except for clicks on links) 2037 if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) { 2038 this.triggered = true; 2039 try { 2040 elem[ type ](); 2041 // prevent IE from throwing an error for some hidden elements 2042 } catch (e) {} 2043 } 2044 2045 this.triggered = false; 2046 } 2047 2048 return val; 2049 }, 2050 2051 handle: function(event) { 2052 // returned undefined or false 2053 var val, ret, namespace, all, handlers; 2054 2055 event = arguments[0] = jQuery.event.fix( event || window.event ); 2056 2057 // Namespaced event handlers 2058 namespace = event.type.split("."); 2059 event.type = namespace[0]; 2060 namespace = namespace[1]; 2061 // Cache this now, all = true means, any handler 2062 all = !namespace && !event.exclusive; 2063 2064 handlers = ( jQuery.data(this, "events") || {} )[event.type]; 2065 2066 for ( var j in handlers ) { 2067 var handler = handlers[j]; 2068 2069 // Filter the functions by class 2070 if ( all || handler.type == namespace ) { 2071 // Pass in a reference to the handler function itself 2072 // So that we can later remove it 2073 event.handler = handler; 2074 event.data = handler.data; 2075 2076 ret = handler.apply( this, arguments ); 2077 2078 if ( val !== false ) 2079 val = ret; 2080 2081 if ( ret === false ) { 2082 event.preventDefault(); 2083 event.stopPropagation(); 2084 } 2085 } 2086 } 2087 2088 return val; 2089 }, 2090 2091 fix: function(event) { 2092 if ( event[expando] == true ) 2093 return event; 2094 2095 // store a copy of the original event object 2096 // and "clone" to set read-only properties 2097 var originalEvent = event; 2098 event = { originalEvent: originalEvent }; 2099 var 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 timeStamp toElement type view wheelDelta which".split(" "); 2100 for ( var i=props.length; i; i-- ) 2101 event[ props[i] ] = originalEvent[ props[i] ]; 2102 2103 // Mark it as fixed 2104 event[expando] = true; 2105 2106 // add preventDefault and stopPropagation since 2107 // they will not work on the clone 2108 event.preventDefault = function() { 2109 // if preventDefault exists run it on the original event 2110 if (originalEvent.preventDefault) 2111 originalEvent.preventDefault(); 2112 // otherwise set the returnValue property of the original event to false (IE) 2113 originalEvent.returnValue = false; 2114 }; 2115 event.stopPropagation = function() { 2116 // if stopPropagation exists run it on the original event 2117 if (originalEvent.stopPropagation) 2118 originalEvent.stopPropagation(); 2119 // otherwise set the cancelBubble property of the original event to true (IE) 2120 originalEvent.cancelBubble = true; 2121 }; 2122 2123 // Fix timeStamp 2124 event.timeStamp = event.timeStamp || now(); 2125 2126 // Fix target property, if necessary 2127 if ( !event.target ) 2128 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either 2129 2130 // check if target is a textnode (safari) 2131 if ( event.target.nodeType == 3 ) 2132 event.target = event.target.parentNode; 2133 2134 // Add relatedTarget, if necessary 2135 if ( !event.relatedTarget && event.fromElement ) 2136 event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement; 2137 2138 // Calculate pageX/Y if missing and clientX/Y available 2139 if ( event.pageX == null && event.clientX != null ) { 2140 var doc = document.documentElement, body = document.body; 2141 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0); 2142 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0); 2143 } 2144 2145 // Add which for key events 2146 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) 2147 event.which = event.charCode || event.keyCode; 2148 2149 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) 2150 if ( !event.metaKey && event.ctrlKey ) 2151 event.metaKey = event.ctrlKey; 2152 2153 // Add which for click: 1 == left; 2 == middle; 3 == right 2154 // Note: button is not normalized, so don't use it 2155 if ( !event.which && event.button ) 2156 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); 2157 2158 return event; 2159 }, 2160 2161 proxy: function( fn, proxy ){ 2162 // Set the guid of unique handler to the same of original handler, so it can be removed 2163 proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++; 2164 // So proxy can be declared as an argument 2165 return proxy; 2166 }, 2167 2168 special: { 2169 ready: { 2170 setup: function() { 2171 // Make sure the ready event is setup 2172 bindReady(); 2173 return; 2174 }, 2175 2176 teardown: function() { return; } 2177 }, 2178 2179 mouseenter: { 2180 setup: function() { 2181 if ( jQuery.browser.msie ) return false; 2182 jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler); 2183 return true; 2184 }, 2185 2186 teardown: function() { 2187 if ( jQuery.browser.msie ) return false; 2188 jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler); 2189 return true; 2190 }, 2191 2192 handler: function(event) { 2193 // If we actually just moused on to a sub-element, ignore it 2194 if ( withinElement(event, this) ) return true; 2195 // Execute the right handlers by setting the event type to mouseenter 2196 event.type = "mouseenter"; 2197 return jQuery.event.handle.apply(this, arguments); 2198 } 2199 }, 2200 2201 mouseleave: { 2202 setup: function() { 2203 if ( jQuery.browser.msie ) return false; 2204 jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler); 2205 return true; 2206 }, 2207 2208 teardown: function() { 2209 if ( jQuery.browser.msie ) return false; 2210 jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler); 2211 return true; 2212 }, 2213 2214 handler: function(event) { 2215 // If we actually just moused on to a sub-element, ignore it 2216 if ( withinElement(event, this) ) return true; 2217 // Execute the right handlers by setting the event type to mouseleave 2218 event.type = "mouseleave"; 2219 return jQuery.event.handle.apply(this, arguments); 2220 } 2221 } 2222 } 2223 }; 2224 2225 jQuery.fn.extend({ 2226 bind: function( type, data, fn ) { 2227 return type == "unload" ? this.one(type, data, fn) : this.each(function(){ 2228 jQuery.event.add( this, type, fn || data, fn && data ); 2229 }); 2230 }, 2231 2232 one: function( type, data, fn ) { 2233 var one = jQuery.event.proxy( fn || data, function(event) { 2234 jQuery(this).unbind(event, one); 2235 return (fn || data).apply( this, arguments ); 2236 }); 2237 return this.each(function(){ 2238 jQuery.event.add( this, type, one, fn && data); 2239 }); 2240 }, 2241 2242 unbind: function( type, fn ) { 2243 return this.each(function(){ 2244 jQuery.event.remove( this, type, fn ); 2245 }); 2246 }, 2247 2248 trigger: function( type, data, fn ) { 2249 return this.each(function(){ 2250 jQuery.event.trigger( type, data, this, true, fn ); 2251 }); 2252 }, 2253 2254 triggerHandler: function( type, data, fn ) { 2255 return this[0] && jQuery.event.trigger( type, data, this[0], false, fn ); 2256 }, 2257 2258 toggle: function( fn ) { 2259 // Save reference to arguments for access in closure 2260 var args = arguments, i = 1; 2261 2262 // link all the functions, so any of them can unbind this click handler 2263 while( i < args.length ) 2264 jQuery.event.proxy( fn, args[i++] ); 2265 2266 return this.click( jQuery.event.proxy( fn, function(event) { 2267 // Figure out which function to execute 2268 this.lastToggle = ( this.lastToggle || 0 ) % i; 2269 2270 // Make sure that clicks stop 2271 event.preventDefault(); 2272 2273 // and execute the function 2274 return args[ this.lastToggle++ ].apply( this, arguments ) || false; 2275 })); 2276 }, 2277 2278 hover: function(fnOver, fnOut) { 2279 return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut); 2280 }, 2281 2282 ready: function(fn) { 2283 // Attach the listeners 2284 bindReady(); 2285 2286 // If the DOM is already ready 2287 if ( jQuery.isReady ) 2288 // Execute the function immediately 2289 fn.call( document, jQuery ); 2290 2291 // Otherwise, remember the function for later 2292 else 2293 // Add the function to the wait list 2294 jQuery.readyList.push( function() { return fn.call(this, jQuery); } ); 2295 2296 return this; 2297 } 2298 }); 2299 2300 jQuery.extend({ 2301 isReady: false, 2302 readyList: [], 2303 // Handle when the DOM is ready 2304 ready: function() { 2305 // Make sure that the DOM is not already loaded 2306 if ( !jQuery.isReady ) { 2307 // Remember that the DOM is ready 2308 jQuery.isReady = true; 2309 2310 // If there are functions bound, to execute 2311 if ( jQuery.readyList ) { 2312 // Execute all of them 2313 jQuery.each( jQuery.readyList, function(){ 2314 this.call( document ); 2315 }); 2316 2317 // Reset the list of functions 2318 jQuery.readyList = null; 2319 } 2320 2321 // Trigger any bound ready events 2322 jQuery(document).triggerHandler("ready"); 2323 } 2324 } 2325 }); 2326 2327 var readyBound = false; 2328 2329 function bindReady(){ 2330 if ( readyBound ) return; 2331 readyBound = true; 2332 2333 // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event 2334 if ( document.addEventListener && !jQuery.browser.opera) 2335 // Use the handy event callback 2336 document.addEventListener( "DOMContentLoaded", jQuery.ready, false ); 2337 2338 // If IE is used and is not in a frame 2339 // Continually check to see if the document is ready 2340 if ( jQuery.browser.msie && window == top ) (function(){ 2341 if (jQuery.isReady) return; 2342 try { 2343 // If IE is used, use the trick by Diego Perini 2344 // http://javascript.nwbox.com/IEContentLoaded/ 2345 document.documentElement.doScroll("left"); 2346 } catch( error ) { 2347 setTimeout( arguments.callee, 0 ); 2348 return; 2349 } 2350 // and execute any waiting functions 2351 jQuery.ready(); 2352 })(); 2353 2354 if ( jQuery.browser.opera ) 2355 document.addEventListener( "DOMContentLoaded", function () { 2356 if (jQuery.isReady) return; 2357 for (var i = 0; i < document.styleSheets.length; i++) 2358 if (document.styleSheets[i].disabled) { 2359 setTimeout( arguments.callee, 0 ); 2360 return; 2361 } 2362 // and execute any waiting functions 2363 jQuery.ready(); 2364 }, false); 2365 2366 if ( jQuery.browser.safari ) { 2367 var numStyles; 2368 (function(){ 2369 if (jQuery.isReady) return; 2370 if ( document.readyState != "loaded" && document.readyState != "complete" ) { 2371 setTimeout( arguments.callee, 0 ); 2372 return; 2373 } 2374 if ( numStyles === undefined ) 2375 numStyles = jQuery("style, link[rel=stylesheet]").length; 2376 if ( document.styleSheets.length != numStyles ) { 2377 setTimeout( arguments.callee, 0 ); 2378 return; 2379 } 2380 // and execute any waiting functions 2381 jQuery.ready(); 2382 })(); 2383 } 2384 2385 // A fallback to window.onload, that will always work 2386 jQuery.event.add( window, "load", jQuery.ready ); 2387 } 2388 2389 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," + 2390 "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + 2391 "submit,keydown,keypress,keyup,error").split(","), function(i, name){ 2392 2393 // Handle event binding 2394 jQuery.fn[name] = function(fn){ 2395 return fn ? this.bind(name, fn) : this.trigger(name); 2396 }; 2397 }); 2398 2399 // Checks if an event happened on an element within another element 2400 // Used in jQuery.event.special.mouseenter and mouseleave handlers 2401 var withinElement = function(event, elem) { 2402 // Check if mouse(over|out) are still within the same parent element 2403 var parent = event.relatedTarget; 2404 // Traverse up the tree 2405 while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; } 2406 // Return true if we actually just moused on to a sub-element 2407 return parent == elem; 2408 }; 2409 2410 // Prevent memory leaks in IE 2411 // And prevent errors on refresh with events like mouseover in other browsers 2412 // Window isn't included so as not to unbind existing unload events 2413 jQuery(window).bind("unload", function() { 2414 jQuery("*").add(document).unbind(); 2415 }); 2416 jQuery.fn.extend({ 2417 // Keep a copy of the old load 2418 _load: jQuery.fn.load, 2419 2420 load: function( url, params, callback ) { 2421 if ( typeof url != 'string' ) 2422 return this._load( url ); 2423 2424 var off = url.indexOf(" "); 2425 if ( off >= 0 ) { 2426 var selector = url.slice(off, url.length); 2427 url = url.slice(0, off); 2428 } 2429 2430 callback = callback || function(){}; 2431 2432 // Default to a GET request 2433 var type = "GET"; 2434 2435 // If the second parameter was provided 2436 if ( params ) 2437 // If it's a function 2438 if ( jQuery.isFunction( params ) ) { 2439 // We assume that it's the callback 2440 callback = params; 2441 params = null; 2442 2443 // Otherwise, build a param string 2444 } else { 2445 params = jQuery.param( params ); 2446 type = "POST"; 2447 } 2448 2449 var self = this; 2450 2451 // Request the remote document 2452 jQuery.ajax({ 2453 url: url, 2454 type: type, 2455 dataType: "html", 2456 data: params, 2457 complete: function(res, status){ 2458 // If successful, inject the HTML into all the matched elements 2459 if ( status == "success" || status == "notmodified" ) 2460 // See if a selector was specified 2461 self.html( selector ? 2462 // Create a dummy div to hold the results 2463 jQuery("<div/>") 2464 // inject the contents of the document in, removing the scripts 2465 // to avoid any 'Permission Denied' errors in IE 2466 .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, "")) 2467 2468 // Locate the specified elements 2469 .find(selector) : 2470 2471 // If not, just inject the full result 2472 res.responseText ); 2473 2474 self.each( callback, [res.responseText, status, res] ); 2475 } 2476 }); 2477 return this; 2478 }, 2479 2480 serialize: function() { 2481 return jQuery.param(this.serializeArray()); 2482 }, 2483 serializeArray: function() { 2484 return this.map(function(){ 2485 return jQuery.nodeName(this, "form") ? 2486 jQuery.makeArray(this.elements) : this; 2487 }) 2488 .filter(function(){ 2489 return this.name && !this.disabled && 2490 (this.checked || /select|textarea/i.test(this.nodeName) || 2491 /text|hidden|password/i.test(this.type)); 2492 }) 2493 .map(function(i, elem){ 2494 var val = jQuery(this).val(); 2495 return val == null ? null : 2496 val.constructor == Array ? 2497 jQuery.map( val, function(val, i){ 2498 return {name: elem.name, value: val}; 2499 }) : 2500 {name: elem.name, value: val}; 2501 }).get(); 2502 } 2503 }); 2504 2505 // Attach a bunch of functions for handling common AJAX events 2506 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){ 2507 jQuery.fn[o] = function(f){ 2508 return this.bind(o, f); 2509 }; 2510 }); 2511 2512 var jsc = now(); 2513 2514 jQuery.extend({ 2515 get: function( url, data, callback, type ) { 2516 // shift arguments if data argument was ommited 2517 if ( jQuery.isFunction( data ) ) { 2518 callback = data; 2519 data = null; 2520 } 2521 2522 return jQuery.ajax({ 2523 type: "GET", 2524 url: url, 2525 data: data, 2526 success: callback, 2527 dataType: type 2528 }); 2529 }, 2530 2531 getScript: function( url, callback ) { 2532 return jQuery.get(url, null, callback, "script"); 2533 }, 2534 2535 getJSON: function( url, data, callback ) { 2536 return jQuery.get(url, data, callback, "json"); 2537 }, 2538 2539 post: function( url, data, callback, type ) { 2540 if ( jQuery.isFunction( data ) ) { 2541 callback = data; 2542 data = {}; 2543 } 2544 2545 return jQuery.ajax({ 2546 type: "POST", 2547 url: url, 2548 data: data, 2549 success: callback, 2550 dataType: type 2551 }); 2552 }, 2553 2554 ajaxSetup: function( settings ) { 2555 jQuery.extend( jQuery.ajaxSettings, settings ); 2556 }, 2557 2558 ajaxSettings: { 2559 url: location.href, 2560 global: true, 2561 type: "GET", 2562 timeout: 0, 2563 contentType: "application/x-www-form-urlencoded", 2564 processData: true, 2565 async: true, 2566 data: null, 2567 username: null, 2568 password: null, 2569 accepts: { 2570 xml: "application/xml, text/xml", 2571 html: "text/html", 2572 script: "text/javascript, application/javascript", 2573 json: "application/json, text/javascript", 2574 text: "text/plain", 2575 _default: "*/*" 2576 } 2577 }, 2578 2579 // Last-Modified header cache for next request 2580 lastModified: {}, 2581 2582 ajax: function( s ) { 2583 // Extend the settings, but re-extend 's' so that it can be 2584 // checked again later (in the test suite, specifically) 2585 s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s)); 2586 2587 var jsonp, jsre = /=\?(&|$)/g, status, data, 2588 type = s.type.toUpperCase(); 2589 2590 // convert data if not already a string 2591 if ( s.data && s.processData && typeof s.data != "string" ) 2592 s.data = jQuery.param(s.data); 2593 2594 // Handle JSONP Parameter Callbacks 2595 if ( s.dataType == "jsonp" ) { 2596 if ( type == "GET" ) { 2597 if ( !s.url.match(jsre) ) 2598 s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?"; 2599 } else if ( !s.data || !s.data.match(jsre) ) 2600 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?"; 2601 s.dataType = "json"; 2602 } 2603 2604 // Build temporary JSONP function 2605 if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) { 2606 jsonp = "jsonp" + jsc++; 2607 2608 // Replace the =? sequence both in the query string and the data 2609 if ( s.data ) 2610 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1"); 2611 s.url = s.url.replace(jsre, "=" + jsonp + "$1"); 2612 2613 // We need to make sure 2614 // that a JSONP style response is executed properly 2615 s.dataType = "script"; 2616 2617 // Handle JSONP-style loading 2618 window[ jsonp ] = function(tmp){ 2619 data = tmp; 2620 success(); 2621 complete(); 2622 // Garbage collect 2623 window[ jsonp ] = undefined; 2624 try{ delete window[ jsonp ]; } catch(e){} 2625 if ( head ) 2626 head.removeChild( script ); 2627 }; 2628 } 2629 2630 if ( s.dataType == "script" && s.cache == null ) 2631 s.cache = false; 2632 2633 if ( s.cache === false && type == "GET" ) { 2634 var ts = now(); 2635 // try replacing _= if it is there 2636 var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2"); 2637 // if nothing was replaced, add timestamp to the end 2638 s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : ""); 2639 } 2640 2641 // If data is available, append data to url for get requests 2642 if ( s.data && type == "GET" ) { 2643 s.url += (s.url.match(/\?/) ? "&" : "?") + s.data; 2644 2645 // IE likes to send both get and post data, prevent this 2646 s.data = null; 2647 } 2648 2649 // Watch for a new set of requests 2650 if ( s.global && ! jQuery.active++ ) 2651 jQuery.event.trigger( "ajaxStart" ); 2652 2653 // Matches an absolute URL, and saves the domain 2654 var remote = /^(?:\w+:)?\/\/([^\/?#]+)/; 2655 2656 // If we're requesting a remote document 2657 // and trying to load JSON or Script with a GET 2658 if ( s.dataType == "script" && type == "GET" 2659 && remote.test(s.url) && remote.exec(s.url)[1] != location.host ){ 2660 var head = document.getElementsByTagName("head")[0]; 2661 var script = document.createElement("script"); 2662 script.src = s.url; 2663 if (s.scriptCharset) 2664 script.charset = s.scriptCharset; 2665 2666 // Handle Script loading 2667 if ( !jsonp ) { 2668 var done = false; 2669 2670 // Attach handlers for all browsers 2671 script.onload = script.onreadystatechange = function(){ 2672 if ( !done && (!this.readyState || 2673 this.readyState == "loaded" || this.readyState == "complete") ) { 2674 done = true; 2675 success(); 2676 complete(); 2677 head.removeChild( script ); 2678 } 2679 }; 2680 } 2681 2682 head.appendChild(script); 2683 2684 // We handle everything using the script element injection 2685 return undefined; 2686 } 2687 2688 var requestDone = false; 2689 2690 // Create the request object; Microsoft failed to properly 2691 // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available 2692 var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(); 2693 2694 // Open the socket 2695 // Passing null username, generates a login popup on Opera (#2865) 2696 if( s.username ) 2697 xhr.open(type, s.url, s.async, s.username, s.password); 2698 else 2699 xhr.open(type, s.url, s.async); 2700 2701 // Need an extra try/catch for cross domain requests in Firefox 3 2702 try { 2703 // Set the correct header, if data is being sent 2704 if ( s.data ) 2705 xhr.setRequestHeader("Content-Type", s.contentType); 2706 2707 // Set the If-Modified-Since header, if ifModified mode. 2708 if ( s.ifModified ) 2709 xhr.setRequestHeader("If-Modified-Since", 2710 jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" ); 2711 2712 // Set header so the called script knows that it's an XMLHttpRequest 2713 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 2714 2715 // Set the Accepts header for the server, depending on the dataType 2716 xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ? 2717 s.accepts[ s.dataType ] + ", */*" : 2718 s.accepts._default ); 2719 } catch(e){} 2720 2721 // Allow custom headers/mimetypes 2722 if ( s.beforeSend && s.beforeSend(xhr, s) === false ) { 2723 // cleanup active request counter 2724 s.global && jQuery.active--; 2725 // close opended socket 2726 xhr.abort(); 2727 return false; 2728 } 2729 2730 if ( s.global ) 2731 jQuery.event.trigger("ajaxSend", [xhr, s]); 2732 2733 // Wait for a response to come back 2734 var onreadystatechange = function(isTimeout){ 2735 // The transfer is complete and the data is available, or the request timed out 2736 if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) { 2737 requestDone = true; 2738 2739 // clear poll interval 2740 if (ival) { 2741 clearInterval(ival); 2742 ival = null; 2743 } 2744 2745 status = isTimeout == "timeout" && "timeout" || 2746 !jQuery.httpSuccess( xhr ) && "error" || 2747 s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" || 2748 "success"; 2749 2750 if ( status == "success" ) { 2751 // Watch for, and catch, XML document parse errors 2752 try { 2753 // process the data (runs the xml through httpData regardless of callback) 2754 data = jQuery.httpData( xhr, s.dataType, s.dataFilter ); 2755 } catch(e) { 2756 status = "parsererror"; 2757 } 2758 } 2759 2760 // Make sure that the request was successful or notmodified 2761 if ( status == "success" ) { 2762 // Cache Last-Modified header, if ifModified mode. 2763 var modRes; 2764 try { 2765 modRes = xhr.getResponseHeader("Last-Modified"); 2766 } catch(e) {} // swallow exception thrown by FF if header is not available 2767 2768 if ( s.ifModified && modRes ) 2769 jQuery.lastModified[s.url] = modRes; 2770 2771 // JSONP handles its own success callback 2772 if ( !jsonp ) 2773 success(); 2774 } else 2775 jQuery.handleError(s, xhr, status); 2776 2777 // Fire the complete handlers 2778 complete(); 2779 2780 // Stop memory leaks 2781 if ( s.async ) 2782 xhr = null; 2783 } 2784 }; 2785 2786 if ( s.async ) { 2787 // don't attach the handler to the request, just poll it instead 2788 var ival = setInterval(onreadystatechange, 13); 2789 2790 // Timeout checker 2791 if ( s.timeout > 0 ) 2792 setTimeout(function(){ 2793 // Check to see if the request is still happening 2794 if ( xhr ) { 2795 // Cancel the request 2796 xhr.abort(); 2797 2798 if( !requestDone ) 2799 onreadystatechange( "timeout" ); 2800 } 2801 }, s.timeout); 2802 } 2803 2804 // Send the data 2805 try { 2806 xhr.send(s.data); 2807 } catch(e) { 2808 jQuery.handleError(s, xhr, null, e); 2809 } 2810 2811 // firefox 1.5 doesn't fire statechange for sync requests 2812 if ( !s.async ) 2813 onreadystatechange(); 2814 2815 function success(){ 2816 // If a local callback was specified, fire it and pass it the data 2817 if ( s.success ) 2818 s.success( data, status ); 2819 2820 // Fire the global callback 2821 if ( s.global ) 2822 jQuery.event.trigger( "ajaxSuccess", [xhr, s] ); 2823 } 2824 2825 function complete(){ 2826 // Process result 2827 if ( s.complete ) 2828 s.complete(xhr, status); 2829 2830 // The request was completed 2831 if ( s.global ) 2832 jQuery.event.trigger( "ajaxComplete", [xhr, s] ); 2833 2834 // Handle the global AJAX counter 2835 if ( s.global && ! --jQuery.active ) 2836 jQuery.event.trigger( "ajaxStop" ); 2837 } 2838 2839 // return XMLHttpRequest to allow aborting the request etc. 2840 return xhr; 2841 }, 2842 2843 handleError: function( s, xhr, status, e ) { 2844 // If a local callback was specified, fire it 2845 if ( s.error ) s.error( xhr, status, e ); 2846 2847 // Fire the global callback 2848 if ( s.global ) 2849 jQuery.event.trigger( "ajaxError", [xhr, s, e] ); 2850 }, 2851 2852 // Counter for holding the number of active queries 2853 active: 0, 2854 2855 // Determines if an XMLHttpRequest was successful or not 2856 httpSuccess: function( xhr ) { 2857 try { 2858 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450 2859 return !xhr.status && location.protocol == "file:" || 2860 ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 || 2861 jQuery.browser.safari && xhr.status == undefined; 2862 } catch(e){} 2863 return false; 2864 }, 2865 2866 // Determines if an XMLHttpRequest returns NotModified 2867 httpNotModified: function( xhr, url ) { 2868 try { 2869 var xhrRes = xhr.getResponseHeader("Last-Modified"); 2870 2871 // Firefox always returns 200. check Last-Modified date 2872 return xhr.status == 304 || xhrRes == jQuery.lastModified[url] || 2873 jQuery.browser.safari && xhr.status == undefined; 2874 } catch(e){} 2875 return false; 2876 }, 2877 2878 httpData: function( xhr, type, filter ) { 2879 var ct = xhr.getResponseHeader("content-type"), 2880 xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0, 2881 data = xml ? xhr.responseXML : xhr.responseText; 2882 2883 if ( xml && data.documentElement.tagName == "parsererror" ) 2884 throw "parsererror"; 2885 2886 // Allow a pre-filtering function to sanitize the response 2887 if( filter ) 2888 data = filter( data, type ); 2889 2890 // If the type is "script", eval it in global context 2891 if ( type == "script" ) 2892 jQuery.globalEval( data ); 2893 2894 // Get the JavaScript object, if JSON is used. 2895 if ( type == "json" ) 2896 data = eval("(" + data + ")"); 2897 2898 return data; 2899 }, 2900 2901 // Serialize an array of form elements or a set of 2902 // key/values into a query string 2903 param: function( a ) { 2904 var s = []; 2905 2906 // If an array was passed in, assume that it is an array 2907 // of form elements 2908 if ( a.constructor == Array || a.jquery ) 2909 // Serialize the form elements 2910 jQuery.each( a, function(){ 2911 s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) ); 2912 }); 2913 2914 // Otherwise, assume that it's an object of key/value pairs 2915 else 2916 // Serialize the key/values 2917 for ( var j in a ) 2918 // If the value is an array then the key names need to be repeated 2919 if ( a[j] && a[j].constructor == Array ) 2920 jQuery.each( a[j], function(){ 2921 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) ); 2922 }); 2923 else 2924 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( jQuery.isFunction(a[j]) ? a[j]() : a[j] ) ); 2925 2926 // Return the resulting serialization 2927 return s.join("&").replace(/%20/g, "+"); 2928 } 2929 2930 }); 2931 jQuery.fn.extend({ 2932 show: function(speed,callback){ 2933 return speed ? 2934 this.animate({ 2935 height: "show", width: "show", opacity: "show" 2936 }, speed, callback) : 2937 2938 this.filter(":hidden").each(function(){ 2939 this.style.display = this.oldblock || ""; 2940 if ( jQuery.css(this,"display") == "none" ) { 2941 var elem = jQuery("<" + this.tagName + " />").appendTo("body"); 2942 this.style.display = elem.css("display"); 2943 // handle an edge condition where css is - div { display:none; } or similar 2944 if (this.style.display == "none") 2945 this.style.display = "block"; 2946 elem.remove(); 2947 } 2948 }).end(); 2949 }, 2950 2951 hide: function(speed,callback){ 2952 return speed ? 2953 this.animate({ 2954 height: "hide", width: "hide", opacity: "hide" 2955 }, speed, callback) : 2956 2957 this.filter(":visible").each(function(){ 2958 this.oldblock = this.oldblock || jQuery.css(this,"display"); 2959 this.style.display = "none"; 2960 }).end(); 2961 }, 2962 2963 // Save the old toggle function 2964 _toggle: jQuery.fn.toggle, 2965 2966 toggle: function( fn, fn2 ){ 2967 return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ? 2968 this._toggle.apply( this, arguments ) : 2969 fn ? 2970 this.animate({ 2971 height: "toggle", width: "toggle", opacity: "toggle" 2972 }, fn, fn2) : 2973 this.each(function(){ 2974 jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ](); 2975 }); 2976 }, 2977 2978 slideDown: function(speed,callback){ 2979 return this.animate({height: "show"}, speed, callback); 2980 }, 2981 2982 slideUp: function(speed,callback){ 2983 return this.animate({height: "hide"}, speed, callback); 2984 }, 2985 2986 slideToggle: function(speed, callback){ 2987 return this.animate({height: "toggle"}, speed, callback); 2988 }, 2989 2990 fadeIn: function(speed, callback){ 2991 return this.animate({opacity: "show"}, speed, callback); 2992 }, 2993 2994 fadeOut: function(speed, callback){ 2995 return this.animate({opacity: "hide"}, speed, callback); 2996 }, 2997 2998 fadeTo: function(speed,to,callback){ 2999 return this.animate({opacity: to}, speed, callback); 3000 }, 3001 3002 animate: function( prop, speed, easing, callback ) { 3003 var optall = jQuery.speed(speed, easing, callback); 3004 3005 return this[ optall.queue === false ? "each" : "queue" ](function(){ 3006 if ( this.nodeType != 1) 3007 return false; 3008 3009 var opt = jQuery.extend({}, optall), p, 3010 hidden = jQuery(this).is(":hidden"), self = this; 3011 3012 for ( p in prop ) { 3013 if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden ) 3014 return opt.complete.call(this); 3015 3016 if ( p == "height" || p == "width" ) { 3017 // Store display property 3018 opt.display = jQuery.css(this, "display"); 3019 3020 // Make sure that nothing sneaks out 3021 opt.overflow = this.style.overflow; 3022 } 3023 } 3024 3025 if ( opt.overflow != null ) 3026 this.style.overflow = "hidden"; 3027 3028 opt.curAnim = jQuery.extend({}, prop); 3029 3030 jQuery.each( prop, function(name, val){ 3031 var e = new jQuery.fx( self, opt, name ); 3032 3033 if ( /toggle|show|hide/.test(val) ) 3034 e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop ); 3035 else { 3036 var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/), 3037 start = e.cur(true) || 0; 3038 3039 if ( parts ) { 3040 var end = parseFloat(parts[2]), 3041 unit = parts[3] || "px"; 3042 3043 // We need to compute starting value 3044 if ( unit != "px" ) { 3045 self.style[ name ] = (end || 1) + unit; 3046 start = ((end || 1) / e.cur(true)) * start; 3047 self.style[ name ] = start + unit; 3048 } 3049 3050 // If a +=/-= token was provided, we're doing a relative animation 3051 if ( parts[1] ) 3052 end = ((parts[1] == "-=" ? -1 : 1) * end) + start; 3053 3054 e.custom( start, end, unit ); 3055 } else 3056 e.custom( start, val, "" ); 3057 } 3058 }); 3059 3060 // For JS strict compliance 3061 return true; 3062 }); 3063 }, 3064 3065 queue: function(type, fn){ 3066 if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) { 3067 fn = type; 3068 type = "fx"; 3069 } 3070 3071 if ( !type || (typeof type == "string" && !fn) ) 3072 return queue( this[0], type ); 3073 3074 return this.each(function(){ 3075 if ( fn.constructor == Array ) 3076 queue(this, type, fn); 3077 else { 3078 queue(this, type).push( fn ); 3079 3080 if ( queue(this, type).length == 1 ) 3081 fn.call(this); 3082 } 3083 }); 3084 }, 3085 3086 stop: function(clearQueue, gotoEnd){ 3087 var timers = jQuery.timers; 3088 3089 if (clearQueue) 3090 this.queue([]); 3091 3092 this.each(function(){ 3093 // go in reverse order so anything added to the queue during the loop is ignored 3094 for ( var i = timers.length - 1; i >= 0; i-- ) 3095 if ( timers[i].elem == this ) { 3096 if (gotoEnd) 3097 // force the next step to be the last 3098 timers[i](true); 3099 timers.splice(i, 1); 3100 } 3101 }); 3102 3103 // start the next in the queue if the last step wasn't forced 3104 if (!gotoEnd) 3105 this.dequeue(); 3106 3107 return this; 3108 } 3109 3110 }); 3111 3112 var queue = function( elem, type, array ) { 3113 if ( elem ){ 3114 3115 type = type || "fx"; 3116 3117 var q = jQuery.data( elem, type + "queue" ); 3118 3119 if ( !q || array ) 3120 q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) ); 3121 3122 } 3123 return q; 3124 }; 3125 3126 jQuery.fn.dequeue = function(type){ 3127 type = type || "fx"; 3128 3129 return this.each(function(){ 3130 var q = queue(this, type); 3131 3132 q.shift(); 3133 3134 if ( q.length ) 3135 q[0].call( this ); 3136 }); 3137 }; 3138 3139 jQuery.extend({ 3140 3141 speed: function(speed, easing, fn) { 3142 var opt = speed && speed.constructor == Object ? speed : { 3143 complete: fn || !fn && easing || 3144 jQuery.isFunction( speed ) && speed, 3145 duration: speed, 3146 easing: fn && easing || easing && easing.constructor != Function && easing 3147 }; 3148 3149 opt.duration = (opt.duration && opt.duration.constructor == Number ? 3150 opt.duration : 3151 jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def; 3152 3153 // Queueing 3154 opt.old = opt.complete; 3155 opt.complete = function(){ 3156 if ( opt.queue !== false ) 3157 jQuery(this).dequeue(); 3158 if ( jQuery.isFunction( opt.old ) ) 3159 opt.old.call( this ); 3160 }; 3161 3162 return opt; 3163 }, 3164 3165 easing: { 3166 linear: function( p, n, firstNum, diff ) { 3167 return firstNum + diff * p; 3168 }, 3169 swing: function( p, n, firstNum, diff ) { 3170 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum; 3171 } 3172 }, 3173 3174 timers: [], 3175 timerId: null, 3176 3177 fx: function( elem, options, prop ){ 3178 this.options = options; 3179 this.elem = elem; 3180 this.prop = prop; 3181 3182 if ( !options.orig ) 3183 options.orig = {}; 3184 } 3185 3186 }); 3187 3188 jQuery.fx.prototype = { 3189 3190 // Simple function for setting a style value 3191 update: function(){ 3192 if ( this.options.step ) 3193 this.options.step.call( this.elem, this.now, this ); 3194 3195 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); 3196 3197 // Set display property to block for height/width animations 3198 if ( this.prop == "height" || this.prop == "width" ) 3199 this.elem.style.display = "block"; 3200 }, 3201 3202 // Get the current size 3203 cur: function(force){ 3204 if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null ) 3205 return this.elem[ this.prop ]; 3206 3207 var r = parseFloat(jQuery.css(this.elem, this.prop, force)); 3208 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0; 3209 }, 3210 3211 // Start an animation from one number to another 3212 custom: function(from, to, unit){ 3213 this.startTime = now(); 3214 this.start = from; 3215 this.end = to; 3216 this.unit = unit || this.unit || "px"; 3217 this.now = this.start; 3218 this.pos = this.state = 0; 3219 this.update(); 3220 3221 var self = this; 3222 function t(gotoEnd){ 3223 return self.step(gotoEnd); 3224 } 3225 3226 t.elem = this.elem; 3227 3228 jQuery.timers.push(t); 3229 3230 if ( jQuery.timerId == null ) { 3231 jQuery.timerId = setInterval(function(){ 3232 var timers = jQuery.timers; 3233 3234 for ( var i = 0; i < timers.length; i++ ) 3235 if ( !timers[i]() ) 3236 timers.splice(i--, 1); 3237 3238 if ( !timers.length ) { 3239 clearInterval( jQuery.timerId ); 3240 jQuery.timerId = null; 3241 } 3242 }, 13); 3243 } 3244 }, 3245 3246 // Simple 'show' function 3247 show: function(){ 3248 // Remember where we started, so that we can go back to it later 3249 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop ); 3250 this.options.show = true; 3251 3252 // Begin the animation 3253 this.custom(0, this.cur()); 3254 3255 // Make sure that we start at a small width/height to avoid any 3256 // flash of content 3257 if ( this.prop == "width" || this.prop == "height" ) 3258 this.elem.style[this.prop] = "1px"; 3259 3260 // Start by showing the element 3261 jQuery(this.elem).show(); 3262 }, 3263 3264 // Simple 'hide' function 3265 hide: function(){ 3266 // Remember where we started, so that we can go back to it later 3267 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop ); 3268 this.options.hide = true; 3269 3270 // Begin the animation 3271 this.custom(this.cur(), 0); 3272 }, 3273 3274 // Each step of an animation 3275 step: function(gotoEnd){ 3276 var t = now(); 3277 3278 if ( gotoEnd || t > this.options.duration + this.startTime ) { 3279 this.now = this.end; 3280 this.pos = this.state = 1; 3281 this.update(); 3282 3283 this.options.curAnim[ this.prop ] = true; 3284 3285 var done = true; 3286 for ( var i in this.options.curAnim ) 3287 if ( this.options.curAnim[i] !== true ) 3288 done = false; 3289 3290 if ( done ) { 3291 if ( this.options.display != null ) { 3292 // Reset the overflow 3293 this.elem.style.overflow = this.options.overflow; 3294 3295 // Reset the display 3296 this.elem.style.display = this.options.display; 3297 if ( jQuery.css(this.elem, "display") == "none" ) 3298 this.elem.style.display = "block"; 3299 } 3300 3301 // Hide the element if the "hide" operation was done 3302 if ( this.options.hide ) 3303 this.elem.style.display = "none"; 3304 3305 // Reset the properties, if the item has been hidden or shown 3306 if ( this.options.hide || this.options.show ) 3307 for ( var p in this.options.curAnim ) 3308 jQuery.attr(this.elem.style, p, this.options.orig[p]); 3309 } 3310 3311 if ( done ) 3312 // Execute the complete function 3313 this.options.complete.call( this.elem ); 3314 3315 return false; 3316 } else { 3317 var n = t - this.startTime; 3318 this.state = n / this.options.duration; 3319 3320 // Perform the easing function, defaults to swing 3321 this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration); 3322 this.now = this.start + ((this.end - this.start) * this.pos); 3323 3324 // Perform the next step of the animation 3325 this.update(); 3326 } 3327 3328 return true; 3329 } 3330 3331 }; 3332 3333 jQuery.extend( jQuery.fx, { 3334 speeds:{ 3335 slow: 600, 3336 fast: 200, 3337 // Default speed 3338 def: 400 3339 }, 3340 step: { 3341 scrollLeft: function(fx){ 3342 fx.elem.scrollLeft = fx.now; 3343 }, 3344 3345 scrollTop: function(fx){ 3346 fx.elem.scrollTop = fx.now; 3347 }, 3348 3349 opacity: function(fx){ 3350 jQuery.attr(fx.elem.style, "opacity", fx.now); 3351 }, 3352 3353 _default: function(fx){ 3354 fx.elem.style[ fx.prop ] = fx.now + fx.unit; 3355 } 3356 } 3357 }); 3358 // The Offset Method 3359 // Originally By Brandon Aaron, part of the Dimension Plugin 3360 // http://jquery.com/plugins/project/dimensions 3361 jQuery.fn.offset = function() { 3362 var left = 0, top = 0, elem = this[0], results; 3363 3364 if ( elem ) with ( jQuery.browser ) { 3365 var parent = elem.parentNode, 3366 offsetChild = elem, 3367 offsetParent = elem.offsetParent, 3368 doc = elem.ownerDocument, 3369 safari2 = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent), 3370 css = jQuery.curCSS, 3371 fixed = css(elem, "position") == "fixed"; 3372 3373 // Use getBoundingClientRect if available 3374 if ( elem.getBoundingClientRect ) { 3375 var box = elem.getBoundingClientRect(); 3376 3377 // Add the document scroll offsets 3378 add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft), 3379 box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)); 3380 3381 // IE adds the HTML element's border, by default it is medium which is 2px 3382 // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; } 3383 // IE 7 standards mode, the border is always 2px 3384 // This border/offset is typically represented by the clientLeft and clientTop properties 3385 // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS 3386 // Therefore this method will be off by 2px in IE while in quirksmode 3387 add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop ); 3388 3389 // Otherwise loop through the offsetParents and parentNodes 3390 } else { 3391 3392 // Initial element offsets 3393 add( elem.offsetLeft, elem.offsetTop ); 3394 3395 // Get parent offsets 3396 while ( offsetParent ) { 3397 // Add offsetParent offsets 3398 add( offsetParent.offsetLeft, offsetParent.offsetTop ); 3399 3400 // Mozilla and Safari > 2 does not include the border on offset parents 3401 // However Mozilla adds the border for table or table cells 3402 if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 ) 3403 border( offsetParent ); 3404 3405 // Add the document scroll offsets if position is fixed on any offsetParent 3406 if ( !fixed && css(offsetParent, "position") == "fixed" ) 3407 fixed = true; 3408 3409 // Set offsetChild to previous offsetParent unless it is the body element 3410 offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent; 3411 // Get next offsetParent 3412 offsetParent = offsetParent.offsetParent; 3413 } 3414 3415 // Get parent scroll offsets 3416 while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) { 3417 // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug 3418 if ( !/^inline|table.*$/i.test(css(parent, "display")) ) 3419 // Subtract parent scroll offsets 3420 add( -parent.scrollLeft, -parent.scrollTop ); 3421 3422 // Mozilla does not add the border for a parent that has overflow != visible 3423 if ( mozilla && css(parent, "overflow") != "visible" ) 3424 border( parent ); 3425 3426 // Get next parent 3427 parent = parent.parentNode; 3428 } 3429 3430 // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild 3431 // Mozilla doubles body offsets with a non-absolutely positioned offsetChild 3432 if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) || 3433 (mozilla && css(offsetChild, "position") != "absolute") ) 3434 add( -doc.body.offsetLeft, -doc.body.offsetTop ); 3435 3436 // Add the document scroll offsets if position is fixed 3437 if ( fixed ) 3438 add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft), 3439 Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)); 3440 } 3441 3442 // Return an object with top and left properties 3443 results = { top: top, left: left }; 3444 } 3445 3446 function border(elem) { 3447 add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) ); 3448 } 3449 3450 function add(l, t) { 3451 left += parseInt(l, 10) || 0; 3452 top += parseInt(t, 10) || 0; 3453 } 3454 3455 return results; 3456 }; 3457 3458 3459 jQuery.fn.extend({ 3460 position: function() { 3461 var left = 0, top = 0, results; 3462 3463 if ( this[0] ) { 3464 // Get *real* offsetParent 3465 var offsetParent = this.offsetParent(), 3466 3467 // Get correct offsets 3468 offset = this.offset(), 3469 parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset(); 3470 3471 // Subtract element margins 3472 // note: when an element has margin: auto the offsetLeft and marginLeft 3473 // are the same in Safari causing offset.left to incorrectly be 0 3474 offset.top -= num( this, 'marginTop' ); 3475 offset.left -= num( this, 'marginLeft' ); 3476 3477 // Add offsetParent borders 3478 parentOffset.top += num( offsetParent, 'borderTopWidth' ); 3479 parentOffset.left += num( offsetParent, 'borderLeftWidth' ); 3480 3481 // Subtract the two offsets 3482 results = { 3483 top: offset.top - parentOffset.top, 3484 left: offset.left - parentOffset.left 3485 }; 3486 } 3487 3488 return results; 3489 }, 3490 3491 offsetParent: function() { 3492 var offsetParent = this[0].offsetParent; 3493 while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') ) 3494 offsetParent = offsetParent.offsetParent; 3495 return jQuery(offsetParent); 3496 } 3497 }); 3498 3499 3500 // Create scrollLeft and scrollTop methods 3501 jQuery.each( ['Left', 'Top'], function(i, name) { 3502 var method = 'scroll' + name; 3503 3504 jQuery.fn[ method ] = function(val) { 3505 if (!this[0]) return; 3506 3507 return val != undefined ? 3508 3509 // Set the scroll offset 3510 this.each(function() { 3511 this == window || this == document ? 3512 window.scrollTo( 3513 !i ? val : jQuery(window).scrollLeft(), 3514 i ? val : jQuery(window).scrollTop() 3515 ) : 3516 this[ method ] = val; 3517 }) : 3518 3519 // Return the scroll offset 3520 this[0] == window || this[0] == document ? 3521 self[ i ? 'pageYOffset' : 'pageXOffset' ] || 3522 jQuery.boxModel && document.documentElement[ method ] || 3523 document.body[ method ] : 3524 this[0][ method ]; 3525 }; 3526 }); 3527 // Create innerHeight, innerWidth, outerHeight and outerWidth methods 3528 jQuery.each([ "Height", "Width" ], function(i, name){ 3529 3530 var tl = i ? "Left" : "Top", // top or left 3531 br = i ? "Right" : "Bottom"; // bottom or right 3532 3533 // innerHeight and innerWidth 3534 jQuery.fn["inner" + name] = function(){ 3535 return this[ name.toLowerCase() ]() + 3536 num(this, "padding" + tl) + 3537 num(this, "padding" + br); 3538 }; 3539 3540 // outerHeight and outerWidth 3541 jQuery.fn["outer" + name] = function(margin) { 3542 return this["inner" + name]() + 3543 num(this, "border" + tl + "Width") + 3544 num(this, "border" + br + "Width") + 3545 (margin ? 3546 num(this, "margin" + tl) + num(this, "margin" + br) : 0); 3547 }; 3548 3549 });})();1 (function(){ 2 /* 3 * jQuery 1.2.6 - New Wave Javascript 4 * 5 * Copyright (c) 2008 John Resig (jquery.com) 6 * Dual licensed under the MIT (MIT-LICENSE.txt) 7 * and GPL (GPL-LICENSE.txt) licenses. 8 * 9 * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $ 10 * $Rev: 5685 $ 11 */ 12 13 // Map over jQuery in case of overwrite 14 var _jQuery = window.jQuery, 15 // Map over the $ in case of overwrite 16 _$ = window.$; 17 18 var jQuery = window.jQuery = window.$ = function( selector, context ) { 19 // The jQuery object is actually just the init constructor 'enhanced' 20 return new jQuery.fn.init( selector, context ); 21 }; 22 23 // A simple way to check for HTML strings or ID strings 24 // (both of which we optimize for) 25 var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/, 26 27 // Is it a simple selector 28 isSimple = /^.[^:#\[\.]*$/, 29 30 // Will speed up references to undefined, and allows munging its name. 31 undefined; 32 33 jQuery.fn = jQuery.prototype = { 34 init: function( selector, context ) { 35 // Make sure that a selection was provided 36 selector = selector || document; 37 38 // Handle $(DOMElement) 39 if ( selector.nodeType ) { 40 this[0] = selector; 41 this.length = 1; 42 return this; 43 } 44 // Handle HTML strings 45 if ( typeof selector == "string" ) { 46 // Are we dealing with HTML string or an ID? 47 var match = quickExpr.exec( selector ); 48 49 // Verify a match, and that no context was specified for #id 50 if ( match && (match[1] || !context) ) { 51 52 // HANDLE: $(html) -> $(array) 53 if ( match[1] ) 54 selector = jQuery.clean( [ match[1] ], context ); 55 56 // HANDLE: $("#id") 57 else { 58 var elem = document.getElementById( match[3] ); 59 60 // Make sure an element was located 61 if ( elem ){ 62 // Handle the case where IE and Opera return items 63 // by name instead of ID 64 if ( elem.id != match[3] ) 65 return jQuery().find( selector ); 66 67 // Otherwise, we inject the element directly into the jQuery object 68 return jQuery( elem ); 69 } 70 selector = []; 71 } 72 73 // HANDLE: $(expr, [context]) 74 // (which is just equivalent to: $(content).find(expr) 75 } else 76 return jQuery( context ).find( selector ); 77 78 // HANDLE: $(function) 79 // Shortcut for document ready 80 } else if ( jQuery.isFunction( selector ) ) 81 return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector ); 82 83 return this.setArray(jQuery.makeArray(selector)); 84 }, 85 86 // The current version of jQuery being used 87 jquery: "1.2.6", 88 89 // The number of elements contained in the matched element set 90 size: function() { 91 return this.length; 92 }, 93 94 // The number of elements contained in the matched element set 95 length: 0, 96 97 // Get the Nth element in the matched element set OR 98 // Get the whole matched element set as a clean array 99 get: function( num ) { 100 return num == undefined ? 101 102 // Return a 'clean' array 103 jQuery.makeArray( this ) : 104 105 // Return just the object 106 this[ num ]; 107 }, 108 109 // Take an array of elements and push it onto the stack 110 // (returning the new matched element set) 111 pushStack: function( elems ) { 112 // Build a new jQuery matched element set 113 var ret = jQuery( elems ); 114 115 // Add the old object onto the stack (as a reference) 116 ret.prevObject = this; 117 118 // Return the newly-formed element set 119 return ret; 120 }, 121 122 // Force the current matched set of elements to become 123 // the specified array of elements (destroying the stack in the process) 124 // You should use pushStack() in order to do this, but maintain the stack 125 setArray: function( elems ) { 126 // Resetting the length to 0, then using the native Array push 127 // is a super-fast way to populate an object with array-like properties 128 this.length = 0; 129 Array.prototype.push.apply( this, elems ); 130 131 return this; 132 }, 133 134 // Execute a callback for every element in the matched set. 135 // (You can seed the arguments with an array of args, but this is 136 // only used internally.) 137 each: function( callback, args ) { 138 return jQuery.each( this, callback, args ); 139 }, 140 141 // Determine the position of an element within 142 // the matched set of elements 143 index: function( elem ) { 144 var ret = -1; 145 146 // Locate the position of the desired element 147 return jQuery.inArray( 148 // If it receives a jQuery object, the first element is used 149 elem && elem.jquery ? elem[0] : elem 150 , this ); 151 }, 152 153 attr: function( name, value, type ) { 154 var options = name; 155 156 // Look for the case where we're accessing a style value 157 if ( name.constructor == String ) 158 if ( value === undefined ) 159 return this[0] && jQuery[ type || "attr" ]( this[0], name ); 160 161 else { 162 options = {}; 163 options[ name ] = value; 164 } 165 166 // Check to see if we're setting style values 167 return this.each(function(i){ 168 // Set all the styles 169 for ( name in options ) 170 jQuery.attr( 171 type ? 172 this.style : 173 this, 174 name, jQuery.prop( this, options[ name ], type, i, name ) 175 ); 176 }); 177 }, 178 179 css: function( key, value ) { 180 // ignore negative width and height values 181 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) 182 value = undefined; 183 return this.attr( key, value, "curCSS" ); 184 }, 185 186 text: function( text ) { 187 if ( typeof text != "object" && text != null ) 188 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); 189 190 var ret = ""; 191 192 jQuery.each( text || this, function(){ 193 jQuery.each( this.childNodes, function(){ 194 if ( this.nodeType != 8 ) 195 ret += this.nodeType != 1 ? 196 this.nodeValue : 197 jQuery.fn.text( [ this ] ); 198 }); 199 }); 200 201 return ret; 202 }, 203 204 wrapAll: function( html ) { 205 if ( this[0] ) 206 // The elements to wrap the target around 207 jQuery( html, this[0].ownerDocument ) 208 .clone() 209 .insertBefore( this[0] ) 210 .map(function(){ 211 var elem = this; 212 213 while ( elem.firstChild ) 214 elem = elem.firstChild; 215 216 return elem; 217 }) 218 .append(this); 219 220 return this; 221 }, 222 223 wrapInner: function( html ) { 224 return this.each(function(){ 225 jQuery( this ).contents().wrapAll( html ); 226 }); 227 }, 228 229 wrap: function( html ) { 230 return this.each(function(){ 231 jQuery( this ).wrapAll( html ); 232 }); 233 }, 234 235 append: function() { 236 return this.domManip(arguments, true, false, function(elem){ 237 if (this.nodeType == 1) 238 this.appendChild( elem ); 239 }); 240 }, 241 242 prepend: function() { 243 return this.domManip(arguments, true, true, function(elem){ 244 if (this.nodeType == 1) 245 this.insertBefore( elem, this.firstChild ); 246 }); 247 }, 248 249 before: function() { 250 return this.domManip(arguments, false, false, function(elem){ 251 this.parentNode.insertBefore( elem, this ); 252 }); 253 }, 254 255 after: function() { 256 return this.domManip(arguments, false, true, function(elem){ 257 this.parentNode.insertBefore( elem, this.nextSibling ); 258 }); 259 }, 260 261 end: function() { 262 return this.prevObject || jQuery( [] ); 263 }, 264 265 find: function( selector ) { 266 var elems = jQuery.map(this, function(elem){ 267 return jQuery.find( selector, elem ); 268 }); 269 270 return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ? 271 jQuery.unique( elems ) : 272 elems ); 273 }, 274 275 clone: function( events ) { 276 // Do the clone 277 var ret = this.map(function(){ 278 if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) { 279 // IE copies events bound via attachEvent when 280 // using cloneNode. Calling detachEvent on the 281 // clone will also remove the events from the orignal 282 // In order to get around this, we use innerHTML. 283 // Unfortunately, this means some modifications to 284 // attributes in IE that are actually only stored 285 // as properties will not be copied (such as the 286 // the name attribute on an input). 287 var clone = this.cloneNode(true), 288 container = document.createElement("div"); 289 container.appendChild(clone); 290 return jQuery.clean([container.innerHTML])[0]; 291 } else 292 return this.cloneNode(true); 293 }); 294 295 // Need to set the expando to null on the cloned set if it exists 296 // removeData doesn't work here, IE removes it from the original as well 297 // this is primarily for IE but the data expando shouldn't be copied over in any browser 298 var clone = ret.find("*").andSelf().each(function(){ 299 if ( this[ expando ] != undefined ) 300 this[ expando ] = null; 301 }); 302 303 // Copy the events from the original to the clone 304 if ( events === true ) 305 this.find("*").andSelf().each(function(i){ 306 if (this.nodeType == 3) 307 return; 308 var events = jQuery.data( this, "events" ); 309 310 for ( var type in events ) 311 for ( var handler in events[ type ] ) 312 jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data ); 313 }); 314 315 // Return the cloned set 316 return ret; 317 }, 318 319 filter: function( selector ) { 320 return this.pushStack( 321 jQuery.isFunction( selector ) && 322 jQuery.grep(this, function(elem, i){ 323 return selector.call( elem, i ); 324 }) || 325 326 jQuery.multiFilter( selector, this ) ); 327 }, 328 329 not: function( selector ) { 330 if ( selector.constructor == String ) 331 // test special case where just one selector is passed in 332 if ( isSimple.test( selector ) ) 333 return this.pushStack( jQuery.multiFilter( selector, this, true ) ); 334 else 335 selector = jQuery.multiFilter( selector, this ); 336 337 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; 338 return this.filter(function() { 339 return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; 340 }); 341 }, 342 343 add: function( selector ) { 344 return this.pushStack( jQuery.unique( jQuery.merge( 345 this.get(), 346 typeof selector == 'string' ? 347 jQuery( selector ) : 348 jQuery.makeArray( selector ) 349 ))); 350 }, 351 352 is: function( selector ) { 353 return !!selector && jQuery.multiFilter( selector, this ).length > 0; 354 }, 355 356 hasClass: function( selector ) { 357 return this.is( "." + selector ); 358 }, 359 360 val: function( value ) { 361 if ( value == undefined ) { 362 363 if ( this.length ) { 364 var elem = this[0]; 365 366 // We need to handle select boxes special 367 if ( jQuery.nodeName( elem, "select" ) ) { 368 var index = elem.selectedIndex, 369 values = [], 370 options = elem.options, 371 one = elem.type == "select-one"; 372 373 // Nothing was selected 374 if ( index < 0 ) 375 return null; 376 377 // Loop through all the selected options 378 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { 379 var option = options[ i ]; 380 381 if ( option.selected ) { 382 // Get the specifc value for the option 383 value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value; 384 385 // We don't need an array for one selects 386 if ( one ) 387 return value; 388 389 // Multi-Selects return an array 390 values.push( value ); 391 } 392 } 393 394 return values; 395 396 // Everything else, we just grab the value 397 } else 398 return (this[0].value || "").replace(/\r/g, ""); 399 400 } 401 402 return undefined; 403 } 404 405 if( value.constructor == Number ) 406 value += ''; 407 408 return this.each(function(){ 409 if ( this.nodeType != 1 ) 410 return; 411 412 if ( value.constructor == Array && /radio|checkbox/.test( this.type ) ) 413 this.checked = (jQuery.inArray(this.value, value) >= 0 || 414 jQuery.inArray(this.name, value) >= 0); 415 416 else if ( jQuery.nodeName( this, "select" ) ) { 417 var values = jQuery.makeArray(value); 418 419 jQuery( "option", this ).each(function(){ 420 this.selected = (jQuery.inArray( this.value, values ) >= 0 || 421 jQuery.inArray( this.text, values ) >= 0); 422 }); 423 424 if ( !values.length ) 425 this.selectedIndex = -1; 426 427 } else 428 this.value = value; 429 }); 430 }, 431 432 html: function( value ) { 433 return value == undefined ? 434 (this[0] ? 435 this[0].innerHTML : 436 null) : 437 this.empty().append( value ); 438 }, 439 440 replaceWith: function( value ) { 441 return this.after( value ).remove(); 442 }, 443 444 eq: function( i ) { 445 return this.slice( i, i + 1 ); 446 }, 447 448 slice: function() { 449 return this.pushStack( Array.prototype.slice.apply( this, arguments ) ); 450 }, 451 452 map: function( callback ) { 453 return this.pushStack( jQuery.map(this, function(elem, i){ 454 return callback.call( elem, i, elem ); 455 })); 456 }, 457 458 andSelf: function() { 459 return this.add( this.prevObject ); 460 }, 461 462 data: function( key, value ){ 463 var parts = key.split("."); 464 parts[1] = parts[1] ? "." + parts[1] : ""; 465 466 if ( value === undefined ) { 467 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); 468 469 if ( data === undefined && this.length ) 470 data = jQuery.data( this[0], key ); 471 472 return data === undefined && parts[1] ? 473 this.data( parts[0] ) : 474 data; 475 } else 476 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){ 477 jQuery.data( this, key, value ); 478 }); 479 }, 480 481 removeData: function( key ){ 482 return this.each(function(){ 483 jQuery.removeData( this, key ); 484 }); 485 }, 486 487 domManip: function( args, table, reverse, callback ) { 488 var clone = this.length > 1, elems; 489 490 return this.each(function(){ 491 if ( !elems ) { 492 elems = jQuery.clean( args, this.ownerDocument ); 493 494 if ( reverse ) 495 elems.reverse(); 496 } 497 498 var obj = this; 499 500 if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) ) 501 obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") ); 502 503 var scripts = jQuery( [] ); 504 505 jQuery.each(elems, function(){ 506 var elem = clone ? 507 jQuery( this ).clone( true )[0] : 508 this; 509 510 // execute all scripts after the elements have been injected 511 if ( jQuery.nodeName( elem, "script" ) ) 512 scripts = scripts.add( elem ); 513 else { 514 // Remove any inner scripts for later evaluation 515 if ( elem.nodeType == 1 ) 516 scripts = scripts.add( jQuery( "script", elem ).remove() ); 517 518 // Inject the elements into the document 519 callback.call( obj, elem ); 520 } 521 }); 522 523 scripts.each( evalScript ); 524 }); 525 } 526 }; 527 528 // Give the init function the jQuery prototype for later instantiation 529 jQuery.fn.init.prototype = jQuery.fn; 530 531 function evalScript( i, elem ) { 532 if ( elem.src ) 533 jQuery.ajax({ 534 url: elem.src, 535 async: false, 536 dataType: "script" 537 }); 538 539 else 540 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); 541 542 if ( elem.parentNode ) 543 elem.parentNode.removeChild( elem ); 544 } 545 546 function now(){ 547 return +new Date; 548 } 549 550 jQuery.extend = jQuery.fn.extend = function() { 551 // copy reference to target object 552 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; 553 554 // Handle a deep copy situation 555 if ( target.constructor == Boolean ) { 556 deep = target; 557 target = arguments[1] || {}; 558 // skip the boolean and the target 559 i = 2; 560 } 561 562 // Handle case when target is a string or something (possible in deep copy) 563 if ( typeof target != "object" && typeof target != "function" ) 564 target = {}; 565 566 // extend jQuery itself if only one argument is passed 567 if ( length == i ) { 568 target = this; 569 --i; 570 } 571 572 for ( ; i < length; i++ ) 573 // Only deal with non-null/undefined values 574 if ( (options = arguments[ i ]) != null ) 575 // Extend the base object 576 for ( var name in options ) { 577 var src = target[ name ], copy = options[ name ]; 578 579 // Prevent never-ending loop 580 if ( target === copy ) 581 continue; 582 583 // Recurse if we're merging object values 584 if ( deep && copy && typeof copy == "object" && !copy.nodeType ) 585 target[ name ] = jQuery.extend( deep, 586 // Never move original objects, clone them 587 src || ( copy.length != null ? [ ] : { } ) 588 , copy ); 589 590 // Don't bring in undefined values 591 else if ( copy !== undefined ) 592 target[ name ] = copy; 593 594 } 595 596 // Return the modified object 597 return target; 598 }; 599 600 var expando = "jQuery" + now(), uuid = 0, windowData = {}, 601 // exclude the following css properties to add px 602 exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, 603 // cache defaultView 604 defaultView = document.defaultView || {}; 605 606 jQuery.extend({ 607 noConflict: function( deep ) { 608 window.$ = _$; 609 610 if ( deep ) 611 window.jQuery = _jQuery; 612 613 return jQuery; 614 }, 615 616 // See test/unit/core.js for details concerning this function. 617 isFunction: function( fn ) { 618 return !!fn && typeof fn != "string" && !fn.nodeName && 619 fn.constructor != Array && /^[\s[]?function/.test( fn + "" ); 620 }, 621 622 // check if an element is in a (or is an) XML document 623 isXMLDoc: function( elem ) { 624 return elem.documentElement && !elem.body || 625 elem.tagName && elem.ownerDocument && !elem.ownerDocument.body; 626 }, 627 628 // Evalulates a script in a global context 629 globalEval: function( data ) { 630 data = jQuery.trim( data ); 631 632 if ( data ) { 633 // Inspired by code by Andrea Giammarchi 634 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html 635 var head = document.getElementsByTagName("head")[0] || document.documentElement, 636 script = document.createElement("script"); 637 638 script.type = "text/javascript"; 639 if ( jQuery.browser.msie ) 640 script.text = data; 641 else 642 script.appendChild( document.createTextNode( data ) ); 643 644 // Use insertBefore instead of appendChild to circumvent an IE6 bug. 645 // This arises when a base node is used (#2709). 646 head.insertBefore( script, head.firstChild ); 647 head.removeChild( script ); 648 } 649 }, 650 651 nodeName: function( elem, name ) { 652 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); 653 }, 654 655 cache: {}, 656 657 data: function( elem, name, data ) { 658 elem = elem == window ? 659 windowData : 660 elem; 661 662 var id = elem[ expando ]; 663 664 // Compute a unique ID for the element 665 if ( !id ) 666 id = elem[ expando ] = ++uuid; 667 668 // Only generate the data cache if we're 669 // trying to access or manipulate it 670 if ( name && !jQuery.cache[ id ] ) 671 jQuery.cache[ id ] = {}; 672 673 // Prevent overriding the named cache with undefined values 674 if ( data !== undefined ) 675 jQuery.cache[ id ][ name ] = data; 676 677 // Return the named cache data, or the ID for the element 678 return name ? 679 jQuery.cache[ id ][ name ] : 680 id; 681 }, 682 683 removeData: function( elem, name ) { 684 elem = elem == window ? 685 windowData : 686 elem; 687 688 var id = elem[ expando ]; 689 690 // If we want to remove a specific section of the element's data 691 if ( name ) { 692 if ( jQuery.cache[ id ] ) { 693 // Remove the section of cache data 694 delete jQuery.cache[ id ][ name ]; 695 696 // If we've removed all the data, remove the element's cache 697 name = ""; 698 699 for ( name in jQuery.cache[ id ] ) 700 break; 701 702 if ( !name ) 703 jQuery.removeData( elem ); 704 } 705 706 // Otherwise, we want to remove all of the element's data 707 } else { 708 // Clean up the element expando 709 try { 710 delete elem[ expando ]; 711 } catch(e){ 712 // IE has trouble directly removing the expando 713 // but it's ok with using removeAttribute 714 if ( elem.removeAttribute ) 715 elem.removeAttribute( expando ); 716 } 717 718 // Completely remove the data cache 719 delete jQuery.cache[ id ]; 720 } 721 }, 722 723 // args is for internal usage only 724 each: function( object, callback, args ) { 725 var name, i = 0, length = object.length; 726 727 if ( args ) { 728 if ( length == undefined ) { 729 for ( name in object ) 730 if ( callback.apply( object[ name ], args ) === false ) 731 break; 732 } else 733 for ( ; i < length; ) 734 if ( callback.apply( object[ i++ ], args ) === false ) 735 break; 736 737 // A special, fast, case for the most common use of each 738 } else { 739 if ( length == undefined ) { 740 for ( name in object ) 741 if ( callback.call( object[ name ], name, object[ name ] ) === false ) 742 break; 743 } else 744 for ( var value = object[0]; 745 i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} 746 } 747 748 return object; 749 }, 750 751 prop: function( elem, value, type, i, name ) { 752 // Handle executable functions 753 if ( jQuery.isFunction( value ) ) 754 value = value.call( elem, i ); 755 756 // Handle passing in a number to a CSS property 757 return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ? 758 value + "px" : 759 value; 760 }, 761 762 className: { 763 // internal only, use addClass("class") 764 add: function( elem, classNames ) { 765 jQuery.each((classNames || "").split(/\s+/), function(i, className){ 766 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) 767 elem.className += (elem.className ? " " : "") + className; 768 }); 769 }, 770 771 // internal only, use removeClass("class") 772 remove: function( elem, classNames ) { 773 if (elem.nodeType == 1) 774 elem.className = classNames != undefined ? 775 jQuery.grep(elem.className.split(/\s+/), function(className){ 776 return !jQuery.className.has( classNames, className ); 777 }).join(" ") : 778 ""; 779 }, 780 781 // internal only, use hasClass("class") 782 has: function( elem, className ) { 783 return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; 784 } 785 }, 786 787 // A method for quickly swapping in/out CSS properties to get correct calculations 788 swap: function( elem, options, callback ) { 789 var old = {}; 790 // Remember the old values, and insert the new ones 791 for ( var name in options ) { 792 old[ name ] = elem.style[ name ]; 793 elem.style[ name ] = options[ name ]; 794 } 795 796 callback.call( elem ); 797 798 // Revert the old values 799 for ( var name in options ) 800 elem.style[ name ] = old[ name ]; 801 }, 802 803 css: function( elem, name, force ) { 804 if ( name == "width" || name == "height" ) { 805 var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; 806 807 function getWH() { 808 val = name == "width" ? elem.offsetWidth : elem.offsetHeight; 809 var padding = 0, border = 0; 810 jQuery.each( which, function() { 811 padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; 812 border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; 813 }); 814 val -= Math.round(padding + border); 815 } 816 817 if ( jQuery(elem).is(":visible") ) 818 getWH(); 819 else 820 jQuery.swap( elem, props, getWH ); 821 822 return Math.max(0, val); 823 } 824 825 return jQuery.curCSS( elem, name, force ); 826 }, 827 828 curCSS: function( elem, name, force ) { 829 var ret, style = elem.style; 830 831 // A helper method for determining if an element's values are broken 832 function color( elem ) { 833 if ( !jQuery.browser.safari ) 834 return false; 835 836 // defaultView is cached 837 var ret = defaultView.getComputedStyle( elem, null ); 838 return !ret || ret.getPropertyValue("color") == ""; 839 } 840 841 // We need to handle opacity special in IE 842 if ( name == "opacity" && jQuery.browser.msie ) { 843 ret = jQuery.attr( style, "opacity" ); 844 845 return ret == "" ? 846 "1" : 847 ret; 848 } 849 // Opera sometimes will give the wrong display answer, this fixes it, see #2037 850 if ( jQuery.browser.opera && name == "display" ) { 851 var save = style.outline; 852 style.outline = "0 solid black"; 853 style.outline = save; 854 } 855 856 // Make sure we're using the right name for getting the float value 857 if ( name.match( /float/i ) ) 858 name = styleFloat; 859 860 if ( !force && style && style[ name ] ) 861 ret = style[ name ]; 862 863 else if ( defaultView.getComputedStyle ) { 864 865 // Only "float" is needed here 866 if ( name.match( /float/i ) ) 867 name = "float"; 868 869 name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); 870 871 var computedStyle = defaultView.getComputedStyle( elem, null ); 872 873 if ( computedStyle && !color( elem ) ) 874 ret = computedStyle.getPropertyValue( name ); 875 876 // If the element isn't reporting its values properly in Safari 877 // then some display: none elements are involved 878 else { 879 var swap = [], stack = [], a = elem, i = 0; 880 881 // Locate all of the parent display: none elements 882 for ( ; a && color(a); a = a.parentNode ) 883 stack.unshift(a); 884 885 // Go through and make them visible, but in reverse 886 // (It would be better if we knew the exact display type that they had) 887 for ( ; i < stack.length; i++ ) 888 if ( color( stack[ i ] ) ) { 889 swap[ i ] = stack[ i ].style.display; 890 stack[ i ].style.display = "block"; 891 } 892 893 // Since we flip the display style, we have to handle that 894 // one special, otherwise get the value 895 ret = name == "display" && swap[ stack.length - 1 ] != null ? 896 "none" : 897 ( computedStyle && computedStyle.getPropertyValue( name ) ) || ""; 898 899 // Finally, revert the display styles back 900 for ( i = 0; i < swap.length; i++ ) 901 if ( swap[ i ] != null ) 902 stack[ i ].style.display = swap[ i ]; 903 } 904 905 // We should always get a number back from opacity 906 if ( name == "opacity" && ret == "" ) 907 ret = "1"; 908 909 } else if ( elem.currentStyle ) { 910 var camelCase = name.replace(/\-(\w)/g, function(all, letter){ 911 return letter.toUpperCase(); 912 }); 913 914 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; 915 916 // From the awesome hack by Dean Edwards 917 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 918 919 // If we're not dealing with a regular pixel number 920 // but a number that has a weird ending, we need to convert it to pixels 921 if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { 922 // Remember the original values 923 var left = style.left, rsLeft = elem.runtimeStyle.left; 924 925 // Put in the new values to get a computed value out 926 elem.runtimeStyle.left = elem.currentStyle.left; 927 style.left = ret || 0; 928 ret = style.pixelLeft + "px"; 929 930 // Revert the changed values 931 style.left = left; 932 elem.runtimeStyle.left = rsLeft; 933 } 934 } 935 936 return ret; 937 }, 938 939 clean: function( elems, context ) { 940 var ret = []; 941 context = context || document; 942 // !context.createElement fails in IE with an error but returns typeof 'object' 943 if (typeof context.createElement == 'undefined') 944 context = context.ownerDocument || context[0] && context[0].ownerDocument || document; 945 946 jQuery.each(elems, function(i, elem){ 947 if ( !elem ) 948 return; 949 950 if ( elem.constructor == Number ) 951 elem += ''; 952 953 // Convert html string into DOM nodes 954 if ( typeof elem == "string" ) { 955 // Fix "XHTML"-style tags in all browsers 956 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ 957 return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? 958 all : 959 front + "></" + tag + ">"; 960 }); 961 962 // Trim whitespace, otherwise indexOf won't work as expected 963 var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div"); 964 965 var wrap = 966 // option or optgroup 967 !tags.indexOf("<opt") && 968 [ 1, "<select multiple='multiple'>", "</select>" ] || 969 970 !tags.indexOf("<leg") && 971 [ 1, "<fieldset>", "</fieldset>" ] || 972 973 tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && 974 [ 1, "<table>", "</table>" ] || 975 976 !tags.indexOf("<tr") && 977 [ 2, "<table><tbody>", "</tbody></table>" ] || 978 979 // <thead> matched above 980 (!tags.indexOf("<td") || !tags.indexOf("<th")) && 981 [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] || 982 983 !tags.indexOf("<col") && 984 [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] || 985 986 // IE can't serialize <link> and <script> tags normally 987 jQuery.browser.msie && 988 [ 1, "div<div>", "</div>" ] || 989 990 [ 0, "", "" ]; 991 992 // Go to html and back, then peel off extra wrappers 993 div.innerHTML = wrap[1] + elem + wrap[2]; 994 995 // Move to the right depth 996 while ( wrap[0]-- ) 997 div = div.lastChild; 998 999 // Remove IE's autoinserted <tbody> from table fragments 1000 if ( jQuery.browser.msie ) { 1001 1002 // String was a <table>, *may* have spurious <tbody> 1003 var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ? 1004 div.firstChild && div.firstChild.childNodes : 1005 1006 // String was a bare <thead> or <tfoot> 1007 wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ? 1008 div.childNodes : 1009 []; 1010 1011 for ( var j = tbody.length - 1; j >= 0 ; --j ) 1012 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) 1013 tbody[ j ].parentNode.removeChild( tbody[ j ] ); 1014 1015 // IE completely kills leading whitespace when innerHTML is used 1016 if ( /^\s/.test( elem ) ) 1017 div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild ); 1018 1019 } 1020 1021 elem = jQuery.makeArray( div.childNodes ); 1022 } 1023 1024 if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) ) 1025 return; 1026 1027 if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options ) 1028 ret.push( elem ); 1029 1030 else 1031 ret = jQuery.merge( ret, elem ); 1032 1033 }); 1034 1035 return ret; 1036 }, 1037 1038 attr: function( elem, name, value ) { 1039 // don't set attributes on text and comment nodes 1040 if (!elem || elem.nodeType == 3 || elem.nodeType == 8) 1041 return undefined; 1042 1043 var notxml = !jQuery.isXMLDoc( elem ), 1044 // Whether we are setting (or getting) 1045 set = value !== undefined, 1046 msie = jQuery.browser.msie; 1047 1048 // Try to normalize/fix the name 1049 name = notxml && jQuery.props[ name ] || name; 1050 1051 // Only do all the following if this is a node (faster for style) 1052 // IE elem.getAttribute passes even for style 1053 if ( elem.tagName ) { 1054 1055 // These attributes require special treatment 1056 var special = /href|src|style/.test( name ); 1057 1058 // Safari mis-reports the default selected property of a hidden option 1059 // Accessing the parent's selectedIndex property fixes it 1060 if ( name == "selected" && jQuery.browser.safari ) 1061 elem.parentNode.selectedIndex; 1062 1063 // If applicable, access the attribute via the DOM 0 way 1064 if ( name in elem && notxml && !special ) { 1065 if ( set ){ 1066 // We can't allow the type property to be changed (since it causes problems in IE) 1067 if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode ) 1068 throw "type property can't be changed"; 1069 1070 elem[ name ] = value; 1071 } 1072 1073 // browsers index elements by id/name on forms, give priority to attributes. 1074 if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) 1075 return elem.getAttributeNode( name ).nodeValue; 1076 1077 return elem[ name ]; 1078 } 1079 1080 if ( msie && notxml && name == "style" ) 1081 return jQuery.attr( elem.style, "cssText", value ); 1082 1083 if ( set ) 1084 // convert the value to a string (all browsers do this but IE) see #1070 1085 elem.setAttribute( name, "" + value ); 1086 1087 var attr = msie && notxml && special 1088 // Some attributes require a special call on IE 1089 ? elem.getAttribute( name, 2 ) 1090 : elem.getAttribute( name ); 1091 1092 // Non-existent attributes return null, we normalize to undefined 1093 return attr === null ? undefined : attr; 1094 } 1095 1096 // elem is actually elem.style ... set the style 1097 1098 // IE uses filters for opacity 1099 if ( msie && name == "opacity" ) { 1100 if ( set ) { 1101 // IE has trouble with opacity if it does not have layout 1102 // Force it by setting the zoom level 1103 elem.zoom = 1; 1104 1105 // Set the alpha filter to set the opacity 1106 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) + 1107 (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")"); 1108 } 1109 1110 return elem.filter && elem.filter.indexOf("opacity=") >= 0 ? 1111 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '': 1112 ""; 1113 } 1114 1115 name = name.replace(/-([a-z])/ig, function(all, letter){ 1116 return letter.toUpperCase(); 1117 }); 1118 1119 if ( set ) 1120 elem[ name ] = value; 1121 1122 return elem[ name ]; 1123 }, 1124 1125 trim: function( text ) { 1126 return (text || "").replace( /^\s+|\s+$/g, "" ); 1127 }, 1128 1129 makeArray: function( array ) { 1130 var ret = []; 1131 1132 if( array != null ){ 1133 var i = array.length; 1134 //the window, strings and functions also have 'length' 1135 if( i == null || array.split || array.setInterval || array.call ) 1136 ret[0] = array; 1137 else 1138 while( i ) 1139 ret[--i] = array[i]; 1140 } 1141 1142 return ret; 1143 }, 1144 1145 inArray: function( elem, array ) { 1146 for ( var i = 0, length = array.length; i < length; i++ ) 1147 // Use === because on IE, window == document 1148 if ( array[ i ] === elem ) 1149 return i; 1150 1151 return -1; 1152 }, 1153 1154 merge: function( first, second ) { 1155 // We have to loop this way because IE & Opera overwrite the length 1156 // expando of getElementsByTagName 1157 var i = 0, elem, pos = first.length; 1158 // Also, we need to make sure that the correct elements are being returned 1159 // (IE returns comment nodes in a '*' query) 1160 if ( jQuery.browser.msie ) { 1161 while ( elem = second[ i++ ] ) 1162 if ( elem.nodeType != 8 ) 1163 first[ pos++ ] = elem; 1164 1165 } else 1166 while ( elem = second[ i++ ] ) 1167 first[ pos++ ] = elem; 1168 1169 return first; 1170 }, 1171 1172 unique: function( array ) { 1173 var ret = [], done = {}; 1174 1175 try { 1176 1177 for ( var i = 0, length = array.length; i < length; i++ ) { 1178 var id = jQuery.data( array[ i ] ); 1179 1180 if ( !done[ id ] ) { 1181 done[ id ] = true; 1182 ret.push( array[ i ] ); 1183 } 1184 } 1185 1186 } catch( e ) { 1187 ret = array; 1188 } 1189 1190 return ret; 1191 }, 1192 1193 grep: function( elems, callback, inv ) { 1194 var ret = []; 1195 1196 // Go through the array, only saving the items 1197 // that pass the validator function 1198 for ( var i = 0, length = elems.length; i < length; i++ ) 1199 if ( !inv != !callback( elems[ i ], i ) ) 1200 ret.push( elems[ i ] ); 1201 1202 return ret; 1203 }, 1204 1205 map: function( elems, callback ) { 1206 var ret = []; 1207 1208 // Go through the array, translating each of the items to their 1209 // new value (or values). 1210 for ( var i = 0, length = elems.length; i < length; i++ ) { 1211 var value = callback( elems[ i ], i ); 1212 1213 if ( value != null ) 1214 ret[ ret.length ] = value; 1215 } 1216 1217 return ret.concat.apply( [], ret ); 1218 } 1219 }); 1220 1221 var userAgent = navigator.userAgent.toLowerCase(); 1222 1223 // Figure out what browser is being used 1224 jQuery.browser = { 1225 version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1], 1226 safari: /webkit/.test( userAgent ), 1227 opera: /opera/.test( userAgent ), 1228 msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ), 1229 mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent ) 1230 }; 1231 1232 var styleFloat = jQuery.browser.msie ? 1233 "styleFloat" : 1234 "cssFloat"; 1235 1236 jQuery.extend({ 1237 // Check to see if the W3C box model is being used 1238 boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat", 1239 1240 props: { 1241 "for": "htmlFor", 1242 "class": "className", 1243 "float": styleFloat, 1244 cssFloat: styleFloat, 1245 styleFloat: styleFloat, 1246 readonly: "readOnly", 1247 maxlength: "maxLength", 1248 cellspacing: "cellSpacing" 1249 } 1250 }); 1251 1252 jQuery.each({ 1253 parent: function(elem){return elem.parentNode;}, 1254 parents: function(elem){return jQuery.dir(elem,"parentNode");}, 1255 next: function(elem){return jQuery.nth(elem,2,"nextSibling");}, 1256 prev: function(elem){return jQuery.nth(elem,2,"previousSibling");}, 1257 nextAll: function(elem){return jQuery.dir(elem,"nextSibling");}, 1258 prevAll: function(elem){return jQuery.dir(elem,"previousSibling");}, 1259 siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);}, 1260 children: function(elem){return jQuery.sibling(elem.firstChild);}, 1261 contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);} 1262 }, function(name, fn){ 1263 jQuery.fn[ name ] = function( selector ) { 1264 var ret = jQuery.map( this, fn ); 1265 1266 if ( selector && typeof selector == "string" ) 1267 ret = jQuery.multiFilter( selector, ret ); 1268 1269 return this.pushStack( jQuery.unique( ret ) ); 1270 }; 1271 }); 1272 1273 jQuery.each({ 1274 appendTo: "append", 1275 prependTo: "prepend", 1276 insertBefore: "before", 1277 insertAfter: "after", 1278 replaceAll: "replaceWith" 1279 }, function(name, original){ 1280 jQuery.fn[ name ] = function() { 1281 var args = arguments; 1282 1283 return this.each(function(){ 1284 for ( var i = 0, length = args.length; i < length; i++ ) 1285 jQuery( args[ i ] )[ original ]( this ); 1286 }); 1287 }; 1288 }); 1289 1290 jQuery.each({ 1291 removeAttr: function( name ) { 1292 jQuery.attr( this, name, "" ); 1293 if (this.nodeType == 1) 1294 this.removeAttribute( name ); 1295 }, 1296 1297 addClass: function( classNames ) { 1298 jQuery.className.add( this, classNames ); 1299 }, 1300 1301 removeClass: function( classNames ) { 1302 jQuery.className.remove( this, classNames ); 1303 }, 1304 1305 toggleClass: function( classNames ) { 1306 jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames ); 1307 }, 1308 1309 remove: function( selector ) { 1310 if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) { 1311 // Prevent memory leaks 1312 jQuery( "*", this ).add(this).each(function(){ 1313 jQuery.event.remove(this); 1314 jQuery.removeData(this); 1315 }); 1316 if (this.parentNode) 1317 this.parentNode.removeChild( this ); 1318 } 1319 }, 1320 1321 empty: function() { 1322 // Remove element nodes and prevent memory leaks 1323 jQuery( ">*", this ).remove(); 1324 1325 // Remove any remaining nodes 1326 while ( this.firstChild ) 1327 this.removeChild( this.firstChild ); 1328 } 1329 }, function(name, fn){ 1330 jQuery.fn[ name ] = function(){ 1331 return this.each( fn, arguments ); 1332 }; 1333 }); 1334 1335 jQuery.each([ "Height", "Width" ], function(i, name){ 1336 var type = name.toLowerCase(); 1337 1338 jQuery.fn[ type ] = function( size ) { 1339 // Get window width or height 1340 return this[0] == window ? 1341 // Opera reports document.body.client[Width/Height] properly in both quirks and standards 1342 jQuery.browser.opera && document.body[ "client" + name ] || 1343 1344 // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths) 1345 jQuery.browser.safari && window[ "inner" + name ] || 1346 1347 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode 1348 document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] : 1349 1350 // Get document width or height 1351 this[0] == document ? 1352 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater 1353 Math.max( 1354 Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]), 1355 Math.max(document.body["offset" + name], document.documentElement["offset" + name]) 1356 ) : 1357 1358 // Get or set width or height on the element 1359 size == undefined ? 1360 // Get width or height on the element 1361 (this.length ? jQuery.css( this[0], type ) : null) : 1362 1363 // Set the width or height on the element (default to pixels if value is unitless) 1364 this.css( type, size.constructor == String ? size : size + "px" ); 1365 }; 1366 }); 1367 1368 // Helper function used by the dimensions and offset modules 1369 function num(elem, prop) { 1370 return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0; 1371 }var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ? 1372 "(?:[\\w*_-]|\\\\.)" : 1373 "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)", 1374 quickChild = new RegExp("^>\\s*(" + chars + "+)"), 1375 quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"), 1376 quickClass = new RegExp("^([#.]?)(" + chars + "*)"); 1377 1378 jQuery.extend({ 1379 expr: { 1380 "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);}, 1381 "#": function(a,i,m){return a.getAttribute("id")==m[2];}, 1382 ":": { 1383 // Position Checks 1384 lt: function(a,i,m){return i<m[3]-0;}, 1385 gt: function(a,i,m){return i>m[3]-0;}, 1386 nth: function(a,i,m){return m[3]-0==i;}, 1387 eq: function(a,i,m){return m[3]-0==i;}, 1388 first: function(a,i){return i==0;}, 1389 last: function(a,i,m,r){return i==r.length-1;}, 1390 even: function(a,i){return i%2==0;}, 1391 odd: function(a,i){return i%2;}, 1392 1393 // Child Checks 1394 "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;}, 1395 "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;}, 1396 "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");}, 1397 1398 // Parent Checks 1399 parent: function(a){return a.firstChild;}, 1400 empty: function(a){return !a.firstChild;}, 1401 1402 // Text Check 1403 contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;}, 1404 1405 // Visibility 1406 visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";}, 1407 hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";}, 1408 1409 // Form attributes 1410 enabled: function(a){return !a.disabled;}, 1411 disabled: function(a){return a.disabled;}, 1412 checked: function(a){return a.checked;}, 1413 selected: function(a){return a.selected||jQuery.attr(a,"selected");}, 1414 1415 // Form elements 1416 text: function(a){return "text"==a.type;}, 1417 radio: function(a){return "radio"==a.type;}, 1418 checkbox: function(a){return "checkbox"==a.type;}, 1419 file: function(a){return "file"==a.type;}, 1420 password: function(a){return "password"==a.type;}, 1421 submit: function(a){return "submit"==a.type;}, 1422 image: function(a){return "image"==a.type;}, 1423 reset: function(a){return "reset"==a.type;}, 1424 button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");}, 1425 input: function(a){return /input|select|textarea|button/i.test(a.nodeName);}, 1426 1427 // :has() 1428 has: function(a,i,m){return jQuery.find(m[3],a).length;}, 1429 1430 // :header 1431 header: function(a){return /h\d/i.test(a.nodeName);}, 1432 1433 // :animated 1434 animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;} 1435 } 1436 }, 1437 1438 // The regular expressions that power the parsing engine 1439 parse: [ 1440 // Match: [@value='test'], [@foo] 1441 /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/, 1442 1443 // Match: :contains('foo') 1444 /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/, 1445 1446 // Match: :even, :last-child, #id, .class 1447 new RegExp("^([:.#]*)(" + chars + "+)") 1448 ], 1449 1450 multiFilter: function( expr, elems, not ) { 1451 var old, cur = []; 1452 1453 while ( expr && expr != old ) { 1454 old = expr; 1455 var f = jQuery.filter( expr, elems, not ); 1456 expr = f.t.replace(/^\s*,\s*/, "" ); 1457 cur = not ? elems = f.r : jQuery.merge( cur, f.r ); 1458 } 1459 1460 return cur; 1461 }, 1462 1463 find: function( t, context ) { 1464 // Quickly handle non-string expressions 1465 if ( typeof t != "string" ) 1466 return [ t ]; 1467 1468 // check to make sure context is a DOM element or a document 1469 if ( context && context.nodeType != 1 && context.nodeType != 9) 1470 return [ ]; 1471 1472 // Set the correct context (if none is provided) 1473 context = context || document; 1474 1475 // Initialize the search 1476 var ret = [context], done = [], last, nodeName; 1477 1478 // Continue while a selector expression exists, and while 1479 // we're no longer looping upon ourselves 1480 while ( t && last != t ) { 1481 var r = []; 1482 last = t; 1483 1484 t = jQuery.trim(t); 1485 1486 var foundToken = false, 1487 1488 // An attempt at speeding up child selectors that 1489 // point to a specific element tag 1490 re = quickChild, 1491 1492 m = re.exec(t); 1493 1494 if ( m ) { 1495 nodeName = m[1].toUpperCase(); 1496 1497 // Perform our own iteration and filter 1498 for ( var i = 0; ret[i]; i++ ) 1499 for ( var c = ret[i].firstChild; c; c = c.nextSibling ) 1500 if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) ) 1501 r.push( c ); 1502 1503 ret = r; 1504 t = t.replace( re, "" ); 1505 if ( t.indexOf(" ") == 0 ) continue; 1506 foundToken = true; 1507 } else { 1508 re = /^([>+~])\s*(\w*)/i; 1509 1510 if ( (m = re.exec(t)) != null ) { 1511 r = []; 1512 1513 var merge = {}; 1514 nodeName = m[2].toUpperCase(); 1515 m = m[1]; 1516 1517 for ( var j = 0, rl = ret.length; j < rl; j++ ) { 1518 var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild; 1519 for ( ; n; n = n.nextSibling ) 1520 if ( n.nodeType == 1 ) { 1521 var id = jQuery.data(n); 1522 1523 if ( m == "~" && merge[id] ) break; 1524 1525 if (!nodeName || n.nodeName.toUpperCase() == nodeName ) { 1526 if ( m == "~" ) merge[id] = true; 1527 r.push( n ); 1528 } 1529 1530 if ( m == "+" ) break; 1531 } 1532 } 1533 1534 ret = r; 1535 1536 // And remove the token 1537 t = jQuery.trim( t.replace( re, "" ) ); 1538 foundToken = true; 1539 } 1540 } 1541 1542 // See if there's still an expression, and that we haven't already 1543 // matched a token 1544 if ( t && !foundToken ) { 1545 // Handle multiple expressions 1546 if ( !t.indexOf(",") ) { 1547 // Clean the result set 1548 if ( context == ret[0] ) ret.shift(); 1549 1550 // Merge the result sets 1551 done = jQuery.merge( done, ret ); 1552 1553 // Reset the context 1554 r = ret = [context]; 1555 1556 // Touch up the selector string 1557 t = " " + t.substr(1,t.length); 1558 1559 } else { 1560 // Optimize for the case nodeName#idName 1561 var re2 = quickID; 1562 var m = re2.exec(t); 1563 1564 // Re-organize the results, so that they're consistent 1565 if ( m ) { 1566 m = [ 0, m[2], m[3], m[1] ]; 1567 1568 } else { 1569 // Otherwise, do a traditional filter check for 1570 // ID, class, and element selectors 1571 re2 = quickClass; 1572 m = re2.exec(t); 1573 } 1574 1575 m[2] = m[2].replace(/\\/g, ""); 1576 1577 var elem = ret[ret.length-1]; 1578 1579 // Try to do a global search by ID, where we can 1580 if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) { 1581 // Optimization for HTML document case 1582 var oid = elem.getElementById(m[2]); 1583 1584 // Do a quick check for the existence of the actual ID attribute 1585 // to avoid selecting by the name attribute in IE 1586 // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form 1587 if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] ) 1588 oid = jQuery('[@id="'+m[2]+'"]', elem)[0]; 1589 1590 // Do a quick check for node name (where applicable) so 1591 // that div#foo searches will be really fast 1592 ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : []; 1593 } else { 1594 // We need to find all descendant elements 1595 for ( var i = 0; ret[i]; i++ ) { 1596 // Grab the tag name being searched for 1597 var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2]; 1598 1599 // Handle IE7 being really dumb about <object>s 1600 if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" ) 1601 tag = "param"; 1602 1603 r = jQuery.merge( r, ret[i].getElementsByTagName( tag )); 1604 } 1605 1606 // It's faster to filter by class and be done with it 1607 if ( m[1] == "." ) 1608 r = jQuery.classFilter( r, m[2] ); 1609 1610 // Same with ID filtering 1611 if ( m[1] == "#" ) { 1612 var tmp = []; 1613 1614 // Try to find the element with the ID 1615 for ( var i = 0; r[i]; i++ ) 1616 if ( r[i].getAttribute("id") == m[2] ) { 1617 tmp = [ r[i] ]; 1618 break; 1619 } 1620 1621 r = tmp; 1622 } 1623 1624 ret = r; 1625 } 1626 1627 t = t.replace( re2, "" ); 1628 } 1629 1630 } 1631 1632 // If a selector string still exists 1633 if ( t ) { 1634 // Attempt to filter it 1635 var val = jQuery.filter(t,r); 1636 ret = r = val.r; 1637 t = jQuery.trim(val.t); 1638 } 1639 } 1640 1641 // An error occurred with the selector; 1642 // just return an empty set instead 1643 if ( t ) 1644 ret = []; 1645 1646 // Remove the root context 1647 if ( ret && context == ret[0] ) 1648 ret.shift(); 1649 1650 // And combine the results 1651 done = jQuery.merge( done, ret ); 1652 1653 return done; 1654 }, 1655 1656 classFilter: function(r,m,not){ 1657 m = " " + m + " "; 1658 var tmp = []; 1659 for ( var i = 0; r[i]; i++ ) { 1660 var pass = (" " + r[i].className + " ").indexOf( m ) >= 0; 1661 if ( !not && pass || not && !pass ) 1662 tmp.push( r[i] ); 1663 } 1664 return tmp; 1665 }, 1666 1667 filter: function(t,r,not) { 1668 var last; 1669 1670 // Look for common filter expressions 1671 while ( t && t != last ) { 1672 last = t; 1673 1674 var p = jQuery.parse, m; 1675 1676 for ( var i = 0; p[i]; i++ ) { 1677 m = p[i].exec( t ); 1678 1679 if ( m ) { 1680 // Remove what we just matched 1681 t = t.substring( m[0].length ); 1682 1683 m[2] = m[2].replace(/\\/g, ""); 1684 break; 1685 } 1686 } 1687 1688 if ( !m ) 1689 break; 1690 1691 // :not() is a special case that can be optimized by 1692 // keeping it out of the expression list 1693 if ( m[1] == ":" && m[2] == "not" ) 1694 // optimize if only one selector found (most common case) 1695 r = isSimple.test( m[3] ) ? 1696 jQuery.filter(m[3], r, true).r : 1697 jQuery( r ).not( m[3] ); 1698 1699 // We can get a big speed boost by filtering by class here 1700 else if ( m[1] == "." ) 1701 r = jQuery.classFilter(r, m[2], not); 1702 1703 else if ( m[1] == "[" ) { 1704 var tmp = [], type = m[3]; 1705 1706 for ( var i = 0, rl = r.length; i < rl; i++ ) { 1707 var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ]; 1708 1709 if ( z == null || /href|src|selected/.test(m[2]) ) 1710 z = jQuery.attr(a,m[2]) || ''; 1711 1712 if ( (type == "" && !!z || 1713 type == "=" && z == m[5] || 1714 type == "!=" && z != m[5] || 1715 type == "^=" && z && !z.indexOf(m[5]) || 1716 type == "$=" && z.substr(z.length - m[5].length) == m[5] || 1717 (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not ) 1718 tmp.push( a ); 1719 } 1720 1721 r = tmp; 1722 1723 // We can get a speed boost by handling nth-child here 1724 } else if ( m[1] == ":" && m[2] == "nth-child" ) { 1725 var merge = {}, tmp = [], 1726 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' 1727 test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( 1728 m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" || 1729 !/\D/.test(m[3]) && "0n+" + m[3] || m[3]), 1730 // calculate the numbers (first)n+(last) including if they are negative 1731 first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0; 1732 1733 // loop through all the elements left in the jQuery object 1734 for ( var i = 0, rl = r.length; i < rl; i++ ) { 1735 var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode); 1736 1737 if ( !merge[id] ) { 1738 var c = 1; 1739 1740 for ( var n = parentNode.firstChild; n; n = n.nextSibling ) 1741 if ( n.nodeType == 1 ) 1742 n.nodeIndex = c++; 1743 1744 merge[id] = true; 1745 } 1746 1747 var add = false; 1748 1749 if ( first == 0 ) { 1750 if ( node.nodeIndex == last ) 1751 add = true; 1752 } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 ) 1753 add = true; 1754 1755 if ( add ^ not ) 1756 tmp.push( node ); 1757 } 1758 1759 r = tmp; 1760 1761 // Otherwise, find the expression to execute 1762 } else { 1763 var fn = jQuery.expr[ m[1] ]; 1764 if ( typeof fn == "object" ) 1765 fn = fn[ m[2] ]; 1766 1767 if ( typeof fn == "string" ) 1768 fn = eval("false||function(a,i){return " + fn + ";}"); 1769 1770 // Execute it against the current filter 1771 r = jQuery.grep( r, function(elem, i){ 1772 return fn(elem, i, m, r); 1773 }, not ); 1774 } 1775 } 1776 1777 // Return an array of filtered elements (r) 1778 // and the modified expression string (t) 1779 return { r: r, t: t }; 1780 }, 1781 1782 dir: function( elem, dir ){ 1783 var matched = [], 1784 cur = elem[dir]; 1785 while ( cur && cur != document ) { 1786 if ( cur.nodeType == 1 ) 1787 matched.push( cur ); 1788 cur = cur[dir]; 1789 } 1790 return matched; 1791 }, 1792 1793 nth: function(cur,result,dir,elem){ 1794 result = result || 1; 1795 var num = 0; 1796 1797 for ( ; cur; cur = cur[dir] ) 1798 if ( cur.nodeType == 1 && ++num == result ) 1799 break; 1800 1801 return cur; 1802 }, 1803 1804 sibling: function( n, elem ) { 1805 var r = []; 1806 1807 for ( ; n; n = n.nextSibling ) { 1808 if ( n.nodeType == 1 && n != elem ) 1809 r.push( n ); 1810 } 1811 1812 return r; 1813 } 1814 }); 1815 /* 1816 * A number of helper functions used for managing events. 1817 * Many of the ideas behind this code orignated from 1818 * Dean Edwards' addEvent library. 1819 */ 1820 jQuery.event = { 1821 1822 // Bind an event to an element 1823 // Original by Dean Edwards 1824 add: function(elem, types, handler, data) { 1825 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1826 return; 1827 1828 // For whatever reason, IE has trouble passing the window object 1829 // around, causing it to be cloned in the process 1830 if ( jQuery.browser.msie && elem.setInterval ) 1831 elem = window; 1832 1833 // Make sure that the function being executed has a unique ID 1834 if ( !handler.guid ) 1835 handler.guid = this.guid++; 1836 1837 // if data is passed, bind to handler 1838 if( data != undefined ) { 1839 // Create temporary function pointer to original handler 1840 var fn = handler; 1841 1842 // Create unique handler function, wrapped around original handler 1843 handler = this.proxy( fn, function() { 1844 // Pass arguments and context to original handler 1845 return fn.apply(this, arguments); 1846 }); 1847 1848 // Store data in unique handler 1849 handler.data = data; 1850 } 1851 1852 // Init the element's event structure 1853 var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}), 1854 handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){ 1855 // Handle the second event of a trigger and when 1856 // an event is called after a page has unloaded 1857 if ( typeof jQuery != "undefined" && !jQuery.event.triggered ) 1858 return jQuery.event.handle.apply(arguments.callee.elem, arguments); 1859 }); 1860 // Add elem as a property of the handle function 1861 // This is to prevent a memory leak with non-native 1862 // event in IE. 1863 handle.elem = elem; 1864 1865 // Handle multiple events separated by a space 1866 // jQuery(...).bind("mouseover mouseout", fn); 1867 jQuery.each(types.split(/\s+/), function(index, type) { 1868 // Namespaced event handlers 1869 var parts = type.split("."); 1870 type = parts[0]; 1871 handler.type = parts[1]; 1872 1873 // Get the current list of functions bound to this event 1874 var handlers = events[type]; 1875 1876 // Init the event handler queue 1877 if (!handlers) { 1878 handlers = events[type] = {}; 1879 1880 // Check for a special event handler 1881 // Only use addEventListener/attachEvent if the special 1882 // events handler returns false 1883 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) { 1884 // Bind the global event handler to the element 1885 if (elem.addEventListener) 1886 elem.addEventListener(type, handle, false); 1887 else if (elem.attachEvent) 1888 elem.attachEvent("on" + type, handle); 1889 } 1890 } 1891 1892 // Add the function to the element's handler list 1893 handlers[handler.guid] = handler; 1894 1895 // Keep track of which events have been used, for global triggering 1896 jQuery.event.global[type] = true; 1897 }); 1898 1899 // Nullify elem to prevent memory leaks in IE 1900 elem = null; 1901 }, 1902 1903 guid: 1, 1904 global: {}, 1905 1906 // Detach an event or set of events from an element 1907 remove: function(elem, types, handler) { 1908 // don't do events on text and comment nodes 1909 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1910 return; 1911 1912 var events = jQuery.data(elem, "events"), ret, index; 1913 1914 if ( events ) { 1915 // Unbind all events for the element 1916 if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") ) 1917 for ( var type in events ) 1918 this.remove( elem, type + (types || "") ); 1919 else { 1920 // types is actually an event object here 1921 if ( types.type ) { 1922 handler = types.handler; 1923 types = types.type; 1924 } 1925 1926 // Handle multiple events seperated by a space 1927 // jQuery(...).unbind("mouseover mouseout", fn); 1928 jQuery.each(types.split(/\s+/), function(index, type){ 1929 // Namespaced event handlers 1930 var parts = type.split("."); 1931 type = parts[0]; 1932 1933 if ( events[type] ) { 1934 // remove the given handler for the given type 1935 if ( handler ) 1936 delete events[type][handler.guid]; 1937 1938 // remove all handlers for the given type 1939 else 1940 for ( handler in events[type] ) 1941 // Handle the removal of namespaced events 1942 if ( !parts[1] || events[type][handler].type == parts[1] ) 1943 delete events[type][handler]; 1944 1945 // remove generic event handler if no more handlers exist 1946 for ( ret in events[type] ) break; 1947 if ( !ret ) { 1948 if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) { 1949 if (elem.removeEventListener) 1950 elem.removeEventListener(type, jQuery.data(elem, "handle"), false); 1951 else if (elem.detachEvent) 1952 elem.detachEvent("on" + type, jQuery.data(elem, "handle")); 1953 } 1954 ret = null; 1955 delete events[type]; 1956 } 1957 } 1958 }); 1959 } 1960 1961 // Remove the expando if it's no longer used 1962 for ( ret in events ) break; 1963 if ( !ret ) { 1964 var handle = jQuery.data( elem, "handle" ); 1965 if ( handle ) handle.elem = null; 1966 jQuery.removeData( elem, "events" ); 1967 jQuery.removeData( elem, "handle" ); 1968 } 1969 } 1970 }, 1971 1972 trigger: function(type, data, elem, donative, extra) { 1973 // Clone the incoming data, if any 1974 data = jQuery.makeArray(data); 1975 1976 if ( type.indexOf("!") >= 0 ) { 1977 type = type.slice(0, -1); 1978 var exclusive = true; 1979 } 1980 1981 // Handle a global trigger 1982 if ( !elem ) { 1983 // Only trigger if we've ever bound an event for it 1984 if ( this.global[type] ) 1985 jQuery("*").add([window, document]).trigger(type, data); 1986 1987 // Handle triggering a single element 1988 } else { 1989 // don't do events on text and comment nodes 1990 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1991 return undefined; 1992 1993 var val, ret, fn = jQuery.isFunction( elem[ type ] || null ), 1994 // Check to see if we need to provide a fake event, or not 1995 event = !data[0] || !data[0].preventDefault; 1996 1997 // Pass along a fake event 1998 if ( event ) { 1999 data.unshift({ 2000 type: type, 2001 target: elem, 2002 preventDefault: function(){}, 2003 stopPropagation: function(){}, 2004 timeStamp: now() 2005 }); 2006 data[0][expando] = true; // no need to fix fake event 2007 } 2008 2009 // Enforce the right trigger type 2010 data[0].type = type; 2011 if ( exclusive ) 2012 data[0].exclusive = true; 2013 2014 // Trigger the event, it is assumed that "handle" is a function 2015 var handle = jQuery.data(elem, "handle"); 2016 if ( handle ) 2017 val = handle.apply( elem, data ); 2018 2019 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links) 2020 if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false ) 2021 val = false; 2022 2023 // Extra functions don't get the custom event object 2024 if ( event ) 2025 data.shift(); 2026 2027 // Handle triggering of extra function 2028 if ( extra && jQuery.isFunction( extra ) ) { 2029 // call the extra function and tack the current return value on the end for possible inspection 2030 ret = extra.apply( elem, val == null ? data : data.concat( val ) ); 2031 // if anything is returned, give it precedence and have it overwrite the previous value 2032 if (ret !== undefined) 2033 val = ret; 2034 } 2035 2036 // Trigger the native events (except for clicks on links) 2037 if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) { 2038 this.triggered = true; 2039 try { 2040 elem[ type ](); 2041 // prevent IE from throwing an error for some hidden elements 2042 } catch (e) {} 2043 } 2044 2045 this.triggered = false; 2046 } 2047 2048 return val; 2049 }, 2050 2051 handle: function(event) { 2052 // returned undefined or false 2053 var val, ret, namespace, all, handlers; 2054 2055 event = arguments[0] = jQuery.event.fix( event || window.event ); 2056 2057 // Namespaced event handlers 2058 namespace = event.type.split("."); 2059 event.type = namespace[0]; 2060 namespace = namespace[1]; 2061 // Cache this now, all = true means, any handler 2062 all = !namespace && !event.exclusive; 2063 2064 handlers = ( jQuery.data(this, "events") || {} )[event.type]; 2065 2066 for ( var j in handlers ) { 2067 var handler = handlers[j]; 2068 2069 // Filter the functions by class 2070 if ( all || handler.type == namespace ) { 2071 // Pass in a reference to the handler function itself 2072 // So that we can later remove it 2073 event.handler = handler; 2074 event.data = handler.data; 2075 2076 ret = handler.apply( this, arguments ); 2077 2078 if ( val !== false ) 2079 val = ret; 2080 2081 if ( ret === false ) { 2082 event.preventDefault(); 2083 event.stopPropagation(); 2084 } 2085 } 2086 } 2087 2088 return val; 2089 }, 2090 2091 fix: function(event) { 2092 if ( event[expando] == true ) 2093 return event; 2094 2095 // store a copy of the original event object 2096 // and "clone" to set read-only properties 2097 var originalEvent = event; 2098 event = { originalEvent: originalEvent }; 2099 var 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 timeStamp toElement type view wheelDelta which".split(" "); 2100 for ( var i=props.length; i; i-- ) 2101 event[ props[i] ] = originalEvent[ props[i] ]; 2102 2103 // Mark it as fixed 2104 event[expando] = true; 2105 2106 // add preventDefault and stopPropagation since 2107 // they will not work on the clone 2108 event.preventDefault = function() { 2109 // if preventDefault exists run it on the original event 2110 if (originalEvent.preventDefault) 2111 originalEvent.preventDefault(); 2112 // otherwise set the returnValue property of the original event to false (IE) 2113 originalEvent.returnValue = false; 2114 }; 2115 event.stopPropagation = function() { 2116 // if stopPropagation exists run it on the original event 2117 if (originalEvent.stopPropagation) 2118 originalEvent.stopPropagation(); 2119 // otherwise set the cancelBubble property of the original event to true (IE) 2120 originalEvent.cancelBubble = true; 2121 }; 2122 2123 // Fix timeStamp 2124 event.timeStamp = event.timeStamp || now(); 2125 2126 // Fix target property, if necessary 2127 if ( !event.target ) 2128 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either 2129 2130 // check if target is a textnode (safari) 2131 if ( event.target.nodeType == 3 ) 2132 event.target = event.target.parentNode; 2133 2134 // Add relatedTarget, if necessary 2135 if ( !event.relatedTarget && event.fromElement ) 2136 event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement; 2137 2138 // Calculate pageX/Y if missing and clientX/Y available 2139 if ( event.pageX == null && event.clientX != null ) { 2140 var doc = document.documentElement, body = document.body; 2141 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0); 2142 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0); 2143 } 2144 2145 // Add which for key events 2146 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) 2147 event.which = event.charCode || event.keyCode; 2148 2149 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) 2150 if ( !event.metaKey && event.ctrlKey ) 2151 event.metaKey = event.ctrlKey; 2152 2153 // Add which for click: 1 == left; 2 == middle; 3 == right 2154 // Note: button is not normalized, so don't use it 2155 if ( !event.which && event.button ) 2156 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); 2157 2158 return event; 2159 }, 2160 2161 proxy: function( fn, proxy ){ 2162 // Set the guid of unique handler to the same of original handler, so it can be removed 2163 proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++; 2164 // So proxy can be declared as an argument 2165 return proxy; 2166 }, 2167 2168 special: { 2169 ready: { 2170 setup: function() { 2171 // Make sure the ready event is setup 2172 bindReady(); 2173 return; 2174 }, 2175 2176 teardown: function() { return; } 2177 }, 2178 2179 mouseenter: { 2180 setup: function() { 2181 if ( jQuery.browser.msie ) return false; 2182 jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler); 2183 return true; 2184 }, 2185 2186 teardown: function() { 2187 if ( jQuery.browser.msie ) return false; 2188 jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler); 2189 return true; 2190 }, 2191 2192 handler: function(event) { 2193 // If we actually just moused on to a sub-element, ignore it 2194 if ( withinElement(event, this) ) return true; 2195 // Execute the right handlers by setting the event type to mouseenter 2196 event.type = "mouseenter"; 2197 return jQuery.event.handle.apply(this, arguments); 2198 } 2199 }, 2200 2201 mouseleave: { 2202 setup: function() { 2203 if ( jQuery.browser.msie ) return false; 2204 jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler); 2205 return true; 2206 }, 2207 2208 teardown: function() { 2209 if ( jQuery.browser.msie ) return false; 2210 jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler); 2211 return true; 2212 }, 2213 2214 handler: function(event) { 2215 // If we actually just moused on to a sub-element, ignore it 2216 if ( withinElement(event, this) ) return true; 2217 // Execute the right handlers by setting the event type to mouseleave 2218 event.type = "mouseleave"; 2219 return jQuery.event.handle.apply(this, arguments); 2220 } 2221 } 2222 } 2223 }; 2224 2225 jQuery.fn.extend({ 2226 bind: function( type, data, fn ) { 2227 return type == "unload" ? this.one(type, data, fn) : this.each(function(){ 2228 jQuery.event.add( this, type, fn || data, fn && data ); 2229 }); 2230 }, 2231 2232 one: function( type, data, fn ) { 2233 var one = jQuery.event.proxy( fn || data, function(event) { 2234 jQuery(this).unbind(event, one); 2235 return (fn || data).apply( this, arguments ); 2236 }); 2237 return this.each(function(){ 2238 jQuery.event.add( this, type, one, fn && data); 2239 }); 2240 }, 2241 2242 unbind: function( type, fn ) { 2243 return this.each(function(){ 2244 jQuery.event.remove( this, type, fn ); 2245 }); 2246 }, 2247 2248 trigger: function( type, data, fn ) { 2249 return this.each(function(){ 2250 jQuery.event.trigger( type, data, this, true, fn ); 2251 }); 2252 }, 2253 2254 triggerHandler: function( type, data, fn ) { 2255 return this[0] && jQuery.event.trigger( type, data, this[0], false, fn ); 2256 }, 2257 2258 toggle: function( fn ) { 2259 // Save reference to arguments for access in closure 2260 var args = arguments, i = 1; 2261 2262 // link all the functions, so any of them can unbind this click handler 2263 while( i < args.length ) 2264 jQuery.event.proxy( fn, args[i++] ); 2265 2266 return this.click( jQuery.event.proxy( fn, function(event) { 2267 // Figure out which function to execute 2268 this.lastToggle = ( this.lastToggle || 0 ) % i; 2269 2270 // Make sure that clicks stop 2271 event.preventDefault(); 2272 2273 // and execute the function 2274 return args[ this.lastToggle++ ].apply( this, arguments ) || false; 2275 })); 2276 }, 2277 2278 hover: function(fnOver, fnOut) { 2279 return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut); 2280 }, 2281 2282 ready: function(fn) { 2283 // Attach the listeners 2284 bindReady(); 2285 2286 // If the DOM is already ready 2287 if ( jQuery.isReady ) 2288 // Execute the function immediately 2289 fn.call( document, jQuery ); 2290 2291 // Otherwise, remember the function for later 2292 else 2293 // Add the function to the wait list 2294 jQuery.readyList.push( function() { return fn.call(this, jQuery); } ); 2295 2296 return this; 2297 } 2298 }); 2299 2300 jQuery.extend({ 2301 isReady: false, 2302 readyList: [], 2303 // Handle when the DOM is ready 2304 ready: function() { 2305 // Make sure that the DOM is not already loaded 2306 if ( !jQuery.isReady ) { 2307 // Remember that the DOM is ready 2308 jQuery.isReady = true; 2309 2310 // If there are functions bound, to execute 2311 if ( jQuery.readyList ) { 2312 // Execute all of them 2313 jQuery.each( jQuery.readyList, function(){ 2314 this.call( document ); 2315 }); 2316 2317 // Reset the list of functions 2318 jQuery.readyList = null; 2319 } 2320 2321 // Trigger any bound ready events 2322 jQuery(document).triggerHandler("ready"); 2323 } 2324 } 2325 }); 2326 2327 var readyBound = false; 2328 2329 function bindReady(){ 2330 if ( readyBound ) return; 2331 readyBound = true; 2332 2333 // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event 2334 if ( document.addEventListener && !jQuery.browser.opera) 2335 // Use the handy event callback 2336 document.addEventListener( "DOMContentLoaded", jQuery.ready, false ); 2337 2338 // If IE is used and is not in a frame 2339 // Continually check to see if the document is ready 2340 if ( jQuery.browser.msie && window == top ) (function(){ 2341 if (jQuery.isReady) return; 2342 try { 2343 // If IE is used, use the trick by Diego Perini 2344 // http://javascript.nwbox.com/IEContentLoaded/ 2345 document.documentElement.doScroll("left"); 2346 } catch( error ) { 2347 setTimeout( arguments.callee, 0 ); 2348 return; 2349 } 2350 // and execute any waiting functions 2351 jQuery.ready(); 2352 })(); 2353 2354 if ( jQuery.browser.opera ) 2355 document.addEventListener( "DOMContentLoaded", function () { 2356 if (jQuery.isReady) return; 2357 for (var i = 0; i < document.styleSheets.length; i++) 2358 if (document.styleSheets[i].disabled) { 2359 setTimeout( arguments.callee, 0 ); 2360 return; 2361 } 2362 // and execute any waiting functions 2363 jQuery.ready(); 2364 }, false); 2365 2366 if ( jQuery.browser.safari ) { 2367 var numStyles; 2368 (function(){ 2369 if (jQuery.isReady) return; 2370 if ( document.readyState != "loaded" && document.readyState != "complete" ) { 2371 setTimeout( arguments.callee, 0 ); 2372 return; 2373 } 2374 if ( numStyles === undefined ) 2375 numStyles = jQuery("style, link[rel=stylesheet]").length; 2376 if ( document.styleSheets.length != numStyles ) { 2377 setTimeout( arguments.callee, 0 ); 2378 return; 2379 } 2380 // and execute any waiting functions 2381 jQuery.ready(); 2382 })(); 2383 } 2384 2385 // A fallback to window.onload, that will always work 2386 jQuery.event.add( window, "load", jQuery.ready ); 2387 } 2388 2389 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," + 2390 "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + 2391 "submit,keydown,keypress,keyup,error").split(","), function(i, name){ 2392 2393 // Handle event binding 2394 jQuery.fn[name] = function(fn){ 2395 return fn ? this.bind(name, fn) : this.trigger(name); 2396 }; 2397 }); 2398 2399 // Checks if an event happened on an element within another element 2400 // Used in jQuery.event.special.mouseenter and mouseleave handlers 2401 var withinElement = function(event, elem) { 2402 // Check if mouse(over|out) are still within the same parent element 2403 var parent = event.relatedTarget; 2404 // Traverse up the tree 2405 while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; } 2406 // Return true if we actually just moused on to a sub-element 2407 return parent == elem; 2408 }; 2409 2410 // Prevent memory leaks in IE 2411 // And prevent errors on refresh with events like mouseover in other browsers 2412 // Window isn't included so as not to unbind existing unload events 2413 jQuery(window).bind("unload", function() { 2414 jQuery("*").add(document).unbind(); 2415 }); 2416 jQuery.fn.extend({ 2417 // Keep a copy of the old load 2418 _load: jQuery.fn.load, 2419 2420 load: function( url, params, callback ) { 2421 if ( typeof url != 'string' ) 2422 return this._load( url ); 2423 2424 var off = url.indexOf(" "); 2425 if ( off >= 0 ) { 2426 var selector = url.slice(off, url.length); 2427 url = url.slice(0, off); 2428 } 2429 2430 callback = callback || function(){}; 2431 2432 // Default to a GET request 2433 var type = "GET"; 2434 2435 // If the second parameter was provided 2436 if ( params ) 2437 // If it's a function 2438 if ( jQuery.isFunction( params ) ) { 2439 // We assume that it's the callback 2440 callback = params; 2441 params = null; 2442 2443 // Otherwise, build a param string 2444 } else { 2445 params = jQuery.param( params ); 2446 type = "POST"; 2447 } 2448 2449 var self = this; 2450 2451 // Request the remote document 2452 jQuery.ajax({ 2453 url: url, 2454 type: type, 2455 dataType: "html", 2456 data: params, 2457 complete: function(res, status){ 2458 // If successful, inject the HTML into all the matched elements 2459 if ( status == "success" || status == "notmodified" ) 2460 // See if a selector was specified 2461 self.html( selector ? 2462 // Create a dummy div to hold the results 2463 jQuery("<div/>") 2464 // inject the contents of the document in, removing the scripts 2465 // to avoid any 'Permission Denied' errors in IE 2466 .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, "")) 2467 2468 // Locate the specified elements 2469 .find(selector) : 2470 2471 // If not, just inject the full result 2472 res.responseText ); 2473 2474 self.each( callback, [res.responseText, status, res] ); 2475 } 2476 }); 2477 return this; 2478 }, 2479 2480 serialize: function() { 2481 return jQuery.param(this.serializeArray()); 2482 }, 2483 serializeArray: function() { 2484 return this.map(function(){ 2485 return jQuery.nodeName(this, "form") ? 2486 jQuery.makeArray(this.elements) : this; 2487 }) 2488 .filter(function(){ 2489 return this.name && !this.disabled && 2490 (this.checked || /select|textarea/i.test(this.nodeName) || 2491 /text|hidden|password/i.test(this.type)); 2492 }) 2493 .map(function(i, elem){ 2494 var val = jQuery(this).val(); 2495 return val == null ? null : 2496 val.constructor == Array ? 2497 jQuery.map( val, function(val, i){ 2498 return {name: elem.name, value: val}; 2499 }) : 2500 {name: elem.name, value: val}; 2501 }).get(); 2502 } 2503 }); 2504 2505 // Attach a bunch of functions for handling common AJAX events 2506 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){ 2507 jQuery.fn[o] = function(f){ 2508 return this.bind(o, f); 2509 }; 2510 }); 2511 2512 var jsc = now(); 2513 2514 jQuery.extend({ 2515 get: function( url, data, callback, type ) { 2516 // shift arguments if data argument was ommited 2517 if ( jQuery.isFunction( data ) ) { 2518 callback = data; 2519 data = null; 2520 } 2521 2522 return jQuery.ajax({ 2523 type: "GET", 2524 url: url, 2525 data: data, 2526 success: callback, 2527 dataType: type 2528 }); 2529 }, 2530 2531 getScript: function( url, callback ) { 2532 return jQuery.get(url, null, callback, "script"); 2533 }, 2534 2535 getJSON: function( url, data, callback ) { 2536 return jQuery.get(url, data, callback, "json"); 2537 }, 2538 2539 post: function( url, data, callback, type ) { 2540 if ( jQuery.isFunction( data ) ) { 2541 callback = data; 2542 data = {}; 2543 } 2544 2545 return jQuery.ajax({ 2546 type: "POST", 2547 url: url, 2548 data: data, 2549 success: callback, 2550 dataType: type 2551 }); 2552 }, 2553 2554 ajaxSetup: function( settings ) { 2555 jQuery.extend( jQuery.ajaxSettings, settings ); 2556 }, 2557 2558 ajaxSettings: { 2559 url: location.href, 2560 global: true, 2561 type: "GET", 2562 timeout: 0, 2563 contentType: "application/x-www-form-urlencoded", 2564 processData: true, 2565 async: true, 2566 data: null, 2567 username: null, 2568 password: null, 2569 accepts: { 2570 xml: "application/xml, text/xml", 2571 html: "text/html", 2572 script: "text/javascript, application/javascript", 2573 json: "application/json, text/javascript", 2574 text: "text/plain", 2575 _default: "*/*" 2576 } 2577 }, 2578 2579 // Last-Modified header cache for next request 2580 lastModified: {}, 2581 2582 ajax: function( s ) { 2583 // Extend the settings, but re-extend 's' so that it can be 2584 // checked again later (in the test suite, specifically) 2585 s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s)); 2586 2587 var jsonp, jsre = /=\?(&|$)/g, status, data, 2588 type = s.type.toUpperCase(); 2589 2590 // convert data if not already a string 2591 if ( s.data && s.processData && typeof s.data != "string" ) 2592 s.data = jQuery.param(s.data); 2593 2594 // Handle JSONP Parameter Callbacks 2595 if ( s.dataType == "jsonp" ) { 2596 if ( type == "GET" ) { 2597 if ( !s.url.match(jsre) ) 2598 s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?"; 2599 } else if ( !s.data || !s.data.match(jsre) ) 2600 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?"; 2601 s.dataType = "json"; 2602 } 2603 2604 // Build temporary JSONP function 2605 if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) { 2606 jsonp = "jsonp" + jsc++; 2607 2608 // Replace the =? sequence both in the query string and the data 2609 if ( s.data ) 2610 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1"); 2611 s.url = s.url.replace(jsre, "=" + jsonp + "$1"); 2612 2613 // We need to make sure 2614 // that a JSONP style response is executed properly 2615 s.dataType = "script"; 2616 2617 // Handle JSONP-style loading 2618 window[ jsonp ] = function(tmp){ 2619 data = tmp; 2620 success(); 2621 complete(); 2622 // Garbage collect 2623 window[ jsonp ] = undefined; 2624 try{ delete window[ jsonp ]; } catch(e){} 2625 if ( head ) 2626 head.removeChild( script ); 2627 }; 2628 } 2629 2630 if ( s.dataType == "script" && s.cache == null ) 2631 s.cache = false; 2632 2633 if ( s.cache === false && type == "GET" ) { 2634 var ts = now(); 2635 // try replacing _= if it is there 2636 var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2"); 2637 // if nothing was replaced, add timestamp to the end 2638 s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : ""); 2639 } 2640 2641 // If data is available, append data to url for get requests 2642 if ( s.data && type == "GET" ) { 2643 s.url += (s.url.match(/\?/) ? "&" : "?") + s.data; 2644 2645 // IE likes to send both get and post data, prevent this 2646 s.data = null; 2647 } 2648 2649 // Watch for a new set of requests 2650 if ( s.global && ! jQuery.active++ ) 2651 jQuery.event.trigger( "ajaxStart" ); 2652 2653 // Matches an absolute URL, and saves the domain 2654 var remote = /^(?:\w+:)?\/\/([^\/?#]+)/; 2655 2656 // If we're requesting a remote document 2657 // and trying to load JSON or Script with a GET 2658 if ( s.dataType == "script" && type == "GET" 2659 && remote.test(s.url) && remote.exec(s.url)[1] != location.host ){ 2660 var head = document.getElementsByTagName("head")[0]; 2661 var script = document.createElement("script"); 2662 script.src = s.url; 2663 if (s.scriptCharset) 2664 script.charset = s.scriptCharset; 2665 2666 // Handle Script loading 2667 if ( !jsonp ) { 2668 var done = false; 2669 2670 // Attach handlers for all browsers 2671 script.onload = script.onreadystatechange = function(){ 2672 if ( !done && (!this.readyState || 2673 this.readyState == "loaded" || this.readyState == "complete") ) { 2674 done = true; 2675 success(); 2676 complete(); 2677 head.removeChild( script ); 2678 } 2679 }; 2680 } 2681 2682 head.appendChild(script); 2683 2684 // We handle everything using the script element injection 2685 return undefined; 2686 } 2687 2688 var requestDone = false; 2689 2690 // Create the request object; Microsoft failed to properly 2691 // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available 2692 var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(); 2693 2694 // Open the socket 2695 // Passing null username, generates a login popup on Opera (#2865) 2696 if( s.username ) 2697 xhr.open(type, s.url, s.async, s.username, s.password); 2698 else 2699 xhr.open(type, s.url, s.async); 2700 2701 // Need an extra try/catch for cross domain requests in Firefox 3 2702 try { 2703 // Set the correct header, if data is being sent 2704 if ( s.data ) 2705 xhr.setRequestHeader("Content-Type", s.contentType); 2706 2707 // Set the If-Modified-Since header, if ifModified mode. 2708 if ( s.ifModified ) 2709 xhr.setRequestHeader("If-Modified-Since", 2710 jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" ); 2711 2712 // Set header so the called script knows that it's an XMLHttpRequest 2713 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 2714 2715 // Set the Accepts header for the server, depending on the dataType 2716 xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ? 2717 s.accepts[ s.dataType ] + ", */*" : 2718 s.accepts._default ); 2719 } catch(e){} 2720 2721 // Allow custom headers/mimetypes 2722 if ( s.beforeSend && s.beforeSend(xhr, s) === false ) { 2723 // cleanup active request counter 2724 s.global && jQuery.active--; 2725 // close opended socket 2726 xhr.abort(); 2727 return false; 2728 } 2729 2730 if ( s.global ) 2731 jQuery.event.trigger("ajaxSend", [xhr, s]); 2732 2733 // Wait for a response to come back 2734 var onreadystatechange = function(isTimeout){ 2735 // The transfer is complete and the data is available, or the request timed out 2736 if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) { 2737 requestDone = true; 2738 2739 // clear poll interval 2740 if (ival) { 2741 clearInterval(ival); 2742 ival = null; 2743 } 2744 2745 status = isTimeout == "timeout" && "timeout" || 2746 !jQuery.httpSuccess( xhr ) && "error" || 2747 s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" || 2748 "success"; 2749 2750 if ( status == "success" ) { 2751 // Watch for, and catch, XML document parse errors 2752 try { 2753 // process the data (runs the xml through httpData regardless of callback) 2754 data = jQuery.httpData( xhr, s.dataType, s.dataFilter ); 2755 } catch(e) { 2756 status = "parsererror"; 2757 } 2758 } 2759 2760 // Make sure that the request was successful or notmodified 2761 if ( status == "success" ) { 2762 // Cache Last-Modified header, if ifModified mode. 2763 var modRes; 2764 try { 2765 modRes = xhr.getResponseHeader("Last-Modified"); 2766 } catch(e) {} // swallow exception thrown by FF if header is not available 2767 2768 if ( s.ifModified && modRes ) 2769 jQuery.lastModified[s.url] = modRes; 2770 2771 // JSONP handles its own success callback 2772 if ( !jsonp ) 2773 success(); 2774 } else 2775 jQuery.handleError(s, xhr, status); 2776 2777 // Fire the complete handlers 2778 complete(); 2779 2780 // Stop memory leaks 2781 if ( s.async ) 2782 xhr = null; 2783 } 2784 }; 2785 2786 if ( s.async ) { 2787 // don't attach the handler to the request, just poll it instead 2788 var ival = setInterval(onreadystatechange, 13); 2789 2790 // Timeout checker 2791 if ( s.timeout > 0 ) 2792 setTimeout(function(){ 2793 // Check to see if the request is still happening 2794 if ( xhr ) { 2795 // Cancel the request 2796 xhr.abort(); 2797 2798 if( !requestDone ) 2799 onreadystatechange( "timeout" ); 2800 } 2801 }, s.timeout); 2802 } 2803 2804 // Send the data 2805 try { 2806 xhr.send(s.data); 2807 } catch(e) { 2808 jQuery.handleError(s, xhr, null, e); 2809 } 2810 2811 // firefox 1.5 doesn't fire statechange for sync requests 2812 if ( !s.async ) 2813 onreadystatechange(); 2814 2815 function success(){ 2816 // If a local callback was specified, fire it and pass it the data 2817 if ( s.success ) 2818 s.success( data, status ); 2819 2820 // Fire the global callback 2821 if ( s.global ) 2822 jQuery.event.trigger( "ajaxSuccess", [xhr, s] ); 2823 } 2824 2825 function complete(){ 2826 // Process result 2827 if ( s.complete ) 2828 s.complete(xhr, status); 2829 2830 // The request was completed 2831 if ( s.global ) 2832 jQuery.event.trigger( "ajaxComplete", [xhr, s] ); 2833 2834 // Handle the global AJAX counter 2835 if ( s.global && ! --jQuery.active ) 2836 jQuery.event.trigger( "ajaxStop" ); 2837 } 2838 2839 // return XMLHttpRequest to allow aborting the request etc. 2840 return xhr; 2841 }, 2842 2843 handleError: function( s, xhr, status, e ) { 2844 // If a local callback was specified, fire it 2845 if ( s.error ) s.error( xhr, status, e ); 2846 2847 // Fire the global callback 2848 if ( s.global ) 2849 jQuery.event.trigger( "ajaxError", [xhr, s, e] ); 2850 }, 2851 2852 // Counter for holding the number of active queries 2853 active: 0, 2854 2855 // Determines if an XMLHttpRequest was successful or not 2856 httpSuccess: function( xhr ) { 2857 try { 2858 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450 2859 return !xhr.status && location.protocol == "file:" || 2860 ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 || 2861 jQuery.browser.safari && xhr.status == undefined; 2862 } catch(e){} 2863 return false; 2864 }, 2865 2866 // Determines if an XMLHttpRequest returns NotModified 2867 httpNotModified: function( xhr, url ) { 2868 try { 2869 var xhrRes = xhr.getResponseHeader("Last-Modified"); 2870 2871 // Firefox always returns 200. check Last-Modified date 2872 return xhr.status == 304 || xhrRes == jQuery.lastModified[url] || 2873 jQuery.browser.safari && xhr.status == undefined; 2874 } catch(e){} 2875 return false; 2876 }, 2877 2878 httpData: function( xhr, type, filter ) { 2879 var ct = xhr.getResponseHeader("content-type"), 2880 xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0, 2881 data = xml ? xhr.responseXML : xhr.responseText; 2882 2883 if ( xml && data.documentElement.tagName == "parsererror" ) 2884 throw "parsererror"; 2885 2886 // Allow a pre-filtering function to sanitize the response 2887 if( filter ) 2888 data = filter( data, type ); 2889 2890 // If the type is "script", eval it in global context 2891 if ( type == "script" ) 2892 jQuery.globalEval( data ); 2893 2894 // Get the JavaScript object, if JSON is used. 2895 if ( type == "json" ) 2896 data = eval("(" + data + ")"); 2897 2898 return data; 2899 }, 2900 2901 // Serialize an array of form elements or a set of 2902 // key/values into a query string 2903 param: function( a ) { 2904 var s = []; 2905 2906 // If an array was passed in, assume that it is an array 2907 // of form elements 2908 if ( a.constructor == Array || a.jquery ) 2909 // Serialize the form elements 2910 jQuery.each( a, function(){ 2911 s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) ); 2912 }); 2913 2914 // Otherwise, assume that it's an object of key/value pairs 2915 else 2916 // Serialize the key/values 2917 for ( var j in a ) 2918 // If the value is an array then the key names need to be repeated 2919 if ( a[j] && a[j].constructor == Array ) 2920 jQuery.each( a[j], function(){ 2921 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) ); 2922 }); 2923 else 2924 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( jQuery.isFunction(a[j]) ? a[j]() : a[j] ) ); 2925 2926 // Return the resulting serialization 2927 return s.join("&").replace(/%20/g, "+"); 2928 } 2929 2930 }); 2931 jQuery.fn.extend({ 2932 show: function(speed,callback){ 2933 return speed ? 2934 this.animate({ 2935 height: "show", width: "show", opacity: "show" 2936 }, speed, callback) : 2937 2938 this.filter(":hidden").each(function(){ 2939 this.style.display = this.oldblock || ""; 2940 if ( jQuery.css(this,"display") == "none" ) { 2941 var elem = jQuery("<" + this.tagName + " />").appendTo("body"); 2942 this.style.display = elem.css("display"); 2943 // handle an edge condition where css is - div { display:none; } or similar 2944 if (this.style.display == "none") 2945 this.style.display = "block"; 2946 elem.remove(); 2947 } 2948 }).end(); 2949 }, 2950 2951 hide: function(speed,callback){ 2952 return speed ? 2953 this.animate({ 2954 height: "hide", width: "hide", opacity: "hide" 2955 }, speed, callback) : 2956 2957 this.filter(":visible").each(function(){ 2958 this.oldblock = this.oldblock || jQuery.css(this,"display"); 2959 this.style.display = "none"; 2960 }).end(); 2961 }, 2962 2963 // Save the old toggle function 2964 _toggle: jQuery.fn.toggle, 2965 2966 toggle: function( fn, fn2 ){ 2967 return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ? 2968 this._toggle.apply( this, arguments ) : 2969 fn ? 2970 this.animate({ 2971 height: "toggle", width: "toggle", opacity: "toggle" 2972 }, fn, fn2) : 2973 this.each(function(){ 2974 jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ](); 2975 }); 2976 }, 2977 2978 slideDown: function(speed,callback){ 2979 return this.animate({height: "show"}, speed, callback); 2980 }, 2981 2982 slideUp: function(speed,callback){ 2983 return this.animate({height: "hide"}, speed, callback); 2984 }, 2985 2986 slideToggle: function(speed, callback){ 2987 return this.animate({height: "toggle"}, speed, callback); 2988 }, 2989 2990 fadeIn: function(speed, callback){ 2991 return this.animate({opacity: "show"}, speed, callback); 2992 }, 2993 2994 fadeOut: function(speed, callback){ 2995 return this.animate({opacity: "hide"}, speed, callback); 2996 }, 2997 2998 fadeTo: function(speed,to,callback){ 2999 return this.animate({opacity: to}, speed, callback); 3000 }, 3001 3002 animate: function( prop, speed, easing, callback ) { 3003 var optall = jQuery.speed(speed, easing, callback); 3004 3005 return this[ optall.queue === false ? "each" : "queue" ](function(){ 3006 if ( this.nodeType != 1) 3007 return false; 3008 3009 var opt = jQuery.extend({}, optall), p, 3010 hidden = jQuery(this).is(":hidden"), self = this; 3011 3012 for ( p in prop ) { 3013 if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden ) 3014 return opt.complete.call(this); 3015 3016 if ( p == "height" || p == "width" ) { 3017 // Store display property 3018 opt.display = jQuery.css(this, "display"); 3019 3020 // Make sure that nothing sneaks out 3021 opt.overflow = this.style.overflow; 3022 } 3023 } 3024 3025 if ( opt.overflow != null ) 3026 this.style.overflow = "hidden"; 3027 3028 opt.curAnim = jQuery.extend({}, prop); 3029 3030 jQuery.each( prop, function(name, val){ 3031 var e = new jQuery.fx( self, opt, name ); 3032 3033 if ( /toggle|show|hide/.test(val) ) 3034 e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop ); 3035 else { 3036 var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/), 3037 start = e.cur(true) || 0; 3038 3039 if ( parts ) { 3040 var end = parseFloat(parts[2]), 3041 unit = parts[3] || "px"; 3042 3043 // We need to compute starting value 3044 if ( unit != "px" ) { 3045 self.style[ name ] = (end || 1) + unit; 3046 start = ((end || 1) / e.cur(true)) * start; 3047 self.style[ name ] = start + unit; 3048 } 3049 3050 // If a +=/-= token was provided, we're doing a relative animation 3051 if ( parts[1] ) 3052 end = ((parts[1] == "-=" ? -1 : 1) * end) + start; 3053 3054 e.custom( start, end, unit ); 3055 } else 3056 e.custom( start, val, "" ); 3057 } 3058 }); 3059 3060 // For JS strict compliance 3061 return true; 3062 }); 3063 }, 3064 3065 queue: function(type, fn){ 3066 if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) { 3067 fn = type; 3068 type = "fx"; 3069 } 3070 3071 if ( !type || (typeof type == "string" && !fn) ) 3072 return queue( this[0], type ); 3073 3074 return this.each(function(){ 3075 if ( fn.constructor == Array ) 3076 queue(this, type, fn); 3077 else { 3078 queue(this, type).push( fn ); 3079 3080 if ( queue(this, type).length == 1 ) 3081 fn.call(this); 3082 } 3083 }); 3084 }, 3085 3086 stop: function(clearQueue, gotoEnd){ 3087 var timers = jQuery.timers; 3088 3089 if (clearQueue) 3090 this.queue([]); 3091 3092 this.each(function(){ 3093 // go in reverse order so anything added to the queue during the loop is ignored 3094 for ( var i = timers.length - 1; i >= 0; i-- ) 3095 if ( timers[i].elem == this ) { 3096 if (gotoEnd) 3097 // force the next step to be the last 3098 timers[i](true); 3099 timers.splice(i, 1); 3100 } 3101 }); 3102 3103 // start the next in the queue if the last step wasn't forced 3104 if (!gotoEnd) 3105 this.dequeue(); 3106 3107 return this; 3108 } 3109 3110 }); 3111 3112 var queue = function( elem, type, array ) { 3113 if ( elem ){ 3114 3115 type = type || "fx"; 3116 3117 var q = jQuery.data( elem, type + "queue" ); 3118 3119 if ( !q || array ) 3120 q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) ); 3121 3122 } 3123 return q; 3124 }; 3125 3126 jQuery.fn.dequeue = function(type){ 3127 type = type || "fx"; 3128 3129 return this.each(function(){ 3130 var q = queue(this, type); 3131 3132 q.shift(); 3133 3134 if ( q.length ) 3135 q[0].call( this ); 3136 }); 3137 }; 3138 3139 jQuery.extend({ 3140 3141 speed: function(speed, easing, fn) { 3142 var opt = speed && speed.constructor == Object ? speed : { 3143 complete: fn || !fn && easing || 3144 jQuery.isFunction( speed ) && speed, 3145 duration: speed, 3146 easing: fn && easing || easing && easing.constructor != Function && easing 3147 }; 3148 3149 opt.duration = (opt.duration && opt.duration.constructor == Number ? 3150 opt.duration : 3151 jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def; 3152 3153 // Queueing 3154 opt.old = opt.complete; 3155 opt.complete = function(){ 3156 if ( opt.queue !== false ) 3157 jQuery(this).dequeue(); 3158 if ( jQuery.isFunction( opt.old ) ) 3159 opt.old.call( this ); 3160 }; 3161 3162 return opt; 3163 }, 3164 3165 easing: { 3166 linear: function( p, n, firstNum, diff ) { 3167 return firstNum + diff * p; 3168 }, 3169 swing: function( p, n, firstNum, diff ) { 3170 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum; 3171 } 3172 }, 3173 3174 timers: [], 3175 timerId: null, 3176 3177 fx: function( elem, options, prop ){ 3178 this.options = options; 3179 this.elem = elem; 3180 this.prop = prop; 3181 3182 if ( !options.orig ) 3183 options.orig = {}; 3184 } 3185 3186 }); 3187 3188 jQuery.fx.prototype = { 3189 3190 // Simple function for setting a style value 3191 update: function(){ 3192 if ( this.options.step ) 3193 this.options.step.call( this.elem, this.now, this ); 3194 3195 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); 3196 3197 // Set display property to block for height/width animations 3198 if ( this.prop == "height" || this.prop == "width" ) 3199 this.elem.style.display = "block"; 3200 }, 3201 3202 // Get the current size 3203 cur: function(force){ 3204 if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null ) 3205 return this.elem[ this.prop ]; 3206 3207 var r = parseFloat(jQuery.css(this.elem, this.prop, force)); 3208 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0; 3209 }, 3210 3211 // Start an animation from one number to another 3212 custom: function(from, to, unit){ 3213 this.startTime = now(); 3214 this.start = from; 3215 this.end = to; 3216 this.unit = unit || this.unit || "px"; 3217 this.now = this.start; 3218 this.pos = this.state = 0; 3219 this.update(); 3220 3221 var self = this; 3222 function t(gotoEnd){ 3223 return self.step(gotoEnd); 3224 } 3225 3226 t.elem = this.elem; 3227 3228 jQuery.timers.push(t); 3229 3230 if ( jQuery.timerId == null ) { 3231 jQuery.timerId = setInterval(function(){ 3232 var timers = jQuery.timers; 3233 3234 for ( var i = 0; i < timers.length; i++ ) 3235 if ( !timers[i]() ) 3236 timers.splice(i--, 1); 3237 3238 if ( !timers.length ) { 3239 clearInterval( jQuery.timerId ); 3240 jQuery.timerId = null; 3241 } 3242 }, 13); 3243 } 3244 }, 3245 3246 // Simple 'show' function 3247 show: function(){ 3248 // Remember where we started, so that we can go back to it later 3249 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop ); 3250 this.options.show = true; 3251 3252 // Begin the animation 3253 this.custom(0, this.cur()); 3254 3255 // Make sure that we start at a small width/height to avoid any 3256 // flash of content 3257 if ( this.prop == "width" || this.prop == "height" ) 3258 this.elem.style[this.prop] = "1px"; 3259 3260 // Start by showing the element 3261 jQuery(this.elem).show(); 3262 }, 3263 3264 // Simple 'hide' function 3265 hide: function(){ 3266 // Remember where we started, so that we can go back to it later 3267 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop ); 3268 this.options.hide = true; 3269 3270 // Begin the animation 3271 this.custom(this.cur(), 0); 3272 }, 3273 3274 // Each step of an animation 3275 step: function(gotoEnd){ 3276 var t = now(); 3277 3278 if ( gotoEnd || t > this.options.duration + this.startTime ) { 3279 this.now = this.end; 3280 this.pos = this.state = 1; 3281 this.update(); 3282 3283 this.options.curAnim[ this.prop ] = true; 3284 3285 var done = true; 3286 for ( var i in this.options.curAnim ) 3287 if ( this.options.curAnim[i] !== true ) 3288 done = false; 3289 3290 if ( done ) { 3291 if ( this.options.display != null ) { 3292 // Reset the overflow 3293 this.elem.style.overflow = this.options.overflow; 3294 3295 // Reset the display 3296 this.elem.style.display = this.options.display; 3297 if ( jQuery.css(this.elem, "display") == "none" ) 3298 this.elem.style.display = "block"; 3299 } 3300 3301 // Hide the element if the "hide" operation was done 3302 if ( this.options.hide ) 3303 this.elem.style.display = "none"; 3304 3305 // Reset the properties, if the item has been hidden or shown 3306 if ( this.options.hide || this.options.show ) 3307 for ( var p in this.options.curAnim ) 3308 jQuery.attr(this.elem.style, p, this.options.orig[p]); 3309 } 3310 3311 if ( done ) 3312 // Execute the complete function 3313 this.options.complete.call( this.elem ); 3314 3315 return false; 3316 } else { 3317 var n = t - this.startTime; 3318 this.state = n / this.options.duration; 3319 3320 // Perform the easing function, defaults to swing 3321 this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration); 3322 this.now = this.start + ((this.end - this.start) * this.pos); 3323 3324 // Perform the next step of the animation 3325 this.update(); 3326 } 3327 3328 return true; 3329 } 3330 3331 }; 3332 3333 jQuery.extend( jQuery.fx, { 3334 speeds:{ 3335 slow: 600, 3336 fast: 200, 3337 // Default speed 3338 def: 400 3339 }, 3340 step: { 3341 scrollLeft: function(fx){ 3342 fx.elem.scrollLeft = fx.now; 3343 }, 3344 3345 scrollTop: function(fx){ 3346 fx.elem.scrollTop = fx.now; 3347 }, 3348 3349 opacity: function(fx){ 3350 jQuery.attr(fx.elem.style, "opacity", fx.now); 3351 }, 3352 3353 _default: function(fx){ 3354 fx.elem.style[ fx.prop ] = fx.now + fx.unit; 3355 } 3356 } 3357 }); 3358 // The Offset Method 3359 // Originally By Brandon Aaron, part of the Dimension Plugin 3360 // http://jquery.com/plugins/project/dimensions 3361 jQuery.fn.offset = function() { 3362 var left = 0, top = 0, elem = this[0], results; 3363 3364 if ( elem ) with ( jQuery.browser ) { 3365 var parent = elem.parentNode, 3366 offsetChild = elem, 3367 offsetParent = elem.offsetParent, 3368 doc = elem.ownerDocument, 3369 safari2 = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent), 3370 css = jQuery.curCSS, 3371 fixed = css(elem, "position") == "fixed"; 3372 3373 // Use getBoundingClientRect if available 3374 if ( elem.getBoundingClientRect ) { 3375 var box = elem.getBoundingClientRect(); 3376 3377 // Add the document scroll offsets 3378 add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft), 3379 box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)); 3380 3381 // IE adds the HTML element's border, by default it is medium which is 2px 3382 // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; } 3383 // IE 7 standards mode, the border is always 2px 3384 // This border/offset is typically represented by the clientLeft and clientTop properties 3385 // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS 3386 // Therefore this method will be off by 2px in IE while in quirksmode 3387 add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop ); 3388 3389 // Otherwise loop through the offsetParents and parentNodes 3390 } else { 3391 3392 // Initial element offsets 3393 add( elem.offsetLeft, elem.offsetTop ); 3394 3395 // Get parent offsets 3396 while ( offsetParent ) { 3397 // Add offsetParent offsets 3398 add( offsetParent.offsetLeft, offsetParent.offsetTop ); 3399 3400 // Mozilla and Safari > 2 does not include the border on offset parents 3401 // However Mozilla adds the border for table or table cells 3402 if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 ) 3403 border( offsetParent ); 3404 3405 // Add the document scroll offsets if position is fixed on any offsetParent 3406 if ( !fixed && css(offsetParent, "position") == "fixed" ) 3407 fixed = true; 3408 3409 // Set offsetChild to previous offsetParent unless it is the body element 3410 offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent; 3411 // Get next offsetParent 3412 offsetParent = offsetParent.offsetParent; 3413 } 3414 3415 // Get parent scroll offsets 3416 while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) { 3417 // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug 3418 if ( !/^inline|table.*$/i.test(css(parent, "display")) ) 3419 // Subtract parent scroll offsets 3420 add( -parent.scrollLeft, -parent.scrollTop ); 3421 3422 // Mozilla does not add the border for a parent that has overflow != visible 3423 if ( mozilla && css(parent, "overflow") != "visible" ) 3424 border( parent ); 3425 3426 // Get next parent 3427 parent = parent.parentNode; 3428 } 3429 3430 // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild 3431 // Mozilla doubles body offsets with a non-absolutely positioned offsetChild 3432 if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) || 3433 (mozilla && css(offsetChild, "position") != "absolute") ) 3434 add( -doc.body.offsetLeft, -doc.body.offsetTop ); 3435 3436 // Add the document scroll offsets if position is fixed 3437 if ( fixed ) 3438 add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft), 3439 Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)); 3440 } 3441 3442 // Return an object with top and left properties 3443 results = { top: top, left: left }; 3444 } 3445 3446 function border(elem) { 3447 add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) ); 3448 } 3449 3450 function add(l, t) { 3451 left += parseInt(l, 10) || 0; 3452 top += parseInt(t, 10) || 0; 3453 } 3454 3455 return results; 3456 }; 3457 3458 3459 jQuery.fn.extend({ 3460 position: function() { 3461 var left = 0, top = 0, results; 3462 3463 if ( this[0] ) { 3464 // Get *real* offsetParent 3465 var offsetParent = this.offsetParent(), 3466 3467 // Get correct offsets 3468 offset = this.offset(), 3469 parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset(); 3470 3471 // Subtract element margins 3472 // note: when an element has margin: auto the offsetLeft and marginLeft 3473 // are the same in Safari causing offset.left to incorrectly be 0 3474 offset.top -= num( this, 'marginTop' ); 3475 offset.left -= num( this, 'marginLeft' ); 3476 3477 // Add offsetParent borders 3478 parentOffset.top += num( offsetParent, 'borderTopWidth' ); 3479 parentOffset.left += num( offsetParent, 'borderLeftWidth' ); 3480 3481 // Subtract the two offsets 3482 results = { 3483 top: offset.top - parentOffset.top, 3484 left: offset.left - parentOffset.left 3485 }; 3486 } 3487 3488 return results; 3489 }, 3490 3491 offsetParent: function() { 3492 var offsetParent = this[0].offsetParent; 3493 while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') ) 3494 offsetParent = offsetParent.offsetParent; 3495 return jQuery(offsetParent); 3496 } 3497 }); 3498 3499 3500 // Create scrollLeft and scrollTop methods 3501 jQuery.each( ['Left', 'Top'], function(i, name) { 3502 var method = 'scroll' + name; 3503 3504 jQuery.fn[ method ] = function(val) { 3505 if (!this[0]) return; 3506 3507 return val != undefined ? 3508 3509 // Set the scroll offset 3510 this.each(function() { 3511 this == window || this == document ? 3512 window.scrollTo( 3513 !i ? val : jQuery(window).scrollLeft(), 3514 i ? val : jQuery(window).scrollTop() 3515 ) : 3516 this[ method ] = val; 3517 }) : 3518 3519 // Return the scroll offset 3520 this[0] == window || this[0] == document ? 3521 self[ i ? 'pageYOffset' : 'pageXOffset' ] || 3522 jQuery.boxModel && document.documentElement[ method ] || 3523 document.body[ method ] : 3524 this[0][ method ]; 3525 }; 3526 }); 3527 // Create innerHeight, innerWidth, outerHeight and outerWidth methods 3528 jQuery.each([ "Height", "Width" ], function(i, name){ 3529 3530 var tl = i ? "Left" : "Top", // top or left 3531 br = i ? "Right" : "Bottom"; // bottom or right 3532 3533 // innerHeight and innerWidth 3534 jQuery.fn["inner" + name] = function(){ 3535 return this[ name.toLowerCase() ]() + 3536 num(this, "padding" + tl) + 3537 num(this, "padding" + br); 3538 }; 3539 3540 // outerHeight and outerWidth 3541 jQuery.fn["outer" + name] = function(margin) { 3542 return this["inner" + name]() + 3543 num(this, "border" + tl + "Width") + 3544 num(this, "border" + br + "Width") + 3545 (margin ? 3546 num(this, "margin" + tl) + num(this, "margin" + br) : 0); 3547 }; 3548 3549 });})();
联系我们 |
---|
文章看不懂?联系我们为您免费解答!免费助力个人,小企站点! |
① 电话:020-2206-9892 |
② QQ咨询:1025174874 |
③ 邮件:info@361sale.com |
④ 工作时间:周一至周五,9:30-18:30,节假日休息 |
THE END
暂无评论内容