2  * jQuery JavaScript Library v1.3.2
 
   5  * Copyright (c) 2009 John Resig
 
   6  * Dual licensed under the MIT and GPL licenses.
 
   7  * http://docs.jquery.com/License
 
   9  * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
 
  15         // Will speed up references to window, and allows munging its name.
 
  17         // Will speed up references to undefined, and allows munging its name.
 
  19         // Map over jQuery in case of overwrite
 
  20         _jQuery = window.jQuery,
 
  21         // Map over the $ in case of overwrite
 
  24         jQuery = window.jQuery = window.$ = function( selector, context ) {
 
  25                 // The jQuery object is actually just the init constructor 'enhanced'
 
  26                 return new jQuery.fn.init( selector, context );
 
  29         // A simple way to check for HTML strings or ID strings
 
  30         // (both of which we optimize for)
 
  31         quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
 
  32         // Is it a simple selector
 
  33         isSimple = /^.[^:#\[\.,]*$/;
 
  35 jQuery.fn = jQuery.prototype = {
 
  36         init: function( selector, context ) {
 
  37                 // Make sure that a selection was provided
 
  38                 selector = selector || document;
 
  40                 // Handle $(DOMElement)
 
  41                 if ( selector.nodeType ) {
 
  44                         this.context = selector;
 
  47                 // Handle HTML strings
 
  48                 if ( typeof selector === "string" ) {
 
  49                         // Are we dealing with HTML string or an ID?
 
  50                         var match = quickExpr.exec( selector );
 
  52                         // Verify a match, and that no context was specified for #id
 
  53                         if ( match && (match[1] || !context) ) {
 
  55                                 // HANDLE: $(html) -> $(array)
 
  57                                         selector = jQuery.clean( [ match[1] ], context );
 
  61                                         var elem = document.getElementById( match[3] );
 
  63                                         // Handle the case where IE and Opera return items
 
  64                                         // by name instead of ID
 
  65                                         if ( elem && elem.id != match[3] )
 
  66                                                 return jQuery().find( selector );
 
  68                                         // Otherwise, we inject the element directly into the jQuery object
 
  69                                         var ret = jQuery( elem || [] );
 
  70                                         ret.context = document;
 
  71                                         ret.selector = selector;
 
  75                         // HANDLE: $(expr, [context])
 
  76                         // (which is just equivalent to: $(content).find(expr)
 
  78                                 return jQuery( context ).find( selector );
 
  80                 // HANDLE: $(function)
 
  81                 // Shortcut for document ready
 
  82                 } else if ( jQuery.isFunction( selector ) )
 
  83                         return jQuery( document ).ready( selector );
 
  85                 // Make sure that old selector state is passed along
 
  86                 if ( selector.selector && selector.context ) {
 
  87                         this.selector = selector.selector;
 
  88                         this.context = selector.context;
 
  91                 return this.setArray(jQuery.isArray( selector ) ?
 
  93                         jQuery.makeArray(selector));
 
  96         // Start with an empty selector
 
  99         // The current version of jQuery being used
 
 102         // The number of elements contained in the matched element set
 
 107         // Get the Nth element in the matched element set OR
 
 108         // Get the whole matched element set as a clean array
 
 109         get: function( num ) {
 
 110                 return num === undefined ?
 
 112                         // Return a 'clean' array
 
 113                         Array.prototype.slice.call( this ) :
 
 115                         // Return just the object
 
 119         // Take an array of elements and push it onto the stack
 
 120         // (returning the new matched element set)
 
 121         pushStack: function( elems, name, selector ) {
 
 122                 // Build a new jQuery matched element set
 
 123                 var ret = jQuery( elems );
 
 125                 // Add the old object onto the stack (as a reference)
 
 126                 ret.prevObject = this;
 
 128                 ret.context = this.context;
 
 130                 if ( name === "find" )
 
 131                         ret.selector = this.selector + (this.selector ? " " : "") + selector;
 
 133                         ret.selector = this.selector + "." + name + "(" + selector + ")";
 
 135                 // Return the newly-formed element set
 
 139         // Force the current matched set of elements to become
 
 140         // the specified array of elements (destroying the stack in the process)
 
 141         // You should use pushStack() in order to do this, but maintain the stack
 
 142         setArray: function( elems ) {
 
 143                 // Resetting the length to 0, then using the native Array push
 
 144                 // is a super-fast way to populate an object with array-like properties
 
 146                 Array.prototype.push.apply( this, elems );
 
 151         // Execute a callback for every element in the matched set.
 
 152         // (You can seed the arguments with an array of args, but this is
 
 153         // only used internally.)
 
 154         each: function( callback, args ) {
 
 155                 return jQuery.each( this, callback, args );
 
 158         // Determine the position of an element within
 
 159         // the matched set of elements
 
 160         index: function( elem ) {
 
 161                 // Locate the position of the desired element
 
 162                 return jQuery.inArray(
 
 163                         // If it receives a jQuery object, the first element is used
 
 164                         elem && elem.jquery ? elem[0] : elem
 
 168         attr: function( name, value, type ) {
 
 171                 // Look for the case where we're accessing a style value
 
 172                 if ( typeof name === "string" )
 
 173                         if ( value === undefined )
 
 174                                 return this[0] && jQuery[ type || "attr" ]( this[0], name );
 
 178                                 options[ name ] = value;
 
 181                 // Check to see if we're setting style values
 
 182                 return this.each(function(i){
 
 183                         // Set all the styles
 
 184                         for ( name in options )
 
 189                                         name, jQuery.prop( this, options[ name ], type, i, name )
 
 194         css: function( key, value ) {
 
 195                 // ignore negative width and height values
 
 196                 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
 
 198                 return this.attr( key, value, "curCSS" );
 
 201         text: function( text ) {
 
 202                 if ( typeof text !== "object" && text != null )
 
 203                         return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
 
 207                 jQuery.each( text || this, function(){
 
 208                         jQuery.each( this.childNodes, function(){
 
 209                                 if ( this.nodeType != 8 )
 
 210                                         ret += this.nodeType != 1 ?
 
 212                                                 jQuery.fn.text( [ this ] );
 
 219         wrapAll: function( html ) {
 
 221                         // The elements to wrap the target around
 
 222                         var wrap = jQuery( html, this[0].ownerDocument ).clone();
 
 224                         if ( this[0].parentNode )
 
 225                                 wrap.insertBefore( this[0] );
 
 230                                 while ( elem.firstChild )
 
 231                                         elem = elem.firstChild;
 
 240         wrapInner: function( html ) {
 
 241                 return this.each(function(){
 
 242                         jQuery( this ).contents().wrapAll( html );
 
 246         wrap: function( html ) {
 
 247                 return this.each(function(){
 
 248                         jQuery( this ).wrapAll( html );
 
 253                 return this.domManip(arguments, true, function(elem){
 
 254                         if (this.nodeType == 1)
 
 255                                 this.appendChild( elem );
 
 259         prepend: function() {
 
 260                 return this.domManip(arguments, true, function(elem){
 
 261                         if (this.nodeType == 1)
 
 262                                 this.insertBefore( elem, this.firstChild );
 
 267                 return this.domManip(arguments, false, function(elem){
 
 268                         this.parentNode.insertBefore( elem, this );
 
 273                 return this.domManip(arguments, false, function(elem){
 
 274                         this.parentNode.insertBefore( elem, this.nextSibling );
 
 279                 return this.prevObject || jQuery( [] );
 
 282         // For internal use only.
 
 283         // Behaves like an Array's method, not like a jQuery method.
 
 288         find: function( selector ) {
 
 289                 if ( this.length === 1 ) {
 
 290                         var ret = this.pushStack( [], "find", selector );
 
 292                         jQuery.find( selector, this[0], ret );
 
 295                         return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
 
 296                                 return jQuery.find( selector, elem );
 
 297                         })), "find", selector );
 
 301         clone: function( events ) {
 
 303                 var ret = this.map(function(){
 
 304                         if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
 
 305                                 // IE copies events bound via attachEvent when
 
 306                                 // using cloneNode. Calling detachEvent on the
 
 307                                 // clone will also remove the events from the orignal
 
 308                                 // In order to get around this, we use innerHTML.
 
 309                                 // Unfortunately, this means some modifications to
 
 310                                 // attributes in IE that are actually only stored
 
 311                                 // as properties will not be copied (such as the
 
 312                                 // the name attribute on an input).
 
 313                                 var html = this.outerHTML;
 
 315                                         var div = this.ownerDocument.createElement("div");
 
 316                                         div.appendChild( this.cloneNode(true) );
 
 317                                         html = div.innerHTML;
 
 320                                 return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
 
 322                                 return this.cloneNode(true);
 
 325                 // Copy the events from the original to the clone
 
 326                 if ( events === true ) {
 
 327                         var orig = this.find("*").andSelf(), i = 0;
 
 329                         ret.find("*").andSelf().each(function(){
 
 330                                 if ( this.nodeName !== orig[i].nodeName )
 
 333                                 var events = jQuery.data( orig[i], "events" );
 
 335                                 for ( var type in events ) {
 
 336                                         for ( var handler in events[ type ] ) {
 
 337                                                 jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
 
 345                 // Return the cloned set
 
 349         filter: function( selector ) {
 
 350                 return this.pushStack(
 
 351                         jQuery.isFunction( selector ) &&
 
 352                         jQuery.grep(this, function(elem, i){
 
 353                                 return selector.call( elem, i );
 
 356                         jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
 
 357                                 return elem.nodeType === 1;
 
 358                         }) ), "filter", selector );
 
 361         closest: function( selector ) {
 
 362                 var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
 
 365                 return this.map(function(){
 
 367                         while ( cur && cur.ownerDocument ) {
 
 368                                 if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
 
 369                                         jQuery.data(cur, "closest", closer);
 
 372                                 cur = cur.parentNode;
 
 378         not: function( selector ) {
 
 379                 if ( typeof selector === "string" )
 
 380                         // test special case where just one selector is passed in
 
 381                         if ( isSimple.test( selector ) )
 
 382                                 return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
 
 384                                 selector = jQuery.multiFilter( selector, this );
 
 386                 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
 
 387                 return this.filter(function() {
 
 388                         return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
 
 392         add: function( selector ) {
 
 393                 return this.pushStack( jQuery.unique( jQuery.merge(
 
 395                         typeof selector === "string" ?
 
 397                                 jQuery.makeArray( selector )
 
 401         is: function( selector ) {
 
 402                 return !!selector && jQuery.multiFilter( selector, this ).length > 0;
 
 405         hasClass: function( selector ) {
 
 406                 return !!selector && this.is( "." + selector );
 
 409         val: function( value ) {
 
 410                 if ( value === undefined ) {                    
 
 414                                 if( jQuery.nodeName( elem, 'option' ) )
 
 415                                         return (elem.attributes.value || {}).specified ? elem.value : elem.text;
 
 417                                 // We need to handle select boxes special
 
 418                                 if ( jQuery.nodeName( elem, "select" ) ) {
 
 419                                         var index = elem.selectedIndex,
 
 421                                                 options = elem.options,
 
 422                                                 one = elem.type == "select-one";
 
 424                                         // Nothing was selected
 
 428                                         // Loop through all the selected options
 
 429                                         for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
 
 430                                                 var option = options[ i ];
 
 432                                                 if ( option.selected ) {
 
 433                                                         // Get the specifc value for the option
 
 434                                                         value = jQuery(option).val();
 
 436                                                         // We don't need an array for one selects
 
 440                                                         // Multi-Selects return an array
 
 441                                                         values.push( value );
 
 448                                 // Everything else, we just grab the value
 
 449                                 return (elem.value || "").replace(/\r/g, "");
 
 456                 if ( typeof value === "number" )
 
 459                 return this.each(function(){
 
 460                         if ( this.nodeType != 1 )
 
 463                         if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
 
 464                                 this.checked = (jQuery.inArray(this.value, value) >= 0 ||
 
 465                                         jQuery.inArray(this.name, value) >= 0);
 
 467                         else if ( jQuery.nodeName( this, "select" ) ) {
 
 468                                 var values = jQuery.makeArray(value);
 
 470                                 jQuery( "option", this ).each(function(){
 
 471                                         this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
 
 472                                                 jQuery.inArray( this.text, values ) >= 0);
 
 475                                 if ( !values.length )
 
 476                                         this.selectedIndex = -1;
 
 483         html: function( value ) {
 
 484                 return value === undefined ?
 
 486                                 this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
 
 488                         this.empty().append( value );
 
 491         replaceWith: function( value ) {
 
 492                 return this.after( value ).remove();
 
 496                 return this.slice( i, +i + 1 );
 
 500                 return this.pushStack( Array.prototype.slice.apply( this, arguments ),
 
 501                         "slice", Array.prototype.slice.call(arguments).join(",") );
 
 504         map: function( callback ) {
 
 505                 return this.pushStack( jQuery.map(this, function(elem, i){
 
 506                         return callback.call( elem, i, elem );
 
 510         andSelf: function() {
 
 511                 return this.add( this.prevObject );
 
 514         domManip: function( args, table, callback ) {
 
 516                         var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
 
 517                                 scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
 
 518                                 first = fragment.firstChild;
 
 521                                 for ( var i = 0, l = this.length; i < l; i++ )
 
 522                                         callback.call( root(this[i], first), this.length > 1 || i > 0 ?
 
 523                                                         fragment.cloneNode(true) : fragment );
 
 526                                 jQuery.each( scripts, evalScript );
 
 531                 function root( elem, cur ) {
 
 532                         return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
 
 533                                 (elem.getElementsByTagName("tbody")[0] ||
 
 534                                 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
 
 540 // Give the init function the jQuery prototype for later instantiation
 
 541 jQuery.fn.init.prototype = jQuery.fn;
 
 543 function evalScript( i, elem ) {
 
 552                 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
 
 554         if ( elem.parentNode )
 
 555                 elem.parentNode.removeChild( elem );
 
 562 jQuery.extend = jQuery.fn.extend = function() {
 
 563         // copy reference to target object
 
 564         var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
 
 566         // Handle a deep copy situation
 
 567         if ( typeof target === "boolean" ) {
 
 569                 target = arguments[1] || {};
 
 570                 // skip the boolean and the target
 
 574         // Handle case when target is a string or something (possible in deep copy)
 
 575         if ( typeof target !== "object" && !jQuery.isFunction(target) )
 
 578         // extend jQuery itself if only one argument is passed
 
 584         for ( ; i < length; i++ )
 
 585                 // Only deal with non-null/undefined values
 
 586                 if ( (options = arguments[ i ]) != null )
 
 587                         // Extend the base object
 
 588                         for ( var name in options ) {
 
 589                                 var src = target[ name ], copy = options[ name ];
 
 591                                 // Prevent never-ending loop
 
 592                                 if ( target === copy )
 
 595                                 // Recurse if we're merging object values
 
 596                                 if ( deep && copy && typeof copy === "object" && !copy.nodeType )
 
 597                                         target[ name ] = jQuery.extend( deep, 
 
 598                                                 // Never move original objects, clone them
 
 599                                                 src || ( copy.length != null ? [ ] : { } )
 
 602                                 // Don't bring in undefined values
 
 603                                 else if ( copy !== undefined )
 
 604                                         target[ name ] = copy;
 
 608         // Return the modified object
 
 612 // exclude the following css properties to add px
 
 613 var     exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
 
 615         defaultView = document.defaultView || {},
 
 616         toString = Object.prototype.toString;
 
 619         noConflict: function( deep ) {
 
 623                         window.jQuery = _jQuery;
 
 628         // See test/unit/core.js for details concerning isFunction.
 
 629         // Since version 1.3, DOM methods and functions like alert
 
 630         // aren't supported. They return false on IE (#2968).
 
 631         isFunction: function( obj ) {
 
 632                 return toString.call(obj) === "[object Function]";
 
 635         isArray: function( obj ) {
 
 636                 return toString.call(obj) === "[object Array]";
 
 639         // check if an element is in a (or is an) XML document
 
 640         isXMLDoc: function( elem ) {
 
 641                 return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
 
 642                         !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
 
 645         // Evalulates a script in a global context
 
 646         globalEval: function( data ) {
 
 647                 if ( data && /\S/.test(data) ) {
 
 648                         // Inspired by code by Andrea Giammarchi
 
 649                         // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
 
 650                         var head = document.getElementsByTagName("head")[0] || document.documentElement,
 
 651                                 script = document.createElement("script");
 
 653                         script.type = "text/javascript";
 
 654                         if ( jQuery.support.scriptEval )
 
 655                                 script.appendChild( document.createTextNode( data ) );
 
 659                         // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
 
 660                         // This arises when a base node is used (#2709).
 
 661                         head.insertBefore( script, head.firstChild );
 
 662                         head.removeChild( script );
 
 666         nodeName: function( elem, name ) {
 
 667                 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
 
 670         // args is for internal usage only
 
 671         each: function( object, callback, args ) {
 
 672                 var name, i = 0, length = object.length;
 
 675                         if ( length === undefined ) {
 
 676                                 for ( name in object )
 
 677                                         if ( callback.apply( object[ name ], args ) === false )
 
 680                                 for ( ; i < length; )
 
 681                                         if ( callback.apply( object[ i++ ], args ) === false )
 
 684                 // A special, fast, case for the most common use of each
 
 686                         if ( length === undefined ) {
 
 687                                 for ( name in object )
 
 688                                         if ( callback.call( object[ name ], name, object[ name ] ) === false )
 
 691                                 for ( var value = object[0];
 
 692                                         i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
 
 698         prop: function( elem, value, type, i, name ) {
 
 699                 // Handle executable functions
 
 700                 if ( jQuery.isFunction( value ) )
 
 701                         value = value.call( elem, i );
 
 703                 // Handle passing in a number to a CSS property
 
 704                 return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
 
 710                 // internal only, use addClass("class")
 
 711                 add: function( elem, classNames ) {
 
 712                         jQuery.each((classNames || "").split(/\s+/), function(i, className){
 
 713                                 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
 
 714                                         elem.className += (elem.className ? " " : "") + className;
 
 718                 // internal only, use removeClass("class")
 
 719                 remove: function( elem, classNames ) {
 
 720                         if (elem.nodeType == 1)
 
 721                                 elem.className = classNames !== undefined ?
 
 722                                         jQuery.grep(elem.className.split(/\s+/), function(className){
 
 723                                                 return !jQuery.className.has( classNames, className );
 
 728                 // internal only, use hasClass("class")
 
 729                 has: function( elem, className ) {
 
 730                         return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
 
 734         // A method for quickly swapping in/out CSS properties to get correct calculations
 
 735         swap: function( elem, options, callback ) {
 
 737                 // Remember the old values, and insert the new ones
 
 738                 for ( var name in options ) {
 
 739                         old[ name ] = elem.style[ name ];
 
 740                         elem.style[ name ] = options[ name ];
 
 743                 callback.call( elem );
 
 745                 // Revert the old values
 
 746                 for ( var name in options )
 
 747                         elem.style[ name ] = old[ name ];
 
 750         css: function( elem, name, force, extra ) {
 
 751                 if ( name == "width" || name == "height" ) {
 
 752                         var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
 
 755                                 val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
 
 757                                 if ( extra === "border" )
 
 760                                 jQuery.each( which, function() {
 
 762                                                 val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
 
 763                                         if ( extra === "margin" )
 
 764                                                 val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
 
 766                                                 val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
 
 770                         if ( elem.offsetWidth !== 0 )
 
 773                                 jQuery.swap( elem, props, getWH );
 
 775                         return Math.max(0, Math.round(val));
 
 778                 return jQuery.curCSS( elem, name, force );
 
 781         curCSS: function( elem, name, force ) {
 
 782                 var ret, style = elem.style;
 
 784                 // We need to handle opacity special in IE
 
 785                 if ( name == "opacity" && !jQuery.support.opacity ) {
 
 786                         ret = jQuery.attr( style, "opacity" );
 
 793                 // Make sure we're using the right name for getting the float value
 
 794                 if ( name.match( /float/i ) )
 
 797                 if ( !force && style && style[ name ] )
 
 800                 else if ( defaultView.getComputedStyle ) {
 
 802                         // Only "float" is needed here
 
 803                         if ( name.match( /float/i ) )
 
 806                         name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
 
 808                         var computedStyle = defaultView.getComputedStyle( elem, null );
 
 811                                 ret = computedStyle.getPropertyValue( name );
 
 813                         // We should always get a number back from opacity
 
 814                         if ( name == "opacity" && ret == "" )
 
 817                 } else if ( elem.currentStyle ) {
 
 818                         var camelCase = name.replace(/\-(\w)/g, function(all, letter){
 
 819                                 return letter.toUpperCase();
 
 822                         ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
 
 824                         // From the awesome hack by Dean Edwards
 
 825                         // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
 
 827                         // If we're not dealing with a regular pixel number
 
 828                         // but a number that has a weird ending, we need to convert it to pixels
 
 829                         if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
 
 830                                 // Remember the original values
 
 831                                 var left = style.left, rsLeft = elem.runtimeStyle.left;
 
 833                                 // Put in the new values to get a computed value out
 
 834                                 elem.runtimeStyle.left = elem.currentStyle.left;
 
 835                                 style.left = ret || 0;
 
 836                                 ret = style.pixelLeft + "px";
 
 838                                 // Revert the changed values
 
 840                                 elem.runtimeStyle.left = rsLeft;
 
 847         clean: function( elems, context, fragment ) {
 
 848                 context = context || document;
 
 850                 // !context.createElement fails in IE with an error but returns typeof 'object'
 
 851                 if ( typeof context.createElement === "undefined" )
 
 852                         context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
 
 854                 // If a single string is passed in and it's a single tag
 
 855                 // just do a createElement and skip the rest
 
 856                 if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
 
 857                         var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
 
 859                                 return [ context.createElement( match[1] ) ];
 
 862                 var ret = [], scripts = [], div = context.createElement("div");
 
 864                 jQuery.each(elems, function(i, elem){
 
 865                         if ( typeof elem === "number" )
 
 871                         // Convert html string into DOM nodes
 
 872                         if ( typeof elem === "string" ) {
 
 873                                 // Fix "XHTML"-style tags in all browsers
 
 874                                 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
 
 875                                         return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
 
 877                                                 front + "></" + tag + ">";
 
 880                                 // Trim whitespace, otherwise indexOf won't work as expected
 
 881                                 var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
 
 884                                         // option or optgroup
 
 885                                         !tags.indexOf("<opt") &&
 
 886                                         [ 1, "<select multiple='multiple'>", "</select>" ] ||
 
 888                                         !tags.indexOf("<leg") &&
 
 889                                         [ 1, "<fieldset>", "</fieldset>" ] ||
 
 891                                         tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
 
 892                                         [ 1, "<table>", "</table>" ] ||
 
 894                                         !tags.indexOf("<tr") &&
 
 895                                         [ 2, "<table><tbody>", "</tbody></table>" ] ||
 
 897                                         // <thead> matched above
 
 898                                         (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
 
 899                                         [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
 
 901                                         !tags.indexOf("<col") &&
 
 902                                         [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
 
 904                                         // IE can't serialize <link> and <script> tags normally
 
 905                                         !jQuery.support.htmlSerialize &&
 
 906                                         [ 1, "div<div>", "</div>" ] ||
 
 910                                 // Go to html and back, then peel off extra wrappers
 
 911                                 div.innerHTML = wrap[1] + elem + wrap[2];
 
 913                                 // Move to the right depth
 
 917                                 // Remove IE's autoinserted <tbody> from table fragments
 
 918                                 if ( !jQuery.support.tbody ) {
 
 920                                         // String was a <table>, *may* have spurious <tbody>
 
 921                                         var hasBody = /<tbody/i.test(elem),
 
 922                                                 tbody = !tags.indexOf("<table") && !hasBody ?
 
 923                                                         div.firstChild && div.firstChild.childNodes :
 
 925                                                 // String was a bare <thead> or <tfoot>
 
 926                                                 wrap[1] == "<table>" && !hasBody ?
 
 930                                         for ( var j = tbody.length - 1; j >= 0 ; --j )
 
 931                                                 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
 
 932                                                         tbody[ j ].parentNode.removeChild( tbody[ j ] );
 
 936                                 // IE completely kills leading whitespace when innerHTML is used
 
 937                                 if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
 
 938                                         div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
 
 940                                 elem = jQuery.makeArray( div.childNodes );
 
 946                                 ret = jQuery.merge( ret, elem );
 
 951                         for ( var i = 0; ret[i]; i++ ) {
 
 952                                 if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
 
 953                                         scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
 
 955                                         if ( ret[i].nodeType === 1 )
 
 956                                                 ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
 
 957                                         fragment.appendChild( ret[i] );
 
 967         attr: function( elem, name, value ) {
 
 968                 // don't set attributes on text and comment nodes
 
 969                 if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
 
 972                 var notxml = !jQuery.isXMLDoc( elem ),
 
 973                         // Whether we are setting (or getting)
 
 974                         set = value !== undefined;
 
 976                 // Try to normalize/fix the name
 
 977                 name = notxml && jQuery.props[ name ] || name;
 
 979                 // Only do all the following if this is a node (faster for style)
 
 980                 // IE elem.getAttribute passes even for style
 
 981                 if ( elem.tagName ) {
 
 983                         // These attributes require special treatment
 
 984                         var special = /href|src|style/.test( name );
 
 986                         // Safari mis-reports the default selected property of a hidden option
 
 987                         // Accessing the parent's selectedIndex property fixes it
 
 988                         if ( name == "selected" && elem.parentNode )
 
 989                                 elem.parentNode.selectedIndex;
 
 991                         // If applicable, access the attribute via the DOM 0 way
 
 992                         if ( name in elem && notxml && !special ) {
 
 994                                         // We can't allow the type property to be changed (since it causes problems in IE)
 
 995                                         if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
 
 996                                                 throw "type property can't be changed";
 
 998                                         elem[ name ] = value;
 
1001                                 // browsers index elements by id/name on forms, give priority to attributes.
 
1002                                 if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
 
1003                                         return elem.getAttributeNode( name ).nodeValue;
 
1005                                 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
 
1006                                 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
 
1007                                 if ( name == "tabIndex" ) {
 
1008                                         var attributeNode = elem.getAttributeNode( "tabIndex" );
 
1009                                         return attributeNode && attributeNode.specified
 
1010                                                 ? attributeNode.value
 
1011                                                 : elem.nodeName.match(/(button|input|object|select|textarea)/i)
 
1013                                                         : elem.nodeName.match(/^(a|area)$/i) && elem.href
 
1018                                 return elem[ name ];
 
1021                         if ( !jQuery.support.style && notxml &&  name == "style" )
 
1022                                 return jQuery.attr( elem.style, "cssText", value );
 
1025                                 // convert the value to a string (all browsers do this but IE) see #1070
 
1026                                 elem.setAttribute( name, "" + value );
 
1028                         var attr = !jQuery.support.hrefNormalized && notxml && special
 
1029                                         // Some attributes require a special call on IE
 
1030                                         ? elem.getAttribute( name, 2 )
 
1031                                         : elem.getAttribute( name );
 
1033                         // Non-existent attributes return null, we normalize to undefined
 
1034                         return attr === null ? undefined : attr;
 
1037                 // elem is actually elem.style ... set the style
 
1039                 // IE uses filters for opacity
 
1040                 if ( !jQuery.support.opacity && name == "opacity" ) {
 
1042                                 // IE has trouble with opacity if it does not have layout
 
1043                                 // Force it by setting the zoom level
 
1046                                 // Set the alpha filter to set the opacity
 
1047                                 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
 
1048                                         (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
 
1051                         return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
 
1052                                 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
 
1056                 name = name.replace(/-([a-z])/ig, function(all, letter){
 
1057                         return letter.toUpperCase();
 
1061                         elem[ name ] = value;
 
1063                 return elem[ name ];
 
1066         trim: function( text ) {
 
1067                 return (text || "").replace( /^\s+|\s+$/g, "" );
 
1070         makeArray: function( array ) {
 
1073                 if( array != null ){
 
1074                         var i = array.length;
 
1075                         // The window, strings (and functions) also have 'length'
 
1076                         if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
 
1080                                         ret[--i] = array[i];
 
1086         inArray: function( elem, array ) {
 
1087                 for ( var i = 0, length = array.length; i < length; i++ )
 
1088                 // Use === because on IE, window == document
 
1089                         if ( array[ i ] === elem )
 
1095         merge: function( first, second ) {
 
1096                 // We have to loop this way because IE & Opera overwrite the length
 
1097                 // expando of getElementsByTagName
 
1098                 var i = 0, elem, pos = first.length;
 
1099                 // Also, we need to make sure that the correct elements are being returned
 
1100                 // (IE returns comment nodes in a '*' query)
 
1101                 if ( !jQuery.support.getAll ) {
 
1102                         while ( (elem = second[ i++ ]) != null )
 
1103                                 if ( elem.nodeType != 8 )
 
1104                                         first[ pos++ ] = elem;
 
1107                         while ( (elem = second[ i++ ]) != null )
 
1108                                 first[ pos++ ] = elem;
 
1113         unique: function( array ) {
 
1114                 var ret = [], done = {};
 
1118                         for ( var i = 0, length = array.length; i < length; i++ ) {
 
1119                                 var id = jQuery.data( array[ i ] );
 
1121                                 if ( !done[ id ] ) {
 
1123                                         ret.push( array[ i ] );
 
1134         grep: function( elems, callback, inv ) {
 
1137                 // Go through the array, only saving the items
 
1138                 // that pass the validator function
 
1139                 for ( var i = 0, length = elems.length; i < length; i++ )
 
1140                         if ( !inv != !callback( elems[ i ], i ) )
 
1141                                 ret.push( elems[ i ] );
 
1146         map: function( elems, callback ) {
 
1149                 // Go through the array, translating each of the items to their
 
1150                 // new value (or values).
 
1151                 for ( var i = 0, length = elems.length; i < length; i++ ) {
 
1152                         var value = callback( elems[ i ], i );
 
1154                         if ( value != null )
 
1155                                 ret[ ret.length ] = value;
 
1158                 return ret.concat.apply( [], ret );
 
1162 // Use of jQuery.browser is deprecated.
 
1163 // It's included for backwards compatibility and plugins,
 
1164 // although they should work to migrate away.
 
1166 var userAgent = navigator.userAgent.toLowerCase();
 
1168 // Figure out what browser is being used
 
1170         version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
 
1171         safari: /webkit/.test( userAgent ),
 
1172         opera: /opera/.test( userAgent ),
 
1173         msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
 
1174         mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
 
1178         parent: function(elem){return elem.parentNode;},
 
1179         parents: function(elem){return jQuery.dir(elem,"parentNode");},
 
1180         next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
 
1181         prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
 
1182         nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
 
1183         prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
 
1184         siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
 
1185         children: function(elem){return jQuery.sibling(elem.firstChild);},
 
1186         contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
 
1187 }, function(name, fn){
 
1188         jQuery.fn[ name ] = function( selector ) {
 
1189                 var ret = jQuery.map( this, fn );
 
1191                 if ( selector && typeof selector == "string" )
 
1192                         ret = jQuery.multiFilter( selector, ret );
 
1194                 return this.pushStack( jQuery.unique( ret ), name, selector );
 
1200         prependTo: "prepend",
 
1201         insertBefore: "before",
 
1202         insertAfter: "after",
 
1203         replaceAll: "replaceWith"
 
1204 }, function(name, original){
 
1205         jQuery.fn[ name ] = function( selector ) {
 
1206                 var ret = [], insert = jQuery( selector );
 
1208                 for ( var i = 0, l = insert.length; i < l; i++ ) {
 
1209                         var elems = (i > 0 ? this.clone(true) : this).get();
 
1210                         jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
 
1211                         ret = ret.concat( elems );
 
1214                 return this.pushStack( ret, name, selector );
 
1219         removeAttr: function( name ) {
 
1220                 jQuery.attr( this, name, "" );
 
1221                 if (this.nodeType == 1)
 
1222                         this.removeAttribute( name );
 
1225         addClass: function( classNames ) {
 
1226                 jQuery.className.add( this, classNames );
 
1229         removeClass: function( classNames ) {
 
1230                 jQuery.className.remove( this, classNames );
 
1233         toggleClass: function( classNames, state ) {
 
1234                 if( typeof state !== "boolean" )
 
1235                         state = !jQuery.className.has( this, classNames );
 
1236                 jQuery.className[ state ? "add" : "remove" ]( this, classNames );
 
1239         remove: function( selector ) {
 
1240                 if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
 
1241                         // Prevent memory leaks
 
1242                         jQuery( "*", this ).add([this]).each(function(){
 
1243                                 jQuery.event.remove(this);
 
1244                                 jQuery.removeData(this);
 
1246                         if (this.parentNode)
 
1247                                 this.parentNode.removeChild( this );
 
1252                 // Remove element nodes and prevent memory leaks
 
1253                 jQuery(this).children().remove();
 
1255                 // Remove any remaining nodes
 
1256                 while ( this.firstChild )
 
1257                         this.removeChild( this.firstChild );
 
1259 }, function(name, fn){
 
1260         jQuery.fn[ name ] = function(){
 
1261                 return this.each( fn, arguments );
 
1265 // Helper function used by the dimensions and offset modules
 
1266 function num(elem, prop) {
 
1267         return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
 
1269 var expando = "jQuery" + now(), uuid = 0, windowData = {};
\r 
1274         data: function( elem, name, data ) {
\r 
1275                 elem = elem == window ?
\r 
1279                 var id = elem[ expando ];
\r 
1281                 // Compute a unique ID for the element
\r 
1283                         id = elem[ expando ] = ++uuid;
\r 
1285                 // Only generate the data cache if we're
\r 
1286                 // trying to access or manipulate it
\r 
1287                 if ( name && !jQuery.cache[ id ] )
\r 
1288                         jQuery.cache[ id ] = {};
\r 
1290                 // Prevent overriding the named cache with undefined values
\r 
1291                 if ( data !== undefined )
\r 
1292                         jQuery.cache[ id ][ name ] = data;
\r 
1294                 // Return the named cache data, or the ID for the element
\r 
1296                         jQuery.cache[ id ][ name ] :
\r 
1300         removeData: function( elem, name ) {
\r 
1301                 elem = elem == window ?
\r 
1305                 var id = elem[ expando ];
\r 
1307                 // If we want to remove a specific section of the element's data
\r 
1309                         if ( jQuery.cache[ id ] ) {
\r 
1310                                 // Remove the section of cache data
\r 
1311                                 delete jQuery.cache[ id ][ name ];
\r 
1313                                 // If we've removed all the data, remove the element's cache
\r 
1316                                 for ( name in jQuery.cache[ id ] )
\r 
1320                                         jQuery.removeData( elem );
\r 
1323                 // Otherwise, we want to remove all of the element's data
\r 
1325                         // Clean up the element expando
\r 
1327                                 delete elem[ expando ];
\r 
1329                                 // IE has trouble directly removing the expando
\r 
1330                                 // but it's ok with using removeAttribute
\r 
1331                                 if ( elem.removeAttribute )
\r 
1332                                         elem.removeAttribute( expando );
\r 
1335                         // Completely remove the data cache
\r 
1336                         delete jQuery.cache[ id ];
\r 
1339         queue: function( elem, type, data ) {
\r 
1342                         type = (type || "fx") + "queue";
\r 
1344                         var q = jQuery.data( elem, type );
\r 
1346                         if ( !q || jQuery.isArray(data) )
\r 
1347                                 q = jQuery.data( elem, type, jQuery.makeArray(data) );
\r 
1355         dequeue: function( elem, type ){
\r 
1356                 var queue = jQuery.queue( elem, type ),
\r 
1357                         fn = queue.shift();
\r 
1359                 if( !type || type === "fx" )
\r 
1362                 if( fn !== undefined )
\r 
1367 jQuery.fn.extend({
\r 
1368         data: function( key, value ){
\r 
1369                 var parts = key.split(".");
\r 
1370                 parts[1] = parts[1] ? "." + parts[1] : "";
\r 
1372                 if ( value === undefined ) {
\r 
1373                         var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
\r 
1375                         if ( data === undefined && this.length )
\r 
1376                                 data = jQuery.data( this[0], key );
\r 
1378                         return data === undefined && parts[1] ?
\r 
1379                                 this.data( parts[0] ) :
\r 
1382                         return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
\r 
1383                                 jQuery.data( this, key, value );
\r 
1387         removeData: function( key ){
\r 
1388                 return this.each(function(){
\r 
1389                         jQuery.removeData( this, key );
\r 
1392         queue: function(type, data){
\r 
1393                 if ( typeof type !== "string" ) {
\r 
1398                 if ( data === undefined )
\r 
1399                         return jQuery.queue( this[0], type );
\r 
1401                 return this.each(function(){
\r 
1402                         var queue = jQuery.queue( this, type, data );
\r 
1404                          if( type == "fx" && queue.length == 1 )
\r 
1405                                 queue[0].call(this);
\r 
1408         dequeue: function(type){
\r 
1409                 return this.each(function(){
\r 
1410                         jQuery.dequeue( this, type );
\r 
1414  * Sizzle CSS Selector Engine - v0.9.3
 
1415  *  Copyright 2009, The Dojo Foundation
 
1416  *  Released under the MIT, BSD, and GPL Licenses.
 
1417  *  More information: http://sizzlejs.com/
 
1421 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
 
1423         toString = Object.prototype.toString;
 
1425 var Sizzle = function(selector, context, results, seed) {
 
1426         results = results || [];
 
1427         context = context || document;
 
1429         if ( context.nodeType !== 1 && context.nodeType !== 9 )
 
1432         if ( !selector || typeof selector !== "string" ) {
 
1436         var parts = [], m, set, checkSet, check, mode, extra, prune = true;
 
1438         // Reset the position of the chunker regexp (start from head)
 
1439         chunker.lastIndex = 0;
 
1441         while ( (m = chunker.exec(selector)) !== null ) {
 
1445                         extra = RegExp.rightContext;
 
1450         if ( parts.length > 1 && origPOS.exec( selector ) ) {
 
1451                 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
 
1452                         set = posProcess( parts[0] + parts[1], context );
 
1454                         set = Expr.relative[ parts[0] ] ?
 
1456                                 Sizzle( parts.shift(), context );
 
1458                         while ( parts.length ) {
 
1459                                 selector = parts.shift();
 
1461                                 if ( Expr.relative[ selector ] )
 
1462                                         selector += parts.shift();
 
1464                                 set = posProcess( selector, set );
 
1469                         { expr: parts.pop(), set: makeArray(seed) } :
 
1470                         Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context, isXML(context) );
 
1471                 set = Sizzle.filter( ret.expr, ret.set );
 
1473                 if ( parts.length > 0 ) {
 
1474                         checkSet = makeArray(set);
 
1479                 while ( parts.length ) {
 
1480                         var cur = parts.pop(), pop = cur;
 
1482                         if ( !Expr.relative[ cur ] ) {
 
1488                         if ( pop == null ) {
 
1492                         Expr.relative[ cur ]( checkSet, pop, isXML(context) );
 
1501                 throw "Syntax error, unrecognized expression: " + (cur || selector);
 
1504         if ( toString.call(checkSet) === "[object Array]" ) {
 
1506                         results.push.apply( results, checkSet );
 
1507                 } else if ( context.nodeType === 1 ) {
 
1508                         for ( var i = 0; checkSet[i] != null; i++ ) {
 
1509                                 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
 
1510                                         results.push( set[i] );
 
1514                         for ( var i = 0; checkSet[i] != null; i++ ) {
 
1515                                 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
 
1516                                         results.push( set[i] );
 
1521                 makeArray( checkSet, results );
 
1525                 Sizzle( extra, context, results, seed );
 
1528                         hasDuplicate = false;
 
1529                         results.sort(sortOrder);
 
1531                         if ( hasDuplicate ) {
 
1532                                 for ( var i = 1; i < results.length; i++ ) {
 
1533                                         if ( results[i] === results[i-1] ) {
 
1534                                                 results.splice(i--, 1);
 
1544 Sizzle.matches = function(expr, set){
 
1545         return Sizzle(expr, null, null, set);
 
1548 Sizzle.find = function(expr, context, isXML){
 
1555         for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
 
1556                 var type = Expr.order[i], match;
 
1558                 if ( (match = Expr.match[ type ].exec( expr )) ) {
 
1559                         var left = RegExp.leftContext;
 
1561                         if ( left.substr( left.length - 1 ) !== "\\" ) {
 
1562                                 match[1] = (match[1] || "").replace(/\\/g, "");
 
1563                                 set = Expr.find[ type ]( match, context, isXML );
 
1564                                 if ( set != null ) {
 
1565                                         expr = expr.replace( Expr.match[ type ], "" );
 
1573                 set = context.getElementsByTagName("*");
 
1576         return {set: set, expr: expr};
 
1579 Sizzle.filter = function(expr, set, inplace, not){
 
1580         var old = expr, result = [], curLoop = set, match, anyFound,
 
1581                 isXMLFilter = set && set[0] && isXML(set[0]);
 
1583         while ( expr && set.length ) {
 
1584                 for ( var type in Expr.filter ) {
 
1585                         if ( (match = Expr.match[ type ].exec( expr )) != null ) {
 
1586                                 var filter = Expr.filter[ type ], found, item;
 
1589                                 if ( curLoop == result ) {
 
1593                                 if ( Expr.preFilter[ type ] ) {
 
1594                                         match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
 
1597                                                 anyFound = found = true;
 
1598                                         } else if ( match === true ) {
 
1604                                         for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
 
1606                                                         found = filter( item, match, i, curLoop );
 
1607                                                         var pass = not ^ !!found;
 
1609                                                         if ( inplace && found != null ) {
 
1615                                                         } else if ( pass ) {
 
1616                                                                 result.push( item );
 
1623                                 if ( found !== undefined ) {
 
1628                                         expr = expr.replace( Expr.match[ type ], "" );
 
1639                 // Improper expression
 
1640                 if ( expr == old ) {
 
1641                         if ( anyFound == null ) {
 
1642                                 throw "Syntax error, unrecognized expression: " + expr;
 
1654 var Expr = Sizzle.selectors = {
 
1655         order: [ "ID", "NAME", "TAG" ],
 
1657                 ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
 
1658                 CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
 
1659                 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
 
1660                 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
 
1661                 TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
 
1662                 CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
 
1663                 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
 
1664                 PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
 
1667                 "class": "className",
 
1671                 href: function(elem){
 
1672                         return elem.getAttribute("href");
 
1676                 "+": function(checkSet, part, isXML){
 
1677                         var isPartStr = typeof part === "string",
 
1678                                 isTag = isPartStr && !/\W/.test(part),
 
1679                                 isPartStrNotTag = isPartStr && !isTag;
 
1681                         if ( isTag && !isXML ) {
 
1682                                 part = part.toUpperCase();
 
1685                         for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
 
1686                                 if ( (elem = checkSet[i]) ) {
 
1687                                         while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
 
1689                                         checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
 
1695                         if ( isPartStrNotTag ) {
 
1696                                 Sizzle.filter( part, checkSet, true );
 
1699                 ">": function(checkSet, part, isXML){
 
1700                         var isPartStr = typeof part === "string";
 
1702                         if ( isPartStr && !/\W/.test(part) ) {
 
1703                                 part = isXML ? part : part.toUpperCase();
 
1705                                 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
 
1706                                         var elem = checkSet[i];
 
1708                                                 var parent = elem.parentNode;
 
1709                                                 checkSet[i] = parent.nodeName === part ? parent : false;
 
1713                                 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
 
1714                                         var elem = checkSet[i];
 
1716                                                 checkSet[i] = isPartStr ?
 
1718                                                         elem.parentNode === part;
 
1723                                         Sizzle.filter( part, checkSet, true );
 
1727                 "": function(checkSet, part, isXML){
 
1728                         var doneName = done++, checkFn = dirCheck;
 
1730                         if ( !part.match(/\W/) ) {
 
1731                                 var nodeCheck = part = isXML ? part : part.toUpperCase();
 
1732                                 checkFn = dirNodeCheck;
 
1735                         checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
 
1737                 "~": function(checkSet, part, isXML){
 
1738                         var doneName = done++, checkFn = dirCheck;
 
1740                         if ( typeof part === "string" && !part.match(/\W/) ) {
 
1741                                 var nodeCheck = part = isXML ? part : part.toUpperCase();
 
1742                                 checkFn = dirNodeCheck;
 
1745                         checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
 
1749                 ID: function(match, context, isXML){
 
1750                         if ( typeof context.getElementById !== "undefined" && !isXML ) {
 
1751                                 var m = context.getElementById(match[1]);
 
1752                                 return m ? [m] : [];
 
1755                 NAME: function(match, context, isXML){
 
1756                         if ( typeof context.getElementsByName !== "undefined" ) {
 
1757                                 var ret = [], results = context.getElementsByName(match[1]);
 
1759                                 for ( var i = 0, l = results.length; i < l; i++ ) {
 
1760                                         if ( results[i].getAttribute("name") === match[1] ) {
 
1761                                                 ret.push( results[i] );
 
1765                                 return ret.length === 0 ? null : ret;
 
1768                 TAG: function(match, context){
 
1769                         return context.getElementsByTagName(match[1]);
 
1773                 CLASS: function(match, curLoop, inplace, result, not, isXML){
 
1774                         match = " " + match[1].replace(/\\/g, "") + " ";
 
1780                         for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
 
1782                                         if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
 
1784                                                         result.push( elem );
 
1785                                         } else if ( inplace ) {
 
1793                 ID: function(match){
 
1794                         return match[1].replace(/\\/g, "");
 
1796                 TAG: function(match, curLoop){
 
1797                         for ( var i = 0; curLoop[i] === false; i++ ){}
 
1798                         return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
 
1800                 CHILD: function(match){
 
1801                         if ( match[1] == "nth" ) {
 
1802                                 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
 
1803                                 var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
 
1804                                         match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
 
1805                                         !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
 
1807                                 // calculate the numbers (first)n+(last) including if they are negative
 
1808                                 match[2] = (test[1] + (test[2] || 1)) - 0;
 
1809                                 match[3] = test[3] - 0;
 
1812                         // TODO: Move to normal caching system
 
1817                 ATTR: function(match, curLoop, inplace, result, not, isXML){
 
1818                         var name = match[1].replace(/\\/g, "");
 
1820                         if ( !isXML && Expr.attrMap[name] ) {
 
1821                                 match[1] = Expr.attrMap[name];
 
1824                         if ( match[2] === "~=" ) {
 
1825                                 match[4] = " " + match[4] + " ";
 
1830                 PSEUDO: function(match, curLoop, inplace, result, not){
 
1831                         if ( match[1] === "not" ) {
 
1832                                 // If we're dealing with a complex expression, or a simple one
 
1833                                 if ( match[3].match(chunker).length > 1 || /^\w/.test(match[3]) ) {
 
1834                                         match[3] = Sizzle(match[3], null, null, curLoop);
 
1836                                         var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
 
1838                                                 result.push.apply( result, ret );
 
1842                         } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
 
1848                 POS: function(match){
 
1849                         match.unshift( true );
 
1854                 enabled: function(elem){
 
1855                         return elem.disabled === false && elem.type !== "hidden";
 
1857                 disabled: function(elem){
 
1858                         return elem.disabled === true;
 
1860                 checked: function(elem){
 
1861                         return elem.checked === true;
 
1863                 selected: function(elem){
 
1864                         // Accessing this property makes selected-by-default
 
1865                         // options in Safari work properly
 
1866                         elem.parentNode.selectedIndex;
 
1867                         return elem.selected === true;
 
1869                 parent: function(elem){
 
1870                         return !!elem.firstChild;
 
1872                 empty: function(elem){
 
1873                         return !elem.firstChild;
 
1875                 has: function(elem, i, match){
 
1876                         return !!Sizzle( match[3], elem ).length;
 
1878                 header: function(elem){
 
1879                         return /h\d/i.test( elem.nodeName );
 
1881                 text: function(elem){
 
1882                         return "text" === elem.type;
 
1884                 radio: function(elem){
 
1885                         return "radio" === elem.type;
 
1887                 checkbox: function(elem){
 
1888                         return "checkbox" === elem.type;
 
1890                 file: function(elem){
 
1891                         return "file" === elem.type;
 
1893                 password: function(elem){
 
1894                         return "password" === elem.type;
 
1896                 submit: function(elem){
 
1897                         return "submit" === elem.type;
 
1899                 image: function(elem){
 
1900                         return "image" === elem.type;
 
1902                 reset: function(elem){
 
1903                         return "reset" === elem.type;
 
1905                 button: function(elem){
 
1906                         return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
 
1908                 input: function(elem){
 
1909                         return /input|select|textarea|button/i.test(elem.nodeName);
 
1913                 first: function(elem, i){
 
1916                 last: function(elem, i, match, array){
 
1917                         return i === array.length - 1;
 
1919                 even: function(elem, i){
 
1922                 odd: function(elem, i){
 
1925                 lt: function(elem, i, match){
 
1926                         return i < match[3] - 0;
 
1928                 gt: function(elem, i, match){
 
1929                         return i > match[3] - 0;
 
1931                 nth: function(elem, i, match){
 
1932                         return match[3] - 0 == i;
 
1934                 eq: function(elem, i, match){
 
1935                         return match[3] - 0 == i;
 
1939                 PSEUDO: function(elem, match, i, array){
 
1940                         var name = match[1], filter = Expr.filters[ name ];
 
1943                                 return filter( elem, i, match, array );
 
1944                         } else if ( name === "contains" ) {
 
1945                                 return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
 
1946                         } else if ( name === "not" ) {
 
1949                                 for ( var i = 0, l = not.length; i < l; i++ ) {
 
1950                                         if ( not[i] === elem ) {
 
1958                 CHILD: function(elem, match){
 
1959                         var type = match[1], node = elem;
 
1963                                         while (node = node.previousSibling)  {
 
1964                                                 if ( node.nodeType === 1 ) return false;
 
1966                                         if ( type == 'first') return true;
 
1969                                         while (node = node.nextSibling)  {
 
1970                                                 if ( node.nodeType === 1 ) return false;
 
1974                                         var first = match[2], last = match[3];
 
1976                                         if ( first == 1 && last == 0 ) {
 
1980                                         var doneName = match[0],
 
1981                                                 parent = elem.parentNode;
 
1983                                         if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
 
1985                                                 for ( node = parent.firstChild; node; node = node.nextSibling ) {
 
1986                                                         if ( node.nodeType === 1 ) {
 
1987                                                                 node.nodeIndex = ++count;
 
1990                                                 parent.sizcache = doneName;
 
1993                                         var diff = elem.nodeIndex - last;
 
1997                                                 return ( diff % first == 0 && diff / first >= 0 );
 
2001                 ID: function(elem, match){
 
2002                         return elem.nodeType === 1 && elem.getAttribute("id") === match;
 
2004                 TAG: function(elem, match){
 
2005                         return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
 
2007                 CLASS: function(elem, match){
 
2008                         return (" " + (elem.className || elem.getAttribute("class")) + " ")
 
2009                                 .indexOf( match ) > -1;
 
2011                 ATTR: function(elem, match){
 
2012                         var name = match[1],
 
2013                                 result = Expr.attrHandle[ name ] ?
 
2014                                         Expr.attrHandle[ name ]( elem ) :
 
2015                                         elem[ name ] != null ?
 
2017                                                 elem.getAttribute( name ),
 
2018                                 value = result + "",
 
2022                         return result == null ?
 
2027                                 value.indexOf(check) >= 0 :
 
2029                                 (" " + value + " ").indexOf(check) >= 0 :
 
2031                                 value && result !== false :
 
2035                                 value.indexOf(check) === 0 :
 
2037                                 value.substr(value.length - check.length) === check :
 
2039                                 value === check || value.substr(0, check.length + 1) === check + "-" :
 
2042                 POS: function(elem, match, i, array){
 
2043                         var name = match[2], filter = Expr.setFilters[ name ];
 
2046                                 return filter( elem, i, match, array );
 
2052 var origPOS = Expr.match.POS;
 
2054 for ( var type in Expr.match ) {
 
2055         Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
 
2058 var makeArray = function(array, results) {
 
2059         array = Array.prototype.slice.call( array );
 
2062                 results.push.apply( results, array );
 
2069 // Perform a simple check to determine if the browser is capable of
 
2070 // converting a NodeList to an array using builtin methods.
 
2072         Array.prototype.slice.call( document.documentElement.childNodes );
 
2074 // Provide a fallback method if it does not work
 
2076         makeArray = function(array, results) {
 
2077                 var ret = results || [];
 
2079                 if ( toString.call(array) === "[object Array]" ) {
 
2080                         Array.prototype.push.apply( ret, array );
 
2082                         if ( typeof array.length === "number" ) {
 
2083                                 for ( var i = 0, l = array.length; i < l; i++ ) {
 
2084                                         ret.push( array[i] );
 
2087                                 for ( var i = 0; array[i]; i++ ) {
 
2088                                         ret.push( array[i] );
 
2099 if ( document.documentElement.compareDocumentPosition ) {
 
2100         sortOrder = function( a, b ) {
 
2101                 var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
 
2103                         hasDuplicate = true;
 
2107 } else if ( "sourceIndex" in document.documentElement ) {
 
2108         sortOrder = function( a, b ) {
 
2109                 var ret = a.sourceIndex - b.sourceIndex;
 
2111                         hasDuplicate = true;
 
2115 } else if ( document.createRange ) {
 
2116         sortOrder = function( a, b ) {
 
2117                 var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
 
2118                 aRange.selectNode(a);
 
2119                 aRange.collapse(true);
 
2120                 bRange.selectNode(b);
 
2121                 bRange.collapse(true);
 
2122                 var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
 
2124                         hasDuplicate = true;
 
2130 // Check to see if the browser returns elements by name when
 
2131 // querying by getElementById (and provide a workaround)
 
2133         // We're going to inject a fake input element with a specified name
 
2134         var form = document.createElement("form"),
 
2135                 id = "script" + (new Date).getTime();
 
2136         form.innerHTML = "<input name='" + id + "'/>";
 
2138         // Inject it into the root element, check its status, and remove it quickly
 
2139         var root = document.documentElement;
 
2140         root.insertBefore( form, root.firstChild );
 
2142         // The workaround has to do additional checks after a getElementById
 
2143         // Which slows things down for other browsers (hence the branching)
 
2144         if ( !!document.getElementById( id ) ) {
 
2145                 Expr.find.ID = function(match, context, isXML){
 
2146                         if ( typeof context.getElementById !== "undefined" && !isXML ) {
 
2147                                 var m = context.getElementById(match[1]);
 
2148                                 return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
 
2152                 Expr.filter.ID = function(elem, match){
 
2153                         var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
 
2154                         return elem.nodeType === 1 && node && node.nodeValue === match;
 
2158         root.removeChild( form );
 
2162         // Check to see if the browser returns only elements
 
2163         // when doing getElementsByTagName("*")
 
2165         // Create a fake element
 
2166         var div = document.createElement("div");
 
2167         div.appendChild( document.createComment("") );
 
2169         // Make sure no comments are found
 
2170         if ( div.getElementsByTagName("*").length > 0 ) {
 
2171                 Expr.find.TAG = function(match, context){
 
2172                         var results = context.getElementsByTagName(match[1]);
 
2174                         // Filter out possible comments
 
2175                         if ( match[1] === "*" ) {
 
2178                                 for ( var i = 0; results[i]; i++ ) {
 
2179                                         if ( results[i].nodeType === 1 ) {
 
2180                                                 tmp.push( results[i] );
 
2191         // Check to see if an attribute returns normalized href attributes
 
2192         div.innerHTML = "<a href='#'></a>";
 
2193         if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
 
2194                         div.firstChild.getAttribute("href") !== "#" ) {
 
2195                 Expr.attrHandle.href = function(elem){
 
2196                         return elem.getAttribute("href", 2);
 
2201 if ( document.querySelectorAll ) (function(){
 
2202         var oldSizzle = Sizzle, div = document.createElement("div");
 
2203         div.innerHTML = "<p class='TEST'></p>";
 
2205         // Safari can't handle uppercase or unicode characters when
 
2207         if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
 
2211         Sizzle = function(query, context, extra, seed){
 
2212                 context = context || document;
 
2214                 // Only use querySelectorAll on non-XML documents
 
2215                 // (ID selectors don't work in non-HTML documents)
 
2216                 if ( !seed && context.nodeType === 9 && !isXML(context) ) {
 
2218                                 return makeArray( context.querySelectorAll(query), extra );
 
2222                 return oldSizzle(query, context, extra, seed);
 
2225         Sizzle.find = oldSizzle.find;
 
2226         Sizzle.filter = oldSizzle.filter;
 
2227         Sizzle.selectors = oldSizzle.selectors;
 
2228         Sizzle.matches = oldSizzle.matches;
 
2231 if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
 
2232         var div = document.createElement("div");
 
2233         div.innerHTML = "<div class='test e'></div><div class='test'></div>";
 
2235         // Opera can't find a second classname (in 9.6)
 
2236         if ( div.getElementsByClassName("e").length === 0 )
 
2239         // Safari caches class attributes, doesn't catch changes (in 3.2)
 
2240         div.lastChild.className = "e";
 
2242         if ( div.getElementsByClassName("e").length === 1 )
 
2245         Expr.order.splice(1, 0, "CLASS");
 
2246         Expr.find.CLASS = function(match, context, isXML) {
 
2247                 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
 
2248                         return context.getElementsByClassName(match[1]);
 
2253 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
 
2254         var sibDir = dir == "previousSibling" && !isXML;
 
2255         for ( var i = 0, l = checkSet.length; i < l; i++ ) {
 
2256                 var elem = checkSet[i];
 
2258                         if ( sibDir && elem.nodeType === 1 ){
 
2259                                 elem.sizcache = doneName;
 
2266                                 if ( elem.sizcache === doneName ) {
 
2267                                         match = checkSet[elem.sizset];
 
2271                                 if ( elem.nodeType === 1 && !isXML ){
 
2272                                         elem.sizcache = doneName;
 
2276                                 if ( elem.nodeName === cur ) {
 
2284                         checkSet[i] = match;
 
2289 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
 
2290         var sibDir = dir == "previousSibling" && !isXML;
 
2291         for ( var i = 0, l = checkSet.length; i < l; i++ ) {
 
2292                 var elem = checkSet[i];
 
2294                         if ( sibDir && elem.nodeType === 1 ) {
 
2295                                 elem.sizcache = doneName;
 
2302                                 if ( elem.sizcache === doneName ) {
 
2303                                         match = checkSet[elem.sizset];
 
2307                                 if ( elem.nodeType === 1 ) {
 
2309                                                 elem.sizcache = doneName;
 
2312                                         if ( typeof cur !== "string" ) {
 
2313                                                 if ( elem === cur ) {
 
2318                                         } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
 
2327                         checkSet[i] = match;
 
2332 var contains = document.compareDocumentPosition ?  function(a, b){
 
2333         return a.compareDocumentPosition(b) & 16;
 
2335         return a !== b && (a.contains ? a.contains(b) : true);
 
2338 var isXML = function(elem){
 
2339         return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
 
2340                 !!elem.ownerDocument && isXML( elem.ownerDocument );
 
2343 var posProcess = function(selector, context){
 
2344         var tmpSet = [], later = "", match,
 
2345                 root = context.nodeType ? [context] : context;
 
2347         // Position selectors must be done after the filter
 
2348         // And so must :not(positional) so we move all PSEUDOs to the end
 
2349         while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
 
2351                 selector = selector.replace( Expr.match.PSEUDO, "" );
 
2354         selector = Expr.relative[selector] ? selector + "*" : selector;
 
2356         for ( var i = 0, l = root.length; i < l; i++ ) {
 
2357                 Sizzle( selector, root[i], tmpSet );
 
2360         return Sizzle.filter( later, tmpSet );
 
2364 jQuery.find = Sizzle;
 
2365 jQuery.filter = Sizzle.filter;
 
2366 jQuery.expr = Sizzle.selectors;
 
2367 jQuery.expr[":"] = jQuery.expr.filters;
 
2369 Sizzle.selectors.filters.hidden = function(elem){
 
2370         return elem.offsetWidth === 0 || elem.offsetHeight === 0;
 
2373 Sizzle.selectors.filters.visible = function(elem){
 
2374         return elem.offsetWidth > 0 || elem.offsetHeight > 0;
 
2377 Sizzle.selectors.filters.animated = function(elem){
 
2378         return jQuery.grep(jQuery.timers, function(fn){
 
2379                 return elem === fn.elem;
 
2383 jQuery.multiFilter = function( expr, elems, not ) {
 
2385                 expr = ":not(" + expr + ")";
 
2388         return Sizzle.matches(expr, elems);
 
2391 jQuery.dir = function( elem, dir ){
 
2392         var matched = [], cur = elem[dir];
 
2393         while ( cur && cur != document ) {
 
2394                 if ( cur.nodeType == 1 )
 
2395                         matched.push( cur );
 
2401 jQuery.nth = function(cur, result, dir, elem){
 
2402         result = result || 1;
 
2405         for ( ; cur; cur = cur[dir] )
 
2406                 if ( cur.nodeType == 1 && ++num == result )
 
2412 jQuery.sibling = function(n, elem){
 
2415         for ( ; n; n = n.nextSibling ) {
 
2416                 if ( n.nodeType == 1 && n != elem )
 
2425 window.Sizzle = Sizzle;
 
2429  * A number of helper functions used for managing events.
 
2430  * Many of the ideas behind this code originated from
 
2431  * Dean Edwards' addEvent library.
 
2435         // Bind an event to an element
 
2436         // Original by Dean Edwards
 
2437         add: function(elem, types, handler, data) {
 
2438                 if ( elem.nodeType == 3 || elem.nodeType == 8 )
 
2441                 // For whatever reason, IE has trouble passing the window object
 
2442                 // around, causing it to be cloned in the process
 
2443                 if ( elem.setInterval && elem != window )
 
2446                 // Make sure that the function being executed has a unique ID
 
2447                 if ( !handler.guid )
 
2448                         handler.guid = this.guid++;
 
2450                 // if data is passed, bind to handler
 
2451                 if ( data !== undefined ) {
 
2452                         // Create temporary function pointer to original handler
 
2455                         // Create unique handler function, wrapped around original handler
 
2456                         handler = this.proxy( fn );
 
2458                         // Store data in unique handler
 
2459                         handler.data = data;
 
2462                 // Init the element's event structure
 
2463                 var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
 
2464                         handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
 
2465                                 // Handle the second event of a trigger and when
 
2466                                 // an event is called after a page has unloaded
 
2467                                 return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
 
2468                                         jQuery.event.handle.apply(arguments.callee.elem, arguments) :
 
2471                 // Add elem as a property of the handle function
 
2472                 // This is to prevent a memory leak with non-native
 
2476                 // Handle multiple events separated by a space
 
2477                 // jQuery(...).bind("mouseover mouseout", fn);
 
2478                 jQuery.each(types.split(/\s+/), function(index, type) {
 
2479                         // Namespaced event handlers
 
2480                         var namespaces = type.split(".");
 
2481                         type = namespaces.shift();
 
2482                         handler.type = namespaces.slice().sort().join(".");
 
2484                         // Get the current list of functions bound to this event
 
2485                         var handlers = events[type];
 
2487                         if ( jQuery.event.specialAll[type] )
 
2488                                 jQuery.event.specialAll[type].setup.call(elem, data, namespaces);
 
2490                         // Init the event handler queue
 
2492                                 handlers = events[type] = {};
 
2494                                 // Check for a special event handler
 
2495                                 // Only use addEventListener/attachEvent if the special
 
2496                                 // events handler returns false
 
2497                                 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) {
 
2498                                         // Bind the global event handler to the element
 
2499                                         if (elem.addEventListener)
 
2500                                                 elem.addEventListener(type, handle, false);
 
2501                                         else if (elem.attachEvent)
 
2502                                                 elem.attachEvent("on" + type, handle);
 
2506                         // Add the function to the element's handler list
 
2507                         handlers[handler.guid] = handler;
 
2509                         // Keep track of which events have been used, for global triggering
 
2510                         jQuery.event.global[type] = true;
 
2513                 // Nullify elem to prevent memory leaks in IE
 
2520         // Detach an event or set of events from an element
 
2521         remove: function(elem, types, handler) {
 
2522                 // don't do events on text and comment nodes
 
2523                 if ( elem.nodeType == 3 || elem.nodeType == 8 )
 
2526                 var events = jQuery.data(elem, "events"), ret, index;
 
2529                         // Unbind all events for the element
 
2530                         if ( types === undefined || (typeof types === "string" && types.charAt(0) == ".") )
 
2531                                 for ( var type in events )
 
2532                                         this.remove( elem, type + (types || "") );
 
2534                                 // types is actually an event object here
 
2536                                         handler = types.handler;
 
2540                                 // Handle multiple events seperated by a space
 
2541                                 // jQuery(...).unbind("mouseover mouseout", fn);
 
2542                                 jQuery.each(types.split(/\s+/), function(index, type){
 
2543                                         // Namespaced event handlers
 
2544                                         var namespaces = type.split(".");
 
2545                                         type = namespaces.shift();
 
2546                                         var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
 
2548                                         if ( events[type] ) {
 
2549                                                 // remove the given handler for the given type
 
2551                                                         delete events[type][handler.guid];
 
2553                                                 // remove all handlers for the given type
 
2555                                                         for ( var handle in events[type] )
 
2556                                                                 // Handle the removal of namespaced events
 
2557                                                                 if ( namespace.test(events[type][handle].type) )
 
2558                                                                         delete events[type][handle];
 
2560                                                 if ( jQuery.event.specialAll[type] )
 
2561                                                         jQuery.event.specialAll[type].teardown.call(elem, namespaces);
 
2563                                                 // remove generic event handler if no more handlers exist
 
2564                                                 for ( ret in events[type] ) break;
 
2566                                                         if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {
 
2567                                                                 if (elem.removeEventListener)
 
2568                                                                         elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
 
2569                                                                 else if (elem.detachEvent)
 
2570                                                                         elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
 
2573                                                         delete events[type];
 
2579                         // Remove the expando if it's no longer used
 
2580                         for ( ret in events ) break;
 
2582                                 var handle = jQuery.data( elem, "handle" );
 
2583                                 if ( handle ) handle.elem = null;
 
2584                                 jQuery.removeData( elem, "events" );
 
2585                                 jQuery.removeData( elem, "handle" );
 
2590         // bubbling is internal
 
2591         trigger: function( event, data, elem, bubbling ) {
 
2592                 // Event object or event type
 
2593                 var type = event.type || event;
 
2596                         event = typeof event === "object" ?
 
2597                                 // jQuery.Event object
 
2598                                 event[expando] ? event :
 
2600                                 jQuery.extend( jQuery.Event(type), event ) :
 
2601                                 // Just the event type (string)
 
2604                         if ( type.indexOf("!") >= 0 ) {
 
2605                                 event.type = type = type.slice(0, -1);
 
2606                                 event.exclusive = true;
 
2609                         // Handle a global trigger
 
2611                                 // Don't bubble custom events when global (to avoid too much overhead)
 
2612                                 event.stopPropagation();
 
2613                                 // Only trigger if we've ever bound an event for it
 
2614                                 if ( this.global[type] )
 
2615                                         jQuery.each( jQuery.cache, function(){
 
2616                                                 if ( this.events && this.events[type] )
 
2617                                                         jQuery.event.trigger( event, data, this.handle.elem );
 
2621                         // Handle triggering a single element
 
2623                         // don't do events on text and comment nodes
 
2624                         if ( !elem || elem.nodeType == 3 || elem.nodeType == 8 )
 
2627                         // Clean up in case it is reused
 
2628                         event.result = undefined;
 
2629                         event.target = elem;
 
2631                         // Clone the incoming data, if any
 
2632                         data = jQuery.makeArray(data);
 
2633                         data.unshift( event );
 
2636                 event.currentTarget = elem;
 
2638                 // Trigger the event, it is assumed that "handle" is a function
 
2639                 var handle = jQuery.data(elem, "handle");
 
2641                         handle.apply( elem, data );
 
2643                 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
 
2644                 if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
 
2645                         event.result = false;
 
2647                 // Trigger the native events (except for clicks on links)
 
2648                 if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
 
2649                         this.triggered = true;
 
2652                         // prevent IE from throwing an error for some hidden elements
 
2656                 this.triggered = false;
 
2658                 if ( !event.isPropagationStopped() ) {
 
2659                         var parent = elem.parentNode || elem.ownerDocument;
 
2661                                 jQuery.event.trigger(event, data, parent, true);
 
2665         handle: function(event) {
 
2666                 // returned undefined or false
 
2669                 event = arguments[0] = jQuery.event.fix( event || window.event );
 
2670                 event.currentTarget = this;
 
2672                 // Namespaced event handlers
 
2673                 var namespaces = event.type.split(".");
 
2674                 event.type = namespaces.shift();
 
2676                 // Cache this now, all = true means, any handler
 
2677                 all = !namespaces.length && !event.exclusive;
 
2679                 var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
 
2681                 handlers = ( jQuery.data(this, "events") || {} )[event.type];
 
2683                 for ( var j in handlers ) {
 
2684                         var handler = handlers[j];
 
2686                         // Filter the functions by class
 
2687                         if ( all || namespace.test(handler.type) ) {
 
2688                                 // Pass in a reference to the handler function itself
 
2689                                 // So that we can later remove it
 
2690                                 event.handler = handler;
 
2691                                 event.data = handler.data;
 
2693                                 var ret = handler.apply(this, arguments);
 
2695                                 if( ret !== undefined ){
 
2697                                         if ( ret === false ) {
 
2698                                                 event.preventDefault();
 
2699                                                 event.stopPropagation();
 
2703                                 if( event.isImmediatePropagationStopped() )
 
2710         props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
 
2712         fix: function(event) {
 
2713                 if ( event[expando] )
 
2716                 // store a copy of the original event object
 
2717                 // and "clone" to set read-only properties
 
2718                 var originalEvent = event;
 
2719                 event = jQuery.Event( originalEvent );
 
2721                 for ( var i = this.props.length, prop; i; ){
 
2722                         prop = this.props[ --i ];
 
2723                         event[ prop ] = originalEvent[ prop ];
 
2726                 // Fix target property, if necessary
 
2727                 if ( !event.target )
 
2728                         event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
 
2730                 // check if target is a textnode (safari)
 
2731                 if ( event.target.nodeType == 3 )
 
2732                         event.target = event.target.parentNode;
 
2734                 // Add relatedTarget, if necessary
 
2735                 if ( !event.relatedTarget && event.fromElement )
 
2736                         event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
 
2738                 // Calculate pageX/Y if missing and clientX/Y available
 
2739                 if ( event.pageX == null && event.clientX != null ) {
 
2740                         var doc = document.documentElement, body = document.body;
 
2741                         event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
 
2742                         event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
 
2745                 // Add which for key events
 
2746                 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
 
2747                         event.which = event.charCode || event.keyCode;
 
2749                 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
 
2750                 if ( !event.metaKey && event.ctrlKey )
 
2751                         event.metaKey = event.ctrlKey;
 
2753                 // Add which for click: 1 == left; 2 == middle; 3 == right
 
2754                 // Note: button is not normalized, so don't use it
 
2755                 if ( !event.which && event.button )
 
2756                         event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
 
2761         proxy: function( fn, proxy ){
 
2762                 proxy = proxy || function(){ return fn.apply(this, arguments); };
 
2763                 // Set the guid of unique handler to the same of original handler, so it can be removed
 
2764                 proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
 
2765                 // So proxy can be declared as an argument
 
2771                         // Make sure the ready event is setup
 
2773                         teardown: function() {}
 
2779                         setup: function( selector, namespaces ){
 
2780                                 jQuery.event.add( this, namespaces[0], liveHandler );
 
2782                         teardown:  function( namespaces ){
 
2783                                 if ( namespaces.length ) {
 
2784                                         var remove = 0, name = RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
 
2786                                         jQuery.each( (jQuery.data(this, "events").live || {}), function(){
 
2787                                                 if ( name.test(this.type) )
 
2792                                                 jQuery.event.remove( this, namespaces[0], liveHandler );
 
2799 jQuery.Event = function( src ){
 
2800         // Allow instantiation without the 'new' keyword
 
2801         if( !this.preventDefault )
 
2802                 return new jQuery.Event(src);
 
2805         if( src && src.type ){
 
2806                 this.originalEvent = src;
 
2807                 this.type = src.type;
 
2812         // timeStamp is buggy for some events on Firefox(#3843)
 
2813         // So we won't rely on the native value
 
2814         this.timeStamp = now();
 
2817         this[expando] = true;
 
2820 function returnFalse(){
 
2823 function returnTrue(){
 
2827 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
 
2828 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
 
2829 jQuery.Event.prototype = {
 
2830         preventDefault: function() {
 
2831                 this.isDefaultPrevented = returnTrue;
 
2833                 var e = this.originalEvent;
 
2836                 // if preventDefault exists run it on the original event
 
2837                 if (e.preventDefault)
 
2839                 // otherwise set the returnValue property of the original event to false (IE)
 
2840                 e.returnValue = false;
 
2842         stopPropagation: function() {
 
2843                 this.isPropagationStopped = returnTrue;
 
2845                 var e = this.originalEvent;
 
2848                 // if stopPropagation exists run it on the original event
 
2849                 if (e.stopPropagation)
 
2850                         e.stopPropagation();
 
2851                 // otherwise set the cancelBubble property of the original event to true (IE)
 
2852                 e.cancelBubble = true;
 
2854         stopImmediatePropagation:function(){
 
2855                 this.isImmediatePropagationStopped = returnTrue;
 
2856                 this.stopPropagation();
 
2858         isDefaultPrevented: returnFalse,
 
2859         isPropagationStopped: returnFalse,
 
2860         isImmediatePropagationStopped: returnFalse
 
2862 // Checks if an event happened on an element within another element
 
2863 // Used in jQuery.event.special.mouseenter and mouseleave handlers
 
2864 var withinElement = function(event) {
 
2865         // Check if mouse(over|out) are still within the same parent element
 
2866         var parent = event.relatedTarget;
 
2867         // Traverse up the tree
 
2868         while ( parent && parent != this )
 
2869                 try { parent = parent.parentNode; }
 
2870                 catch(e) { parent = this; }
 
2872         if( parent != this ){
 
2873                 // set the correct event type
 
2874                 event.type = event.data;
 
2875                 // handle event if we actually just moused on to a non sub-element
 
2876                 jQuery.event.handle.apply( this, arguments );
 
2881         mouseover: 'mouseenter', 
 
2882         mouseout: 'mouseleave'
 
2883 }, function( orig, fix ){
 
2884         jQuery.event.special[ fix ] = {
 
2886                         jQuery.event.add( this, orig, withinElement, fix );
 
2888                 teardown: function(){
 
2889                         jQuery.event.remove( this, orig, withinElement );
 
2895         bind: function( type, data, fn ) {
 
2896                 return type == "unload" ? this.one(type, data, fn) : this.each(function(){
 
2897                         jQuery.event.add( this, type, fn || data, fn && data );
 
2901         one: function( type, data, fn ) {
 
2902                 var one = jQuery.event.proxy( fn || data, function(event) {
 
2903                         jQuery(this).unbind(event, one);
 
2904                         return (fn || data).apply( this, arguments );
 
2906                 return this.each(function(){
 
2907                         jQuery.event.add( this, type, one, fn && data);
 
2911         unbind: function( type, fn ) {
 
2912                 return this.each(function(){
 
2913                         jQuery.event.remove( this, type, fn );
 
2917         trigger: function( type, data ) {
 
2918                 return this.each(function(){
 
2919                         jQuery.event.trigger( type, data, this );
 
2923         triggerHandler: function( type, data ) {
 
2925                         var event = jQuery.Event(type);
 
2926                         event.preventDefault();
 
2927                         event.stopPropagation();
 
2928                         jQuery.event.trigger( event, data, this[0] );
 
2929                         return event.result;
 
2933         toggle: function( fn ) {
 
2934                 // Save reference to arguments for access in closure
 
2935                 var args = arguments, i = 1;
 
2937                 // link all the functions, so any of them can unbind this click handler
 
2938                 while( i < args.length )
 
2939                         jQuery.event.proxy( fn, args[i++] );
 
2941                 return this.click( jQuery.event.proxy( fn, function(event) {
 
2942                         // Figure out which function to execute
 
2943                         this.lastToggle = ( this.lastToggle || 0 ) % i;
 
2945                         // Make sure that clicks stop
 
2946                         event.preventDefault();
 
2948                         // and execute the function
 
2949                         return args[ this.lastToggle++ ].apply( this, arguments ) || false;
 
2953         hover: function(fnOver, fnOut) {
 
2954                 return this.mouseenter(fnOver).mouseleave(fnOut);
 
2957         ready: function(fn) {
 
2958                 // Attach the listeners
 
2961                 // If the DOM is already ready
 
2962                 if ( jQuery.isReady )
 
2963                         // Execute the function immediately
 
2964                         fn.call( document, jQuery );
 
2966                 // Otherwise, remember the function for later
 
2968                         // Add the function to the wait list
 
2969                         jQuery.readyList.push( fn );
 
2974         live: function( type, fn ){
 
2975                 var proxy = jQuery.event.proxy( fn );
 
2976                 proxy.guid += this.selector + type;
 
2978                 jQuery(document).bind( liveConvert(type, this.selector), this.selector, proxy );
 
2983         die: function( type, fn ){
 
2984                 jQuery(document).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type } : null );
 
2989 function liveHandler( event ){
 
2990         var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"),
 
2994         jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){
 
2995                 if ( check.test(fn.type) ) {
 
2996                         var elem = jQuery(event.target).closest(fn.data)[0];
 
2998                                 elems.push({ elem: elem, fn: fn });
 
3002         elems.sort(function(a,b) {
 
3003                 return jQuery.data(a.elem, "closest") - jQuery.data(b.elem, "closest");
 
3006         jQuery.each(elems, function(){
 
3007                 if ( this.fn.call(this.elem, event, this.fn.data) === false )
 
3008                         return (stop = false);
 
3014 function liveConvert(type, selector){
 
3015         return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "|")].join(".");
 
3021         // Handle when the DOM is ready
 
3023                 // Make sure that the DOM is not already loaded
 
3024                 if ( !jQuery.isReady ) {
 
3025                         // Remember that the DOM is ready
 
3026                         jQuery.isReady = true;
 
3028                         // If there are functions bound, to execute
 
3029                         if ( jQuery.readyList ) {
 
3030                                 // Execute all of them
 
3031                                 jQuery.each( jQuery.readyList, function(){
 
3032                                         this.call( document, jQuery );
 
3035                                 // Reset the list of functions
 
3036                                 jQuery.readyList = null;
 
3039                         // Trigger any bound ready events
 
3040                         jQuery(document).triggerHandler("ready");
 
3045 var readyBound = false;
 
3047 function bindReady(){
 
3048         if ( readyBound ) return;
 
3051         // Mozilla, Opera and webkit nightlies currently support this event
 
3052         if ( document.addEventListener ) {
 
3053                 // Use the handy event callback
 
3054                 document.addEventListener( "DOMContentLoaded", function(){
 
3055                         document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
 
3059         // If IE event model is used
 
3060         } else if ( document.attachEvent ) {
 
3061                 // ensure firing before onload,
 
3062                 // maybe late but safe also for iframes
 
3063                 document.attachEvent("onreadystatechange", function(){
 
3064                         if ( document.readyState === "complete" ) {
 
3065                                 document.detachEvent( "onreadystatechange", arguments.callee );
 
3070                 // If IE and not an iframe
 
3071                 // continually check to see if the document is ready
 
3072                 if ( document.documentElement.doScroll && window == window.top ) (function(){
 
3073                         if ( jQuery.isReady ) return;
 
3076                                 // If IE is used, use the trick by Diego Perini
 
3077                                 // http://javascript.nwbox.com/IEContentLoaded/
 
3078                                 document.documentElement.doScroll("left");
 
3080                                 setTimeout( arguments.callee, 0 );
 
3084                         // and execute any waiting functions
 
3089         // A fallback to window.onload, that will always work
 
3090         jQuery.event.add( window, "load", jQuery.ready );
 
3093 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
 
3094         "mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave," +
 
3095         "change,select,submit,keydown,keypress,keyup,error").split(","), function(i, name){
 
3097         // Handle event binding
 
3098         jQuery.fn[name] = function(fn){
 
3099                 return fn ? this.bind(name, fn) : this.trigger(name);
 
3103 // Prevent memory leaks in IE
 
3104 // And prevent errors on refresh with events like mouseover in other browsers
 
3105 // Window isn't included so as not to unbind existing unload events
 
3106 jQuery( window ).bind( 'unload', function(){ 
 
3107         for ( var id in jQuery.cache )
 
3109                 if ( id != 1 && jQuery.cache[ id ].handle )
 
3110                         jQuery.event.remove( jQuery.cache[ id ].handle.elem );
 
3114         jQuery.support = {};
 
3116         var root = document.documentElement,
 
3117                 script = document.createElement("script"),
 
3118                 div = document.createElement("div"),
 
3119                 id = "script" + (new Date).getTime();
 
3121         div.style.display = "none";
 
3122         div.innerHTML = '   <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';
 
3124         var all = div.getElementsByTagName("*"),
 
3125                 a = div.getElementsByTagName("a")[0];
 
3127         // Can't get basic test support
 
3128         if ( !all || !all.length || !a ) {
 
3133                 // IE strips leading whitespace when .innerHTML is used
 
3134                 leadingWhitespace: div.firstChild.nodeType == 3,
 
3136                 // Make sure that tbody elements aren't automatically inserted
 
3137                 // IE will insert them into empty tables
 
3138                 tbody: !div.getElementsByTagName("tbody").length,
 
3140                 // Make sure that you can get all elements in an <object> element
 
3141                 // IE 7 always returns no results
 
3142                 objectAll: !!div.getElementsByTagName("object")[0]
 
3143                         .getElementsByTagName("*").length,
 
3145                 // Make sure that link elements get serialized correctly by innerHTML
 
3146                 // This requires a wrapper element in IE
 
3147                 htmlSerialize: !!div.getElementsByTagName("link").length,
 
3149                 // Get the style information from getAttribute
 
3150                 // (IE uses .cssText insted)
 
3151                 style: /red/.test( a.getAttribute("style") ),
 
3153                 // Make sure that URLs aren't manipulated
 
3154                 // (IE normalizes it by default)
 
3155                 hrefNormalized: a.getAttribute("href") === "/a",
 
3157                 // Make sure that element opacity exists
 
3158                 // (IE uses filter instead)
 
3159                 opacity: a.style.opacity === "0.5",
 
3161                 // Verify style float existence
 
3162                 // (IE uses styleFloat instead of cssFloat)
 
3163                 cssFloat: !!a.style.cssFloat,
 
3165                 // Will be defined later
 
3171         script.type = "text/javascript";
 
3173                 script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
 
3176         root.insertBefore( script, root.firstChild );
 
3178         // Make sure that the execution of code works by injecting a script
 
3179         // tag with appendChild/createTextNode
 
3180         // (IE doesn't support this, fails, and uses .text instead)
 
3181         if ( window[ id ] ) {
 
3182                 jQuery.support.scriptEval = true;
 
3183                 delete window[ id ];
 
3186         root.removeChild( script );
 
3188         if ( div.attachEvent && div.fireEvent ) {
 
3189                 div.attachEvent("onclick", function(){
 
3190                         // Cloning a node shouldn't copy over any
 
3191                         // bound event handlers (IE does this)
 
3192                         jQuery.support.noCloneEvent = false;
 
3193                         div.detachEvent("onclick", arguments.callee);
 
3195                 div.cloneNode(true).fireEvent("onclick");
 
3198         // Figure out if the W3C box model works as expected
 
3199         // document.body must exist before we can do this
 
3201                 var div = document.createElement("div");
 
3202                 div.style.width = div.style.paddingLeft = "1px";
 
3204                 document.body.appendChild( div );
 
3205                 jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
 
3206                 document.body.removeChild( div ).style.display = 'none';
 
3210 var styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat";
 
3214         "class": "className",
 
3215         "float": styleFloat,
 
3216         cssFloat: styleFloat,
 
3217         styleFloat: styleFloat,
 
3218         readonly: "readOnly",
 
3219         maxlength: "maxLength",
 
3220         cellspacing: "cellSpacing",
 
3222         tabindex: "tabIndex"
 
3225         // Keep a copy of the old load
 
3226         _load: jQuery.fn.load,
 
3228         load: function( url, params, callback ) {
 
3229                 if ( typeof url !== "string" )
 
3230                         return this._load( url );
 
3232                 var off = url.indexOf(" ");
 
3234                         var selector = url.slice(off, url.length);
 
3235                         url = url.slice(0, off);
 
3238                 // Default to a GET request
 
3241                 // If the second parameter was provided
 
3243                         // If it's a function
 
3244                         if ( jQuery.isFunction( params ) ) {
 
3245                                 // We assume that it's the callback
 
3249                         // Otherwise, build a param string
 
3250                         } else if( typeof params === "object" ) {
 
3251                                 params = jQuery.param( params );
 
3257                 // Request the remote document
 
3263                         complete: function(res, status){
 
3264                                 // If successful, inject the HTML into all the matched elements
 
3265                                 if ( status == "success" || status == "notmodified" )
 
3266                                         // See if a selector was specified
 
3267                                         self.html( selector ?
 
3268                                                 // Create a dummy div to hold the results
 
3270                                                         // inject the contents of the document in, removing the scripts
 
3271                                                         // to avoid any 'Permission Denied' errors in IE
 
3272                                                         .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
 
3274                                                         // Locate the specified elements
 
3277                                                 // If not, just inject the full result
 
3281                                         self.each( callback, [res.responseText, status, res] );
 
3287         serialize: function() {
 
3288                 return jQuery.param(this.serializeArray());
 
3290         serializeArray: function() {
 
3291                 return this.map(function(){
 
3292                         return this.elements ? jQuery.makeArray(this.elements) : this;
 
3295                         return this.name && !this.disabled &&
 
3296                                 (this.checked || /select|textarea/i.test(this.nodeName) ||
 
3297                                         /text|hidden|password|search/i.test(this.type));
 
3299                 .map(function(i, elem){
 
3300                         var val = jQuery(this).val();
 
3301                         return val == null ? null :
 
3302                                 jQuery.isArray(val) ?
 
3303                                         jQuery.map( val, function(val, i){
 
3304                                                 return {name: elem.name, value: val};
 
3306                                         {name: elem.name, value: val};
 
3311 // Attach a bunch of functions for handling common AJAX events
 
3312 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
 
3313         jQuery.fn[o] = function(f){
 
3314                 return this.bind(o, f);
 
3322         get: function( url, data, callback, type ) {
 
3323                 // shift arguments if data argument was ommited
 
3324                 if ( jQuery.isFunction( data ) ) {
 
3329                 return jQuery.ajax({
 
3338         getScript: function( url, callback ) {
 
3339                 return jQuery.get(url, null, callback, "script");
 
3342         getJSON: function( url, data, callback ) {
 
3343                 return jQuery.get(url, data, callback, "json");
 
3346         post: function( url, data, callback, type ) {
 
3347                 if ( jQuery.isFunction( data ) ) {
 
3352                 return jQuery.ajax({
 
3361         ajaxSetup: function( settings ) {
 
3362                 jQuery.extend( jQuery.ajaxSettings, settings );
 
3369                 contentType: "application/x-www-form-urlencoded",
 
3378                 // Create the request object; Microsoft failed to properly
 
3379                 // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
 
3380                 // This function can be overriden by calling jQuery.ajaxSetup
 
3382                         return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
 
3385                         xml: "application/xml, text/xml",
 
3387                         script: "text/javascript, application/javascript",
 
3388                         json: "application/json, text/javascript",
 
3394         // Last-Modified header cache for next request
 
3397         ajax: function( s ) {
 
3398                 // Extend the settings, but re-extend 's' so that it can be
 
3399                 // checked again later (in the test suite, specifically)
 
3400                 s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
 
3402                 var jsonp, jsre = /=\?(&|$)/g, status, data,
 
3403                         type = s.type.toUpperCase();
 
3405                 // convert data if not already a string
 
3406                 if ( s.data && s.processData && typeof s.data !== "string" )
 
3407                         s.data = jQuery.param(s.data);
 
3409                 // Handle JSONP Parameter Callbacks
 
3410                 if ( s.dataType == "jsonp" ) {
 
3411                         if ( type == "GET" ) {
 
3412                                 if ( !s.url.match(jsre) )
 
3413                                         s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
 
3414                         } else if ( !s.data || !s.data.match(jsre) )
 
3415                                 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
 
3416                         s.dataType = "json";
 
3419                 // Build temporary JSONP function
 
3420                 if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
 
3421                         jsonp = "jsonp" + jsc++;
 
3423                         // Replace the =? sequence both in the query string and the data
 
3425                                 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
 
3426                         s.url = s.url.replace(jsre, "=" + jsonp + "$1");
 
3428                         // We need to make sure
 
3429                         // that a JSONP style response is executed properly
 
3430                         s.dataType = "script";
 
3432                         // Handle JSONP-style loading
 
3433                         window[ jsonp ] = function(tmp){
 
3438                                 window[ jsonp ] = undefined;
 
3439                                 try{ delete window[ jsonp ]; } catch(e){}
 
3441                                         head.removeChild( script );
 
3445                 if ( s.dataType == "script" && s.cache == null )
 
3448                 if ( s.cache === false && type == "GET" ) {
 
3450                         // try replacing _= if it is there
 
3451                         var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
 
3452                         // if nothing was replaced, add timestamp to the end
 
3453                         s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
 
3456                 // If data is available, append data to url for get requests
 
3457                 if ( s.data && type == "GET" ) {
 
3458                         s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
 
3460                         // IE likes to send both get and post data, prevent this
 
3464                 // Watch for a new set of requests
 
3465                 if ( s.global && ! jQuery.active++ )
 
3466                         jQuery.event.trigger( "ajaxStart" );
 
3468                 // Matches an absolute URL, and saves the domain
 
3469                 var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec( s.url );
 
3471                 // If we're requesting a remote document
 
3472                 // and trying to load JSON or Script with a GET
 
3473                 if ( s.dataType == "script" && type == "GET" && parts
 
3474                         && ( parts[1] && parts[1] != location.protocol || parts[2] != location.host )){
 
3476                         var head = document.getElementsByTagName("head")[0];
 
3477                         var script = document.createElement("script");
 
3479                         if (s.scriptCharset)
 
3480                                 script.charset = s.scriptCharset;
 
3482                         // Handle Script loading
 
3486                                 // Attach handlers for all browsers
 
3487                                 script.onload = script.onreadystatechange = function(){
 
3488                                         if ( !done && (!this.readyState ||
 
3489                                                         this.readyState == "loaded" || this.readyState == "complete") ) {
 
3494                                                 // Handle memory leak in IE
 
3495                                                 script.onload = script.onreadystatechange = null;
 
3496                                                 head.removeChild( script );
 
3501                         head.appendChild(script);
 
3503                         // We handle everything using the script element injection
 
3507                 var requestDone = false;
 
3509                 // Create the request object
 
3513                 // Passing null username, generates a login popup on Opera (#2865)
 
3515                         xhr.open(type, s.url, s.async, s.username, s.password);
 
3517                         xhr.open(type, s.url, s.async);
 
3519                 // Need an extra try/catch for cross domain requests in Firefox 3
 
3521                         // Set the correct header, if data is being sent
 
3523                                 xhr.setRequestHeader("Content-Type", s.contentType);
 
3525                         // Set the If-Modified-Since header, if ifModified mode.
 
3527                                 xhr.setRequestHeader("If-Modified-Since",
 
3528                                         jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
 
3530                         // Set header so the called script knows that it's an XMLHttpRequest
 
3531                         xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
 
3533                         // Set the Accepts header for the server, depending on the dataType
 
3534                         xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
 
3535                                 s.accepts[ s.dataType ] + ", */*" :
 
3536                                 s.accepts._default );
 
3539                 // Allow custom headers/mimetypes and early abort
 
3540                 if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
 
3541                         // Handle the global AJAX counter
 
3542                         if ( s.global && ! --jQuery.active )
 
3543                                 jQuery.event.trigger( "ajaxStop" );
 
3544                         // close opended socket
 
3550                         jQuery.event.trigger("ajaxSend", [xhr, s]);
 
3552                 // Wait for a response to come back
 
3553                 var onreadystatechange = function(isTimeout){
 
3554                         // The request was aborted, clear the interval and decrement jQuery.active
 
3555                         if (xhr.readyState == 0) {
 
3557                                         // clear poll interval
 
3558                                         clearInterval(ival);
 
3560                                         // Handle the global AJAX counter
 
3561                                         if ( s.global && ! --jQuery.active )
 
3562                                                 jQuery.event.trigger( "ajaxStop" );
 
3564                         // The transfer is complete and the data is available, or the request timed out
 
3565                         } else if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
 
3568                                 // clear poll interval
 
3570                                         clearInterval(ival);
 
3574                                 status = isTimeout == "timeout" ? "timeout" :
 
3575                                         !jQuery.httpSuccess( xhr ) ? "error" :
 
3576                                         s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" :
 
3579                                 if ( status == "success" ) {
 
3580                                         // Watch for, and catch, XML document parse errors
 
3582                                                 // process the data (runs the xml through httpData regardless of callback)
 
3583                                                 data = jQuery.httpData( xhr, s.dataType, s );
 
3585                                                 status = "parsererror";
 
3589                                 // Make sure that the request was successful or notmodified
 
3590                                 if ( status == "success" ) {
 
3591                                         // Cache Last-Modified header, if ifModified mode.
 
3594                                                 modRes = xhr.getResponseHeader("Last-Modified");
 
3595                                         } catch(e) {} // swallow exception thrown by FF if header is not available
 
3597                                         if ( s.ifModified && modRes )
 
3598                                                 jQuery.lastModified[s.url] = modRes;
 
3600                                         // JSONP handles its own success callback
 
3604                                         jQuery.handleError(s, xhr, status);
 
3606                                 // Fire the complete handlers
 
3612                                 // Stop memory leaks
 
3619                         // don't attach the handler to the request, just poll it instead
 
3620                         var ival = setInterval(onreadystatechange, 13);
 
3623                         if ( s.timeout > 0 )
 
3624                                 setTimeout(function(){
 
3625                                         // Check to see if the request is still happening
 
3626                                         if ( xhr && !requestDone )
 
3627                                                 onreadystatechange( "timeout" );
 
3635                         jQuery.handleError(s, xhr, null, e);
 
3638                 // firefox 1.5 doesn't fire statechange for sync requests
 
3640                         onreadystatechange();
 
3643                         // If a local callback was specified, fire it and pass it the data
 
3645                                 s.success( data, status );
 
3647                         // Fire the global callback
 
3649                                 jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
 
3652                 function complete(){
 
3655                                 s.complete(xhr, status);
 
3657                         // The request was completed
 
3659                                 jQuery.event.trigger( "ajaxComplete", [xhr, s] );
 
3661                         // Handle the global AJAX counter
 
3662                         if ( s.global && ! --jQuery.active )
 
3663                                 jQuery.event.trigger( "ajaxStop" );
 
3666                 // return XMLHttpRequest to allow aborting the request etc.
 
3670         handleError: function( s, xhr, status, e ) {
 
3671                 // If a local callback was specified, fire it
 
3672                 if ( s.error ) s.error( xhr, status, e );
 
3674                 // Fire the global callback
 
3676                         jQuery.event.trigger( "ajaxError", [xhr, s, e] );
 
3679         // Counter for holding the number of active queries
 
3682         // Determines if an XMLHttpRequest was successful or not
 
3683         httpSuccess: function( xhr ) {
 
3685                         // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
 
3686                         return !xhr.status && location.protocol == "file:" ||
 
3687                                 ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223;
 
3692         // Determines if an XMLHttpRequest returns NotModified
 
3693         httpNotModified: function( xhr, url ) {
 
3695                         var xhrRes = xhr.getResponseHeader("Last-Modified");
 
3697                         // Firefox always returns 200. check Last-Modified date
 
3698                         return xhr.status == 304 || xhrRes == jQuery.lastModified[url];
 
3703         httpData: function( xhr, type, s ) {
 
3704                 var ct = xhr.getResponseHeader("content-type"),
 
3705                         xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
 
3706                         data = xml ? xhr.responseXML : xhr.responseText;
 
3708                 if ( xml && data.documentElement.tagName == "parsererror" )
 
3709                         throw "parsererror";
 
3711                 // Allow a pre-filtering function to sanitize the response
 
3712                 // s != null is checked to keep backwards compatibility
 
3713                 if( s && s.dataFilter )
 
3714                         data = s.dataFilter( data, type );
 
3716                 // The filter can actually parse the response
 
3717                 if( typeof data === "string" ){
 
3719                         // If the type is "script", eval it in global context
 
3720                         if ( type == "script" )
 
3721                                 jQuery.globalEval( data );
 
3723                         // Get the JavaScript object, if JSON is used.
 
3724                         if ( type == "json" )
 
3725                                 data = window["eval"]("(" + data + ")");
 
3731         // Serialize an array of form elements or a set of
 
3732         // key/values into a query string
 
3733         param: function( a ) {
 
3736                 function add( key, value ){
 
3737                         s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
 
3740                 // If an array was passed in, assume that it is an array
 
3742                 if ( jQuery.isArray(a) || a.jquery )
 
3743                         // Serialize the form elements
 
3744                         jQuery.each( a, function(){
 
3745                                 add( this.name, this.value );
 
3748                 // Otherwise, assume that it's an object of key/value pairs
 
3750                         // Serialize the key/values
 
3752                                 // If the value is an array then the key names need to be repeated
 
3753                                 if ( jQuery.isArray(a[j]) )
 
3754                                         jQuery.each( a[j], function(){
 
3758                                         add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
 
3760                 // Return the resulting serialization
 
3761                 return s.join("&").replace(/%20/g, "+");
 
3765 var elemdisplay = {},
 
3768                 // height animations
 
3769                 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
 
3771                 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
 
3772                 // opacity animations
 
3776 function genFx( type, num ){
 
3778         jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function(){
 
3785         show: function(speed,callback){
 
3787                         return this.animate( genFx("show", 3), speed, callback);
 
3789                         for ( var i = 0, l = this.length; i < l; i++ ){
 
3790                                 var old = jQuery.data(this[i], "olddisplay");
 
3792                                 this[i].style.display = old || "";
 
3794                                 if ( jQuery.css(this[i], "display") === "none" ) {
 
3795                                         var tagName = this[i].tagName, display;
 
3797                                         if ( elemdisplay[ tagName ] ) {
 
3798                                                 display = elemdisplay[ tagName ];
 
3800                                                 var elem = jQuery("<" + tagName + " />").appendTo("body");
 
3802                                                 display = elem.css("display");
 
3803                                                 if ( display === "none" )
 
3808                                                 elemdisplay[ tagName ] = display;
 
3811                                         jQuery.data(this[i], "olddisplay", display);
 
3815                         // Set the display of the elements in a second loop
 
3816                         // to avoid the constant reflow
 
3817                         for ( var i = 0, l = this.length; i < l; i++ ){
 
3818                                 this[i].style.display = jQuery.data(this[i], "olddisplay") || "";
 
3825         hide: function(speed,callback){
 
3827                         return this.animate( genFx("hide", 3), speed, callback);
 
3829                         for ( var i = 0, l = this.length; i < l; i++ ){
 
3830                                 var old = jQuery.data(this[i], "olddisplay");
 
3831                                 if ( !old && old !== "none" )
 
3832                                         jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
 
3835                         // Set the display of the elements in a second loop
 
3836                         // to avoid the constant reflow
 
3837                         for ( var i = 0, l = this.length; i < l; i++ ){
 
3838                                 this[i].style.display = "none";
 
3845         // Save the old toggle function
 
3846         _toggle: jQuery.fn.toggle,
 
3848         toggle: function( fn, fn2 ){
 
3849                 var bool = typeof fn === "boolean";
 
3851                 return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
 
3852                         this._toggle.apply( this, arguments ) :
 
3853                         fn == null || bool ?
 
3854                                 this.each(function(){
 
3855                                         var state = bool ? fn : jQuery(this).is(":hidden");
 
3856                                         jQuery(this)[ state ? "show" : "hide" ]();
 
3858                                 this.animate(genFx("toggle", 3), fn, fn2);
 
3861         fadeTo: function(speed,to,callback){
 
3862                 return this.animate({opacity: to}, speed, callback);
 
3865         animate: function( prop, speed, easing, callback ) {
 
3866                 var optall = jQuery.speed(speed, easing, callback);
 
3868                 return this[ optall.queue === false ? "each" : "queue" ](function(){
 
3870                         var opt = jQuery.extend({}, optall), p,
 
3871                                 hidden = this.nodeType == 1 && jQuery(this).is(":hidden"),
 
3875                                 if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
 
3876                                         return opt.complete.call(this);
 
3878                                 if ( ( p == "height" || p == "width" ) && this.style ) {
 
3879                                         // Store display property
 
3880                                         opt.display = jQuery.css(this, "display");
 
3882                                         // Make sure that nothing sneaks out
 
3883                                         opt.overflow = this.style.overflow;
 
3887                         if ( opt.overflow != null )
 
3888                                 this.style.overflow = "hidden";
 
3890                         opt.curAnim = jQuery.extend({}, prop);
 
3892                         jQuery.each( prop, function(name, val){
 
3893                                 var e = new jQuery.fx( self, opt, name );
 
3895                                 if ( /toggle|show|hide/.test(val) )
 
3896                                         e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
 
3898                                         var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
 
3899                                                 start = e.cur(true) || 0;
 
3902                                                 var end = parseFloat(parts[2]),
 
3903                                                         unit = parts[3] || "px";
 
3905                                                 // We need to compute starting value
 
3906                                                 if ( unit != "px" ) {
 
3907                                                         self.style[ name ] = (end || 1) + unit;
 
3908                                                         start = ((end || 1) / e.cur(true)) * start;
 
3909                                                         self.style[ name ] = start + unit;
 
3912                                                 // If a +=/-= token was provided, we're doing a relative animation
 
3914                                                         end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
 
3916                                                 e.custom( start, end, unit );
 
3918                                                 e.custom( start, val, "" );
 
3922                         // For JS strict compliance
 
3927         stop: function(clearQueue, gotoEnd){
 
3928                 var timers = jQuery.timers;
 
3933                 this.each(function(){
 
3934                         // go in reverse order so anything added to the queue during the loop is ignored
 
3935                         for ( var i = timers.length - 1; i >= 0; i-- )
 
3936                                 if ( timers[i].elem == this ) {
 
3938                                                 // force the next step to be the last
 
3940                                         timers.splice(i, 1);
 
3944                 // start the next in the queue if the last step wasn't forced
 
3953 // Generate shortcuts for custom animations
 
3955         slideDown: genFx("show", 1),
 
3956         slideUp: genFx("hide", 1),
 
3957         slideToggle: genFx("toggle", 1),
 
3958         fadeIn: { opacity: "show" },
 
3959         fadeOut: { opacity: "hide" }
 
3960 }, function( name, props ){
 
3961         jQuery.fn[ name ] = function( speed, callback ){
 
3962                 return this.animate( props, speed, callback );
 
3968         speed: function(speed, easing, fn) {
 
3969                 var opt = typeof speed === "object" ? speed : {
 
3970                         complete: fn || !fn && easing ||
 
3971                                 jQuery.isFunction( speed ) && speed,
 
3973                         easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
 
3976                 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
 
3977                         jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
 
3980                 opt.old = opt.complete;
 
3981                 opt.complete = function(){
 
3982                         if ( opt.queue !== false )
 
3983                                 jQuery(this).dequeue();
 
3984                         if ( jQuery.isFunction( opt.old ) )
 
3985                                 opt.old.call( this );
 
3992                 linear: function( p, n, firstNum, diff ) {
 
3993                         return firstNum + diff * p;
 
3995                 swing: function( p, n, firstNum, diff ) {
 
3996                         return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
 
4002         fx: function( elem, options, prop ){
 
4003                 this.options = options;
 
4007                 if ( !options.orig )
 
4013 jQuery.fx.prototype = {
 
4015         // Simple function for setting a style value
 
4017                 if ( this.options.step )
 
4018                         this.options.step.call( this.elem, this.now, this );
 
4020                 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
 
4022                 // Set display property to block for height/width animations
 
4023                 if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style )
 
4024                         this.elem.style.display = "block";
 
4027         // Get the current size
 
4028         cur: function(force){
 
4029                 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) )
 
4030                         return this.elem[ this.prop ];
 
4032                 var r = parseFloat(jQuery.css(this.elem, this.prop, force));
 
4033                 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
 
4036         // Start an animation from one number to another
 
4037         custom: function(from, to, unit){
 
4038                 this.startTime = now();
 
4041                 this.unit = unit || this.unit || "px";
 
4042                 this.now = this.start;
 
4043                 this.pos = this.state = 0;
 
4046                 function t(gotoEnd){
 
4047                         return self.step(gotoEnd);
 
4052                 if ( t() && jQuery.timers.push(t) && !timerId ) {
 
4053                         timerId = setInterval(function(){
 
4054                                 var timers = jQuery.timers;
 
4056                                 for ( var i = 0; i < timers.length; i++ )
 
4058                                                 timers.splice(i--, 1);
 
4060                                 if ( !timers.length ) {
 
4061                                         clearInterval( timerId );
 
4062                                         timerId = undefined;
 
4068         // Simple 'show' function
 
4070                 // Remember where we started, so that we can go back to it later
 
4071                 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
 
4072                 this.options.show = true;
 
4074                 // Begin the animation
 
4075                 // Make sure that we start at a small width/height to avoid any
 
4077                 this.custom(this.prop == "width" || this.prop == "height" ? 1 : 0, this.cur());
 
4079                 // Start by showing the element
 
4080                 jQuery(this.elem).show();
 
4083         // Simple 'hide' function
 
4085                 // Remember where we started, so that we can go back to it later
 
4086                 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
 
4087                 this.options.hide = true;
 
4089                 // Begin the animation
 
4090                 this.custom(this.cur(), 0);
 
4093         // Each step of an animation
 
4094         step: function(gotoEnd){
 
4097                 if ( gotoEnd || t >= this.options.duration + this.startTime ) {
 
4098                         this.now = this.end;
 
4099                         this.pos = this.state = 1;
 
4102                         this.options.curAnim[ this.prop ] = true;
 
4105                         for ( var i in this.options.curAnim )
 
4106                                 if ( this.options.curAnim[i] !== true )
 
4110                                 if ( this.options.display != null ) {
 
4111                                         // Reset the overflow
 
4112                                         this.elem.style.overflow = this.options.overflow;
 
4114                                         // Reset the display
 
4115                                         this.elem.style.display = this.options.display;
 
4116                                         if ( jQuery.css(this.elem, "display") == "none" )
 
4117                                                 this.elem.style.display = "block";
 
4120                                 // Hide the element if the "hide" operation was done
 
4121                                 if ( this.options.hide )
 
4122                                         jQuery(this.elem).hide();
 
4124                                 // Reset the properties, if the item has been hidden or shown
 
4125                                 if ( this.options.hide || this.options.show )
 
4126                                         for ( var p in this.options.curAnim )
 
4127                                                 jQuery.attr(this.elem.style, p, this.options.orig[p]);
 
4129                                 // Execute the complete function
 
4130                                 this.options.complete.call( this.elem );
 
4135                         var n = t - this.startTime;
 
4136                         this.state = n / this.options.duration;
 
4138                         // Perform the easing function, defaults to swing
 
4139                         this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
 
4140                         this.now = this.start + ((this.end - this.start) * this.pos);
 
4142                         // Perform the next step of the animation
 
4151 jQuery.extend( jQuery.fx, {
 
4160                 opacity: function(fx){
 
4161                         jQuery.attr(fx.elem.style, "opacity", fx.now);
 
4164                 _default: function(fx){
 
4165                         if ( fx.elem.style && fx.elem.style[ fx.prop ] != null )
 
4166                                 fx.elem.style[ fx.prop ] = fx.now + fx.unit;
 
4168                                 fx.elem[ fx.prop ] = fx.now;
 
4172 if ( document.documentElement["getBoundingClientRect"] )
 
4173         jQuery.fn.offset = function() {
 
4174                 if ( !this[0] ) return { top: 0, left: 0 };
 
4175                 if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
 
4176                 var box  = this[0].getBoundingClientRect(), doc = this[0].ownerDocument, body = doc.body, docElem = doc.documentElement,
 
4177                         clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
 
4178                         top  = box.top  + (self.pageYOffset || jQuery.boxModel && docElem.scrollTop  || body.scrollTop ) - clientTop,
 
4179                         left = box.left + (self.pageXOffset || jQuery.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
 
4180                 return { top: top, left: left };
 
4183         jQuery.fn.offset = function() {
 
4184                 if ( !this[0] ) return { top: 0, left: 0 };
 
4185                 if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
 
4186                 jQuery.offset.initialized || jQuery.offset.initialize();
 
4188                 var elem = this[0], offsetParent = elem.offsetParent, prevOffsetParent = elem,
 
4189                         doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
 
4190                         body = doc.body, defaultView = doc.defaultView,
 
4191                         prevComputedStyle = defaultView.getComputedStyle(elem, null),
 
4192                         top = elem.offsetTop, left = elem.offsetLeft;
 
4194                 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
 
4195                         computedStyle = defaultView.getComputedStyle(elem, null);
 
4196                         top -= elem.scrollTop, left -= elem.scrollLeft;
 
4197                         if ( elem === offsetParent ) {
 
4198                                 top += elem.offsetTop, left += elem.offsetLeft;
 
4199                                 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.tagName)) )
 
4200                                         top  += parseInt( computedStyle.borderTopWidth,  10) || 0,
 
4201                                         left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
 
4202                                 prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
 
4204                         if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" )
 
4205                                 top  += parseInt( computedStyle.borderTopWidth,  10) || 0,
 
4206                                 left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
 
4207                         prevComputedStyle = computedStyle;
 
4210                 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" )
 
4211                         top  += body.offsetTop,
 
4212                         left += body.offsetLeft;
 
4214                 if ( prevComputedStyle.position === "fixed" )
 
4215                         top  += Math.max(docElem.scrollTop, body.scrollTop),
 
4216                         left += Math.max(docElem.scrollLeft, body.scrollLeft);
 
4218                 return { top: top, left: left };
 
4222         initialize: function() {
 
4223                 if ( this.initialized ) return;
 
4224                 var body = document.body, container = document.createElement('div'), innerDiv, checkDiv, table, td, rules, prop, bodyMarginTop = body.style.marginTop,
 
4225                         html = '<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';
 
4227                 rules = { position: 'absolute', top: 0, left: 0, margin: 0, border: 0, width: '1px', height: '1px', visibility: 'hidden' };
 
4228                 for ( prop in rules ) container.style[prop] = rules[prop];
 
4230                 container.innerHTML = html;
 
4231                 body.insertBefore(container, body.firstChild);
 
4232                 innerDiv = container.firstChild, checkDiv = innerDiv.firstChild, td = innerDiv.nextSibling.firstChild.firstChild;
 
4234                 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
 
4235                 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
 
4237                 innerDiv.style.overflow = 'hidden', innerDiv.style.position = 'relative';
 
4238                 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
 
4240                 body.style.marginTop = '1px';
 
4241                 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop === 0);
 
4242                 body.style.marginTop = bodyMarginTop;
 
4244                 body.removeChild(container);
 
4245                 this.initialized = true;
 
4248         bodyOffset: function(body) {
 
4249                 jQuery.offset.initialized || jQuery.offset.initialize();
 
4250                 var top = body.offsetTop, left = body.offsetLeft;
 
4251                 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset )
 
4252                         top  += parseInt( jQuery.curCSS(body, 'marginTop',  true), 10 ) || 0,
 
4253                         left += parseInt( jQuery.curCSS(body, 'marginLeft', true), 10 ) || 0;
 
4254                 return { top: top, left: left };
 
4260         position: function() {
 
4261                 var left = 0, top = 0, results;
 
4264                         // Get *real* offsetParent
 
4265                         var offsetParent = this.offsetParent(),
 
4267                         // Get correct offsets
 
4268                         offset       = this.offset(),
 
4269                         parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
 
4271                         // Subtract element margins
 
4272                         // note: when an element has margin: auto the offsetLeft and marginLeft 
 
4273                         // are the same in Safari causing offset.left to incorrectly be 0
 
4274                         offset.top  -= num( this, 'marginTop'  );
 
4275                         offset.left -= num( this, 'marginLeft' );
 
4277                         // Add offsetParent borders
 
4278                         parentOffset.top  += num( offsetParent, 'borderTopWidth'  );
 
4279                         parentOffset.left += num( offsetParent, 'borderLeftWidth' );
 
4281                         // Subtract the two offsets
 
4283                                 top:  offset.top  - parentOffset.top,
 
4284                                 left: offset.left - parentOffset.left
 
4291         offsetParent: function() {
 
4292                 var offsetParent = this[0].offsetParent || document.body;
 
4293                 while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
 
4294                         offsetParent = offsetParent.offsetParent;
 
4295                 return jQuery(offsetParent);
 
4300 // Create scrollLeft and scrollTop methods
 
4301 jQuery.each( ['Left', 'Top'], function(i, name) {
 
4302         var method = 'scroll' + name;
 
4304         jQuery.fn[ method ] = function(val) {
 
4305                 if (!this[0]) return null;
 
4307                 return val !== undefined ?
 
4309                         // Set the scroll offset
 
4310                         this.each(function() {
 
4311                                 this == window || this == document ?
 
4313                                                 !i ? val : jQuery(window).scrollLeft(),
 
4314                                                  i ? val : jQuery(window).scrollTop()
 
4316                                         this[ method ] = val;
 
4319                         // Return the scroll offset
 
4320                         this[0] == window || this[0] == document ?
 
4321                                 self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
 
4322                                         jQuery.boxModel && document.documentElement[ method ] ||
 
4323                                         document.body[ method ] :
 
4327 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
 
4328 jQuery.each([ "Height", "Width" ], function(i, name){
 
4330         var tl = i ? "Left"  : "Top",  // top or left
 
4331                 br = i ? "Right" : "Bottom", // bottom or right
 
4332                 lower = name.toLowerCase();
 
4334         // innerHeight and innerWidth
 
4335         jQuery.fn["inner" + name] = function(){
 
4337                         jQuery.css( this[0], lower, false, "padding" ) :
 
4341         // outerHeight and outerWidth
 
4342         jQuery.fn["outer" + name] = function(margin) {
 
4344                         jQuery.css( this[0], lower, false, margin ? "margin" : "border" ) :
 
4348         var type = name.toLowerCase();
 
4350         jQuery.fn[ type ] = function( size ) {
 
4351                 // Get window width or height
 
4352                 return this[0] == window ?
 
4353                         // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
 
4354                         document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] ||
 
4355                         document.body[ "client" + name ] :
 
4357                         // Get document width or height
 
4358                         this[0] == document ?
 
4359                                 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
 
4361                                         document.documentElement["client" + name],
 
4362                                         document.body["scroll" + name], document.documentElement["scroll" + name],
 
4363                                         document.body["offset" + name], document.documentElement["offset" + name]
 
4366                                 // Get or set width or height on the element
 
4367                                 size === undefined ?
 
4368                                         // Get width or height on the element
 
4369                                         (this.length ? jQuery.css( this[0], type ) : null) :
 
4371                                         // Set the width or height on the element (default to pixels if value is unitless)
 
4372                                         this.css( type, typeof size === "string" ? size : size + "px" );