[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/libraries/jquery/colorpicker/js/ -> jquery.js (source)

   1  /*!

   2   * jQuery JavaScript Library v1.3.2

   3   * http://jquery.com/

   4   *

   5   * Copyright (c) 2009 John Resig

   6   * Dual licensed under the MIT and GPL licenses.

   7   * http://docs.jquery.com/License

   8   *

   9   * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)

  10   * Revision: 6246

  11   */
  12  (function(){
  13  
  14  var 
  15      // Will speed up references to window, and allows munging its name.

  16      window = this,
  17      // Will speed up references to undefined, and allows munging its name.

  18      undefined,
  19      // Map over jQuery in case of overwrite

  20      _jQuery = window.jQuery,
  21      // Map over the $ in case of overwrite

  22      _$ = window.$,
  23  
  24      jQuery = window.jQuery = window.$ = function( selector, context ) {
  25          // The jQuery object is actually just the init constructor 'enhanced'

  26          return new jQuery.fn.init( selector, context );
  27      },
  28  
  29      // A simple way to check for HTML strings or ID strings

  30      // (both of which we optimize for)

  31      quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
  32      // Is it a simple selector

  33      isSimple = /^.[^:#\[\.,]*$/;
  34  
  35  jQuery.fn = jQuery.prototype = {
  36      init: function( selector, context ) {
  37          // Make sure that a selection was provided

  38          selector = selector || document;
  39  
  40          // Handle $(DOMElement)

  41          if ( selector.nodeType ) {
  42              this[0] = selector;
  43              this.length = 1;
  44              this.context = selector;
  45              return this;
  46          }
  47          // Handle HTML strings

  48          if ( typeof selector === "string" ) {
  49              // Are we dealing with HTML string or an ID?

  50              var match = quickExpr.exec( selector );
  51  
  52              // Verify a match, and that no context was specified for #id

  53              if ( match && (match[1] || !context) ) {
  54  
  55                  // HANDLE: $(html) -> $(array)

  56                  if ( match[1] )
  57                      selector = jQuery.clean( [ match[1] ], context );
  58  
  59                  // HANDLE: $("#id")

  60                  else {
  61                      var elem = document.getElementById( match[3] );
  62  
  63                      // Handle the case where IE and Opera return items

  64                      // by name instead of ID

  65                      if ( elem && elem.id != match[3] )
  66                          return jQuery().find( selector );
  67  
  68                      // Otherwise, we inject the element directly into the jQuery object

  69                      var ret = jQuery( elem || [] );
  70                      ret.context = document;
  71                      ret.selector = selector;
  72                      return ret;
  73                  }
  74  
  75              // HANDLE: $(expr, [context])

  76              // (which is just equivalent to: $(content).find(expr)

  77              } else
  78                  return jQuery( context ).find( selector );
  79  
  80          // HANDLE: $(function)

  81          // Shortcut for document ready

  82          } else if ( jQuery.isFunction( selector ) )
  83              return jQuery( document ).ready( selector );
  84  
  85          // Make sure that old selector state is passed along

  86          if ( selector.selector && selector.context ) {
  87              this.selector = selector.selector;
  88              this.context = selector.context;
  89          }
  90  
  91          return this.setArray(jQuery.isArray( selector ) ?
  92              selector :
  93              jQuery.makeArray(selector));
  94      },
  95  
  96      // Start with an empty selector

  97      selector: "",
  98  
  99      // The current version of jQuery being used

 100      jquery: "1.3.2",
 101  
 102      // The number of elements contained in the matched element set

 103      size: function() {
 104          return this.length;
 105      },
 106  
 107      // Get the Nth element in the matched element set OR

 108      // Get the whole matched element set as a clean array

 109      get: function( num ) {
 110          return num === undefined ?
 111  
 112              // Return a 'clean' array

 113              Array.prototype.slice.call( this ) :
 114  
 115              // Return just the object

 116              this[ num ];
 117      },
 118  
 119      // Take an array of elements and push it onto the stack

 120      // (returning the new matched element set)

 121      pushStack: function( elems, name, selector ) {
 122          // Build a new jQuery matched element set

 123          var ret = jQuery( elems );
 124  
 125          // Add the old object onto the stack (as a reference)

 126          ret.prevObject = this;
 127  
 128          ret.context = this.context;
 129  
 130          if ( name === "find" )
 131              ret.selector = this.selector + (this.selector ? " " : "") + selector;
 132          else if ( name )
 133              ret.selector = this.selector + "." + name + "(" + selector + ")";
 134  
 135          // Return the newly-formed element set

 136          return ret;
 137      },
 138  
 139      // Force the current matched set of elements to become

 140      // the specified array of elements (destroying the stack in the process)

 141      // You should use pushStack() in order to do this, but maintain the stack

 142      setArray: function( elems ) {
 143          // Resetting the length to 0, then using the native Array push

 144          // is a super-fast way to populate an object with array-like properties

 145          this.length = 0;
 146          Array.prototype.push.apply( this, elems );
 147  
 148          return this;
 149      },
 150  
 151      // Execute a callback for every element in the matched set.

 152      // (You can seed the arguments with an array of args, but this is

 153      // only used internally.)

 154      each: function( callback, args ) {
 155          return jQuery.each( this, callback, args );
 156      },
 157  
 158      // Determine the position of an element within

 159      // the matched set of elements

 160      index: function( elem ) {
 161          // Locate the position of the desired element

 162          return jQuery.inArray(
 163              // If it receives a jQuery object, the first element is used

 164              elem && elem.jquery ? elem[0] : elem
 165          , this );
 166      },
 167  
 168      attr: function( name, value, type ) {
 169          var options = name;
 170  
 171          // Look for the case where we're accessing a style value

 172          if ( typeof name === "string" )
 173              if ( value === undefined )
 174                  return this[0] && jQuery[ type || "attr" ]( this[0], name );
 175  
 176              else {
 177                  options = {};
 178                  options[ name ] = value;
 179              }
 180  
 181          // Check to see if we're setting style values

 182          return this.each(function(i){
 183              // Set all the styles

 184              for ( name in options )
 185                  jQuery.attr(
 186                      type ?
 187                          this.style :
 188                          this,
 189                      name, jQuery.prop( this, options[ name ], type, i, name )
 190                  );
 191          });
 192      },
 193  
 194      css: function( key, value ) {
 195          // ignore negative width and height values

 196          if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
 197              value = undefined;
 198          return this.attr( key, value, "curCSS" );
 199      },
 200  
 201      text: function( text ) {
 202          if ( typeof text !== "object" && text != null )
 203              return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
 204  
 205          var ret = "";
 206  
 207          jQuery.each( text || this, function(){
 208              jQuery.each( this.childNodes, function(){
 209                  if ( this.nodeType != 8 )
 210                      ret += this.nodeType != 1 ?
 211                          this.nodeValue :
 212                          jQuery.fn.text( [ this ] );
 213              });
 214          });
 215  
 216          return ret;
 217      },
 218  
 219      wrapAll: function( html ) {
 220          if ( this[0] ) {
 221              // The elements to wrap the target around

 222              var wrap = jQuery( html, this[0].ownerDocument ).clone();
 223  
 224              if ( this[0].parentNode )
 225                  wrap.insertBefore( this[0] );
 226  
 227              wrap.map(function(){
 228                  var elem = this;
 229  
 230                  while ( elem.firstChild )
 231                      elem = elem.firstChild;
 232  
 233                  return elem;
 234              }).append(this);
 235          }
 236  
 237          return this;
 238      },
 239  
 240      wrapInner: function( html ) {
 241          return this.each(function(){
 242              jQuery( this ).contents().wrapAll( html );
 243          });
 244      },
 245  
 246      wrap: function( html ) {
 247          return this.each(function(){
 248              jQuery( this ).wrapAll( html );
 249          });
 250      },
 251  
 252      append: function() {
 253          return this.domManip(arguments, true, function(elem){
 254              if (this.nodeType == 1)
 255                  this.appendChild( elem );
 256          });
 257      },
 258  
 259      prepend: function() {
 260          return this.domManip(arguments, true, function(elem){
 261              if (this.nodeType == 1)
 262                  this.insertBefore( elem, this.firstChild );
 263          });
 264      },
 265  
 266      before: function() {
 267          return this.domManip(arguments, false, function(elem){
 268              this.parentNode.insertBefore( elem, this );
 269          });
 270      },
 271  
 272      after: function() {
 273          return this.domManip(arguments, false, function(elem){
 274              this.parentNode.insertBefore( elem, this.nextSibling );
 275          });
 276      },
 277  
 278      end: function() {
 279          return this.prevObject || jQuery( [] );
 280      },
 281  
 282      // For internal use only.

 283      // Behaves like an Array's method, not like a jQuery method.

 284      push: [].push,
 285      sort: [].sort,
 286      splice: [].splice,
 287  
 288      find: function( selector ) {
 289          if ( this.length === 1 ) {
 290              var ret = this.pushStack( [], "find", selector );
 291              ret.length = 0;
 292              jQuery.find( selector, this[0], ret );
 293              return ret;
 294          } else {
 295              return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
 296                  return jQuery.find( selector, elem );
 297              })), "find", selector );
 298          }
 299      },
 300  
 301      clone: function( events ) {
 302          // Do the clone

 303          var ret = this.map(function(){
 304              if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
 305                  // IE copies events bound via attachEvent when

 306                  // using cloneNode. Calling detachEvent on the

 307                  // clone will also remove the events from the orignal

 308                  // In order to get around this, we use innerHTML.

 309                  // Unfortunately, this means some modifications to

 310                  // attributes in IE that are actually only stored

 311                  // as properties will not be copied (such as the

 312                  // the name attribute on an input).

 313                  var html = this.outerHTML;
 314                  if ( !html ) {
 315                      var div = this.ownerDocument.createElement("div");
 316                      div.appendChild( this.cloneNode(true) );
 317                      html = div.innerHTML;
 318                  }
 319  
 320                  return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
 321              } else
 322                  return this.cloneNode(true);
 323          });
 324  
 325          // Copy the events from the original to the clone

 326          if ( events === true ) {
 327              var orig = this.find("*").andSelf(), i = 0;
 328  
 329              ret.find("*").andSelf().each(function(){
 330                  if ( this.nodeName !== orig[i].nodeName )
 331                      return;
 332  
 333                  var events = jQuery.data( orig[i], "events" );
 334  
 335                  for ( var type in events ) {
 336                      for ( var handler in events[ type ] ) {
 337                          jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
 338                      }
 339                  }
 340  
 341                  i++;
 342              });
 343          }
 344  
 345          // Return the cloned set

 346          return ret;
 347      },
 348  
 349      filter: function( selector ) {
 350          return this.pushStack(
 351              jQuery.isFunction( selector ) &&
 352              jQuery.grep(this, function(elem, i){
 353                  return selector.call( elem, i );
 354              }) ||
 355  
 356              jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
 357                  return elem.nodeType === 1;
 358              }) ), "filter", selector );
 359      },
 360  
 361      closest: function( selector ) {
 362          var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
 363              closer = 0;
 364  
 365          return this.map(function(){
 366              var cur = this;
 367              while ( cur && cur.ownerDocument ) {
 368                  if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
 369                      jQuery.data(cur, "closest", closer);
 370                      return cur;
 371                  }
 372                  cur = cur.parentNode;
 373                  closer++;
 374              }
 375          });
 376      },
 377  
 378      not: function( selector ) {
 379          if ( typeof selector === "string" )
 380              // test special case where just one selector is passed in

 381              if ( isSimple.test( selector ) )
 382                  return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
 383              else
 384                  selector = jQuery.multiFilter( selector, this );
 385  
 386          var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
 387          return this.filter(function() {
 388              return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
 389          });
 390      },
 391  
 392      add: function( selector ) {
 393          return this.pushStack( jQuery.unique( jQuery.merge(
 394              this.get(),
 395              typeof selector === "string" ?
 396                  jQuery( selector ) :
 397                  jQuery.makeArray( selector )
 398          )));
 399      },
 400  
 401      is: function( selector ) {
 402          return !!selector && jQuery.multiFilter( selector, this ).length > 0;
 403      },
 404  
 405      hasClass: function( selector ) {
 406          return !!selector && this.is( "." + selector );
 407      },
 408  
 409      val: function( value ) {
 410          if ( value === undefined ) {            
 411              var elem = this[0];
 412  
 413              if ( elem ) {
 414                  if( jQuery.nodeName( elem, 'option' ) )
 415                      return (elem.attributes.value || {}).specified ? elem.value : elem.text;
 416                  
 417                  // We need to handle select boxes special

 418                  if ( jQuery.nodeName( elem, "select" ) ) {
 419                      var index = elem.selectedIndex,
 420                          values = [],
 421                          options = elem.options,
 422                          one = elem.type == "select-one";
 423  
 424                      // Nothing was selected

 425                      if ( index < 0 )
 426                          return null;
 427  
 428                      // Loop through all the selected options

 429                      for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
 430                          var option = options[ i ];
 431  
 432                          if ( option.selected ) {
 433                              // Get the specifc value for the option

 434                              value = jQuery(option).val();
 435  
 436                              // We don't need an array for one selects

 437                              if ( one )
 438                                  return value;
 439  
 440                              // Multi-Selects return an array

 441                              values.push( value );
 442                          }
 443                      }
 444  
 445                      return values;                
 446                  }
 447  
 448                  // Everything else, we just grab the value

 449                  return (elem.value || "").replace(/\r/g, "");
 450  
 451              }
 452  
 453              return undefined;
 454          }
 455  
 456          if ( typeof value === "number" )
 457              value += '';
 458  
 459          return this.each(function(){
 460              if ( this.nodeType != 1 )
 461                  return;
 462  
 463              if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
 464                  this.checked = (jQuery.inArray(this.value, value) >= 0 ||
 465                      jQuery.inArray(this.name, value) >= 0);
 466  
 467              else if ( jQuery.nodeName( this, "select" ) ) {
 468                  var values = jQuery.makeArray(value);
 469  
 470                  jQuery( "option", this ).each(function(){
 471                      this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
 472                          jQuery.inArray( this.text, values ) >= 0);
 473                  });
 474  
 475                  if ( !values.length )
 476                      this.selectedIndex = -1;
 477  
 478              } else
 479                  this.value = value;
 480          });
 481      },
 482  
 483      html: function( value ) {
 484          return value === undefined ?
 485              (this[0] ?
 486                  this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
 487                  null) :
 488              this.empty().append( value );
 489      },
 490  
 491      replaceWith: function( value ) {
 492          return this.after( value ).remove();
 493      },
 494  
 495      eq: function( i ) {
 496          return this.slice( i, +i + 1 );
 497      },
 498  
 499      slice: function() {
 500          return this.pushStack( Array.prototype.slice.apply( this, arguments ),
 501              "slice", Array.prototype.slice.call(arguments).join(",") );
 502      },
 503  
 504      map: function( callback ) {
 505          return this.pushStack( jQuery.map(this, function(elem, i){
 506              return callback.call( elem, i, elem );
 507          }));
 508      },
 509  
 510      andSelf: function() {
 511          return this.add( this.prevObject );
 512      },
 513  
 514      domManip: function( args, table, callback ) {
 515          if ( this[0] ) {
 516              var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
 517                  scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
 518                  first = fragment.firstChild;
 519  
 520              if ( first )
 521                  for ( var i = 0, l = this.length; i < l; i++ )
 522                      callback.call( root(this[i], first), this.length > 1 || i > 0 ?
 523                              fragment.cloneNode(true) : fragment );
 524          
 525              if ( scripts )
 526                  jQuery.each( scripts, evalScript );
 527          }
 528  
 529          return this;
 530          
 531  		function root( elem, cur ) {
 532              return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
 533                  (elem.getElementsByTagName("tbody")[0] ||
 534                  elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
 535                  elem;
 536          }
 537      }
 538  };
 539  
 540  // Give the init function the jQuery prototype for later instantiation

 541  jQuery.fn.init.prototype = jQuery.fn;
 542  
 543  function evalScript( i, elem ) {
 544      if ( elem.src )
 545          jQuery.ajax({
 546              url: elem.src,
 547              async: false,
 548              dataType: "script"
 549          });
 550  
 551      else
 552          jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
 553  
 554      if ( elem.parentNode )
 555          elem.parentNode.removeChild( elem );
 556  }
 557  
 558  function now(){
 559      return +new Date;
 560  }
 561  
 562  jQuery.extend = jQuery.fn.extend = function() {
 563      // copy reference to target object

 564      var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
 565  
 566      // Handle a deep copy situation

 567      if ( typeof target === "boolean" ) {
 568          deep = target;
 569          target = arguments[1] || {};
 570          // skip the boolean and the target

 571          i = 2;
 572      }
 573  
 574      // Handle case when target is a string or something (possible in deep copy)

 575      if ( typeof target !== "object" && !jQuery.isFunction(target) )
 576          target = {};
 577  
 578      // extend jQuery itself if only one argument is passed

 579      if ( length == i ) {
 580          target = this;
 581          --i;
 582      }
 583  
 584      for ( ; i < length; i++ )
 585          // Only deal with non-null/undefined values

 586          if ( (options = arguments[ i ]) != null )
 587              // Extend the base object

 588              for ( var name in options ) {
 589                  var src = target[ name ], copy = options[ name ];
 590  
 591                  // Prevent never-ending loop

 592                  if ( target === copy )
 593                      continue;
 594  
 595                  // Recurse if we're merging object values

 596                  if ( deep && copy && typeof copy === "object" && !copy.nodeType )
 597                      target[ name ] = jQuery.extend( deep, 
 598                          // Never move original objects, clone them

 599                          src || ( copy.length != null ? [ ] : { } )
 600                      , copy );
 601  
 602                  // Don't bring in undefined values

 603                  else if ( copy !== undefined )
 604                      target[ name ] = copy;
 605  
 606              }
 607  
 608      // Return the modified object

 609      return target;
 610  };
 611  
 612  // exclude the following css properties to add px

 613  var    exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
 614      // cache defaultView

 615      defaultView = document.defaultView || {},
 616      toString = Object.prototype.toString;
 617  
 618  jQuery.extend({
 619      noConflict: function( deep ) {
 620          window.$ = _$;
 621  
 622          if ( deep )
 623              window.jQuery = _jQuery;
 624  
 625          return jQuery;
 626      },
 627  
 628      // See test/unit/core.js for details concerning isFunction.

 629      // Since version 1.3, DOM methods and functions like alert

 630      // aren't supported. They return false on IE (#2968).

 631      isFunction: function( obj ) {
 632          return toString.call(obj) === "[object Function]";
 633      },
 634  
 635      isArray: function( obj ) {
 636          return toString.call(obj) === "[object Array]";
 637      },
 638  
 639      // check if an element is in a (or is an) XML document

 640      isXMLDoc: function( elem ) {
 641          return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
 642              !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
 643      },
 644  
 645      // Evalulates a script in a global context

 646      globalEval: function( data ) {
 647          if ( data && /\S/.test(data) ) {
 648              // Inspired by code by Andrea Giammarchi

 649              // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html

 650              var head = document.getElementsByTagName("head")[0] || document.documentElement,
 651                  script = document.createElement("script");
 652  
 653              script.type = "text/javascript";
 654              if ( jQuery.support.scriptEval )
 655                  script.appendChild( document.createTextNode( data ) );
 656              else
 657                  script.text = data;
 658  
 659              // Use insertBefore instead of appendChild  to circumvent an IE6 bug.

 660              // This arises when a base node is used (#2709).

 661              head.insertBefore( script, head.firstChild );
 662              head.removeChild( script );
 663          }
 664      },
 665  
 666      nodeName: function( elem, name ) {
 667          return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
 668      },
 669  
 670      // args is for internal usage only

 671      each: function( object, callback, args ) {
 672          var name, i = 0, length = object.length;
 673  
 674          if ( args ) {
 675              if ( length === undefined ) {
 676                  for ( name in object )
 677                      if ( callback.apply( object[ name ], args ) === false )
 678                          break;
 679              } else
 680                  for ( ; i < length; )
 681                      if ( callback.apply( object[ i++ ], args ) === false )
 682                          break;
 683  
 684          // A special, fast, case for the most common use of each

 685          } else {
 686              if ( length === undefined ) {
 687                  for ( name in object )
 688                      if ( callback.call( object[ name ], name, object[ name ] ) === false )
 689                          break;
 690              } else
 691                  for ( var value = object[0];
 692                      i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
 693          }
 694  
 695          return object;
 696      },
 697  
 698      prop: function( elem, value, type, i, name ) {
 699          // Handle executable functions

 700          if ( jQuery.isFunction( value ) )
 701              value = value.call( elem, i );
 702  
 703          // Handle passing in a number to a CSS property

 704          return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
 705              value + "px" :
 706              value;
 707      },
 708  
 709      className: {
 710          // internal only, use addClass("class")

 711          add: function( elem, classNames ) {
 712              jQuery.each((classNames || "").split(/\s+/), function(i, className){
 713                  if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
 714                      elem.className += (elem.className ? " " : "") + className;
 715              });
 716          },
 717  
 718          // internal only, use removeClass("class")

 719          remove: function( elem, classNames ) {
 720              if (elem.nodeType == 1)
 721                  elem.className = classNames !== undefined ?
 722                      jQuery.grep(elem.className.split(/\s+/), function(className){
 723                          return !jQuery.className.has( classNames, className );
 724                      }).join(" ") :
 725                      "";
 726          },
 727  
 728          // internal only, use hasClass("class")

 729          has: function( elem, className ) {
 730              return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
 731          }
 732      },
 733  
 734      // A method for quickly swapping in/out CSS properties to get correct calculations

 735      swap: function( elem, options, callback ) {
 736          var old = {};
 737          // Remember the old values, and insert the new ones

 738          for ( var name in options ) {
 739              old[ name ] = elem.style[ name ];
 740              elem.style[ name ] = options[ name ];
 741          }
 742  
 743          callback.call( elem );
 744  
 745          // Revert the old values

 746          for ( var name in options )
 747              elem.style[ name ] = old[ name ];
 748      },
 749  
 750      css: function( elem, name, force, extra ) {
 751          if ( name == "width" || name == "height" ) {
 752              var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
 753  
 754  			function getWH() {
 755                  val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
 756  
 757                  if ( extra === "border" )
 758                      return;
 759  
 760                  jQuery.each( which, function() {
 761                      if ( !extra )
 762                          val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
 763                      if ( extra === "margin" )
 764                          val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
 765                      else
 766                          val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
 767                  });
 768              }
 769  
 770              if ( elem.offsetWidth !== 0 )
 771                  getWH();
 772              else
 773                  jQuery.swap( elem, props, getWH );
 774  
 775              return Math.max(0, Math.round(val));
 776          }
 777  
 778          return jQuery.curCSS( elem, name, force );
 779      },
 780  
 781      curCSS: function( elem, name, force ) {
 782          var ret, style = elem.style;
 783  
 784          // We need to handle opacity special in IE

 785          if ( name == "opacity" && !jQuery.support.opacity ) {
 786              ret = jQuery.attr( style, "opacity" );
 787  
 788              return ret == "" ?
 789                  "1" :
 790                  ret;
 791          }
 792  
 793          // Make sure we're using the right name for getting the float value

 794          if ( name.match( /float/i ) )
 795              name = styleFloat;
 796  
 797          if ( !force && style && style[ name ] )
 798              ret = style[ name ];
 799  
 800          else if ( defaultView.getComputedStyle ) {
 801  
 802              // Only "float" is needed here

 803              if ( name.match( /float/i ) )
 804                  name = "float";
 805  
 806              name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
 807  
 808              var computedStyle = defaultView.getComputedStyle( elem, null );
 809  
 810              if ( computedStyle )
 811                  ret = computedStyle.getPropertyValue( name );
 812  
 813              // We should always get a number back from opacity

 814              if ( name == "opacity" && ret == "" )
 815                  ret = "1";
 816  
 817          } else if ( elem.currentStyle ) {
 818              var camelCase = name.replace(/\-(\w)/g, function(all, letter){
 819                  return letter.toUpperCase();
 820              });
 821  
 822              ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
 823  
 824              // From the awesome hack by Dean Edwards

 825              // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291

 826  
 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;
 832  
 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";
 837  
 838                  // Revert the changed values

 839                  style.left = left;
 840                  elem.runtimeStyle.left = rsLeft;
 841              }
 842          }
 843  
 844          return ret;
 845      },
 846  
 847      clean: function( elems, context, fragment ) {
 848          context = context || document;
 849  
 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;
 853  
 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]);
 858              if ( match )
 859                  return [ context.createElement( match[1] ) ];
 860          }
 861  
 862          var ret = [], scripts = [], div = context.createElement("div");
 863  
 864          jQuery.each(elems, function(i, elem){
 865              if ( typeof elem === "number" )
 866                  elem += '';
 867  
 868              if ( !elem )
 869                  return;
 870  
 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) ?
 876                          all :
 877                          front + "></" + tag + ">";
 878                  });
 879  
 880                  // Trim whitespace, otherwise indexOf won't work as expected

 881                  var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
 882  
 883                  var wrap =
 884                      // option or optgroup

 885                      !tags.indexOf("<opt") &&
 886                      [ 1, "<select multiple='multiple'>", "</select>" ] ||
 887  
 888                      !tags.indexOf("<leg") &&
 889                      [ 1, "<fieldset>", "</fieldset>" ] ||
 890  
 891                      tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
 892                      [ 1, "<table>", "</table>" ] ||
 893  
 894                      !tags.indexOf("<tr") &&
 895                      [ 2, "<table><tbody>", "</tbody></table>" ] ||
 896  
 897                       // <thead> matched above

 898                      (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
 899                      [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
 900  
 901                      !tags.indexOf("<col") &&
 902                      [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
 903  
 904                      // IE can't serialize <link> and <script> tags normally

 905                      !jQuery.support.htmlSerialize &&
 906                      [ 1, "div<div>", "</div>" ] ||
 907  
 908                      [ 0, "", "" ];
 909  
 910                  // Go to html and back, then peel off extra wrappers

 911                  div.innerHTML = wrap[1] + elem + wrap[2];
 912  
 913                  // Move to the right depth

 914                  while ( wrap[0]-- )
 915                      div = div.lastChild;
 916  
 917                  // Remove IE's autoinserted <tbody> from table fragments

 918                  if ( !jQuery.support.tbody ) {
 919  
 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 :
 924  
 925                          // String was a bare <thead> or <tfoot>

 926                          wrap[1] == "<table>" && !hasBody ?
 927                              div.childNodes :
 928                              [];
 929  
 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 ] );
 933  
 934                      }
 935  
 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 );
 939                  
 940                  elem = jQuery.makeArray( div.childNodes );
 941              }
 942  
 943              if ( elem.nodeType )
 944                  ret.push( elem );
 945              else
 946                  ret = jQuery.merge( ret, elem );
 947  
 948          });
 949  
 950          if ( fragment ) {
 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] );
 954                  } else {
 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] );
 958                  }
 959              }
 960              
 961              return scripts;
 962          }
 963  
 964          return ret;
 965      },
 966  
 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)
 970              return undefined;
 971  
 972          var notxml = !jQuery.isXMLDoc( elem ),
 973              // Whether we are setting (or getting)

 974              set = value !== undefined;
 975  
 976          // Try to normalize/fix the name

 977          name = notxml && jQuery.props[ name ] || name;
 978  
 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 ) {
 982  
 983              // These attributes require special treatment

 984              var special = /href|src|style/.test( name );
 985  
 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;
 990  
 991              // If applicable, access the attribute via the DOM 0 way

 992              if ( name in elem && notxml && !special ) {
 993                  if ( set ){
 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";
 997  
 998                      elem[ name ] = value;
 999                  }
1000  
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;
1004  
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)
1012                              ? 0
1013                              : elem.nodeName.match(/^(a|area)$/i) && elem.href
1014                                  ? 0
1015                                  : undefined;
1016                  }
1017  
1018                  return elem[ name ];
1019              }
1020  
1021              if ( !jQuery.support.style && notxml &&  name == "style" )
1022                  return jQuery.attr( elem.style, "cssText", value );
1023  
1024              if ( set )
1025                  // convert the value to a string (all browsers do this but IE) see #1070

1026                  elem.setAttribute( name, "" + value );
1027  
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 );
1032  
1033              // Non-existent attributes return null, we normalize to undefined

1034              return attr === null ? undefined : attr;
1035          }
1036  
1037          // elem is actually elem.style ... set the style

1038  
1039          // IE uses filters for opacity

1040          if ( !jQuery.support.opacity && name == "opacity" ) {
1041              if ( set ) {
1042                  // IE has trouble with opacity if it does not have layout

1043                  // Force it by setting the zoom level

1044                  elem.zoom = 1;
1045  
1046                  // Set the alpha filter to set the opacity

1047                  elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
1048                      (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
1049              }
1050  
1051              return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
1052                  (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
1053                  "";
1054          }
1055  
1056          name = name.replace(/-([a-z])/ig, function(all, letter){
1057              return letter.toUpperCase();
1058          });
1059  
1060          if ( set )
1061              elem[ name ] = value;
1062  
1063          return elem[ name ];
1064      },
1065  
1066      trim: function( text ) {
1067          return (text || "").replace( /^\s+|\s+$/g, "" );
1068      },
1069  
1070      makeArray: function( array ) {
1071          var ret = [];
1072  
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 )
1077                  ret[0] = array;
1078              else
1079                  while( i )
1080                      ret[--i] = array[i];
1081          }
1082  
1083          return ret;
1084      },
1085  
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 )
1090                  return i;
1091  
1092          return -1;
1093      },
1094  
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;
1105  
1106          } else
1107              while ( (elem = second[ i++ ]) != null )
1108                  first[ pos++ ] = elem;
1109  
1110          return first;
1111      },
1112  
1113      unique: function( array ) {
1114          var ret = [], done = {};
1115  
1116          try {
1117  
1118              for ( var i = 0, length = array.length; i < length; i++ ) {
1119                  var id = jQuery.data( array[ i ] );
1120  
1121                  if ( !done[ id ] ) {
1122                      done[ id ] = true;
1123                      ret.push( array[ i ] );
1124                  }
1125              }
1126  
1127          } catch( e ) {
1128              ret = array;
1129          }
1130  
1131          return ret;
1132      },
1133  
1134      grep: function( elems, callback, inv ) {
1135          var ret = [];
1136  
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 ] );
1142  
1143          return ret;
1144      },
1145  
1146      map: function( elems, callback ) {
1147          var ret = [];
1148  
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 );
1153  
1154              if ( value != null )
1155                  ret[ ret.length ] = value;
1156          }
1157  
1158          return ret.concat.apply( [], ret );
1159      }
1160  });
1161  
1162  // Use of jQuery.browser is deprecated.

1163  // It's included for backwards compatibility and plugins,

1164  // although they should work to migrate away.

1165  
1166  var userAgent = navigator.userAgent.toLowerCase();
1167  
1168  // Figure out what browser is being used

1169  jQuery.browser = {
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 )
1175  };
1176  
1177  jQuery.each({
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 );
1190  
1191          if ( selector && typeof selector == "string" )
1192              ret = jQuery.multiFilter( selector, ret );
1193  
1194          return this.pushStack( jQuery.unique( ret ), name, selector );
1195      };
1196  });
1197  
1198  jQuery.each({
1199      appendTo: "append",
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 );
1207  
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 );
1212          }
1213  
1214          return this.pushStack( ret, name, selector );
1215      };
1216  });
1217  
1218  jQuery.each({
1219      removeAttr: function( name ) {
1220          jQuery.attr( this, name, "" );
1221          if (this.nodeType == 1)
1222              this.removeAttribute( name );
1223      },
1224  
1225      addClass: function( classNames ) {
1226          jQuery.className.add( this, classNames );
1227      },
1228  
1229      removeClass: function( classNames ) {
1230          jQuery.className.remove( this, classNames );
1231      },
1232  
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 );
1237      },
1238  
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);
1245              });
1246              if (this.parentNode)
1247                  this.parentNode.removeChild( this );
1248          }
1249      },
1250  
1251      empty: function() {
1252          // Remove element nodes and prevent memory leaks

1253          jQuery(this).children().remove();
1254  
1255          // Remove any remaining nodes

1256          while ( this.firstChild )
1257              this.removeChild( this.firstChild );
1258      }
1259  }, function(name, fn){
1260      jQuery.fn[ name ] = function(){
1261          return this.each( fn, arguments );
1262      };
1263  });
1264  
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;
1268  }
1269  var expando = "jQuery" + now(), uuid = 0, windowData = {};
1270  
1271  jQuery.extend({
1272      cache: {},
1273  
1274      data: function( elem, name, data ) {
1275          elem = elem == window ?
1276              windowData :
1277              elem;
1278  
1279          var id = elem[ expando ];
1280  
1281          // Compute a unique ID for the element

1282          if ( !id )
1283              id = elem[ expando ] = ++uuid;
1284  
1285          // Only generate the data cache if we're

1286          // trying to access or manipulate it

1287          if ( name && !jQuery.cache[ id ] )
1288              jQuery.cache[ id ] = {};
1289  
1290          // Prevent overriding the named cache with undefined values

1291          if ( data !== undefined )
1292              jQuery.cache[ id ][ name ] = data;
1293  
1294          // Return the named cache data, or the ID for the element

1295          return name ?
1296              jQuery.cache[ id ][ name ] :
1297              id;
1298      },
1299  
1300      removeData: function( elem, name ) {
1301          elem = elem == window ?
1302              windowData :
1303              elem;
1304  
1305          var id = elem[ expando ];
1306  
1307          // If we want to remove a specific section of the element's data

1308          if ( name ) {
1309              if ( jQuery.cache[ id ] ) {
1310                  // Remove the section of cache data

1311                  delete jQuery.cache[ id ][ name ];
1312  
1313                  // If we've removed all the data, remove the element's cache

1314                  name = "";
1315  
1316                  for ( name in jQuery.cache[ id ] )
1317                      break;
1318  
1319                  if ( !name )
1320                      jQuery.removeData( elem );
1321              }
1322  
1323          // Otherwise, we want to remove all of the element's data

1324          } else {
1325              // Clean up the element expando

1326              try {
1327                  delete elem[ expando ];
1328              } catch(e){
1329                  // IE has trouble directly removing the expando

1330                  // but it's ok with using removeAttribute

1331                  if ( elem.removeAttribute )
1332                      elem.removeAttribute( expando );
1333              }
1334  
1335              // Completely remove the data cache

1336              delete jQuery.cache[ id ];
1337          }
1338      },
1339      queue: function( elem, type, data ) {
1340          if ( elem ){
1341      
1342              type = (type || "fx") + "queue";
1343      
1344              var q = jQuery.data( elem, type );
1345      
1346              if ( !q || jQuery.isArray(data) )
1347                  q = jQuery.data( elem, type, jQuery.makeArray(data) );
1348              else if( data )
1349                  q.push( data );
1350      
1351          }
1352          return q;
1353      },
1354  
1355      dequeue: function( elem, type ){
1356          var queue = jQuery.queue( elem, type ),
1357              fn = queue.shift();
1358          
1359          if( !type || type === "fx" )
1360              fn = queue[0];
1361              
1362          if( fn !== undefined )
1363              fn.call(elem);
1364      }
1365  });
1366  
1367  jQuery.fn.extend({
1368      data: function( key, value ){
1369          var parts = key.split(".");
1370          parts[1] = parts[1] ? "." + parts[1] : "";
1371  
1372          if ( value === undefined ) {
1373              var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1374  
1375              if ( data === undefined && this.length )
1376                  data = jQuery.data( this[0], key );
1377  
1378              return data === undefined && parts[1] ?
1379                  this.data( parts[0] ) :
1380                  data;
1381          } else
1382              return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
1383                  jQuery.data( this, key, value );
1384              });
1385      },
1386  
1387      removeData: function( key ){
1388          return this.each(function(){
1389              jQuery.removeData( this, key );
1390          });
1391      },
1392      queue: function(type, data){
1393          if ( typeof type !== "string" ) {
1394              data = type;
1395              type = "fx";
1396          }
1397  
1398          if ( data === undefined )
1399              return jQuery.queue( this[0], type );
1400  
1401          return this.each(function(){
1402              var queue = jQuery.queue( this, type, data );
1403              
1404               if( type == "fx" && queue.length == 1 )
1405                  queue[0].call(this);
1406          });
1407      },
1408      dequeue: function(type){
1409          return this.each(function(){
1410              jQuery.dequeue( this, type );
1411          });
1412      }
1413  });/*!

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/

1418   */
1419  (function(){
1420  
1421  var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
1422      done = 0,
1423      toString = Object.prototype.toString;
1424  
1425  var Sizzle = function(selector, context, results, seed) {
1426      results = results || [];
1427      context = context || document;
1428  
1429      if ( context.nodeType !== 1 && context.nodeType !== 9 )
1430          return [];
1431      
1432      if ( !selector || typeof selector !== "string" ) {
1433          return results;
1434      }
1435  
1436      var parts = [], m, set, checkSet, check, mode, extra, prune = true;
1437      
1438      // Reset the position of the chunker regexp (start from head)

1439      chunker.lastIndex = 0;
1440      
1441      while ( (m = chunker.exec(selector)) !== null ) {
1442          parts.push( m[1] );
1443          
1444          if ( m[2] ) {
1445              extra = RegExp.rightContext;
1446              break;
1447          }
1448      }
1449  
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 );
1453          } else {
1454              set = Expr.relative[ parts[0] ] ?
1455                  [ context ] :
1456                  Sizzle( parts.shift(), context );
1457  
1458              while ( parts.length ) {
1459                  selector = parts.shift();
1460  
1461                  if ( Expr.relative[ selector ] )
1462                      selector += parts.shift();
1463  
1464                  set = posProcess( selector, set );
1465              }
1466          }
1467      } else {
1468          var ret = seed ?
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 );
1472  
1473          if ( parts.length > 0 ) {
1474              checkSet = makeArray(set);
1475          } else {
1476              prune = false;
1477          }
1478  
1479          while ( parts.length ) {
1480              var cur = parts.pop(), pop = cur;
1481  
1482              if ( !Expr.relative[ cur ] ) {
1483                  cur = "";
1484              } else {
1485                  pop = parts.pop();
1486              }
1487  
1488              if ( pop == null ) {
1489                  pop = context;
1490              }
1491  
1492              Expr.relative[ cur ]( checkSet, pop, isXML(context) );
1493          }
1494      }
1495  
1496      if ( !checkSet ) {
1497          checkSet = set;
1498      }
1499  
1500      if ( !checkSet ) {
1501          throw "Syntax error, unrecognized expression: " + (cur || selector);
1502      }
1503  
1504      if ( toString.call(checkSet) === "[object Array]" ) {
1505          if ( !prune ) {
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] );
1511                  }
1512              }
1513          } else {
1514              for ( var i = 0; checkSet[i] != null; i++ ) {
1515                  if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
1516                      results.push( set[i] );
1517                  }
1518              }
1519          }
1520      } else {
1521          makeArray( checkSet, results );
1522      }
1523  
1524      if ( extra ) {
1525          Sizzle( extra, context, results, seed );
1526  
1527          if ( sortOrder ) {
1528              hasDuplicate = false;
1529              results.sort(sortOrder);
1530  
1531              if ( hasDuplicate ) {
1532                  for ( var i = 1; i < results.length; i++ ) {
1533                      if ( results[i] === results[i-1] ) {
1534                          results.splice(i--, 1);
1535                      }
1536                  }
1537              }
1538          }
1539      }
1540  
1541      return results;
1542  };
1543  
1544  Sizzle.matches = function(expr, set){
1545      return Sizzle(expr, null, null, set);
1546  };
1547  
1548  Sizzle.find = function(expr, context, isXML){
1549      var set, match;
1550  
1551      if ( !expr ) {
1552          return [];
1553      }
1554  
1555      for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
1556          var type = Expr.order[i], match;
1557          
1558          if ( (match = Expr.match[ type ].exec( expr )) ) {
1559              var left = RegExp.leftContext;
1560  
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 ], "" );
1566                      break;
1567                  }
1568              }
1569          }
1570      }
1571  
1572      if ( !set ) {
1573          set = context.getElementsByTagName("*");
1574      }
1575  
1576      return {set: set, expr: expr};
1577  };
1578  
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]);
1582  
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;
1587                  anyFound = false;
1588  
1589                  if ( curLoop == result ) {
1590                      result = [];
1591                  }
1592  
1593                  if ( Expr.preFilter[ type ] ) {
1594                      match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
1595  
1596                      if ( !match ) {
1597                          anyFound = found = true;
1598                      } else if ( match === true ) {
1599                          continue;
1600                      }
1601                  }
1602  
1603                  if ( match ) {
1604                      for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
1605                          if ( item ) {
1606                              found = filter( item, match, i, curLoop );
1607                              var pass = not ^ !!found;
1608  
1609                              if ( inplace && found != null ) {
1610                                  if ( pass ) {
1611                                      anyFound = true;
1612                                  } else {
1613                                      curLoop[i] = false;
1614                                  }
1615                              } else if ( pass ) {
1616                                  result.push( item );
1617                                  anyFound = true;
1618                              }
1619                          }
1620                      }
1621                  }
1622  
1623                  if ( found !== undefined ) {
1624                      if ( !inplace ) {
1625                          curLoop = result;
1626                      }
1627  
1628                      expr = expr.replace( Expr.match[ type ], "" );
1629  
1630                      if ( !anyFound ) {
1631                          return [];
1632                      }
1633  
1634                      break;
1635                  }
1636              }
1637          }
1638  
1639          // Improper expression

1640          if ( expr == old ) {
1641              if ( anyFound == null ) {
1642                  throw "Syntax error, unrecognized expression: " + expr;
1643              } else {
1644                  break;
1645              }
1646          }
1647  
1648          old = expr;
1649      }
1650  
1651      return curLoop;
1652  };
1653  
1654  var Expr = Sizzle.selectors = {
1655      order: [ "ID", "NAME", "TAG" ],
1656      match: {
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\))?/
1665      },
1666      attrMap: {
1667          "class": "className",
1668          "for": "htmlFor"
1669      },
1670      attrHandle: {
1671          href: function(elem){
1672              return elem.getAttribute("href");
1673          }
1674      },
1675      relative: {
1676          "+": function(checkSet, part, isXML){
1677              var isPartStr = typeof part === "string",
1678                  isTag = isPartStr && !/\W/.test(part),
1679                  isPartStrNotTag = isPartStr && !isTag;
1680  
1681              if ( isTag && !isXML ) {
1682                  part = part.toUpperCase();
1683              }
1684  
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 ) {}
1688  
1689                      checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
1690                          elem || false :
1691                          elem === part;
1692                  }
1693              }
1694  
1695              if ( isPartStrNotTag ) {
1696                  Sizzle.filter( part, checkSet, true );
1697              }
1698          },
1699          ">": function(checkSet, part, isXML){
1700              var isPartStr = typeof part === "string";
1701  
1702              if ( isPartStr && !/\W/.test(part) ) {
1703                  part = isXML ? part : part.toUpperCase();
1704  
1705                  for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1706                      var elem = checkSet[i];
1707                      if ( elem ) {
1708                          var parent = elem.parentNode;
1709                          checkSet[i] = parent.nodeName === part ? parent : false;
1710                      }
1711                  }
1712              } else {
1713                  for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1714                      var elem = checkSet[i];
1715                      if ( elem ) {
1716                          checkSet[i] = isPartStr ?
1717                              elem.parentNode :
1718                              elem.parentNode === part;
1719                      }
1720                  }
1721  
1722                  if ( isPartStr ) {
1723                      Sizzle.filter( part, checkSet, true );
1724                  }
1725              }
1726          },
1727          "": function(checkSet, part, isXML){
1728              var doneName = done++, checkFn = dirCheck;
1729  
1730              if ( !part.match(/\W/) ) {
1731                  var nodeCheck = part = isXML ? part : part.toUpperCase();
1732                  checkFn = dirNodeCheck;
1733              }
1734  
1735              checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
1736          },
1737          "~": function(checkSet, part, isXML){
1738              var doneName = done++, checkFn = dirCheck;
1739  
1740              if ( typeof part === "string" && !part.match(/\W/) ) {
1741                  var nodeCheck = part = isXML ? part : part.toUpperCase();
1742                  checkFn = dirNodeCheck;
1743              }
1744  
1745              checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
1746          }
1747      },
1748      find: {
1749          ID: function(match, context, isXML){
1750              if ( typeof context.getElementById !== "undefined" && !isXML ) {
1751                  var m = context.getElementById(match[1]);
1752                  return m ? [m] : [];
1753              }
1754          },
1755          NAME: function(match, context, isXML){
1756              if ( typeof context.getElementsByName !== "undefined" ) {
1757                  var ret = [], results = context.getElementsByName(match[1]);
1758  
1759                  for ( var i = 0, l = results.length; i < l; i++ ) {
1760                      if ( results[i].getAttribute("name") === match[1] ) {
1761                          ret.push( results[i] );
1762                      }
1763                  }
1764  
1765                  return ret.length === 0 ? null : ret;
1766              }
1767          },
1768          TAG: function(match, context){
1769              return context.getElementsByTagName(match[1]);
1770          }
1771      },
1772      preFilter: {
1773          CLASS: function(match, curLoop, inplace, result, not, isXML){
1774              match = " " + match[1].replace(/\\/g, "") + " ";
1775  
1776              if ( isXML ) {
1777                  return match;
1778              }
1779  
1780              for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
1781                  if ( elem ) {
1782                      if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
1783                          if ( !inplace )
1784                              result.push( elem );
1785                      } else if ( inplace ) {
1786                          curLoop[i] = false;
1787                      }
1788                  }
1789              }
1790  
1791              return false;
1792          },
1793          ID: function(match){
1794              return match[1].replace(/\\/g, "");
1795          },
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();
1799          },
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]);
1806  
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;
1810              }
1811  
1812              // TODO: Move to normal caching system

1813              match[0] = done++;
1814  
1815              return match;
1816          },
1817          ATTR: function(match, curLoop, inplace, result, not, isXML){
1818              var name = match[1].replace(/\\/g, "");
1819              
1820              if ( !isXML && Expr.attrMap[name] ) {
1821                  match[1] = Expr.attrMap[name];
1822              }
1823  
1824              if ( match[2] === "~=" ) {
1825                  match[4] = " " + match[4] + " ";
1826              }
1827  
1828              return match;
1829          },
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);
1835                  } else {
1836                      var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
1837                      if ( !inplace ) {
1838                          result.push.apply( result, ret );
1839                      }
1840                      return false;
1841                  }
1842              } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
1843                  return true;
1844              }
1845              
1846              return match;
1847          },
1848          POS: function(match){
1849              match.unshift( true );
1850              return match;
1851          }
1852      },
1853      filters: {
1854          enabled: function(elem){
1855              return elem.disabled === false && elem.type !== "hidden";
1856          },
1857          disabled: function(elem){
1858              return elem.disabled === true;
1859          },
1860          checked: function(elem){
1861              return elem.checked === true;
1862          },
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;
1868          },
1869          parent: function(elem){
1870              return !!elem.firstChild;
1871          },
1872          empty: function(elem){
1873              return !elem.firstChild;
1874          },
1875          has: function(elem, i, match){
1876              return !!Sizzle( match[3], elem ).length;
1877          },
1878          header: function(elem){
1879              return /h\d/i.test( elem.nodeName );
1880          },
1881          text: function(elem){
1882              return "text" === elem.type;
1883          },
1884          radio: function(elem){
1885              return "radio" === elem.type;
1886          },
1887          checkbox: function(elem){
1888              return "checkbox" === elem.type;
1889          },
1890          file: function(elem){
1891              return "file" === elem.type;
1892          },
1893          password: function(elem){
1894              return "password" === elem.type;
1895          },
1896          submit: function(elem){
1897              return "submit" === elem.type;
1898          },
1899          image: function(elem){
1900              return "image" === elem.type;
1901          },
1902          reset: function(elem){
1903              return "reset" === elem.type;
1904          },
1905          button: function(elem){
1906              return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
1907          },
1908          input: function(elem){
1909              return /input|select|textarea|button/i.test(elem.nodeName);
1910          }
1911      },
1912      setFilters: {
1913          first: function(elem, i){
1914              return i === 0;
1915          },
1916          last: function(elem, i, match, array){
1917              return i === array.length - 1;
1918          },
1919          even: function(elem, i){
1920              return i % 2 === 0;
1921          },
1922          odd: function(elem, i){
1923              return i % 2 === 1;
1924          },
1925          lt: function(elem, i, match){
1926              return i < match[3] - 0;
1927          },
1928          gt: function(elem, i, match){
1929              return i > match[3] - 0;
1930          },
1931          nth: function(elem, i, match){
1932              return match[3] - 0 == i;
1933          },
1934          eq: function(elem, i, match){
1935              return match[3] - 0 == i;
1936          }
1937      },
1938      filter: {
1939          PSEUDO: function(elem, match, i, array){
1940              var name = match[1], filter = Expr.filters[ name ];
1941  
1942              if ( filter ) {
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" ) {
1947                  var not = match[3];
1948  
1949                  for ( var i = 0, l = not.length; i < l; i++ ) {
1950                      if ( not[i] === elem ) {
1951                          return false;
1952                      }
1953                  }
1954  
1955                  return true;
1956              }
1957          },
1958          CHILD: function(elem, match){
1959              var type = match[1], node = elem;
1960              switch (type) {
1961                  case 'only':
1962                  case 'first':
1963                      while (node = node.previousSibling)  {
1964                          if ( node.nodeType === 1 ) return false;
1965                      }
1966                      if ( type == 'first') return true;
1967                      node = elem;
1968                  case 'last':
1969                      while (node = node.nextSibling)  {
1970                          if ( node.nodeType === 1 ) return false;
1971                      }
1972                      return true;
1973                  case 'nth':
1974                      var first = match[2], last = match[3];
1975  
1976                      if ( first == 1 && last == 0 ) {
1977                          return true;
1978                      }
1979                      
1980                      var doneName = match[0],
1981                          parent = elem.parentNode;
1982      
1983                      if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
1984                          var count = 0;
1985                          for ( node = parent.firstChild; node; node = node.nextSibling ) {
1986                              if ( node.nodeType === 1 ) {
1987                                  node.nodeIndex = ++count;
1988                              }
1989                          } 
1990                          parent.sizcache = doneName;
1991                      }
1992                      
1993                      var diff = elem.nodeIndex - last;
1994                      if ( first == 0 ) {
1995                          return diff == 0;
1996                      } else {
1997                          return ( diff % first == 0 && diff / first >= 0 );
1998                      }
1999              }
2000          },
2001          ID: function(elem, match){
2002              return elem.nodeType === 1 && elem.getAttribute("id") === match;
2003          },
2004          TAG: function(elem, match){
2005              return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
2006          },
2007          CLASS: function(elem, match){
2008              return (" " + (elem.className || elem.getAttribute("class")) + " ")
2009                  .indexOf( match ) > -1;
2010          },
2011          ATTR: function(elem, match){
2012              var name = match[1],
2013                  result = Expr.attrHandle[ name ] ?
2014                      Expr.attrHandle[ name ]( elem ) :
2015                      elem[ name ] != null ?
2016                          elem[ name ] :
2017                          elem.getAttribute( name ),
2018                  value = result + "",
2019                  type = match[2],
2020                  check = match[4];
2021  
2022              return result == null ?
2023                  type === "!=" :
2024                  type === "=" ?
2025                  value === check :
2026                  type === "*=" ?
2027                  value.indexOf(check) >= 0 :
2028                  type === "~=" ?
2029                  (" " + value + " ").indexOf(check) >= 0 :
2030                  !check ?
2031                  value && result !== false :
2032                  type === "!=" ?
2033                  value != check :
2034                  type === "^=" ?
2035                  value.indexOf(check) === 0 :
2036                  type === "$=" ?
2037                  value.substr(value.length - check.length) === check :
2038                  type === "|=" ?
2039                  value === check || value.substr(0, check.length + 1) === check + "-" :
2040                  false;
2041          },
2042          POS: function(elem, match, i, array){
2043              var name = match[2], filter = Expr.setFilters[ name ];
2044  
2045              if ( filter ) {
2046                  return filter( elem, i, match, array );
2047              }
2048          }
2049      }
2050  };
2051  
2052  var origPOS = Expr.match.POS;
2053  
2054  for ( var type in Expr.match ) {
2055      Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
2056  }
2057  
2058  var makeArray = function(array, results) {
2059      array = Array.prototype.slice.call( array );
2060  
2061      if ( results ) {
2062          results.push.apply( results, array );
2063          return results;
2064      }
2065      
2066      return array;
2067  };
2068  
2069  // Perform a simple check to determine if the browser is capable of

2070  // converting a NodeList to an array using builtin methods.

2071  try {
2072      Array.prototype.slice.call( document.documentElement.childNodes );
2073  
2074  // Provide a fallback method if it does not work

2075  } catch(e){
2076      makeArray = function(array, results) {
2077          var ret = results || [];
2078  
2079          if ( toString.call(array) === "[object Array]" ) {
2080              Array.prototype.push.apply( ret, array );
2081          } else {
2082              if ( typeof array.length === "number" ) {
2083                  for ( var i = 0, l = array.length; i < l; i++ ) {
2084                      ret.push( array[i] );
2085                  }
2086              } else {
2087                  for ( var i = 0; array[i]; i++ ) {
2088                      ret.push( array[i] );
2089                  }
2090              }
2091          }
2092  
2093          return ret;
2094      };
2095  }
2096  
2097  var sortOrder;
2098  
2099  if ( document.documentElement.compareDocumentPosition ) {
2100      sortOrder = function( a, b ) {
2101          var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
2102          if ( ret === 0 ) {
2103              hasDuplicate = true;
2104          }
2105          return ret;
2106      };
2107  } else if ( "sourceIndex" in document.documentElement ) {
2108      sortOrder = function( a, b ) {
2109          var ret = a.sourceIndex - b.sourceIndex;
2110          if ( ret === 0 ) {
2111              hasDuplicate = true;
2112          }
2113          return ret;
2114      };
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);
2123          if ( ret === 0 ) {
2124              hasDuplicate = true;
2125          }
2126          return ret;
2127      };
2128  }
2129  
2130  // Check to see if the browser returns elements by name when

2131  // querying by getElementById (and provide a workaround)

2132  (function(){
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 + "'/>";
2137  
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 );
2141  
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 : [];
2149              }
2150          };
2151  
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;
2155          };
2156      }
2157  
2158      root.removeChild( form );
2159  })();
2160  
2161  (function(){
2162      // Check to see if the browser returns only elements

2163      // when doing getElementsByTagName("*")

2164  
2165      // Create a fake element

2166      var div = document.createElement("div");
2167      div.appendChild( document.createComment("") );
2168  
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]);
2173  
2174              // Filter out possible comments

2175              if ( match[1] === "*" ) {
2176                  var tmp = [];
2177  
2178                  for ( var i = 0; results[i]; i++ ) {
2179                      if ( results[i].nodeType === 1 ) {
2180                          tmp.push( results[i] );
2181                      }
2182                  }
2183  
2184                  results = tmp;
2185              }
2186  
2187              return results;
2188          };
2189      }
2190  
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);
2197          };
2198      }
2199  })();
2200  
2201  if ( document.querySelectorAll ) (function(){
2202      var oldSizzle = Sizzle, div = document.createElement("div");
2203      div.innerHTML = "<p class='TEST'></p>";
2204  
2205      // Safari can't handle uppercase or unicode characters when

2206      // in quirks mode.

2207      if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
2208          return;
2209      }
2210      
2211      Sizzle = function(query, context, extra, seed){
2212          context = context || document;
2213  
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) ) {
2217              try {
2218                  return makeArray( context.querySelectorAll(query), extra );
2219              } catch(e){}
2220          }
2221          
2222          return oldSizzle(query, context, extra, seed);
2223      };
2224  
2225      Sizzle.find = oldSizzle.find;
2226      Sizzle.filter = oldSizzle.filter;
2227      Sizzle.selectors = oldSizzle.selectors;
2228      Sizzle.matches = oldSizzle.matches;
2229  })();
2230  
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>";
2234  
2235      // Opera can't find a second classname (in 9.6)

2236      if ( div.getElementsByClassName("e").length === 0 )
2237          return;
2238  
2239      // Safari caches class attributes, doesn't catch changes (in 3.2)

2240      div.lastChild.className = "e";
2241  
2242      if ( div.getElementsByClassName("e").length === 1 )
2243          return;
2244  
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]);
2249          }
2250      };
2251  })();
2252  
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];
2257          if ( elem ) {
2258              if ( sibDir && elem.nodeType === 1 ){
2259                  elem.sizcache = doneName;
2260                  elem.sizset = i;
2261              }
2262              elem = elem[dir];
2263              var match = false;
2264  
2265              while ( elem ) {
2266                  if ( elem.sizcache === doneName ) {
2267                      match = checkSet[elem.sizset];
2268                      break;
2269                  }
2270  
2271                  if ( elem.nodeType === 1 && !isXML ){
2272                      elem.sizcache = doneName;
2273                      elem.sizset = i;
2274                  }
2275  
2276                  if ( elem.nodeName === cur ) {
2277                      match = elem;
2278                      break;
2279                  }
2280  
2281                  elem = elem[dir];
2282              }
2283  
2284              checkSet[i] = match;
2285          }
2286      }
2287  }
2288  
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];
2293          if ( elem ) {
2294              if ( sibDir && elem.nodeType === 1 ) {
2295                  elem.sizcache = doneName;
2296                  elem.sizset = i;
2297              }
2298              elem = elem[dir];
2299              var match = false;
2300  
2301              while ( elem ) {
2302                  if ( elem.sizcache === doneName ) {
2303                      match = checkSet[elem.sizset];
2304                      break;
2305                  }
2306  
2307                  if ( elem.nodeType === 1 ) {
2308                      if ( !isXML ) {
2309                          elem.sizcache = doneName;
2310                          elem.sizset = i;
2311                      }
2312                      if ( typeof cur !== "string" ) {
2313                          if ( elem === cur ) {
2314                              match = true;
2315                              break;
2316                          }
2317  
2318                      } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
2319                          match = elem;
2320                          break;
2321                      }
2322                  }
2323  
2324                  elem = elem[dir];
2325              }
2326  
2327              checkSet[i] = match;
2328          }
2329      }
2330  }
2331  
2332  var contains = document.compareDocumentPosition ?  function(a, b){
2333      return a.compareDocumentPosition(b) & 16;
2334  } : function(a, b){
2335      return a !== b && (a.contains ? a.contains(b) : true);
2336  };
2337  
2338  var isXML = function(elem){
2339      return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
2340          !!elem.ownerDocument && isXML( elem.ownerDocument );
2341  };
2342  
2343  var posProcess = function(selector, context){
2344      var tmpSet = [], later = "", match,
2345          root = context.nodeType ? [context] : context;
2346  
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 )) ) {
2350          later += match[0];
2351          selector = selector.replace( Expr.match.PSEUDO, "" );
2352      }
2353  
2354      selector = Expr.relative[selector] ? selector + "*" : selector;
2355  
2356      for ( var i = 0, l = root.length; i < l; i++ ) {
2357          Sizzle( selector, root[i], tmpSet );
2358      }
2359  
2360      return Sizzle.filter( later, tmpSet );
2361  };
2362  
2363  // EXPOSE

2364  jQuery.find = Sizzle;
2365  jQuery.filter = Sizzle.filter;
2366  jQuery.expr = Sizzle.selectors;
2367  jQuery.expr[":"] = jQuery.expr.filters;
2368  
2369  Sizzle.selectors.filters.hidden = function(elem){
2370      return elem.offsetWidth === 0 || elem.offsetHeight === 0;
2371  };
2372  
2373  Sizzle.selectors.filters.visible = function(elem){
2374      return elem.offsetWidth > 0 || elem.offsetHeight > 0;
2375  };
2376  
2377  Sizzle.selectors.filters.animated = function(elem){
2378      return jQuery.grep(jQuery.timers, function(fn){
2379          return elem === fn.elem;
2380      }).length;
2381  };
2382  
2383  jQuery.multiFilter = function( expr, elems, not ) {
2384      if ( not ) {
2385          expr = ":not(" + expr + ")";
2386      }
2387  
2388      return Sizzle.matches(expr, elems);
2389  };
2390  
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 );
2396          cur = cur[dir];
2397      }
2398      return matched;
2399  };
2400  
2401  jQuery.nth = function(cur, result, dir, elem){
2402      result = result || 1;
2403      var num = 0;
2404  
2405      for ( ; cur; cur = cur[dir] )
2406          if ( cur.nodeType == 1 && ++num == result )
2407              break;
2408  
2409      return cur;
2410  };
2411  
2412  jQuery.sibling = function(n, elem){
2413      var r = [];
2414  
2415      for ( ; n; n = n.nextSibling ) {
2416          if ( n.nodeType == 1 && n != elem )
2417              r.push( n );
2418      }
2419  
2420      return r;
2421  };
2422  
2423  return;
2424  
2425  window.Sizzle = Sizzle;
2426  
2427  })();
2428  /*

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.

2432   */
2433  jQuery.event = {
2434  
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 )
2439              return;
2440  
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 )
2444              elem = window;
2445  
2446          // Make sure that the function being executed has a unique ID

2447          if ( !handler.guid )
2448              handler.guid = this.guid++;
2449  
2450          // if data is passed, bind to handler

2451          if ( data !== undefined ) {
2452              // Create temporary function pointer to original handler

2453              var fn = handler;
2454  
2455              // Create unique handler function, wrapped around original handler

2456              handler = this.proxy( fn );
2457  
2458              // Store data in unique handler

2459              handler.data = data;
2460          }
2461  
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) :
2469                      undefined;
2470              });
2471          // Add elem as a property of the handle function

2472          // This is to prevent a memory leak with non-native

2473          // event in IE.

2474          handle.elem = elem;
2475  
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(".");
2483  
2484              // Get the current list of functions bound to this event

2485              var handlers = events[type];
2486              
2487              if ( jQuery.event.specialAll[type] )
2488                  jQuery.event.specialAll[type].setup.call(elem, data, namespaces);
2489  
2490              // Init the event handler queue

2491              if (!handlers) {
2492                  handlers = events[type] = {};
2493  
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);
2503                  }
2504              }
2505  
2506              // Add the function to the element's handler list

2507              handlers[handler.guid] = handler;
2508  
2509              // Keep track of which events have been used, for global triggering

2510              jQuery.event.global[type] = true;
2511          });
2512  
2513          // Nullify elem to prevent memory leaks in IE

2514          elem = null;
2515      },
2516  
2517      guid: 1,
2518      global: {},
2519  
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 )
2524              return;
2525  
2526          var events = jQuery.data(elem, "events"), ret, index;
2527  
2528          if ( events ) {
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 || "") );
2533              else {
2534                  // types is actually an event object here

2535                  if ( types.type ) {
2536                      handler = types.handler;
2537                      types = types.type;
2538                  }
2539  
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(".*\\.") + "(\\.|$)");
2547  
2548                      if ( events[type] ) {
2549                          // remove the given handler for the given type

2550                          if ( handler )
2551                              delete events[type][handler.guid];
2552  
2553                          // remove all handlers for the given type

2554                          else
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];
2559                                      
2560                          if ( jQuery.event.specialAll[type] )
2561                              jQuery.event.specialAll[type].teardown.call(elem, namespaces);
2562  
2563                          // remove generic event handler if no more handlers exist

2564                          for ( ret in events[type] ) break;
2565                          if ( !ret ) {
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"));
2571                              }
2572                              ret = null;
2573                              delete events[type];
2574                          }
2575                      }
2576                  });
2577              }
2578  
2579              // Remove the expando if it's no longer used

2580              for ( ret in events ) break;
2581              if ( !ret ) {
2582                  var handle = jQuery.data( elem, "handle" );
2583                  if ( handle ) handle.elem = null;
2584                  jQuery.removeData( elem, "events" );
2585                  jQuery.removeData( elem, "handle" );
2586              }
2587          }
2588      },
2589  
2590      // bubbling is internal

2591      trigger: function( event, data, elem, bubbling ) {
2592          // Event object or event type

2593          var type = event.type || event;
2594  
2595          if( !bubbling ){
2596              event = typeof event === "object" ?
2597                  // jQuery.Event object

2598                  event[expando] ? event :
2599                  // Object literal

2600                  jQuery.extend( jQuery.Event(type), event ) :
2601                  // Just the event type (string)

2602                  jQuery.Event(type);
2603  
2604              if ( type.indexOf("!") >= 0 ) {
2605                  event.type = type = type.slice(0, -1);
2606                  event.exclusive = true;
2607              }
2608  
2609              // Handle a global trigger

2610              if ( !elem ) {
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 );
2618                      });
2619              }
2620  
2621              // Handle triggering a single element

2622  
2623              // don't do events on text and comment nodes

2624              if ( !elem || elem.nodeType == 3 || elem.nodeType == 8 )
2625                  return undefined;
2626              
2627              // Clean up in case it is reused

2628              event.result = undefined;
2629              event.target = elem;
2630              
2631              // Clone the incoming data, if any

2632              data = jQuery.makeArray(data);
2633              data.unshift( event );
2634          }
2635  
2636          event.currentTarget = elem;
2637  
2638          // Trigger the event, it is assumed that "handle" is a function

2639          var handle = jQuery.data(elem, "handle");
2640          if ( handle )
2641              handle.apply( elem, data );
2642  
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;
2646  
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;
2650              try {
2651                  elem[ type ]();
2652              // prevent IE from throwing an error for some hidden elements

2653              } catch (e) {}
2654          }
2655  
2656          this.triggered = false;
2657  
2658          if ( !event.isPropagationStopped() ) {
2659              var parent = elem.parentNode || elem.ownerDocument;
2660              if ( parent )
2661                  jQuery.event.trigger(event, data, parent, true);
2662          }
2663      },
2664  
2665      handle: function(event) {
2666          // returned undefined or false

2667          var all, handlers;
2668  
2669          event = arguments[0] = jQuery.event.fix( event || window.event );
2670          event.currentTarget = this;
2671          
2672          // Namespaced event handlers

2673          var namespaces = event.type.split(".");
2674          event.type = namespaces.shift();
2675  
2676          // Cache this now, all = true means, any handler

2677          all = !namespaces.length && !event.exclusive;
2678          
2679          var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
2680  
2681          handlers = ( jQuery.data(this, "events") || {} )[event.type];
2682  
2683          for ( var j in handlers ) {
2684              var handler = handlers[j];
2685  
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;
2692  
2693                  var ret = handler.apply(this, arguments);
2694  
2695                  if( ret !== undefined ){
2696                      event.result = ret;
2697                      if ( ret === false ) {
2698                          event.preventDefault();
2699                          event.stopPropagation();
2700                      }
2701                  }
2702  
2703                  if( event.isImmediatePropagationStopped() )
2704                      break;
2705  
2706              }
2707          }
2708      },
2709  
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(" "),
2711  
2712      fix: function(event) {
2713          if ( event[expando] )
2714              return event;
2715  
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 );
2720  
2721          for ( var i = this.props.length, prop; i; ){
2722              prop = this.props[ --i ];
2723              event[ prop ] = originalEvent[ prop ];
2724          }
2725  
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

2729  
2730          // check if target is a textnode (safari)

2731          if ( event.target.nodeType == 3 )
2732              event.target = event.target.parentNode;
2733  
2734          // Add relatedTarget, if necessary

2735          if ( !event.relatedTarget && event.fromElement )
2736              event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
2737  
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);
2743          }
2744  
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;
2748  
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;
2752  
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 ) ));
2757  
2758          return event;
2759      },
2760  
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

2766          return proxy;
2767      },
2768  
2769      special: {
2770          ready: {
2771              // Make sure the ready event is setup

2772              setup: bindReady,
2773              teardown: function() {}
2774          }
2775      },
2776      
2777      specialAll: {
2778          live: {
2779              setup: function( selector, namespaces ){
2780                  jQuery.event.add( this, namespaces[0], liveHandler );
2781              },
2782              teardown:  function( namespaces ){
2783                  if ( namespaces.length ) {
2784                      var remove = 0, name = RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
2785                      
2786                      jQuery.each( (jQuery.data(this, "events").live || {}), function(){
2787                          if ( name.test(this.type) )
2788                              remove++;
2789                      });
2790                      
2791                      if ( remove < 1 )
2792                          jQuery.event.remove( this, namespaces[0], liveHandler );
2793                  }
2794              }
2795          }
2796      }
2797  };
2798  
2799  jQuery.Event = function( src ){
2800      // Allow instantiation without the 'new' keyword

2801      if( !this.preventDefault )
2802          return new jQuery.Event(src);
2803      
2804      // Event object

2805      if( src && src.type ){
2806          this.originalEvent = src;
2807          this.type = src.type;
2808      // Event type

2809      }else
2810          this.type = src;
2811  
2812      // timeStamp is buggy for some events on Firefox(#3843)

2813      // So we won't rely on the native value

2814      this.timeStamp = now();
2815      
2816      // Mark it as fixed

2817      this[expando] = true;
2818  };
2819  
2820  function returnFalse(){
2821      return false;
2822  }
2823  function returnTrue(){
2824      return true;
2825  }
2826  
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;
2832  
2833          var e = this.originalEvent;
2834          if( !e )
2835              return;
2836          // if preventDefault exists run it on the original event

2837          if (e.preventDefault)
2838              e.preventDefault();
2839          // otherwise set the returnValue property of the original event to false (IE)

2840          e.returnValue = false;
2841      },
2842      stopPropagation: function() {
2843          this.isPropagationStopped = returnTrue;
2844  
2845          var e = this.originalEvent;
2846          if( !e )
2847              return;
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;
2853      },
2854      stopImmediatePropagation:function(){
2855          this.isImmediatePropagationStopped = returnTrue;
2856          this.stopPropagation();
2857      },
2858      isDefaultPrevented: returnFalse,
2859      isPropagationStopped: returnFalse,
2860      isImmediatePropagationStopped: returnFalse
2861  };
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; }
2871      
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 );
2877      }
2878  };
2879      
2880  jQuery.each({ 
2881      mouseover: 'mouseenter', 
2882      mouseout: 'mouseleave'
2883  }, function( orig, fix ){
2884      jQuery.event.special[ fix ] = {
2885          setup: function(){
2886              jQuery.event.add( this, orig, withinElement, fix );
2887          },
2888          teardown: function(){
2889              jQuery.event.remove( this, orig, withinElement );
2890          }
2891      };               
2892  });
2893  
2894  jQuery.fn.extend({
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 );
2898          });
2899      },
2900  
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 );
2905          });
2906          return this.each(function(){
2907              jQuery.event.add( this, type, one, fn && data);
2908          });
2909      },
2910  
2911      unbind: function( type, fn ) {
2912          return this.each(function(){
2913              jQuery.event.remove( this, type, fn );
2914          });
2915      },
2916  
2917      trigger: function( type, data ) {
2918          return this.each(function(){
2919              jQuery.event.trigger( type, data, this );
2920          });
2921      },
2922  
2923      triggerHandler: function( type, data ) {
2924          if( this[0] ){
2925              var event = jQuery.Event(type);
2926              event.preventDefault();
2927              event.stopPropagation();
2928              jQuery.event.trigger( event, data, this[0] );
2929              return event.result;
2930          }        
2931      },
2932  
2933      toggle: function( fn ) {
2934          // Save reference to arguments for access in closure

2935          var args = arguments, i = 1;
2936  
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++] );
2940  
2941          return this.click( jQuery.event.proxy( fn, function(event) {
2942              // Figure out which function to execute

2943              this.lastToggle = ( this.lastToggle || 0 ) % i;
2944  
2945              // Make sure that clicks stop

2946              event.preventDefault();
2947  
2948              // and execute the function

2949              return args[ this.lastToggle++ ].apply( this, arguments ) || false;
2950          }));
2951      },
2952  
2953      hover: function(fnOver, fnOut) {
2954          return this.mouseenter(fnOver).mouseleave(fnOut);
2955      },
2956  
2957      ready: function(fn) {
2958          // Attach the listeners

2959          bindReady();
2960  
2961          // If the DOM is already ready

2962          if ( jQuery.isReady )
2963              // Execute the function immediately

2964              fn.call( document, jQuery );
2965  
2966          // Otherwise, remember the function for later

2967          else
2968              // Add the function to the wait list

2969              jQuery.readyList.push( fn );
2970  
2971          return this;
2972      },
2973      
2974      live: function( type, fn ){
2975          var proxy = jQuery.event.proxy( fn );
2976          proxy.guid += this.selector + type;
2977  
2978          jQuery(document).bind( liveConvert(type, this.selector), this.selector, proxy );
2979  
2980          return this;
2981      },
2982      
2983      die: function( type, fn ){
2984          jQuery(document).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type } : null );
2985          return this;
2986      }
2987  });
2988  
2989  function liveHandler( event ){
2990      var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"),
2991          stop = true,
2992          elems = [];
2993  
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];
2997              if ( elem )
2998                  elems.push({ elem: elem, fn: fn });
2999          }
3000      });
3001  
3002      elems.sort(function(a,b) {
3003          return jQuery.data(a.elem, "closest") - jQuery.data(b.elem, "closest");
3004      });
3005      
3006      jQuery.each(elems, function(){
3007          if ( this.fn.call(this.elem, event, this.fn.data) === false )
3008              return (stop = false);
3009      });
3010  
3011      return stop;
3012  }
3013  
3014  function liveConvert(type, selector){
3015      return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "|")].join(".");
3016  }
3017  
3018  jQuery.extend({
3019      isReady: false,
3020      readyList: [],
3021      // Handle when the DOM is ready

3022      ready: function() {
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;
3027  
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 );
3033                  });
3034  
3035                  // Reset the list of functions

3036                  jQuery.readyList = null;
3037              }
3038  
3039              // Trigger any bound ready events

3040              jQuery(document).triggerHandler("ready");
3041          }
3042      }
3043  });
3044  
3045  var readyBound = false;
3046  
3047  function bindReady(){
3048      if ( readyBound ) return;
3049      readyBound = true;
3050  
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 );
3056              jQuery.ready();
3057          }, false );
3058  
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 );
3066                  jQuery.ready();
3067              }
3068          });
3069  
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;
3074  
3075              try {
3076                  // If IE is used, use the trick by Diego Perini

3077                  // http://javascript.nwbox.com/IEContentLoaded/

3078                  document.documentElement.doScroll("left");
3079              } catch( error ) {
3080                  setTimeout( arguments.callee, 0 );
3081                  return;
3082              }
3083  
3084              // and execute any waiting functions

3085              jQuery.ready();
3086          })();
3087      }
3088  
3089      // A fallback to window.onload, that will always work

3090      jQuery.event.add( window, "load", jQuery.ready );
3091  }
3092  
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){
3096  
3097      // Handle event binding

3098      jQuery.fn[name] = function(fn){
3099          return fn ? this.bind(name, fn) : this.trigger(name);
3100      };
3101  });
3102  
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 )
3108          // Skip the window

3109          if ( id != 1 && jQuery.cache[ id ].handle )
3110              jQuery.event.remove( jQuery.cache[ id ].handle.elem );
3111  }); 
3112  (function(){
3113  
3114      jQuery.support = {};
3115  
3116      var root = document.documentElement,
3117          script = document.createElement("script"),
3118          div = document.createElement("div"),
3119          id = "script" + (new Date).getTime();
3120  
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>';
3123  
3124      var all = div.getElementsByTagName("*"),
3125          a = div.getElementsByTagName("a")[0];
3126  
3127      // Can't get basic test support

3128      if ( !all || !all.length || !a ) {
3129          return;
3130      }
3131  
3132      jQuery.support = {
3133          // IE strips leading whitespace when .innerHTML is used

3134          leadingWhitespace: div.firstChild.nodeType == 3,
3135          
3136          // Make sure that tbody elements aren't automatically inserted

3137          // IE will insert them into empty tables

3138          tbody: !div.getElementsByTagName("tbody").length,
3139          
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,
3144          
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,
3148          
3149          // Get the style information from getAttribute

3150          // (IE uses .cssText insted)

3151          style: /red/.test( a.getAttribute("style") ),
3152          
3153          // Make sure that URLs aren't manipulated

3154          // (IE normalizes it by default)

3155          hrefNormalized: a.getAttribute("href") === "/a",
3156          
3157          // Make sure that element opacity exists

3158          // (IE uses filter instead)

3159          opacity: a.style.opacity === "0.5",
3160          
3161          // Verify style float existence

3162          // (IE uses styleFloat instead of cssFloat)

3163          cssFloat: !!a.style.cssFloat,
3164  
3165          // Will be defined later

3166          scriptEval: false,
3167          noCloneEvent: true,
3168          boxModel: null
3169      };
3170      
3171      script.type = "text/javascript";
3172      try {
3173          script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
3174      } catch(e){}
3175  
3176      root.insertBefore( script, root.firstChild );
3177      
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 ];
3184      }
3185  
3186      root.removeChild( script );
3187  
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);
3194          });
3195          div.cloneNode(true).fireEvent("onclick");
3196      }
3197  
3198      // Figure out if the W3C box model works as expected

3199      // document.body must exist before we can do this

3200      jQuery(function(){
3201          var div = document.createElement("div");
3202          div.style.width = div.style.paddingLeft = "1px";
3203  
3204          document.body.appendChild( div );
3205          jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
3206          document.body.removeChild( div ).style.display = 'none';
3207      });
3208  })();
3209  
3210  var styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat";
3211  
3212  jQuery.props = {
3213      "for": "htmlFor",
3214      "class": "className",
3215      "float": styleFloat,
3216      cssFloat: styleFloat,
3217      styleFloat: styleFloat,
3218      readonly: "readOnly",
3219      maxlength: "maxLength",
3220      cellspacing: "cellSpacing",
3221      rowspan: "rowSpan",
3222      tabindex: "tabIndex"
3223  };
3224  jQuery.fn.extend({
3225      // Keep a copy of the old load

3226      _load: jQuery.fn.load,
3227  
3228      load: function( url, params, callback ) {
3229          if ( typeof url !== "string" )
3230              return this._load( url );
3231  
3232          var off = url.indexOf(" ");
3233          if ( off >= 0 ) {
3234              var selector = url.slice(off, url.length);
3235              url = url.slice(0, off);
3236          }
3237  
3238          // Default to a GET request

3239          var type = "GET";
3240  
3241          // If the second parameter was provided

3242          if ( params )
3243              // If it's a function

3244              if ( jQuery.isFunction( params ) ) {
3245                  // We assume that it's the callback

3246                  callback = params;
3247                  params = null;
3248  
3249              // Otherwise, build a param string

3250              } else if( typeof params === "object" ) {
3251                  params = jQuery.param( params );
3252                  type = "POST";
3253              }
3254  
3255          var self = this;
3256  
3257          // Request the remote document

3258          jQuery.ajax({
3259              url: url,
3260              type: type,
3261              dataType: "html",
3262              data: params,
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

3269                          jQuery("<div/>")
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, ""))
3273  
3274                              // Locate the specified elements

3275                              .find(selector) :
3276  
3277                          // If not, just inject the full result

3278                          res.responseText );
3279  
3280                  if( callback )
3281                      self.each( callback, [res.responseText, status, res] );
3282              }
3283          });
3284          return this;
3285      },
3286  
3287      serialize: function() {
3288          return jQuery.param(this.serializeArray());
3289      },
3290      serializeArray: function() {
3291          return this.map(function(){
3292              return this.elements ? jQuery.makeArray(this.elements) : this;
3293          })
3294          .filter(function(){
3295              return this.name && !this.disabled &&
3296                  (this.checked || /select|textarea/i.test(this.nodeName) ||
3297                      /text|hidden|password|search/i.test(this.type));
3298          })
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};
3305                      }) :
3306                      {name: elem.name, value: val};
3307          }).get();
3308      }
3309  });
3310  
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);
3315      };
3316  });
3317  
3318  var jsc = now();
3319  
3320  jQuery.extend({
3321    
3322      get: function( url, data, callback, type ) {
3323          // shift arguments if data argument was ommited

3324          if ( jQuery.isFunction( data ) ) {
3325              callback = data;
3326              data = null;
3327          }
3328  
3329          return jQuery.ajax({
3330              type: "GET",
3331              url: url,
3332              data: data,
3333              success: callback,
3334              dataType: type
3335          });
3336      },
3337  
3338      getScript: function( url, callback ) {
3339          return jQuery.get(url, null, callback, "script");
3340      },
3341  
3342      getJSON: function( url, data, callback ) {
3343          return jQuery.get(url, data, callback, "json");
3344      },
3345  
3346      post: function( url, data, callback, type ) {
3347          if ( jQuery.isFunction( data ) ) {
3348              callback = data;
3349              data = {};
3350          }
3351  
3352          return jQuery.ajax({
3353              type: "POST",
3354              url: url,
3355              data: data,
3356              success: callback,
3357              dataType: type
3358          });
3359      },
3360  
3361      ajaxSetup: function( settings ) {
3362          jQuery.extend( jQuery.ajaxSettings, settings );
3363      },
3364  
3365      ajaxSettings: {
3366          url: location.href,
3367          global: true,
3368          type: "GET",
3369          contentType: "application/x-www-form-urlencoded",
3370          processData: true,
3371          async: true,
3372          /*

3373          timeout: 0,

3374          data: null,

3375          username: null,

3376          password: null,

3377          */
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

3381          xhr:function(){
3382              return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
3383          },
3384          accepts: {
3385              xml: "application/xml, text/xml",
3386              html: "text/html",
3387              script: "text/javascript, application/javascript",
3388              json: "application/json, text/javascript",
3389              text: "text/plain",
3390              _default: "*/*"

3391          }

3392      },

3393  

3394      // Last-Modified header cache for next request

3395      lastModified: {},

3396  

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));

3401  

3402          var jsonp, jsre = /=\?(&|$)/g, status, data,

3403              type = s.type.toUpperCase();

3404  

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);

3408  

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";

3417          }

3418  

3419          // Build temporary JSONP function

3420          if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {

3421              jsonp = "jsonp" + jsc++;

3422  

3423              // Replace the =? sequence both in the query string and the data

3424              if ( s.data )

3425                  s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");

3426              s.url = s.url.replace(jsre, "=" + jsonp + "$1");

3427  

3428              // We need to make sure

3429              // that a JSONP style response is executed properly

3430              s.dataType = "script";

3431  

3432              // Handle JSONP-style loading

3433              window[ jsonp ] = function(tmp){

3434                  data = tmp;

3435                  success();

3436                  complete();

3437                  // Garbage collect

3438                  window[ jsonp ] = undefined;

3439                  try{ delete window[ jsonp ]; } catch(e){}

3440                  if ( head )

3441                      head.removeChild( script );

3442              };

3443          }

3444  

3445          if ( s.dataType == "script" && s.cache == null )

3446              s.cache = false;

3447  

3448          if ( s.cache === false && type == "GET" ) {

3449              var ts = now();

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 : "");

3454          }

3455  

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;

3459  

3460              // IE likes to send both get and post data, prevent this

3461              s.data = null;

3462          }

3463  

3464          // Watch for a new set of requests

3465          if ( s.global && ! jQuery.active++ )

3466              jQuery.event.trigger( "ajaxStart" );

3467  

3468          // Matches an absolute URL, and saves the domain

3469          var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec( s.url );

3470  

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 )){

3475  

3476              var head = document.getElementsByTagName("head")[0];

3477              var script = document.createElement("script");

3478              script.src = s.url;

3479              if (s.scriptCharset)

3480                  script.charset = s.scriptCharset;

3481  

3482              // Handle Script loading

3483              if ( !jsonp ) {

3484                  var done = false;

3485  

3486                  // Attach handlers for all browsers

3487                  script.onload = script.onreadystatechange = function(){

3488                      if ( !done && (!this.readyState ||

3489                              this.readyState == "loaded" || this.readyState == "complete") ) {

3490                          done = true;

3491                          success();

3492                          complete();

3493  

3494                          // Handle memory leak in IE

3495                          script.onload = script.onreadystatechange = null;

3496                          head.removeChild( script );

3497                      }

3498                  };

3499              }

3500  

3501              head.appendChild(script);

3502  

3503              // We handle everything using the script element injection

3504              return undefined;

3505          }

3506  

3507          var requestDone = false;

3508  

3509          // Create the request object

3510          var xhr = s.xhr();

3511  

3512          // Open the socket

3513          // Passing null username, generates a login popup on Opera (#2865)

3514          if( s.username )

3515              xhr.open(type, s.url, s.async, s.username, s.password);

3516          else

3517              xhr.open(type, s.url, s.async);

3518  

3519          // Need an extra try/catch for cross domain requests in Firefox 3

3520          try {

3521              // Set the correct header, if data is being sent

3522              if ( s.data )

3523                  xhr.setRequestHeader("Content-Type", s.contentType);

3524  

3525              // Set the If-Modified-Since header, if ifModified mode.

3526              if ( s.ifModified )

3527                  xhr.setRequestHeader("If-Modified-Since",

3528                      jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );

3529  

3530              // Set header so the called script knows that it's an XMLHttpRequest

3531              xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");

3532  

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 );
3537          } catch(e){}
3538  
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

3545              xhr.abort();
3546              return false;
3547          }
3548  
3549          if ( s.global )
3550              jQuery.event.trigger("ajaxSend", [xhr, s]);
3551  
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) {
3556                  if (ival) {
3557                      // clear poll interval

3558                      clearInterval(ival);
3559                      ival = null;
3560                      // Handle the global AJAX counter

3561                      if ( s.global && ! --jQuery.active )
3562                          jQuery.event.trigger( "ajaxStop" );
3563                  }
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") ) {
3566                  requestDone = true;
3567  
3568                  // clear poll interval

3569                  if (ival) {
3570                      clearInterval(ival);
3571                      ival = null;
3572                  }
3573  
3574                  status = isTimeout == "timeout" ? "timeout" :
3575                      !jQuery.httpSuccess( xhr ) ? "error" :
3576                      s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" :
3577                      "success";
3578  
3579                  if ( status == "success" ) {
3580                      // Watch for, and catch, XML document parse errors

3581                      try {
3582                          // process the data (runs the xml through httpData regardless of callback)

3583                          data = jQuery.httpData( xhr, s.dataType, s );
3584                      } catch(e) {
3585                          status = "parsererror";
3586                      }
3587                  }
3588  
3589                  // Make sure that the request was successful or notmodified

3590                  if ( status == "success" ) {
3591                      // Cache Last-Modified header, if ifModified mode.

3592                      var modRes;
3593                      try {
3594                          modRes = xhr.getResponseHeader("Last-Modified");
3595                      } catch(e) {} // swallow exception thrown by FF if header is not available

3596  
3597                      if ( s.ifModified && modRes )
3598                          jQuery.lastModified[s.url] = modRes;
3599  
3600                      // JSONP handles its own success callback

3601                      if ( !jsonp )
3602                          success();
3603                  } else
3604                      jQuery.handleError(s, xhr, status);
3605  
3606                  // Fire the complete handlers

3607                  complete();
3608  
3609                  if ( isTimeout )
3610                      xhr.abort();
3611  
3612                  // Stop memory leaks

3613                  if ( s.async )
3614                      xhr = null;
3615              }
3616          };
3617  
3618          if ( s.async ) {
3619              // don't attach the handler to the request, just poll it instead

3620              var ival = setInterval(onreadystatechange, 13);
3621  
3622              // Timeout checker

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" );
3628                  }, s.timeout);
3629          }
3630  
3631          // Send the data

3632          try {
3633              xhr.send(s.data);
3634          } catch(e) {
3635              jQuery.handleError(s, xhr, null, e);
3636          }
3637  
3638          // firefox 1.5 doesn't fire statechange for sync requests

3639          if ( !s.async )
3640              onreadystatechange();
3641  
3642  		function success(){
3643              // If a local callback was specified, fire it and pass it the data

3644              if ( s.success )
3645                  s.success( data, status );
3646  
3647              // Fire the global callback

3648              if ( s.global )
3649                  jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
3650          }
3651  
3652  		function complete(){
3653              // Process result

3654              if ( s.complete )
3655                  s.complete(xhr, status);
3656  
3657              // The request was completed

3658              if ( s.global )
3659                  jQuery.event.trigger( "ajaxComplete", [xhr, s] );
3660  
3661              // Handle the global AJAX counter

3662              if ( s.global && ! --jQuery.active )
3663                  jQuery.event.trigger( "ajaxStop" );
3664          }
3665  
3666          // return XMLHttpRequest to allow aborting the request etc.

3667          return xhr;
3668      },
3669  
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 );
3673  
3674          // Fire the global callback

3675          if ( s.global )
3676              jQuery.event.trigger( "ajaxError", [xhr, s, e] );
3677      },
3678  
3679      // Counter for holding the number of active queries

3680      active: 0,
3681  
3682      // Determines if an XMLHttpRequest was successful or not

3683      httpSuccess: function( xhr ) {
3684          try {
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;
3688          } catch(e){}
3689          return false;
3690      },
3691  
3692      // Determines if an XMLHttpRequest returns NotModified

3693      httpNotModified: function( xhr, url ) {
3694          try {
3695              var xhrRes = xhr.getResponseHeader("Last-Modified");
3696  
3697              // Firefox always returns 200. check Last-Modified date

3698              return xhr.status == 304 || xhrRes == jQuery.lastModified[url];
3699          } catch(e){}
3700          return false;
3701      },
3702  
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;
3707  
3708          if ( xml && data.documentElement.tagName == "parsererror" )
3709              throw "parsererror";
3710              
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 );
3715  
3716          // The filter can actually parse the response

3717          if( typeof data === "string" ){
3718  
3719              // If the type is "script", eval it in global context

3720              if ( type == "script" )
3721                  jQuery.globalEval( data );
3722  
3723              // Get the JavaScript object, if JSON is used.

3724              if ( type == "json" )
3725                  data = window["eval"]("(" + data + ")");
3726          }
3727          
3728          return data;
3729      },
3730  
3731      // Serialize an array of form elements or a set of

3732      // key/values into a query string

3733      param: function( a ) {
3734          var s = [ ];
3735  
3736  		function add( key, value ){
3737              s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
3738          };
3739  
3740          // If an array was passed in, assume that it is an array

3741          // of form elements

3742          if ( jQuery.isArray(a) || a.jquery )
3743              // Serialize the form elements

3744              jQuery.each( a, function(){
3745                  add( this.name, this.value );
3746              });
3747  
3748          // Otherwise, assume that it's an object of key/value pairs

3749          else
3750              // Serialize the key/values

3751              for ( var j in a )
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(){
3755                          add( j, this );
3756                      });
3757                  else
3758                      add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
3759  
3760          // Return the resulting serialization

3761          return s.join("&").replace(/%20/g, "+");
3762      }
3763  
3764  });
3765  var elemdisplay = {},
3766      timerId,
3767      fxAttrs = [
3768          // height animations

3769          [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
3770          // width animations

3771          [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
3772          // opacity animations

3773          [ "opacity" ]
3774      ];
3775  
3776  function genFx( type, num ){
3777      var obj = {};
3778      jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function(){
3779          obj[ this ] = type;
3780      });
3781      return obj;
3782  }
3783  
3784  jQuery.fn.extend({
3785      show: function(speed,callback){
3786          if ( speed ) {
3787              return this.animate( genFx("show", 3), speed, callback);
3788          } else {
3789              for ( var i = 0, l = this.length; i < l; i++ ){
3790                  var old = jQuery.data(this[i], "olddisplay");
3791                  
3792                  this[i].style.display = old || "";
3793                  
3794                  if ( jQuery.css(this[i], "display") === "none" ) {
3795                      var tagName = this[i].tagName, display;
3796                      
3797                      if ( elemdisplay[ tagName ] ) {
3798                          display = elemdisplay[ tagName ];
3799                      } else {
3800                          var elem = jQuery("<" + tagName + " />").appendTo("body");
3801                          
3802                          display = elem.css("display");
3803                          if ( display === "none" )
3804                              display = "block";
3805                          
3806                          elem.remove();
3807                          
3808                          elemdisplay[ tagName ] = display;
3809                      }
3810                      
3811                      jQuery.data(this[i], "olddisplay", display);
3812                  }
3813              }
3814  
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") || "";
3819              }
3820              
3821              return this;
3822          }
3823      },
3824  
3825      hide: function(speed,callback){
3826          if ( speed ) {
3827              return this.animate( genFx("hide", 3), speed, callback);
3828          } else {
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"));
3833              }
3834  
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";
3839              }
3840  
3841              return this;
3842          }
3843      },
3844  
3845      // Save the old toggle function

3846      _toggle: jQuery.fn.toggle,
3847  
3848      toggle: function( fn, fn2 ){
3849          var bool = typeof fn === "boolean";
3850  
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" ]();
3857                  }) :
3858                  this.animate(genFx("toggle", 3), fn, fn2);
3859      },
3860  
3861      fadeTo: function(speed,to,callback){
3862          return this.animate({opacity: to}, speed, callback);
3863      },
3864  
3865      animate: function( prop, speed, easing, callback ) {
3866          var optall = jQuery.speed(speed, easing, callback);
3867  
3868          return this[ optall.queue === false ? "each" : "queue" ](function(){
3869          
3870              var opt = jQuery.extend({}, optall), p,
3871                  hidden = this.nodeType == 1 && jQuery(this).is(":hidden"),
3872                  self = this;
3873      
3874              for ( p in prop ) {
3875                  if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
3876                      return opt.complete.call(this);
3877  
3878                  if ( ( p == "height" || p == "width" ) && this.style ) {
3879                      // Store display property

3880                      opt.display = jQuery.css(this, "display");
3881  
3882                      // Make sure that nothing sneaks out

3883                      opt.overflow = this.style.overflow;
3884                  }
3885              }
3886  
3887              if ( opt.overflow != null )
3888                  this.style.overflow = "hidden";
3889  
3890              opt.curAnim = jQuery.extend({}, prop);
3891  
3892              jQuery.each( prop, function(name, val){
3893                  var e = new jQuery.fx( self, opt, name );
3894  
3895                  if ( /toggle|show|hide/.test(val) )
3896                      e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
3897                  else {
3898                      var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
3899                          start = e.cur(true) || 0;
3900  
3901                      if ( parts ) {
3902                          var end = parseFloat(parts[2]),
3903                              unit = parts[3] || "px";
3904  
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;
3910                          }
3911  
3912                          // If a +=/-= token was provided, we're doing a relative animation

3913                          if ( parts[1] )
3914                              end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
3915  
3916                          e.custom( start, end, unit );
3917                      } else
3918                          e.custom( start, val, "" );
3919                  }
3920              });
3921  
3922              // For JS strict compliance

3923              return true;
3924          });
3925      },
3926  
3927      stop: function(clearQueue, gotoEnd){
3928          var timers = jQuery.timers;
3929  
3930          if (clearQueue)
3931              this.queue([]);
3932  
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 ) {
3937                      if (gotoEnd)
3938                          // force the next step to be the last

3939                          timers[i](true);
3940                      timers.splice(i, 1);
3941                  }
3942          });
3943  
3944          // start the next in the queue if the last step wasn't forced

3945          if (!gotoEnd)
3946              this.dequeue();
3947  
3948          return this;
3949      }
3950  
3951  });
3952  
3953  // Generate shortcuts for custom animations

3954  jQuery.each({
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 );
3963      };
3964  });
3965  
3966  jQuery.extend({
3967  
3968      speed: function(speed, easing, fn) {
3969          var opt = typeof speed === "object" ? speed : {
3970              complete: fn || !fn && easing ||
3971                  jQuery.isFunction( speed ) && speed,
3972              duration: speed,
3973              easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
3974          };
3975  
3976          opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
3977              jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
3978  
3979          // Queueing

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 );
3986          };
3987  
3988          return opt;
3989      },
3990  
3991      easing: {
3992          linear: function( p, n, firstNum, diff ) {
3993              return firstNum + diff * p;
3994          },
3995          swing: function( p, n, firstNum, diff ) {
3996              return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
3997          }
3998      },
3999  
4000      timers: [],
4001  
4002      fx: function( elem, options, prop ){
4003          this.options = options;
4004          this.elem = elem;
4005          this.prop = prop;
4006  
4007          if ( !options.orig )
4008              options.orig = {};
4009      }
4010  
4011  });
4012  
4013  jQuery.fx.prototype = {
4014  
4015      // Simple function for setting a style value

4016      update: function(){
4017          if ( this.options.step )
4018              this.options.step.call( this.elem, this.now, this );
4019  
4020          (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
4021  
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";
4025      },
4026  
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 ];
4031  
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;
4034      },
4035  
4036      // Start an animation from one number to another

4037      custom: function(from, to, unit){
4038          this.startTime = now();
4039          this.start = from;
4040          this.end = to;
4041          this.unit = unit || this.unit || "px";
4042          this.now = this.start;
4043          this.pos = this.state = 0;
4044  
4045          var self = this;
4046          function t(gotoEnd){
4047              return self.step(gotoEnd);
4048          }
4049  
4050          t.elem = this.elem;
4051  
4052          if ( t() && jQuery.timers.push(t) && !timerId ) {
4053              timerId = setInterval(function(){
4054                  var timers = jQuery.timers;
4055  
4056                  for ( var i = 0; i < timers.length; i++ )
4057                      if ( !timers[i]() )
4058                          timers.splice(i--, 1);
4059  
4060                  if ( !timers.length ) {
4061                      clearInterval( timerId );
4062                      timerId = undefined;
4063                  }
4064              }, 13);
4065          }
4066      },
4067  
4068      // Simple 'show' function

4069      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;
4073  
4074          // Begin the animation

4075          // Make sure that we start at a small width/height to avoid any

4076          // flash of content

4077          this.custom(this.prop == "width" || this.prop == "height" ? 1 : 0, this.cur());
4078  
4079          // Start by showing the element

4080          jQuery(this.elem).show();
4081      },
4082  
4083      // Simple 'hide' function

4084      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;
4088  
4089          // Begin the animation

4090          this.custom(this.cur(), 0);
4091      },
4092  
4093      // Each step of an animation

4094      step: function(gotoEnd){
4095          var t = now();
4096  
4097          if ( gotoEnd || t >= this.options.duration + this.startTime ) {
4098              this.now = this.end;
4099              this.pos = this.state = 1;
4100              this.update();
4101  
4102              this.options.curAnim[ this.prop ] = true;
4103  
4104              var done = true;
4105              for ( var i in this.options.curAnim )
4106                  if ( this.options.curAnim[i] !== true )
4107                      done = false;
4108  
4109              if ( done ) {
4110                  if ( this.options.display != null ) {
4111                      // Reset the overflow

4112                      this.elem.style.overflow = this.options.overflow;
4113  
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";
4118                  }
4119  
4120                  // Hide the element if the "hide" operation was done

4121                  if ( this.options.hide )
4122                      jQuery(this.elem).hide();
4123  
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]);
4128                      
4129                  // Execute the complete function

4130                  this.options.complete.call( this.elem );
4131              }
4132  
4133              return false;
4134          } else {
4135              var n = t - this.startTime;
4136              this.state = n / this.options.duration;
4137  
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);
4141  
4142              // Perform the next step of the animation

4143              this.update();
4144          }
4145  
4146          return true;
4147      }
4148  
4149  };
4150  
4151  jQuery.extend( jQuery.fx, {
4152      speeds:{
4153          slow: 600,
4154           fast: 200,
4155           // Default speed

4156           _default: 400
4157      },
4158      step: {
4159  
4160          opacity: function(fx){
4161              jQuery.attr(fx.elem.style, "opacity", fx.now);
4162          },
4163  
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;
4167              else
4168                  fx.elem[ fx.prop ] = fx.now;
4169          }
4170      }
4171  });
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 };
4181      };
4182  else 
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();
4187  
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;
4193  
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;
4203              }
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;
4208          }
4209  
4210          if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" )
4211              top  += body.offsetTop,
4212              left += body.offsetLeft;
4213  
4214          if ( prevComputedStyle.position === "fixed" )
4215              top  += Math.max(docElem.scrollTop, body.scrollTop),
4216              left += Math.max(docElem.scrollLeft, body.scrollLeft);
4217  
4218          return { top: top, left: left };
4219      };
4220  
4221  jQuery.offset = {
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>';
4226  
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];
4229  
4230          container.innerHTML = html;
4231          body.insertBefore(container, body.firstChild);
4232          innerDiv = container.firstChild, checkDiv = innerDiv.firstChild, td = innerDiv.nextSibling.firstChild.firstChild;
4233  
4234          this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
4235          this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
4236  
4237          innerDiv.style.overflow = 'hidden', innerDiv.style.position = 'relative';
4238          this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
4239  
4240          body.style.marginTop = '1px';
4241          this.doesNotIncludeMarginInBodyOffset = (body.offsetTop === 0);
4242          body.style.marginTop = bodyMarginTop;
4243  
4244          body.removeChild(container);
4245          this.initialized = true;
4246      },
4247  
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 };
4255      }
4256  };
4257  
4258  
4259  jQuery.fn.extend({
4260      position: function() {
4261          var left = 0, top = 0, results;
4262  
4263          if ( this[0] ) {
4264              // Get *real* offsetParent

4265              var offsetParent = this.offsetParent(),
4266  
4267              // Get correct offsets

4268              offset       = this.offset(),
4269              parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
4270  
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' );
4276  
4277              // Add offsetParent borders

4278              parentOffset.top  += num( offsetParent, 'borderTopWidth'  );
4279              parentOffset.left += num( offsetParent, 'borderLeftWidth' );
4280  
4281              // Subtract the two offsets

4282              results = {
4283                  top:  offset.top  - parentOffset.top,
4284                  left: offset.left - parentOffset.left
4285              };
4286          }
4287  
4288          return results;
4289      },
4290  
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);
4296      }
4297  });
4298  
4299  
4300  // Create scrollLeft and scrollTop methods

4301  jQuery.each( ['Left', 'Top'], function(i, name) {
4302      var method = 'scroll' + name;
4303      
4304      jQuery.fn[ method ] = function(val) {
4305          if (!this[0]) return null;
4306  
4307          return val !== undefined ?
4308  
4309              // Set the scroll offset

4310              this.each(function() {
4311                  this == window || this == document ?
4312                      window.scrollTo(
4313                          !i ? val : jQuery(window).scrollLeft(),
4314                           i ? val : jQuery(window).scrollTop()
4315                      ) :
4316                      this[ method ] = val;
4317              }) :
4318  
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 ] :
4324                  this[0][ method ];
4325      };
4326  });
4327  // Create innerHeight, innerWidth, outerHeight and outerWidth methods

4328  jQuery.each([ "Height", "Width" ], function(i, name){
4329  
4330      var tl = i ? "Left"  : "Top",  // top or left
4331          br = i ? "Right" : "Bottom", // bottom or right
4332          lower = name.toLowerCase();
4333  
4334      // innerHeight and innerWidth

4335      jQuery.fn["inner" + name] = function(){
4336          return this[0] ?
4337              jQuery.css( this[0], lower, false, "padding" ) :
4338              null;
4339      };
4340  
4341      // outerHeight and outerWidth

4342      jQuery.fn["outer" + name] = function(margin) {
4343          return this[0] ?
4344              jQuery.css( this[0], lower, false, margin ? "margin" : "border" ) :
4345              null;
4346      };
4347      
4348      var type = name.toLowerCase();
4349  
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 ] :
4356  
4357              // Get document width or height

4358              this[0] == document ?
4359                  // Either scroll[Width/Height] or offset[Width/Height], whichever is greater

4360                  Math.max(
4361                      document.documentElement["client" + name],
4362                      document.body["scroll" + name], document.documentElement["scroll" + name],
4363                      document.body["offset" + name], document.documentElement["offset" + name]
4364                  ) :
4365  
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) :
4370  
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" );
4373      };
4374  
4375  });
4376  })();


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1