[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/libraries/bootstrap/js/tests/vendor/ -> jquery.js (source)

   1  /*! jQuery v1.7.1 jquery.com | jquery.org/license */
   2  (function( window, undefined ) {
   3  
   4  // Use the correct document accordingly with window argument (sandbox)
   5  var document = window.document,
   6      navigator = window.navigator,
   7      location = window.location;
   8  var jQuery = (function() {
   9  
  10  // Define a local copy of jQuery
  11  var jQuery = function( selector, context ) {
  12          // The jQuery object is actually just the init constructor 'enhanced'
  13          return new jQuery.fn.init( selector, context, rootjQuery );
  14      },
  15  
  16      // Map over jQuery in case of overwrite
  17      _jQuery = window.jQuery,
  18  
  19      // Map over the $ in case of overwrite
  20      _$ = window.$,
  21  
  22      // A central reference to the root jQuery(document)
  23      rootjQuery,
  24  
  25      // A simple way to check for HTML strings or ID strings
  26      // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
  27      quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
  28  
  29      // Check if a string has a non-whitespace character in it
  30      rnotwhite = /\S/,
  31  
  32      // Used for trimming whitespace
  33      trimLeft = /^\s+/,
  34      trimRight = /\s+$/,
  35  
  36      // Match a standalone tag
  37      rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
  38  
  39      // JSON RegExp
  40      rvalidchars = /^[\],:{}\s]*$/,
  41      rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
  42      rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
  43      rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
  44  
  45      // Useragent RegExp
  46      rwebkit = /(webkit)[ \/]([\w.]+)/,
  47      ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
  48      rmsie = /(msie) ([\w.]+)/,
  49      rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
  50  
  51      // Matches dashed string for camelizing
  52      rdashAlpha = /-([a-z]|[0-9])/ig,
  53      rmsPrefix = /^-ms-/,
  54  
  55      // Used by jQuery.camelCase as callback to replace()
  56      fcamelCase = function( all, letter ) {
  57          return ( letter + "" ).toUpperCase();
  58      },
  59  
  60      // Keep a UserAgent string for use with jQuery.browser
  61      userAgent = navigator.userAgent,
  62  
  63      // For matching the engine and version of the browser
  64      browserMatch,
  65  
  66      // The deferred used on DOM ready
  67      readyList,
  68  
  69      // The ready event handler
  70      DOMContentLoaded,
  71  
  72      // Save a reference to some core methods
  73      toString = Object.prototype.toString,
  74      hasOwn = Object.prototype.hasOwnProperty,
  75      push = Array.prototype.push,
  76      slice = Array.prototype.slice,
  77      trim = String.prototype.trim,
  78      indexOf = Array.prototype.indexOf,
  79  
  80      // [[Class]] -> type pairs
  81      class2type = {};
  82  
  83  jQuery.fn = jQuery.prototype = {
  84      constructor: jQuery,
  85      init: function( selector, context, rootjQuery ) {
  86          var match, elem, ret, doc;
  87  
  88          // Handle $(""), $(null), or $(undefined)
  89          if ( !selector ) {
  90              return this;
  91          }
  92  
  93          // Handle $(DOMElement)
  94          if ( selector.nodeType ) {
  95              this.context = this[0] = selector;
  96              this.length = 1;
  97              return this;
  98          }
  99  
 100          // The body element only exists once, optimize finding it
 101          if ( selector === "body" && !context && document.body ) {
 102              this.context = document;
 103              this[0] = document.body;
 104              this.selector = selector;
 105              this.length = 1;
 106              return this;
 107          }
 108  
 109          // Handle HTML strings
 110          if ( typeof selector === "string" ) {
 111              // Are we dealing with HTML string or an ID?
 112              if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
 113                  // Assume that strings that start and end with <> are HTML and skip the regex check
 114                  match = [ null, selector, null ];
 115  
 116              } else {
 117                  match = quickExpr.exec( selector );
 118              }
 119  
 120              // Verify a match, and that no context was specified for #id
 121              if ( match && (match[1] || !context) ) {
 122  
 123                  // HANDLE: $(html) -> $(array)
 124                  if ( match[1] ) {
 125                      context = context instanceof jQuery ? context[0] : context;
 126                      doc = ( context ? context.ownerDocument || context : document );
 127  
 128                      // If a single string is passed in and it's a single tag
 129                      // just do a createElement and skip the rest
 130                      ret = rsingleTag.exec( selector );
 131  
 132                      if ( ret ) {
 133                          if ( jQuery.isPlainObject( context ) ) {
 134                              selector = [ document.createElement( ret[1] ) ];
 135                              jQuery.fn.attr.call( selector, context, true );
 136  
 137                          } else {
 138                              selector = [ doc.createElement( ret[1] ) ];
 139                          }
 140  
 141                      } else {
 142                          ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
 143                          selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes;
 144                      }
 145  
 146                      return jQuery.merge( this, selector );
 147  
 148                  // HANDLE: $("#id")
 149                  } else {
 150                      elem = document.getElementById( match[2] );
 151  
 152                      // Check parentNode to catch when Blackberry 4.6 returns
 153                      // nodes that are no longer in the document #6963
 154                      if ( elem && elem.parentNode ) {
 155                          // Handle the case where IE and Opera return items
 156                          // by name instead of ID
 157                          if ( elem.id !== match[2] ) {
 158                              return rootjQuery.find( selector );
 159                          }
 160  
 161                          // Otherwise, we inject the element directly into the jQuery object
 162                          this.length = 1;
 163                          this[0] = elem;
 164                      }
 165  
 166                      this.context = document;
 167                      this.selector = selector;
 168                      return this;
 169                  }
 170  
 171              // HANDLE: $(expr, $(...))
 172              } else if ( !context || context.jquery ) {
 173                  return ( context || rootjQuery ).find( selector );
 174  
 175              // HANDLE: $(expr, context)
 176              // (which is just equivalent to: $(context).find(expr)
 177              } else {
 178                  return this.constructor( context ).find( selector );
 179              }
 180  
 181          // HANDLE: $(function)
 182          // Shortcut for document ready
 183          } else if ( jQuery.isFunction( selector ) ) {
 184              return rootjQuery.ready( selector );
 185          }
 186  
 187          if ( selector.selector !== undefined ) {
 188              this.selector = selector.selector;
 189              this.context = selector.context;
 190          }
 191  
 192          return jQuery.makeArray( selector, this );
 193      },
 194  
 195      // Start with an empty selector
 196      selector: "",
 197  
 198      // The current version of jQuery being used
 199      jquery: "1.7.1",
 200  
 201      // The default length of a jQuery object is 0
 202      length: 0,
 203  
 204      // The number of elements contained in the matched element set
 205      size: function() {
 206          return this.length;
 207      },
 208  
 209      toArray: function() {
 210          return slice.call( this, 0 );
 211      },
 212  
 213      // Get the Nth element in the matched element set OR
 214      // Get the whole matched element set as a clean array
 215      get: function( num ) {
 216          return num == null ?
 217  
 218              // Return a 'clean' array
 219              this.toArray() :
 220  
 221              // Return just the object
 222              ( num < 0 ? this[ this.length + num ] : this[ num ] );
 223      },
 224  
 225      // Take an array of elements and push it onto the stack
 226      // (returning the new matched element set)
 227      pushStack: function( elems, name, selector ) {
 228          // Build a new jQuery matched element set
 229          var ret = this.constructor();
 230  
 231          if ( jQuery.isArray( elems ) ) {
 232              push.apply( ret, elems );
 233  
 234          } else {
 235              jQuery.merge( ret, elems );
 236          }
 237  
 238          // Add the old object onto the stack (as a reference)
 239          ret.prevObject = this;
 240  
 241          ret.context = this.context;
 242  
 243          if ( name === "find" ) {
 244              ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;
 245          } else if ( name ) {
 246              ret.selector = this.selector + "." + name + "(" + selector + ")";
 247          }
 248  
 249          // Return the newly-formed element set
 250          return ret;
 251      },
 252  
 253      // Execute a callback for every element in the matched set.
 254      // (You can seed the arguments with an array of args, but this is
 255      // only used internally.)
 256      each: function( callback, args ) {
 257          return jQuery.each( this, callback, args );
 258      },
 259  
 260      ready: function( fn ) {
 261          // Attach the listeners
 262          jQuery.bindReady();
 263  
 264          // Add the callback
 265          readyList.add( fn );
 266  
 267          return this;
 268      },
 269  
 270      eq: function( i ) {
 271          i = +i;
 272          return i === -1 ?
 273              this.slice( i ) :
 274              this.slice( i, i + 1 );
 275      },
 276  
 277      first: function() {
 278          return this.eq( 0 );
 279      },
 280  
 281      last: function() {
 282          return this.eq( -1 );
 283      },
 284  
 285      slice: function() {
 286          return this.pushStack( slice.apply( this, arguments ),
 287              "slice", slice.call(arguments).join(",") );
 288      },
 289  
 290      map: function( callback ) {
 291          return this.pushStack( jQuery.map(this, function( elem, i ) {
 292              return callback.call( elem, i, elem );
 293          }));
 294      },
 295  
 296      end: function() {
 297          return this.prevObject || this.constructor(null);
 298      },
 299  
 300      // For internal use only.
 301      // Behaves like an Array's method, not like a jQuery method.
 302      push: push,
 303      sort: [].sort,
 304      splice: [].splice
 305  };
 306  
 307  // Give the init function the jQuery prototype for later instantiation
 308  jQuery.fn.init.prototype = jQuery.fn;
 309  
 310  jQuery.extend = jQuery.fn.extend = function() {
 311      var options, name, src, copy, copyIsArray, clone,
 312          target = arguments[0] || {},
 313          i = 1,
 314          length = arguments.length,
 315          deep = false;
 316  
 317      // Handle a deep copy situation
 318      if ( typeof target === "boolean" ) {
 319          deep = target;
 320          target = arguments[1] || {};
 321          // skip the boolean and the target
 322          i = 2;
 323      }
 324  
 325      // Handle case when target is a string or something (possible in deep copy)
 326      if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
 327          target = {};
 328      }
 329  
 330      // extend jQuery itself if only one argument is passed
 331      if ( length === i ) {
 332          target = this;
 333          --i;
 334      }
 335  
 336      for ( ; i < length; i++ ) {
 337          // Only deal with non-null/undefined values
 338          if ( (options = arguments[ i ]) != null ) {
 339              // Extend the base object
 340              for ( name in options ) {
 341                  src = target[ name ];
 342                  copy = options[ name ];
 343  
 344                  // Prevent never-ending loop
 345                  if ( target === copy ) {
 346                      continue;
 347                  }
 348  
 349                  // Recurse if we're merging plain objects or arrays
 350                  if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
 351                      if ( copyIsArray ) {
 352                          copyIsArray = false;
 353                          clone = src && jQuery.isArray(src) ? src : [];
 354  
 355                      } else {
 356                          clone = src && jQuery.isPlainObject(src) ? src : {};
 357                      }
 358  
 359                      // Never move original objects, clone them
 360                      target[ name ] = jQuery.extend( deep, clone, copy );
 361  
 362                  // Don't bring in undefined values
 363                  } else if ( copy !== undefined ) {
 364                      target[ name ] = copy;
 365                  }
 366              }
 367          }
 368      }
 369  
 370      // Return the modified object
 371      return target;
 372  };
 373  
 374  jQuery.extend({
 375      noConflict: function( deep ) {
 376          if ( window.$ === jQuery ) {
 377              window.$ = _$;
 378          }
 379  
 380          if ( deep && window.jQuery === jQuery ) {
 381              window.jQuery = _jQuery;
 382          }
 383  
 384          return jQuery;
 385      },
 386  
 387      // Is the DOM ready to be used? Set to true once it occurs.
 388      isReady: false,
 389  
 390      // A counter to track how many items to wait for before
 391      // the ready event fires. See #6781
 392      readyWait: 1,
 393  
 394      // Hold (or release) the ready event
 395      holdReady: function( hold ) {
 396          if ( hold ) {
 397              jQuery.readyWait++;
 398          } else {
 399              jQuery.ready( true );
 400          }
 401      },
 402  
 403      // Handle when the DOM is ready
 404      ready: function( wait ) {
 405          // Either a released hold or an DOMready/load event and not yet ready
 406          if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
 407              // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
 408              if ( !document.body ) {
 409                  return setTimeout( jQuery.ready, 1 );
 410              }
 411  
 412              // Remember that the DOM is ready
 413              jQuery.isReady = true;
 414  
 415              // If a normal DOM Ready event fired, decrement, and wait if need be
 416              if ( wait !== true && --jQuery.readyWait > 0 ) {
 417                  return;
 418              }
 419  
 420              // If there are functions bound, to execute
 421              readyList.fireWith( document, [ jQuery ] );
 422  
 423              // Trigger any bound ready events
 424              if ( jQuery.fn.trigger ) {
 425                  jQuery( document ).trigger( "ready" ).off( "ready" );
 426              }
 427          }
 428      },
 429  
 430      bindReady: function() {
 431          if ( readyList ) {
 432              return;
 433          }
 434  
 435          readyList = jQuery.Callbacks( "once memory" );
 436  
 437          // Catch cases where $(document).ready() is called after the
 438          // browser event has already occurred.
 439          if ( document.readyState === "complete" ) {
 440              // Handle it asynchronously to allow scripts the opportunity to delay ready
 441              return setTimeout( jQuery.ready, 1 );
 442          }
 443  
 444          // Mozilla, Opera and webkit nightlies currently support this event
 445          if ( document.addEventListener ) {
 446              // Use the handy event callback
 447              document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
 448  
 449              // A fallback to window.onload, that will always work
 450              window.addEventListener( "load", jQuery.ready, false );
 451  
 452          // If IE event model is used
 453          } else if ( document.attachEvent ) {
 454              // ensure firing before onload,
 455              // maybe late but safe also for iframes
 456              document.attachEvent( "onreadystatechange", DOMContentLoaded );
 457  
 458              // A fallback to window.onload, that will always work
 459              window.attachEvent( "onload", jQuery.ready );
 460  
 461              // If IE and not a frame
 462              // continually check to see if the document is ready
 463              var toplevel = false;
 464  
 465              try {
 466                  toplevel = window.frameElement == null;
 467              } catch(e) {}
 468  
 469              if ( document.documentElement.doScroll && toplevel ) {
 470                  doScrollCheck();
 471              }
 472          }
 473      },
 474  
 475      // See test/unit/core.js for details concerning isFunction.
 476      // Since version 1.3, DOM methods and functions like alert
 477      // aren't supported. They return false on IE (#2968).
 478      isFunction: function( obj ) {
 479          return jQuery.type(obj) === "function";
 480      },
 481  
 482      isArray: Array.isArray || function( obj ) {
 483          return jQuery.type(obj) === "array";
 484      },
 485  
 486      // A crude way of determining if an object is a window
 487      isWindow: function( obj ) {
 488          return obj && typeof obj === "object" && "setInterval" in obj;
 489      },
 490  
 491      isNumeric: function( obj ) {
 492          return !isNaN( parseFloat(obj) ) && isFinite( obj );
 493      },
 494  
 495      type: function( obj ) {
 496          return obj == null ?
 497              String( obj ) :
 498              class2type[ toString.call(obj) ] || "object";
 499      },
 500  
 501      isPlainObject: function( obj ) {
 502          // Must be an Object.
 503          // Because of IE, we also have to check the presence of the constructor property.
 504          // Make sure that DOM nodes and window objects don't pass through, as well
 505          if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
 506              return false;
 507          }
 508  
 509          try {
 510              // Not own constructor property must be Object
 511              if ( obj.constructor &&
 512                  !hasOwn.call(obj, "constructor") &&
 513                  !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
 514                  return false;
 515              }
 516          } catch ( e ) {
 517              // IE8,9 Will throw exceptions on certain host objects #9897
 518              return false;
 519          }
 520  
 521          // Own properties are enumerated firstly, so to speed up,
 522          // if last one is own, then all properties are own.
 523  
 524          var key;
 525          for ( key in obj ) {}
 526  
 527          return key === undefined || hasOwn.call( obj, key );
 528      },
 529  
 530      isEmptyObject: function( obj ) {
 531          for ( var name in obj ) {
 532              return false;
 533          }
 534          return true;
 535      },
 536  
 537      error: function( msg ) {
 538          throw new Error( msg );
 539      },
 540  
 541      parseJSON: function( data ) {
 542          if ( typeof data !== "string" || !data ) {
 543              return null;
 544          }
 545  
 546          // Make sure leading/trailing whitespace is removed (IE can't handle it)
 547          data = jQuery.trim( data );
 548  
 549          // Attempt to parse using the native JSON parser first
 550          if ( window.JSON && window.JSON.parse ) {
 551              return window.JSON.parse( data );
 552          }
 553  
 554          // Make sure the incoming data is actual JSON
 555          // Logic borrowed from http://json.org/json2.js
 556          if ( rvalidchars.test( data.replace( rvalidescape, "@" )
 557              .replace( rvalidtokens, "]" )
 558              .replace( rvalidbraces, "")) ) {
 559  
 560              return ( new Function( "return " + data ) )();
 561  
 562          }
 563          jQuery.error( "Invalid JSON: " + data );
 564      },
 565  
 566      // Cross-browser xml parsing
 567      parseXML: function( data ) {
 568          var xml, tmp;
 569          try {
 570              if ( window.DOMParser ) { // Standard
 571                  tmp = new DOMParser();
 572                  xml = tmp.parseFromString( data , "text/xml" );
 573              } else { // IE
 574                  xml = new ActiveXObject( "Microsoft.XMLDOM" );
 575                  xml.async = "false";
 576                  xml.loadXML( data );
 577              }
 578          } catch( e ) {
 579              xml = undefined;
 580          }
 581          if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
 582              jQuery.error( "Invalid XML: " + data );
 583          }
 584          return xml;
 585      },
 586  
 587      noop: function() {},
 588  
 589      // Evaluates a script in a global context
 590      // Workarounds based on findings by Jim Driscoll
 591      // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
 592      globalEval: function( data ) {
 593          if ( data && rnotwhite.test( data ) ) {
 594              // We use execScript on Internet Explorer
 595              // We use an anonymous function so that context is window
 596              // rather than jQuery in Firefox
 597              ( window.execScript || function( data ) {
 598                  window[ "eval" ].call( window, data );
 599              } )( data );
 600          }
 601      },
 602  
 603      // Convert dashed to camelCase; used by the css and data modules
 604      // Microsoft forgot to hump their vendor prefix (#9572)
 605      camelCase: function( string ) {
 606          return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
 607      },
 608  
 609      nodeName: function( elem, name ) {
 610          return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
 611      },
 612  
 613      // args is for internal usage only
 614      each: function( object, callback, args ) {
 615          var name, i = 0,
 616              length = object.length,
 617              isObj = length === undefined || jQuery.isFunction( object );
 618  
 619          if ( args ) {
 620              if ( isObj ) {
 621                  for ( name in object ) {
 622                      if ( callback.apply( object[ name ], args ) === false ) {
 623                          break;
 624                      }
 625                  }
 626              } else {
 627                  for ( ; i < length; ) {
 628                      if ( callback.apply( object[ i++ ], args ) === false ) {
 629                          break;
 630                      }
 631                  }
 632              }
 633  
 634          // A special, fast, case for the most common use of each
 635          } else {
 636              if ( isObj ) {
 637                  for ( name in object ) {
 638                      if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
 639                          break;
 640                      }
 641                  }
 642              } else {
 643                  for ( ; i < length; ) {
 644                      if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
 645                          break;
 646                      }
 647                  }
 648              }
 649          }
 650  
 651          return object;
 652      },
 653  
 654      // Use native String.trim function wherever possible
 655      trim: trim ?
 656          function( text ) {
 657              return text == null ?
 658                  "" :
 659                  trim.call( text );
 660          } :
 661  
 662          // Otherwise use our own trimming functionality
 663          function( text ) {
 664              return text == null ?
 665                  "" :
 666                  text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
 667          },
 668  
 669      // results is for internal usage only
 670      makeArray: function( array, results ) {
 671          var ret = results || [];
 672  
 673          if ( array != null ) {
 674              // The window, strings (and functions) also have 'length'
 675              // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
 676              var type = jQuery.type( array );
 677  
 678              if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
 679                  push.call( ret, array );
 680              } else {
 681                  jQuery.merge( ret, array );
 682              }
 683          }
 684  
 685          return ret;
 686      },
 687  
 688      inArray: function( elem, array, i ) {
 689          var len;
 690  
 691          if ( array ) {
 692              if ( indexOf ) {
 693                  return indexOf.call( array, elem, i );
 694              }
 695  
 696              len = array.length;
 697              i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
 698  
 699              for ( ; i < len; i++ ) {
 700                  // Skip accessing in sparse arrays
 701                  if ( i in array && array[ i ] === elem ) {
 702                      return i;
 703                  }
 704              }
 705          }
 706  
 707          return -1;
 708      },
 709  
 710      merge: function( first, second ) {
 711          var i = first.length,
 712              j = 0;
 713  
 714          if ( typeof second.length === "number" ) {
 715              for ( var l = second.length; j < l; j++ ) {
 716                  first[ i++ ] = second[ j ];
 717              }
 718  
 719          } else {
 720              while ( second[j] !== undefined ) {
 721                  first[ i++ ] = second[ j++ ];
 722              }
 723          }
 724  
 725          first.length = i;
 726  
 727          return first;
 728      },
 729  
 730      grep: function( elems, callback, inv ) {
 731          var ret = [], retVal;
 732          inv = !!inv;
 733  
 734          // Go through the array, only saving the items
 735          // that pass the validator function
 736          for ( var i = 0, length = elems.length; i < length; i++ ) {
 737              retVal = !!callback( elems[ i ], i );
 738              if ( inv !== retVal ) {
 739                  ret.push( elems[ i ] );
 740              }
 741          }
 742  
 743          return ret;
 744      },
 745  
 746      // arg is for internal usage only
 747      map: function( elems, callback, arg ) {
 748          var value, key, ret = [],
 749              i = 0,
 750              length = elems.length,
 751              // jquery objects are treated as arrays
 752              isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
 753  
 754          // Go through the array, translating each of the items to their
 755          if ( isArray ) {
 756              for ( ; i < length; i++ ) {
 757                  value = callback( elems[ i ], i, arg );
 758  
 759                  if ( value != null ) {
 760                      ret[ ret.length ] = value;
 761                  }
 762              }
 763  
 764          // Go through every key on the object
 765          } else {
 766              for ( key in elems ) {
 767                  value = callback( elems[ key ], key, arg );
 768  
 769                  if ( value != null ) {
 770                      ret[ ret.length ] = value;
 771                  }
 772              }
 773          }
 774  
 775          // Flatten any nested arrays
 776          return ret.concat.apply( [], ret );
 777      },
 778  
 779      // A global GUID counter for objects
 780      guid: 1,
 781  
 782      // Bind a function to a context, optionally partially applying any
 783      // arguments.
 784      proxy: function( fn, context ) {
 785          if ( typeof context === "string" ) {
 786              var tmp = fn[ context ];
 787              context = fn;
 788              fn = tmp;
 789          }
 790  
 791          // Quick check to determine if target is callable, in the spec
 792          // this throws a TypeError, but we will just return undefined.
 793          if ( !jQuery.isFunction( fn ) ) {
 794              return undefined;
 795          }
 796  
 797          // Simulated bind
 798          var args = slice.call( arguments, 2 ),
 799              proxy = function() {
 800                  return fn.apply( context, args.concat( slice.call( arguments ) ) );
 801              };
 802  
 803          // Set the guid of unique handler to the same of original handler, so it can be removed
 804          proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
 805  
 806          return proxy;
 807      },
 808  
 809      // Mutifunctional method to get and set values to a collection
 810      // The value/s can optionally be executed if it's a function
 811      access: function( elems, key, value, exec, fn, pass ) {
 812          var length = elems.length;
 813  
 814          // Setting many attributes
 815          if ( typeof key === "object" ) {
 816              for ( var k in key ) {
 817                  jQuery.access( elems, k, key[k], exec, fn, value );
 818              }
 819              return elems;
 820          }
 821  
 822          // Setting one attribute
 823          if ( value !== undefined ) {
 824              // Optionally, function values get executed if exec is true
 825              exec = !pass && exec && jQuery.isFunction(value);
 826  
 827              for ( var i = 0; i < length; i++ ) {
 828                  fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
 829              }
 830  
 831              return elems;
 832          }
 833  
 834          // Getting an attribute
 835          return length ? fn( elems[0], key ) : undefined;
 836      },
 837  
 838      now: function() {
 839          return ( new Date() ).getTime();
 840      },
 841  
 842      // Use of jQuery.browser is frowned upon.
 843      // More details: http://docs.jquery.com/Utilities/jQuery.browser
 844      uaMatch: function( ua ) {
 845          ua = ua.toLowerCase();
 846  
 847          var match = rwebkit.exec( ua ) ||
 848              ropera.exec( ua ) ||
 849              rmsie.exec( ua ) ||
 850              ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
 851              [];
 852  
 853          return { browser: match[1] || "", version: match[2] || "0" };
 854      },
 855  
 856      sub: function() {
 857  		function jQuerySub( selector, context ) {
 858              return new jQuerySub.fn.init( selector, context );
 859          }
 860          jQuery.extend( true, jQuerySub, this );
 861          jQuerySub.superclass = this;
 862          jQuerySub.fn = jQuerySub.prototype = this();
 863          jQuerySub.fn.constructor = jQuerySub;
 864          jQuerySub.sub = this.sub;
 865          jQuerySub.fn.init = function init( selector, context ) {
 866              if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
 867                  context = jQuerySub( context );
 868              }
 869  
 870              return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
 871          };
 872          jQuerySub.fn.init.prototype = jQuerySub.fn;
 873          var rootjQuerySub = jQuerySub(document);
 874          return jQuerySub;
 875      },
 876  
 877      browser: {}
 878  });
 879  
 880  // Populate the class2type map
 881  jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
 882      class2type[ "[object " + name + "]" ] = name.toLowerCase();
 883  });
 884  
 885  browserMatch = jQuery.uaMatch( userAgent );
 886  if ( browserMatch.browser ) {
 887      jQuery.browser[ browserMatch.browser ] = true;
 888      jQuery.browser.version = browserMatch.version;
 889  }
 890  
 891  // Deprecated, use jQuery.browser.webkit instead
 892  if ( jQuery.browser.webkit ) {
 893      jQuery.browser.safari = true;
 894  }
 895  
 896  // IE doesn't match non-breaking spaces with \s
 897  if ( rnotwhite.test( "\xA0" ) ) {
 898      trimLeft = /^[\s\xA0]+/;
 899      trimRight = /[\s\xA0]+$/;
 900  }
 901  
 902  // All jQuery objects should point back to these
 903  rootjQuery = jQuery(document);
 904  
 905  // Cleanup functions for the document ready method
 906  if ( document.addEventListener ) {
 907      DOMContentLoaded = function() {
 908          document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
 909          jQuery.ready();
 910      };
 911  
 912  } else if ( document.attachEvent ) {
 913      DOMContentLoaded = function() {
 914          // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
 915          if ( document.readyState === "complete" ) {
 916              document.detachEvent( "onreadystatechange", DOMContentLoaded );
 917              jQuery.ready();
 918          }
 919      };
 920  }
 921  
 922  // The DOM ready check for Internet Explorer
 923  function doScrollCheck() {
 924      if ( jQuery.isReady ) {
 925          return;
 926      }
 927  
 928      try {
 929          // If IE is used, use the trick by Diego Perini
 930          // http://javascript.nwbox.com/IEContentLoaded/
 931          document.documentElement.doScroll("left");
 932      } catch(e) {
 933          setTimeout( doScrollCheck, 1 );
 934          return;
 935      }
 936  
 937      // and execute any waiting functions
 938      jQuery.ready();
 939  }
 940  
 941  return jQuery;
 942  
 943  })();
 944  
 945  
 946  // String to Object flags format cache
 947  var flagsCache = {};
 948  
 949  // Convert String-formatted flags into Object-formatted ones and store in cache
 950  function createFlags( flags ) {
 951      var object = flagsCache[ flags ] = {},
 952          i, length;
 953      flags = flags.split( /\s+/ );
 954      for ( i = 0, length = flags.length; i < length; i++ ) {
 955          object[ flags[i] ] = true;
 956      }
 957      return object;
 958  }
 959  
 960  /*
 961   * Create a callback list using the following parameters:
 962   *
 963   *    flags:    an optional list of space-separated flags that will change how
 964   *            the callback list behaves
 965   *
 966   * By default a callback list will act like an event callback list and can be
 967   * "fired" multiple times.
 968   *
 969   * Possible flags:
 970   *
 971   *    once:            will ensure the callback list can only be fired once (like a Deferred)
 972   *
 973   *    memory:            will keep track of previous values and will call any callback added
 974   *                    after the list has been fired right away with the latest "memorized"
 975   *                    values (like a Deferred)
 976   *
 977   *    unique:            will ensure a callback can only be added once (no duplicate in the list)
 978   *
 979   *    stopOnFalse:    interrupt callings when a callback returns false
 980   *
 981   */
 982  jQuery.Callbacks = function( flags ) {
 983  
 984      // Convert flags from String-formatted to Object-formatted
 985      // (we check in cache first)
 986      flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {};
 987  
 988      var // Actual callback list
 989          list = [],
 990          // Stack of fire calls for repeatable lists
 991          stack = [],
 992          // Last fire value (for non-forgettable lists)
 993          memory,
 994          // Flag to know if list is currently firing
 995          firing,
 996          // First callback to fire (used internally by add and fireWith)
 997          firingStart,
 998          // End of the loop when firing
 999          firingLength,
1000          // Index of currently firing callback (modified by remove if needed)
1001          firingIndex,
1002          // Add one or several callbacks to the list
1003          add = function( args ) {
1004              var i,
1005                  length,
1006                  elem,
1007                  type,
1008                  actual;
1009              for ( i = 0, length = args.length; i < length; i++ ) {
1010                  elem = args[ i ];
1011                  type = jQuery.type( elem );
1012                  if ( type === "array" ) {
1013                      // Inspect recursively
1014                      add( elem );
1015                  } else if ( type === "function" ) {
1016                      // Add if not in unique mode and callback is not in
1017                      if ( !flags.unique || !self.has( elem ) ) {
1018                          list.push( elem );
1019                      }
1020                  }
1021              }
1022          },
1023          // Fire callbacks
1024          fire = function( context, args ) {
1025              args = args || [];
1026              memory = !flags.memory || [ context, args ];
1027              firing = true;
1028              firingIndex = firingStart || 0;
1029              firingStart = 0;
1030              firingLength = list.length;
1031              for ( ; list && firingIndex < firingLength; firingIndex++ ) {
1032                  if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) {
1033                      memory = true; // Mark as halted
1034                      break;
1035                  }
1036              }
1037              firing = false;
1038              if ( list ) {
1039                  if ( !flags.once ) {
1040                      if ( stack && stack.length ) {
1041                          memory = stack.shift();
1042                          self.fireWith( memory[ 0 ], memory[ 1 ] );
1043                      }
1044                  } else if ( memory === true ) {
1045                      self.disable();
1046                  } else {
1047                      list = [];
1048                  }
1049              }
1050          },
1051          // Actual Callbacks object
1052          self = {
1053              // Add a callback or a collection of callbacks to the list
1054              add: function() {
1055                  if ( list ) {
1056                      var length = list.length;
1057                      add( arguments );
1058                      // Do we need to add the callbacks to the
1059                      // current firing batch?
1060                      if ( firing ) {
1061                          firingLength = list.length;
1062                      // With memory, if we're not firing then
1063                      // we should call right away, unless previous
1064                      // firing was halted (stopOnFalse)
1065                      } else if ( memory && memory !== true ) {
1066                          firingStart = length;
1067                          fire( memory[ 0 ], memory[ 1 ] );
1068                      }
1069                  }
1070                  return this;
1071              },
1072              // Remove a callback from the list
1073              remove: function() {
1074                  if ( list ) {
1075                      var args = arguments,
1076                          argIndex = 0,
1077                          argLength = args.length;
1078                      for ( ; argIndex < argLength ; argIndex++ ) {
1079                          for ( var i = 0; i < list.length; i++ ) {
1080                              if ( args[ argIndex ] === list[ i ] ) {
1081                                  // Handle firingIndex and firingLength
1082                                  if ( firing ) {
1083                                      if ( i <= firingLength ) {
1084                                          firingLength--;
1085                                          if ( i <= firingIndex ) {
1086                                              firingIndex--;
1087                                          }
1088                                      }
1089                                  }
1090                                  // Remove the element
1091                                  list.splice( i--, 1 );
1092                                  // If we have some unicity property then
1093                                  // we only need to do this once
1094                                  if ( flags.unique ) {
1095                                      break;
1096                                  }
1097                              }
1098                          }
1099                      }
1100                  }
1101                  return this;
1102              },
1103              // Control if a given callback is in the list
1104              has: function( fn ) {
1105                  if ( list ) {
1106                      var i = 0,
1107                          length = list.length;
1108                      for ( ; i < length; i++ ) {
1109                          if ( fn === list[ i ] ) {
1110                              return true;
1111                          }
1112                      }
1113                  }
1114                  return false;
1115              },
1116              // Remove all callbacks from the list
1117              empty: function() {
1118                  list = [];
1119                  return this;
1120              },
1121              // Have the list do nothing anymore
1122              disable: function() {
1123                  list = stack = memory = undefined;
1124                  return this;
1125              },
1126              // Is it disabled?
1127              disabled: function() {
1128                  return !list;
1129              },
1130              // Lock the list in its current state
1131              lock: function() {
1132                  stack = undefined;
1133                  if ( !memory || memory === true ) {
1134                      self.disable();
1135                  }
1136                  return this;
1137              },
1138              // Is it locked?
1139              locked: function() {
1140                  return !stack;
1141              },
1142              // Call all callbacks with the given context and arguments
1143              fireWith: function( context, args ) {
1144                  if ( stack ) {
1145                      if ( firing ) {
1146                          if ( !flags.once ) {
1147                              stack.push( [ context, args ] );
1148                          }
1149                      } else if ( !( flags.once && memory ) ) {
1150                          fire( context, args );
1151                      }
1152                  }
1153                  return this;
1154              },
1155              // Call all the callbacks with the given arguments
1156              fire: function() {
1157                  self.fireWith( this, arguments );
1158                  return this;
1159              },
1160              // To know if the callbacks have already been called at least once
1161              fired: function() {
1162                  return !!memory;
1163              }
1164          };
1165  
1166      return self;
1167  };
1168  
1169  
1170  
1171  
1172  var // Static reference to slice
1173      sliceDeferred = [].slice;
1174  
1175  jQuery.extend({
1176  
1177      Deferred: function( func ) {
1178          var doneList = jQuery.Callbacks( "once memory" ),
1179              failList = jQuery.Callbacks( "once memory" ),
1180              progressList = jQuery.Callbacks( "memory" ),
1181              state = "pending",
1182              lists = {
1183                  resolve: doneList,
1184                  reject: failList,
1185                  notify: progressList
1186              },
1187              promise = {
1188                  done: doneList.add,
1189                  fail: failList.add,
1190                  progress: progressList.add,
1191  
1192                  state: function() {
1193                      return state;
1194                  },
1195  
1196                  // Deprecated
1197                  isResolved: doneList.fired,
1198                  isRejected: failList.fired,
1199  
1200                  then: function( doneCallbacks, failCallbacks, progressCallbacks ) {
1201                      deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks );
1202                      return this;
1203                  },
1204                  always: function() {
1205                      deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments );
1206                      return this;
1207                  },
1208                  pipe: function( fnDone, fnFail, fnProgress ) {
1209                      return jQuery.Deferred(function( newDefer ) {
1210                          jQuery.each( {
1211                              done: [ fnDone, "resolve" ],
1212                              fail: [ fnFail, "reject" ],
1213                              progress: [ fnProgress, "notify" ]
1214                          }, function( handler, data ) {
1215                              var fn = data[ 0 ],
1216                                  action = data[ 1 ],
1217                                  returned;
1218                              if ( jQuery.isFunction( fn ) ) {
1219                                  deferred[ handler ](function() {
1220                                      returned = fn.apply( this, arguments );
1221                                      if ( returned && jQuery.isFunction( returned.promise ) ) {
1222                                          returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify );
1223                                      } else {
1224                                          newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
1225                                      }
1226                                  });
1227                              } else {
1228                                  deferred[ handler ]( newDefer[ action ] );
1229                              }
1230                          });
1231                      }).promise();
1232                  },
1233                  // Get a promise for this deferred
1234                  // If obj is provided, the promise aspect is added to the object
1235                  promise: function( obj ) {
1236                      if ( obj == null ) {
1237                          obj = promise;
1238                      } else {
1239                          for ( var key in promise ) {
1240                              obj[ key ] = promise[ key ];
1241                          }
1242                      }
1243                      return obj;
1244                  }
1245              },
1246              deferred = promise.promise({}),
1247              key;
1248  
1249          for ( key in lists ) {
1250              deferred[ key ] = lists[ key ].fire;
1251              deferred[ key + "With" ] = lists[ key ].fireWith;
1252          }
1253  
1254          // Handle state
1255          deferred.done( function() {
1256              state = "resolved";
1257          }, failList.disable, progressList.lock ).fail( function() {
1258              state = "rejected";
1259          }, doneList.disable, progressList.lock );
1260  
1261          // Call given func if any
1262          if ( func ) {
1263              func.call( deferred, deferred );
1264          }
1265  
1266          // All done!
1267          return deferred;
1268      },
1269  
1270      // Deferred helper
1271      when: function( firstParam ) {
1272          var args = sliceDeferred.call( arguments, 0 ),
1273              i = 0,
1274              length = args.length,
1275              pValues = new Array( length ),
1276              count = length,
1277              pCount = length,
1278              deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1279                  firstParam :
1280                  jQuery.Deferred(),
1281              promise = deferred.promise();
1282  		function resolveFunc( i ) {
1283              return function( value ) {
1284                  args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1285                  if ( !( --count ) ) {
1286                      deferred.resolveWith( deferred, args );
1287                  }
1288              };
1289          }
1290  		function progressFunc( i ) {
1291              return function( value ) {
1292                  pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1293                  deferred.notifyWith( promise, pValues );
1294              };
1295          }
1296          if ( length > 1 ) {
1297              for ( ; i < length; i++ ) {
1298                  if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) {
1299                      args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) );
1300                  } else {
1301                      --count;
1302                  }
1303              }
1304              if ( !count ) {
1305                  deferred.resolveWith( deferred, args );
1306              }
1307          } else if ( deferred !== firstParam ) {
1308              deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
1309          }
1310          return promise;
1311      }
1312  });
1313  
1314  
1315  
1316  
1317  jQuery.support = (function() {
1318  
1319      var support,
1320          all,
1321          a,
1322          select,
1323          opt,
1324          input,
1325          marginDiv,
1326          fragment,
1327          tds,
1328          events,
1329          eventName,
1330          i,
1331          isSupported,
1332          div = document.createElement( "div" ),
1333          documentElement = document.documentElement;
1334  
1335      // Preliminary tests
1336      div.setAttribute("className", "t");
1337      div.innerHTML = "   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
1338  
1339      all = div.getElementsByTagName( "*" );
1340      a = div.getElementsByTagName( "a" )[ 0 ];
1341  
1342      // Can't get basic test support
1343      if ( !all || !all.length || !a ) {
1344          return {};
1345      }
1346  
1347      // First batch of supports tests
1348      select = document.createElement( "select" );
1349      opt = select.appendChild( document.createElement("option") );
1350      input = div.getElementsByTagName( "input" )[ 0 ];
1351  
1352      support = {
1353          // IE strips leading whitespace when .innerHTML is used
1354          leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1355  
1356          // Make sure that tbody elements aren't automatically inserted
1357          // IE will insert them into empty tables
1358          tbody: !div.getElementsByTagName("tbody").length,
1359  
1360          // Make sure that link elements get serialized correctly by innerHTML
1361          // This requires a wrapper element in IE
1362          htmlSerialize: !!div.getElementsByTagName("link").length,
1363  
1364          // Get the style information from getAttribute
1365          // (IE uses .cssText instead)
1366          style: /top/.test( a.getAttribute("style") ),
1367  
1368          // Make sure that URLs aren't manipulated
1369          // (IE normalizes it by default)
1370          hrefNormalized: ( a.getAttribute("href") === "/a" ),
1371  
1372          // Make sure that element opacity exists
1373          // (IE uses filter instead)
1374          // Use a regex to work around a WebKit issue. See #5145
1375          opacity: /^0.55/.test( a.style.opacity ),
1376  
1377          // Verify style float existence
1378          // (IE uses styleFloat instead of cssFloat)
1379          cssFloat: !!a.style.cssFloat,
1380  
1381          // Make sure that if no value is specified for a checkbox
1382          // that it defaults to "on".
1383          // (WebKit defaults to "" instead)
1384          checkOn: ( input.value === "on" ),
1385  
1386          // Make sure that a selected-by-default option has a working selected property.
1387          // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1388          optSelected: opt.selected,
1389  
1390          // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1391          getSetAttribute: div.className !== "t",
1392  
1393          // Tests for enctype support on a form(#6743)
1394          enctype: !!document.createElement("form").enctype,
1395  
1396          // Makes sure cloning an html5 element does not cause problems
1397          // Where outerHTML is undefined, this still works
1398          html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",
1399  
1400          // Will be defined later
1401          submitBubbles: true,
1402          changeBubbles: true,
1403          focusinBubbles: false,
1404          deleteExpando: true,
1405          noCloneEvent: true,
1406          inlineBlockNeedsLayout: false,
1407          shrinkWrapBlocks: false,
1408          reliableMarginRight: true
1409      };
1410  
1411      // Make sure checked status is properly cloned
1412      input.checked = true;
1413      support.noCloneChecked = input.cloneNode( true ).checked;
1414  
1415      // Make sure that the options inside disabled selects aren't marked as disabled
1416      // (WebKit marks them as disabled)
1417      select.disabled = true;
1418      support.optDisabled = !opt.disabled;
1419  
1420      // Test to see if it's possible to delete an expando from an element
1421      // Fails in Internet Explorer
1422      try {
1423          delete div.test;
1424      } catch( e ) {
1425          support.deleteExpando = false;
1426      }
1427  
1428      if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1429          div.attachEvent( "onclick", function() {
1430              // Cloning a node shouldn't copy over any
1431              // bound event handlers (IE does this)
1432              support.noCloneEvent = false;
1433          });
1434          div.cloneNode( true ).fireEvent( "onclick" );
1435      }
1436  
1437      // Check if a radio maintains its value
1438      // after being appended to the DOM
1439      input = document.createElement("input");
1440      input.value = "t";
1441      input.setAttribute("type", "radio");
1442      support.radioValue = input.value === "t";
1443  
1444      input.setAttribute("checked", "checked");
1445      div.appendChild( input );
1446      fragment = document.createDocumentFragment();
1447      fragment.appendChild( div.lastChild );
1448  
1449      // WebKit doesn't clone checked state correctly in fragments
1450      support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1451  
1452      // Check if a disconnected checkbox will retain its checked
1453      // value of true after appended to the DOM (IE6/7)
1454      support.appendChecked = input.checked;
1455  
1456      fragment.removeChild( input );
1457      fragment.appendChild( div );
1458  
1459      div.innerHTML = "";
1460  
1461      // Check if div with explicit width and no margin-right incorrectly
1462      // gets computed margin-right based on width of container. For more
1463      // info see bug #3333
1464      // Fails in WebKit before Feb 2011 nightlies
1465      // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1466      if ( window.getComputedStyle ) {
1467          marginDiv = document.createElement( "div" );
1468          marginDiv.style.width = "0";
1469          marginDiv.style.marginRight = "0";
1470          div.style.width = "2px";
1471          div.appendChild( marginDiv );
1472          support.reliableMarginRight =
1473              ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
1474      }
1475  
1476      // Technique from Juriy Zaytsev
1477      // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
1478      // We only care about the case where non-standard event systems
1479      // are used, namely in IE. Short-circuiting here helps us to
1480      // avoid an eval call (in setAttribute) which can cause CSP
1481      // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1482      if ( div.attachEvent ) {
1483          for( i in {
1484              submit: 1,
1485              change: 1,
1486              focusin: 1
1487          }) {
1488              eventName = "on" + i;
1489              isSupported = ( eventName in div );
1490              if ( !isSupported ) {
1491                  div.setAttribute( eventName, "return;" );
1492                  isSupported = ( typeof div[ eventName ] === "function" );
1493              }
1494              support[ i + "Bubbles" ] = isSupported;
1495          }
1496      }
1497  
1498      fragment.removeChild( div );
1499  
1500      // Null elements to avoid leaks in IE
1501      fragment = select = opt = marginDiv = div = input = null;
1502  
1503      // Run tests that need a body at doc ready
1504      jQuery(function() {
1505          var container, outer, inner, table, td, offsetSupport,
1506              conMarginTop, ptlm, vb, style, html,
1507              body = document.getElementsByTagName("body")[0];
1508  
1509          if ( !body ) {
1510              // Return for frameset docs that don't have a body
1511              return;
1512          }
1513  
1514          conMarginTop = 1;
1515          ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";
1516          vb = "visibility:hidden;border:0;";
1517          style = "style='" + ptlm + "border:5px solid #000;padding:0;'";
1518          html = "<div " + style + "><div></div></div>" +
1519              "<table " + style + " cellpadding='0' cellspacing='0'>" +
1520              "<tr><td></td></tr></table>";
1521  
1522          container = document.createElement("div");
1523          container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px";
1524          body.insertBefore( container, body.firstChild );
1525  
1526          // Construct the test element
1527          div = document.createElement("div");
1528          container.appendChild( div );
1529  
1530          // Check if table cells still have offsetWidth/Height when they are set
1531          // to display:none and there are still other visible table cells in a
1532          // table row; if so, offsetWidth/Height are not reliable for use when
1533          // determining if an element has been hidden directly using
1534          // display:none (it is still safe to use offsets if a parent element is
1535          // hidden; don safety goggles and see bug #4512 for more information).
1536          // (only IE 8 fails this test)
1537          div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1538          tds = div.getElementsByTagName( "td" );
1539          isSupported = ( tds[ 0 ].offsetHeight === 0 );
1540  
1541          tds[ 0 ].style.display = "";
1542          tds[ 1 ].style.display = "none";
1543  
1544          // Check if empty table cells still have offsetWidth/Height
1545          // (IE <= 8 fail this test)
1546          support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1547  
1548          // Figure out if the W3C box model works as expected
1549          div.innerHTML = "";
1550          div.style.width = div.style.paddingLeft = "1px";
1551          jQuery.boxModel = support.boxModel = div.offsetWidth === 2;
1552  
1553          if ( typeof div.style.zoom !== "undefined" ) {
1554              // Check if natively block-level elements act like inline-block
1555              // elements when setting their display to 'inline' and giving
1556              // them layout
1557              // (IE < 8 does this)
1558              div.style.display = "inline";
1559              div.style.zoom = 1;
1560              support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
1561  
1562              // Check if elements with layout shrink-wrap their children
1563              // (IE 6 does this)
1564              div.style.display = "";
1565              div.innerHTML = "<div style='width:4px;'></div>";
1566              support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
1567          }
1568  
1569          div.style.cssText = ptlm + vb;
1570          div.innerHTML = html;
1571  
1572          outer = div.firstChild;
1573          inner = outer.firstChild;
1574          td = outer.nextSibling.firstChild.firstChild;
1575  
1576          offsetSupport = {
1577              doesNotAddBorder: ( inner.offsetTop !== 5 ),
1578              doesAddBorderForTableAndCells: ( td.offsetTop === 5 )
1579          };
1580  
1581          inner.style.position = "fixed";
1582          inner.style.top = "20px";
1583  
1584          // safari subtracts parent border width here which is 5px
1585          offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 );
1586          inner.style.position = inner.style.top = "";
1587  
1588          outer.style.overflow = "hidden";
1589          outer.style.position = "relative";
1590  
1591          offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 );
1592          offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop );
1593  
1594          body.removeChild( container );
1595          div  = container = null;
1596  
1597          jQuery.extend( support, offsetSupport );
1598      });
1599  
1600      return support;
1601  })();
1602  
1603  
1604  
1605  
1606  var rbrace = /^(?:\{.*\}|\[.*\])$/,
1607      rmultiDash = /([A-Z])/g;
1608  
1609  jQuery.extend({
1610      cache: {},
1611  
1612      // Please use with caution
1613      uuid: 0,
1614  
1615      // Unique for each copy of jQuery on the page
1616      // Non-digits removed to match rinlinejQuery
1617      expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1618  
1619      // The following elements throw uncatchable exceptions if you
1620      // attempt to add expando properties to them.
1621      noData: {
1622          "embed": true,
1623          // Ban all objects except for Flash (which handle expandos)
1624          "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1625          "applet": true
1626      },
1627  
1628      hasData: function( elem ) {
1629          elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1630          return !!elem && !isEmptyDataObject( elem );
1631      },
1632  
1633      data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1634          if ( !jQuery.acceptData( elem ) ) {
1635              return;
1636          }
1637  
1638          var privateCache, thisCache, ret,
1639              internalKey = jQuery.expando,
1640              getByName = typeof name === "string",
1641  
1642              // We have to handle DOM nodes and JS objects differently because IE6-7
1643              // can't GC object references properly across the DOM-JS boundary
1644              isNode = elem.nodeType,
1645  
1646              // Only DOM nodes need the global jQuery cache; JS object data is
1647              // attached directly to the object so GC can occur automatically
1648              cache = isNode ? jQuery.cache : elem,
1649  
1650              // Only defining an ID for JS objects if its cache already exists allows
1651              // the code to shortcut on the same path as a DOM node with no cache
1652              id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey,
1653              isEvents = name === "events";
1654  
1655          // Avoid doing any more work than we need to when trying to get data on an
1656          // object that has no data at all
1657          if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) {
1658              return;
1659          }
1660  
1661          if ( !id ) {
1662              // Only DOM nodes need a new unique ID for each element since their data
1663              // ends up in the global cache
1664              if ( isNode ) {
1665                  elem[ internalKey ] = id = ++jQuery.uuid;
1666              } else {
1667                  id = internalKey;
1668              }
1669          }
1670  
1671          if ( !cache[ id ] ) {
1672              cache[ id ] = {};
1673  
1674              // Avoids exposing jQuery metadata on plain JS objects when the object
1675              // is serialized using JSON.stringify
1676              if ( !isNode ) {
1677                  cache[ id ].toJSON = jQuery.noop;
1678              }
1679          }
1680  
1681          // An object can be passed to jQuery.data instead of a key/value pair; this gets
1682          // shallow copied over onto the existing cache
1683          if ( typeof name === "object" || typeof name === "function" ) {
1684              if ( pvt ) {
1685                  cache[ id ] = jQuery.extend( cache[ id ], name );
1686              } else {
1687                  cache[ id ].data = jQuery.extend( cache[ id ].data, name );
1688              }
1689          }
1690  
1691          privateCache = thisCache = cache[ id ];
1692  
1693          // jQuery data() is stored in a separate object inside the object's internal data
1694          // cache in order to avoid key collisions between internal data and user-defined
1695          // data.
1696          if ( !pvt ) {
1697              if ( !thisCache.data ) {
1698                  thisCache.data = {};
1699              }
1700  
1701              thisCache = thisCache.data;
1702          }
1703  
1704          if ( data !== undefined ) {
1705              thisCache[ jQuery.camelCase( name ) ] = data;
1706          }
1707  
1708          // Users should not attempt to inspect the internal events object using jQuery.data,
1709          // it is undocumented and subject to change. But does anyone listen? No.
1710          if ( isEvents && !thisCache[ name ] ) {
1711              return privateCache.events;
1712          }
1713  
1714          // Check for both converted-to-camel and non-converted data property names
1715          // If a data property was specified
1716          if ( getByName ) {
1717  
1718              // First Try to find as-is property data
1719              ret = thisCache[ name ];
1720  
1721              // Test for null|undefined property data
1722              if ( ret == null ) {
1723  
1724                  // Try to find the camelCased property
1725                  ret = thisCache[ jQuery.camelCase( name ) ];
1726              }
1727          } else {
1728              ret = thisCache;
1729          }
1730  
1731          return ret;
1732      },
1733  
1734      removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1735          if ( !jQuery.acceptData( elem ) ) {
1736              return;
1737          }
1738  
1739          var thisCache, i, l,
1740  
1741              // Reference to internal data cache key
1742              internalKey = jQuery.expando,
1743  
1744              isNode = elem.nodeType,
1745  
1746              // See jQuery.data for more information
1747              cache = isNode ? jQuery.cache : elem,
1748  
1749              // See jQuery.data for more information
1750              id = isNode ? elem[ internalKey ] : internalKey;
1751  
1752          // If there is already no cache entry for this object, there is no
1753          // purpose in continuing
1754          if ( !cache[ id ] ) {
1755              return;
1756          }
1757  
1758          if ( name ) {
1759  
1760              thisCache = pvt ? cache[ id ] : cache[ id ].data;
1761  
1762              if ( thisCache ) {
1763  
1764                  // Support array or space separated string names for data keys
1765                  if ( !jQuery.isArray( name ) ) {
1766  
1767                      // try the string as a key before any manipulation
1768                      if ( name in thisCache ) {
1769                          name = [ name ];
1770                      } else {
1771  
1772                          // split the camel cased version by spaces unless a key with the spaces exists
1773                          name = jQuery.camelCase( name );
1774                          if ( name in thisCache ) {
1775                              name = [ name ];
1776                          } else {
1777                              name = name.split( " " );
1778                          }
1779                      }
1780                  }
1781  
1782                  for ( i = 0, l = name.length; i < l; i++ ) {
1783                      delete thisCache[ name[i] ];
1784                  }
1785  
1786                  // If there is no data left in the cache, we want to continue
1787                  // and let the cache object itself get destroyed
1788                  if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
1789                      return;
1790                  }
1791              }
1792          }
1793  
1794          // See jQuery.data for more information
1795          if ( !pvt ) {
1796              delete cache[ id ].data;
1797  
1798              // Don't destroy the parent cache unless the internal data object
1799              // had been the only thing left in it
1800              if ( !isEmptyDataObject(cache[ id ]) ) {
1801                  return;
1802              }
1803          }
1804  
1805          // Browsers that fail expando deletion also refuse to delete expandos on
1806          // the window, but it will allow it on all other JS objects; other browsers
1807          // don't care
1808          // Ensure that `cache` is not a window object #10080
1809          if ( jQuery.support.deleteExpando || !cache.setInterval ) {
1810              delete cache[ id ];
1811          } else {
1812              cache[ id ] = null;
1813          }
1814  
1815          // We destroyed the cache and need to eliminate the expando on the node to avoid
1816          // false lookups in the cache for entries that no longer exist
1817          if ( isNode ) {
1818              // IE does not allow us to delete expando properties from nodes,
1819              // nor does it have a removeAttribute function on Document nodes;
1820              // we must handle all of these cases
1821              if ( jQuery.support.deleteExpando ) {
1822                  delete elem[ internalKey ];
1823              } else if ( elem.removeAttribute ) {
1824                  elem.removeAttribute( internalKey );
1825              } else {
1826                  elem[ internalKey ] = null;
1827              }
1828          }
1829      },
1830  
1831      // For internal use only.
1832      _data: function( elem, name, data ) {
1833          return jQuery.data( elem, name, data, true );
1834      },
1835  
1836      // A method for determining if a DOM node can handle the data expando
1837      acceptData: function( elem ) {
1838          if ( elem.nodeName ) {
1839              var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1840  
1841              if ( match ) {
1842                  return !(match === true || elem.getAttribute("classid") !== match);
1843              }
1844          }
1845  
1846          return true;
1847      }
1848  });
1849  
1850  jQuery.fn.extend({
1851      data: function( key, value ) {
1852          var parts, attr, name,
1853              data = null;
1854  
1855          if ( typeof key === "undefined" ) {
1856              if ( this.length ) {
1857                  data = jQuery.data( this[0] );
1858  
1859                  if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) {
1860                      attr = this[0].attributes;
1861                      for ( var i = 0, l = attr.length; i < l; i++ ) {
1862                          name = attr[i].name;
1863  
1864                          if ( name.indexOf( "data-" ) === 0 ) {
1865                              name = jQuery.camelCase( name.substring(5) );
1866  
1867                              dataAttr( this[0], name, data[ name ] );
1868                          }
1869                      }
1870                      jQuery._data( this[0], "parsedAttrs", true );
1871                  }
1872              }
1873  
1874              return data;
1875  
1876          } else if ( typeof key === "object" ) {
1877              return this.each(function() {
1878                  jQuery.data( this, key );
1879              });
1880          }
1881  
1882          parts = key.split(".");
1883          parts[1] = parts[1] ? "." + parts[1] : "";
1884  
1885          if ( value === undefined ) {
1886              data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1887  
1888              // Try to fetch any internally stored data first
1889              if ( data === undefined && this.length ) {
1890                  data = jQuery.data( this[0], key );
1891                  data = dataAttr( this[0], key, data );
1892              }
1893  
1894              return data === undefined && parts[1] ?
1895                  this.data( parts[0] ) :
1896                  data;
1897  
1898          } else {
1899              return this.each(function() {
1900                  var self = jQuery( this ),
1901                      args = [ parts[0], value ];
1902  
1903                  self.triggerHandler( "setData" + parts[1] + "!", args );
1904                  jQuery.data( this, key, value );
1905                  self.triggerHandler( "changeData" + parts[1] + "!", args );
1906              });
1907          }
1908      },
1909  
1910      removeData: function( key ) {
1911          return this.each(function() {
1912              jQuery.removeData( this, key );
1913          });
1914      }
1915  });
1916  
1917  function dataAttr( elem, key, data ) {
1918      // If nothing was found internally, try to fetch any
1919      // data from the HTML5 data-* attribute
1920      if ( data === undefined && elem.nodeType === 1 ) {
1921  
1922          var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
1923  
1924          data = elem.getAttribute( name );
1925  
1926          if ( typeof data === "string" ) {
1927              try {
1928                  data = data === "true" ? true :
1929                  data === "false" ? false :
1930                  data === "null" ? null :
1931                  jQuery.isNumeric( data ) ? parseFloat( data ) :
1932                      rbrace.test( data ) ? jQuery.parseJSON( data ) :
1933                      data;
1934              } catch( e ) {}
1935  
1936              // Make sure we set the data so it isn't changed later
1937              jQuery.data( elem, key, data );
1938  
1939          } else {
1940              data = undefined;
1941          }
1942      }
1943  
1944      return data;
1945  }
1946  
1947  // checks a cache object for emptiness
1948  function isEmptyDataObject( obj ) {
1949      for ( var name in obj ) {
1950  
1951          // if the public data object is empty, the private is still empty
1952          if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
1953              continue;
1954          }
1955          if ( name !== "toJSON" ) {
1956              return false;
1957          }
1958      }
1959  
1960      return true;
1961  }
1962  
1963  
1964  
1965  
1966  function handleQueueMarkDefer( elem, type, src ) {
1967      var deferDataKey = type + "defer",
1968          queueDataKey = type + "queue",
1969          markDataKey = type + "mark",
1970          defer = jQuery._data( elem, deferDataKey );
1971      if ( defer &&
1972          ( src === "queue" || !jQuery._data(elem, queueDataKey) ) &&
1973          ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) {
1974          // Give room for hard-coded callbacks to fire first
1975          // and eventually mark/queue something else on the element
1976          setTimeout( function() {
1977              if ( !jQuery._data( elem, queueDataKey ) &&
1978                  !jQuery._data( elem, markDataKey ) ) {
1979                  jQuery.removeData( elem, deferDataKey, true );
1980                  defer.fire();
1981              }
1982          }, 0 );
1983      }
1984  }
1985  
1986  jQuery.extend({
1987  
1988      _mark: function( elem, type ) {
1989          if ( elem ) {
1990              type = ( type || "fx" ) + "mark";
1991              jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 );
1992          }
1993      },
1994  
1995      _unmark: function( force, elem, type ) {
1996          if ( force !== true ) {
1997              type = elem;
1998              elem = force;
1999              force = false;
2000          }
2001          if ( elem ) {
2002              type = type || "fx";
2003              var key = type + "mark",
2004                  count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 );
2005              if ( count ) {
2006                  jQuery._data( elem, key, count );
2007              } else {
2008                  jQuery.removeData( elem, key, true );
2009                  handleQueueMarkDefer( elem, type, "mark" );
2010              }
2011          }
2012      },
2013  
2014      queue: function( elem, type, data ) {
2015          var q;
2016          if ( elem ) {
2017              type = ( type || "fx" ) + "queue";
2018              q = jQuery._data( elem, type );
2019  
2020              // Speed up dequeue by getting out quickly if this is just a lookup
2021              if ( data ) {
2022                  if ( !q || jQuery.isArray(data) ) {
2023                      q = jQuery._data( elem, type, jQuery.makeArray(data) );
2024                  } else {
2025                      q.push( data );
2026                  }
2027              }
2028              return q || [];
2029          }
2030      },
2031  
2032      dequeue: function( elem, type ) {
2033          type = type || "fx";
2034  
2035          var queue = jQuery.queue( elem, type ),
2036              fn = queue.shift(),
2037              hooks = {};
2038  
2039          // If the fx queue is dequeued, always remove the progress sentinel
2040          if ( fn === "inprogress" ) {
2041              fn = queue.shift();
2042          }
2043  
2044          if ( fn ) {
2045              // Add a progress sentinel to prevent the fx queue from being
2046              // automatically dequeued
2047              if ( type === "fx" ) {
2048                  queue.unshift( "inprogress" );
2049              }
2050  
2051              jQuery._data( elem, type + ".run", hooks );
2052              fn.call( elem, function() {
2053                  jQuery.dequeue( elem, type );
2054              }, hooks );
2055          }
2056  
2057          if ( !queue.length ) {
2058              jQuery.removeData( elem, type + "queue " + type + ".run", true );
2059              handleQueueMarkDefer( elem, type, "queue" );
2060          }
2061      }
2062  });
2063  
2064  jQuery.fn.extend({
2065      queue: function( type, data ) {
2066          if ( typeof type !== "string" ) {
2067              data = type;
2068              type = "fx";
2069          }
2070  
2071          if ( data === undefined ) {
2072              return jQuery.queue( this[0], type );
2073          }
2074          return this.each(function() {
2075              var queue = jQuery.queue( this, type, data );
2076  
2077              if ( type === "fx" && queue[0] !== "inprogress" ) {
2078                  jQuery.dequeue( this, type );
2079              }
2080          });
2081      },
2082      dequeue: function( type ) {
2083          return this.each(function() {
2084              jQuery.dequeue( this, type );
2085          });
2086      },
2087      // Based off of the plugin by Clint Helfers, with permission.
2088      // http://blindsignals.com/index.php/2009/07/jquery-delay/
2089      delay: function( time, type ) {
2090          time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
2091          type = type || "fx";
2092  
2093          return this.queue( type, function( next, hooks ) {
2094              var timeout = setTimeout( next, time );
2095              hooks.stop = function() {
2096                  clearTimeout( timeout );
2097              };
2098          });
2099      },
2100      clearQueue: function( type ) {
2101          return this.queue( type || "fx", [] );
2102      },
2103      // Get a promise resolved when queues of a certain type
2104      // are emptied (fx is the type by default)
2105      promise: function( type, object ) {
2106          if ( typeof type !== "string" ) {
2107              object = type;
2108              type = undefined;
2109          }
2110          type = type || "fx";
2111          var defer = jQuery.Deferred(),
2112              elements = this,
2113              i = elements.length,
2114              count = 1,
2115              deferDataKey = type + "defer",
2116              queueDataKey = type + "queue",
2117              markDataKey = type + "mark",
2118              tmp;
2119  		function resolve() {
2120              if ( !( --count ) ) {
2121                  defer.resolveWith( elements, [ elements ] );
2122              }
2123          }
2124          while( i-- ) {
2125              if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
2126                      ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
2127                          jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
2128                      jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) {
2129                  count++;
2130                  tmp.add( resolve );
2131              }
2132          }
2133          resolve();
2134          return defer.promise();
2135      }
2136  });
2137  
2138  
2139  
2140  
2141  var rclass = /[\n\t\r]/g,
2142      rspace = /\s+/,
2143      rreturn = /\r/g,
2144      rtype = /^(?:button|input)$/i,
2145      rfocusable = /^(?:button|input|object|select|textarea)$/i,
2146      rclickable = /^a(?:rea)?$/i,
2147      rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
2148      getSetAttribute = jQuery.support.getSetAttribute,
2149      nodeHook, boolHook, fixSpecified;
2150  
2151  jQuery.fn.extend({
2152      attr: function( name, value ) {
2153          return jQuery.access( this, name, value, true, jQuery.attr );
2154      },
2155  
2156      removeAttr: function( name ) {
2157          return this.each(function() {
2158              jQuery.removeAttr( this, name );
2159          });
2160      },
2161  
2162      prop: function( name, value ) {
2163          return jQuery.access( this, name, value, true, jQuery.prop );
2164      },
2165  
2166      removeProp: function( name ) {
2167          name = jQuery.propFix[ name ] || name;
2168          return this.each(function() {
2169              // try/catch handles cases where IE balks (such as removing a property on window)
2170              try {
2171                  this[ name ] = undefined;
2172                  delete this[ name ];
2173              } catch( e ) {}
2174          });
2175      },
2176  
2177      addClass: function( value ) {
2178          var classNames, i, l, elem,
2179              setClass, c, cl;
2180  
2181          if ( jQuery.isFunction( value ) ) {
2182              return this.each(function( j ) {
2183                  jQuery( this ).addClass( value.call(this, j, this.className) );
2184              });
2185          }
2186  
2187          if ( value && typeof value === "string" ) {
2188              classNames = value.split( rspace );
2189  
2190              for ( i = 0, l = this.length; i < l; i++ ) {
2191                  elem = this[ i ];
2192  
2193                  if ( elem.nodeType === 1 ) {
2194                      if ( !elem.className && classNames.length === 1 ) {
2195                          elem.className = value;
2196  
2197                      } else {
2198                          setClass = " " + elem.className + " ";
2199  
2200                          for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2201                              if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
2202                                  setClass += classNames[ c ] + " ";
2203                              }
2204                          }
2205                          elem.className = jQuery.trim( setClass );
2206                      }
2207                  }
2208              }
2209          }
2210  
2211          return this;
2212      },
2213  
2214      removeClass: function( value ) {
2215          var classNames, i, l, elem, className, c, cl;
2216  
2217          if ( jQuery.isFunction( value ) ) {
2218              return this.each(function( j ) {
2219                  jQuery( this ).removeClass( value.call(this, j, this.className) );
2220              });
2221          }
2222  
2223          if ( (value && typeof value === "string") || value === undefined ) {
2224              classNames = ( value || "" ).split( rspace );
2225  
2226              for ( i = 0, l = this.length; i < l; i++ ) {
2227                  elem = this[ i ];
2228  
2229                  if ( elem.nodeType === 1 && elem.className ) {
2230                      if ( value ) {
2231                          className = (" " + elem.className + " ").replace( rclass, " " );
2232                          for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2233                              className = className.replace(" " + classNames[ c ] + " ", " ");
2234                          }
2235                          elem.className = jQuery.trim( className );
2236  
2237                      } else {
2238                          elem.className = "";
2239                      }
2240                  }
2241              }
2242          }
2243  
2244          return this;
2245      },
2246  
2247      toggleClass: function( value, stateVal ) {
2248          var type = typeof value,
2249              isBool = typeof stateVal === "boolean";
2250  
2251          if ( jQuery.isFunction( value ) ) {
2252              return this.each(function( i ) {
2253                  jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
2254              });
2255          }
2256  
2257          return this.each(function() {
2258              if ( type === "string" ) {
2259                  // toggle individual class names
2260                  var className,
2261                      i = 0,
2262                      self = jQuery( this ),
2263                      state = stateVal,
2264                      classNames = value.split( rspace );
2265  
2266                  while ( (className = classNames[ i++ ]) ) {
2267                      // check each className given, space seperated list
2268                      state = isBool ? state : !self.hasClass( className );
2269                      self[ state ? "addClass" : "removeClass" ]( className );
2270                  }
2271  
2272              } else if ( type === "undefined" || type === "boolean" ) {
2273                  if ( this.className ) {
2274                      // store className if set
2275                      jQuery._data( this, "__className__", this.className );
2276                  }
2277  
2278                  // toggle whole className
2279                  this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2280              }
2281          });
2282      },
2283  
2284      hasClass: function( selector ) {
2285          var className = " " + selector + " ",
2286              i = 0,
2287              l = this.length;
2288          for ( ; i < l; i++ ) {
2289              if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
2290                  return true;
2291              }
2292          }
2293  
2294          return false;
2295      },
2296  
2297      val: function( value ) {
2298          var hooks, ret, isFunction,
2299              elem = this[0];
2300  
2301          if ( !arguments.length ) {
2302              if ( elem ) {
2303                  hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
2304  
2305                  if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2306                      return ret;
2307                  }
2308  
2309                  ret = elem.value;
2310  
2311                  return typeof ret === "string" ?
2312                      // handle most common string cases
2313                      ret.replace(rreturn, "") :
2314                      // handle cases where value is null/undef or number
2315                      ret == null ? "" : ret;
2316              }
2317  
2318              return;
2319          }
2320  
2321          isFunction = jQuery.isFunction( value );
2322  
2323          return this.each(function( i ) {
2324              var self = jQuery(this), val;
2325  
2326              if ( this.nodeType !== 1 ) {
2327                  return;
2328              }
2329  
2330              if ( isFunction ) {
2331                  val = value.call( this, i, self.val() );
2332              } else {
2333                  val = value;
2334              }
2335  
2336              // Treat null/undefined as ""; convert numbers to string
2337              if ( val == null ) {
2338                  val = "";
2339              } else if ( typeof val === "number" ) {
2340                  val += "";
2341              } else if ( jQuery.isArray( val ) ) {
2342                  val = jQuery.map(val, function ( value ) {
2343                      return value == null ? "" : value + "";
2344                  });
2345              }
2346  
2347              hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
2348  
2349              // If set returns undefined, fall back to normal setting
2350              if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2351                  this.value = val;
2352              }
2353          });
2354      }
2355  });
2356  
2357  jQuery.extend({
2358      valHooks: {
2359          option: {
2360              get: function( elem ) {
2361                  // attributes.value is undefined in Blackberry 4.7 but
2362                  // uses .value. See #6932
2363                  var val = elem.attributes.value;
2364                  return !val || val.specified ? elem.value : elem.text;
2365              }
2366          },
2367          select: {
2368              get: function( elem ) {
2369                  var value, i, max, option,
2370                      index = elem.selectedIndex,
2371                      values = [],
2372                      options = elem.options,
2373                      one = elem.type === "select-one";
2374  
2375                  // Nothing was selected
2376                  if ( index < 0 ) {
2377                      return null;
2378                  }
2379  
2380                  // Loop through all the selected options
2381                  i = one ? index : 0;
2382                  max = one ? index + 1 : options.length;
2383                  for ( ; i < max; i++ ) {
2384                      option = options[ i ];
2385  
2386                      // Don't return options that are disabled or in a disabled optgroup
2387                      if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2388                              (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2389  
2390                          // Get the specific value for the option
2391                          value = jQuery( option ).val();
2392  
2393                          // We don't need an array for one selects
2394                          if ( one ) {
2395                              return value;
2396                          }
2397  
2398                          // Multi-Selects return an array
2399                          values.push( value );
2400                      }
2401                  }
2402  
2403                  // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2404                  if ( one && !values.length && options.length ) {
2405                      return jQuery( options[ index ] ).val();
2406                  }
2407  
2408                  return values;
2409              },
2410  
2411              set: function( elem, value ) {
2412                  var values = jQuery.makeArray( value );
2413  
2414                  jQuery(elem).find("option").each(function() {
2415                      this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2416                  });
2417  
2418                  if ( !values.length ) {
2419                      elem.selectedIndex = -1;
2420                  }
2421                  return values;
2422              }
2423          }
2424      },
2425  
2426      attrFn: {
2427          val: true,
2428          css: true,
2429          html: true,
2430          text: true,
2431          data: true,
2432          width: true,
2433          height: true,
2434          offset: true
2435      },
2436  
2437      attr: function( elem, name, value, pass ) {
2438          var ret, hooks, notxml,
2439              nType = elem.nodeType;
2440  
2441          // don't get/set attributes on text, comment and attribute nodes
2442          if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2443              return;
2444          }
2445  
2446          if ( pass && name in jQuery.attrFn ) {
2447              return jQuery( elem )[ name ]( value );
2448          }
2449  
2450          // Fallback to prop when attributes are not supported
2451          if ( typeof elem.getAttribute === "undefined" ) {
2452              return jQuery.prop( elem, name, value );
2453          }
2454  
2455          notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2456  
2457          // All attributes are lowercase
2458          // Grab necessary hook if one is defined
2459          if ( notxml ) {
2460              name = name.toLowerCase();
2461              hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
2462          }
2463  
2464          if ( value !== undefined ) {
2465  
2466              if ( value === null ) {
2467                  jQuery.removeAttr( elem, name );
2468                  return;
2469  
2470              } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2471                  return ret;
2472  
2473              } else {
2474                  elem.setAttribute( name, "" + value );
2475                  return value;
2476              }
2477  
2478          } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
2479              return ret;
2480  
2481          } else {
2482  
2483              ret = elem.getAttribute( name );
2484  
2485              // Non-existent attributes return null, we normalize to undefined
2486              return ret === null ?
2487                  undefined :
2488                  ret;
2489          }
2490      },
2491  
2492      removeAttr: function( elem, value ) {
2493          var propName, attrNames, name, l,
2494              i = 0;
2495  
2496          if ( value && elem.nodeType === 1 ) {
2497              attrNames = value.toLowerCase().split( rspace );
2498              l = attrNames.length;
2499  
2500              for ( ; i < l; i++ ) {
2501                  name = attrNames[ i ];
2502  
2503                  if ( name ) {
2504                      propName = jQuery.propFix[ name ] || name;
2505  
2506                      // See #9699 for explanation of this approach (setting first, then removal)
2507                      jQuery.attr( elem, name, "" );
2508                      elem.removeAttribute( getSetAttribute ? name : propName );
2509  
2510                      // Set corresponding property to false for boolean attributes
2511                      if ( rboolean.test( name ) && propName in elem ) {
2512                          elem[ propName ] = false;
2513                      }
2514                  }
2515              }
2516          }
2517      },
2518  
2519      attrHooks: {
2520          type: {
2521              set: function( elem, value ) {
2522                  // We can't allow the type property to be changed (since it causes problems in IE)
2523                  if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2524                      jQuery.error( "type property can't be changed" );
2525                  } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2526                      // Setting the type on a radio button after the value resets the value in IE6-9
2527                      // Reset value to it's default in case type is set after value
2528                      // This is for element creation
2529                      var val = elem.value;
2530                      elem.setAttribute( "type", value );
2531                      if ( val ) {
2532                          elem.value = val;
2533                      }
2534                      return value;
2535                  }
2536              }
2537          },
2538          // Use the value property for back compat
2539          // Use the nodeHook for button elements in IE6/7 (#1954)
2540          value: {
2541              get: function( elem, name ) {
2542                  if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2543                      return nodeHook.get( elem, name );
2544                  }
2545                  return name in elem ?
2546                      elem.value :
2547                      null;
2548              },
2549              set: function( elem, value, name ) {
2550                  if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2551                      return nodeHook.set( elem, value, name );
2552                  }
2553                  // Does not return so that setAttribute is also used
2554                  elem.value = value;
2555              }
2556          }
2557      },
2558  
2559      propFix: {
2560          tabindex: "tabIndex",
2561          readonly: "readOnly",
2562          "for": "htmlFor",
2563          "class": "className",
2564          maxlength: "maxLength",
2565          cellspacing: "cellSpacing",
2566          cellpadding: "cellPadding",
2567          rowspan: "rowSpan",
2568          colspan: "colSpan",
2569          usemap: "useMap",
2570          frameborder: "frameBorder",
2571          contenteditable: "contentEditable"
2572      },
2573  
2574      prop: function( elem, name, value ) {
2575          var ret, hooks, notxml,
2576              nType = elem.nodeType;
2577  
2578          // don't get/set properties on text, comment and attribute nodes
2579          if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2580              return;
2581          }
2582  
2583          notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2584  
2585          if ( notxml ) {
2586              // Fix name and attach hooks
2587              name = jQuery.propFix[ name ] || name;
2588              hooks = jQuery.propHooks[ name ];
2589          }
2590  
2591          if ( value !== undefined ) {
2592              if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2593                  return ret;
2594  
2595              } else {
2596                  return ( elem[ name ] = value );
2597              }
2598  
2599          } else {
2600              if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
2601                  return ret;
2602  
2603              } else {
2604                  return elem[ name ];
2605              }
2606          }
2607      },
2608  
2609      propHooks: {
2610          tabIndex: {
2611              get: function( elem ) {
2612                  // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2613                  // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2614                  var attributeNode = elem.getAttributeNode("tabindex");
2615  
2616                  return attributeNode && attributeNode.specified ?
2617                      parseInt( attributeNode.value, 10 ) :
2618                      rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2619                          0 :
2620                          undefined;
2621              }
2622          }
2623      }
2624  });
2625  
2626  // Add the tabIndex propHook to attrHooks for back-compat (different case is intentional)
2627  jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex;
2628  
2629  // Hook for boolean attributes
2630  boolHook = {
2631      get: function( elem, name ) {
2632          // Align boolean attributes with corresponding properties
2633          // Fall back to attribute presence where some booleans are not supported
2634          var attrNode,
2635              property = jQuery.prop( elem, name );
2636          return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
2637              name.toLowerCase() :
2638              undefined;
2639      },
2640      set: function( elem, value, name ) {
2641          var propName;
2642          if ( value === false ) {
2643              // Remove boolean attributes when set to false
2644              jQuery.removeAttr( elem, name );
2645          } else {
2646              // value is true since we know at this point it's type boolean and not false
2647              // Set boolean attributes to the same name and set the DOM property
2648              propName = jQuery.propFix[ name ] || name;
2649              if ( propName in elem ) {
2650                  // Only set the IDL specifically if it already exists on the element
2651                  elem[ propName ] = true;
2652              }
2653  
2654              elem.setAttribute( name, name.toLowerCase() );
2655          }
2656          return name;
2657      }
2658  };
2659  
2660  // IE6/7 do not support getting/setting some attributes with get/setAttribute
2661  if ( !getSetAttribute ) {
2662  
2663      fixSpecified = {
2664          name: true,
2665          id: true
2666      };
2667  
2668      // Use this for any attribute in IE6/7
2669      // This fixes almost every IE6/7 issue
2670      nodeHook = jQuery.valHooks.button = {
2671          get: function( elem, name ) {
2672              var ret;
2673              ret = elem.getAttributeNode( name );
2674              return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ?
2675                  ret.nodeValue :
2676                  undefined;
2677          },
2678          set: function( elem, value, name ) {
2679              // Set the existing or create a new attribute node
2680              var ret = elem.getAttributeNode( name );
2681              if ( !ret ) {
2682                  ret = document.createAttribute( name );
2683                  elem.setAttributeNode( ret );
2684              }
2685              return ( ret.nodeValue = value + "" );
2686          }
2687      };
2688  
2689      // Apply the nodeHook to tabindex
2690      jQuery.attrHooks.tabindex.set = nodeHook.set;
2691  
2692      // Set width and height to auto instead of 0 on empty string( Bug #8150 )
2693      // This is for removals
2694      jQuery.each([ "width", "height" ], function( i, name ) {
2695          jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2696              set: function( elem, value ) {
2697                  if ( value === "" ) {
2698                      elem.setAttribute( name, "auto" );
2699                      return value;
2700                  }
2701              }
2702          });
2703      });
2704  
2705      // Set contenteditable to false on removals(#10429)
2706      // Setting to empty string throws an error as an invalid value
2707      jQuery.attrHooks.contenteditable = {
2708          get: nodeHook.get,
2709          set: function( elem, value, name ) {
2710              if ( value === "" ) {
2711                  value = "false";
2712              }
2713              nodeHook.set( elem, value, name );
2714          }
2715      };
2716  }
2717  
2718  
2719  // Some attributes require a special call on IE
2720  if ( !jQuery.support.hrefNormalized ) {
2721      jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2722          jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2723              get: function( elem ) {
2724                  var ret = elem.getAttribute( name, 2 );
2725                  return ret === null ? undefined : ret;
2726              }
2727          });
2728      });
2729  }
2730  
2731  if ( !jQuery.support.style ) {
2732      jQuery.attrHooks.style = {
2733          get: function( elem ) {
2734              // Return undefined in the case of empty string
2735              // Normalize to lowercase since IE uppercases css property names
2736              return elem.style.cssText.toLowerCase() || undefined;
2737          },
2738          set: function( elem, value ) {
2739              return ( elem.style.cssText = "" + value );
2740          }
2741      };
2742  }
2743  
2744  // Safari mis-reports the default selected property of an option
2745  // Accessing the parent's selectedIndex property fixes it
2746  if ( !jQuery.support.optSelected ) {
2747      jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2748          get: function( elem ) {
2749              var parent = elem.parentNode;
2750  
2751              if ( parent ) {
2752                  parent.selectedIndex;
2753  
2754                  // Make sure that it also works with optgroups, see #5701
2755                  if ( parent.parentNode ) {
2756                      parent.parentNode.selectedIndex;
2757                  }
2758              }
2759              return null;
2760          }
2761      });
2762  }
2763  
2764  // IE6/7 call enctype encoding
2765  if ( !jQuery.support.enctype ) {
2766      jQuery.propFix.enctype = "encoding";
2767  }
2768  
2769  // Radios and checkboxes getter/setter
2770  if ( !jQuery.support.checkOn ) {
2771      jQuery.each([ "radio", "checkbox" ], function() {
2772          jQuery.valHooks[ this ] = {
2773              get: function( elem ) {
2774                  // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2775                  return elem.getAttribute("value") === null ? "on" : elem.value;
2776              }
2777          };
2778      });
2779  }
2780  jQuery.each([ "radio", "checkbox" ], function() {
2781      jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2782          set: function( elem, value ) {
2783              if ( jQuery.isArray( value ) ) {
2784                  return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
2785              }
2786          }
2787      });
2788  });
2789  
2790  
2791  
2792  
2793  var rformElems = /^(?:textarea|input|select)$/i,
2794      rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/,
2795      rhoverHack = /\bhover(\.\S+)?\b/,
2796      rkeyEvent = /^key/,
2797      rmouseEvent = /^(?:mouse|contextmenu)|click/,
2798      rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
2799      rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,
2800      quickParse = function( selector ) {
2801          var quick = rquickIs.exec( selector );
2802          if ( quick ) {
2803              //   0  1    2   3
2804              // [ _, tag, id, class ]
2805              quick[1] = ( quick[1] || "" ).toLowerCase();
2806              quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" );
2807          }
2808          return quick;
2809      },
2810      quickIs = function( elem, m ) {
2811          var attrs = elem.attributes || {};
2812          return (
2813              (!m[1] || elem.nodeName.toLowerCase() === m[1]) &&
2814              (!m[2] || (attrs.id || {}).value === m[2]) &&
2815              (!m[3] || m[3].test( (attrs[ "class" ] || {}).value ))
2816          );
2817      },
2818      hoverHack = function( events ) {
2819          return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
2820      };
2821  
2822  /*
2823   * Helper functions for managing events -- not part of the public interface.
2824   * Props to Dean Edwards' addEvent library for many of the ideas.
2825   */
2826  jQuery.event = {
2827  
2828      add: function( elem, types, handler, data, selector ) {
2829  
2830          var elemData, eventHandle, events,
2831              t, tns, type, namespaces, handleObj,
2832              handleObjIn, quick, handlers, special;
2833  
2834          // Don't attach events to noData or text/comment nodes (allow plain objects tho)
2835          if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {
2836              return;
2837          }
2838  
2839          // Caller can pass in an object of custom data in lieu of the handler
2840          if ( handler.handler ) {
2841              handleObjIn = handler;
2842              handler = handleObjIn.handler;
2843          }
2844  
2845          // Make sure that the handler has a unique ID, used to find/remove it later
2846          if ( !handler.guid ) {
2847              handler.guid = jQuery.guid++;
2848          }
2849  
2850          // Init the element's event structure and main handler, if this is the first
2851          events = elemData.events;
2852          if ( !events ) {
2853              elemData.events = events = {};
2854          }
2855          eventHandle = elemData.handle;
2856          if ( !eventHandle ) {
2857              elemData.handle = eventHandle = function( e ) {
2858                  // Discard the second event of a jQuery.event.trigger() and
2859                  // when an event is called after a page has unloaded
2860                  return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2861                      jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
2862                      undefined;
2863              };
2864              // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
2865              eventHandle.elem = elem;
2866          }
2867  
2868          // Handle multiple events separated by a space
2869          // jQuery(...).bind("mouseover mouseout", fn);
2870          types = jQuery.trim( hoverHack(types) ).split( " " );
2871          for ( t = 0; t < types.length; t++ ) {
2872  
2873              tns = rtypenamespace.exec( types[t] ) || [];
2874              type = tns[1];
2875              namespaces = ( tns[2] || "" ).split( "." ).sort();
2876  
2877              // If event changes its type, use the special event handlers for the changed type
2878              special = jQuery.event.special[ type ] || {};
2879  
2880              // If selector defined, determine special event api type, otherwise given type
2881              type = ( selector ? special.delegateType : special.bindType ) || type;
2882  
2883              // Update special based on newly reset type
2884              special = jQuery.event.special[ type ] || {};
2885  
2886              // handleObj is passed to all event handlers
2887              handleObj = jQuery.extend({
2888                  type: type,
2889                  origType: tns[1],
2890                  data: data,
2891                  handler: handler,
2892                  guid: handler.guid,
2893                  selector: selector,
2894                  quick: quickParse( selector ),
2895                  namespace: namespaces.join(".")
2896              }, handleObjIn );
2897  
2898              // Init the event handler queue if we're the first
2899              handlers = events[ type ];
2900              if ( !handlers ) {
2901                  handlers = events[ type ] = [];
2902                  handlers.delegateCount = 0;
2903  
2904                  // Only use addEventListener/attachEvent if the special events handler returns false
2905                  if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2906                      // Bind the global event handler to the element
2907                      if ( elem.addEventListener ) {
2908                          elem.addEventListener( type, eventHandle, false );
2909  
2910                      } else if ( elem.attachEvent ) {
2911                          elem.attachEvent( "on" + type, eventHandle );
2912                      }
2913                  }
2914              }
2915  
2916              if ( special.add ) {
2917                  special.add.call( elem, handleObj );
2918  
2919                  if ( !handleObj.handler.guid ) {
2920                      handleObj.handler.guid = handler.guid;
2921                  }
2922              }
2923  
2924              // Add to the element's handler list, delegates in front
2925              if ( selector ) {
2926                  handlers.splice( handlers.delegateCount++, 0, handleObj );
2927              } else {
2928                  handlers.push( handleObj );
2929              }
2930  
2931              // Keep track of which events have ever been used, for event optimization
2932              jQuery.event.global[ type ] = true;
2933          }
2934  
2935          // Nullify elem to prevent memory leaks in IE
2936          elem = null;
2937      },
2938  
2939      global: {},
2940  
2941      // Detach an event or set of events from an element
2942      remove: function( elem, types, handler, selector, mappedTypes ) {
2943  
2944          var elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
2945              t, tns, type, origType, namespaces, origCount,
2946              j, events, special, handle, eventType, handleObj;
2947  
2948          if ( !elemData || !(events = elemData.events) ) {
2949              return;
2950          }
2951  
2952          // Once for each type.namespace in types; type may be omitted
2953          types = jQuery.trim( hoverHack( types || "" ) ).split(" ");
2954          for ( t = 0; t < types.length; t++ ) {
2955              tns = rtypenamespace.exec( types[t] ) || [];
2956              type = origType = tns[1];
2957              namespaces = tns[2];
2958  
2959              // Unbind all events (on this namespace, if provided) for the element
2960              if ( !type ) {
2961                  for ( type in events ) {
2962                      jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
2963                  }
2964                  continue;
2965              }
2966  
2967              special = jQuery.event.special[ type ] || {};
2968              type = ( selector? special.delegateType : special.bindType ) || type;
2969              eventType = events[ type ] || [];
2970              origCount = eventType.length;
2971              namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
2972  
2973              // Remove matching events
2974              for ( j = 0; j < eventType.length; j++ ) {
2975                  handleObj = eventType[ j ];
2976  
2977                  if ( ( mappedTypes || origType === handleObj.origType ) &&
2978                       ( !handler || handler.guid === handleObj.guid ) &&
2979                       ( !namespaces || namespaces.test( handleObj.namespace ) ) &&
2980                       ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
2981                      eventType.splice( j--, 1 );
2982  
2983                      if ( handleObj.selector ) {
2984                          eventType.delegateCount--;
2985                      }
2986                      if ( special.remove ) {
2987                          special.remove.call( elem, handleObj );
2988                      }
2989                  }
2990              }
2991  
2992              // Remove generic event handler if we removed something and no more handlers exist
2993              // (avoids potential for endless recursion during removal of special event handlers)
2994              if ( eventType.length === 0 && origCount !== eventType.length ) {
2995                  if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2996                      jQuery.removeEvent( elem, type, elemData.handle );
2997                  }
2998  
2999                  delete events[ type ];
3000              }
3001          }
3002  
3003          // Remove the expando if it's no longer used
3004          if ( jQuery.isEmptyObject( events ) ) {
3005              handle = elemData.handle;
3006              if ( handle ) {
3007                  handle.elem = null;
3008              }
3009  
3010              // removeData also checks for emptiness and clears the expando if empty
3011              // so use it instead of delete
3012              jQuery.removeData( elem, [ "events", "handle" ], true );
3013          }
3014      },
3015  
3016      // Events that are safe to short-circuit if no handlers are attached.
3017      // Native DOM events should not be added, they may have inline handlers.
3018      customEvent: {
3019          "getData": true,
3020          "setData": true,
3021          "changeData": true
3022      },
3023  
3024      trigger: function( event, data, elem, onlyHandlers ) {
3025          // Don't do events on text and comment nodes
3026          if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {
3027              return;
3028          }
3029  
3030          // Event object or event type
3031          var type = event.type || event,
3032              namespaces = [],
3033              cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType;
3034  
3035          // focus/blur morphs to focusin/out; ensure we're not firing them right now
3036          if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
3037              return;
3038          }
3039  
3040          if ( type.indexOf( "!" ) >= 0 ) {
3041              // Exclusive events trigger only for the exact event (no namespaces)
3042              type = type.slice(0, -1);
3043              exclusive = true;
3044          }
3045  
3046          if ( type.indexOf( "." ) >= 0 ) {
3047              // Namespaced trigger; create a regexp to match event type in handle()
3048              namespaces = type.split(".");
3049              type = namespaces.shift();
3050              namespaces.sort();
3051          }
3052  
3053          if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
3054              // No jQuery handlers for this event type, and it can't have inline handlers
3055              return;
3056          }
3057  
3058          // Caller can pass in an Event, Object, or just an event type string
3059          event = typeof event === "object" ?
3060              // jQuery.Event object
3061              event[ jQuery.expando ] ? event :
3062              // Object literal
3063              new jQuery.Event( type, event ) :
3064              // Just the event type (string)
3065              new jQuery.Event( type );
3066  
3067          event.type = type;
3068          event.isTrigger = true;
3069          event.exclusive = exclusive;
3070          event.namespace = namespaces.join( "." );
3071          event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
3072          ontype = type.indexOf( ":" ) < 0 ? "on" + type : "";
3073  
3074          // Handle a global trigger
3075          if ( !elem ) {
3076  
3077              // TODO: Stop taunting the data cache; remove global events and always attach to document
3078              cache = jQuery.cache;
3079              for ( i in cache ) {
3080                  if ( cache[ i ].events && cache[ i ].events[ type ] ) {
3081                      jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );
3082                  }
3083              }
3084              return;
3085          }
3086  
3087          // Clean up the event in case it is being reused
3088          event.result = undefined;
3089          if ( !event.target ) {
3090              event.target = elem;
3091          }
3092  
3093          // Clone any incoming data and prepend the event, creating the handler arg list
3094          data = data != null ? jQuery.makeArray( data ) : [];
3095          data.unshift( event );
3096  
3097          // Allow special events to draw outside the lines
3098          special = jQuery.event.special[ type ] || {};
3099          if ( special.trigger && special.trigger.apply( elem, data ) === false ) {
3100              return;
3101          }
3102  
3103          // Determine event propagation path in advance, per W3C events spec (#9951)
3104          // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
3105          eventPath = [[ elem, special.bindType || type ]];
3106          if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
3107  
3108              bubbleType = special.delegateType || type;
3109              cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;
3110              old = null;
3111              for ( ; cur; cur = cur.parentNode ) {
3112                  eventPath.push([ cur, bubbleType ]);
3113                  old = cur;
3114              }
3115  
3116              // Only add window if we got to document (e.g., not plain obj or detached DOM)
3117              if ( old && old === elem.ownerDocument ) {
3118                  eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);
3119              }
3120          }
3121  
3122          // Fire handlers on the event path
3123          for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {
3124  
3125              cur = eventPath[i][0];
3126              event.type = eventPath[i][1];
3127  
3128              handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
3129              if ( handle ) {
3130                  handle.apply( cur, data );
3131              }
3132              // Note that this is a bare JS function and not a jQuery handler
3133              handle = ontype && cur[ ontype ];
3134              if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) {
3135                  event.preventDefault();
3136              }
3137          }
3138          event.type = type;
3139  
3140          // If nobody prevented the default action, do it now
3141          if ( !onlyHandlers && !event.isDefaultPrevented() ) {
3142  
3143              if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&
3144                  !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
3145  
3146                  // Call a native DOM method on the target with the same name name as the event.
3147                  // Can't use an .isFunction() check here because IE6/7 fails that test.
3148                  // Don't do default actions on window, that's where global variables be (#6170)
3149                  // IE<9 dies on focus/blur to hidden element (#1486)
3150                  if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {
3151  
3152                      // Don't re-trigger an onFOO event when we call its FOO() method
3153                      old = elem[ ontype ];
3154  
3155                      if ( old ) {
3156                          elem[ ontype ] = null;
3157                      }
3158  
3159                      // Prevent re-triggering of the same event, since we already bubbled it above
3160                      jQuery.event.triggered = type;
3161                      elem[ type ]();
3162                      jQuery.event.triggered = undefined;
3163  
3164                      if ( old ) {
3165                          elem[ ontype ] = old;
3166                      }
3167                  }
3168              }
3169          }
3170  
3171          return event.result;
3172      },
3173  
3174      dispatch: function( event ) {
3175  
3176          // Make a writable jQuery.Event from the native event object
3177          event = jQuery.event.fix( event || window.event );
3178  
3179          var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),
3180              delegateCount = handlers.delegateCount,
3181              args = [].slice.call( arguments, 0 ),
3182              run_all = !event.exclusive && !event.namespace,
3183              handlerQueue = [],
3184              i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related;
3185  
3186          // Use the fix-ed jQuery.Event rather than the (read-only) native event
3187          args[0] = event;
3188          event.delegateTarget = this;
3189  
3190          // Determine handlers that should run if there are delegated events
3191          // Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861)
3192          if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) {
3193  
3194              // Pregenerate a single jQuery object for reuse with .is()
3195              jqcur = jQuery(this);
3196              jqcur.context = this.ownerDocument || this;
3197  
3198              for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {
3199                  selMatch = {};
3200                  matches = [];
3201                  jqcur[0] = cur;
3202                  for ( i = 0; i < delegateCount; i++ ) {
3203                      handleObj = handlers[ i ];
3204                      sel = handleObj.selector;
3205  
3206                      if ( selMatch[ sel ] === undefined ) {
3207                          selMatch[ sel ] = (
3208                              handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel )
3209                          );
3210                      }
3211                      if ( selMatch[ sel ] ) {
3212                          matches.push( handleObj );
3213                      }
3214                  }
3215                  if ( matches.length ) {
3216                      handlerQueue.push({ elem: cur, matches: matches });
3217                  }
3218              }
3219          }
3220  
3221          // Add the remaining (directly-bound) handlers
3222          if ( handlers.length > delegateCount ) {
3223              handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });
3224          }
3225  
3226          // Run delegates first; they may want to stop propagation beneath us
3227          for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {
3228              matched = handlerQueue[ i ];
3229              event.currentTarget = matched.elem;
3230  
3231              for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {
3232                  handleObj = matched.matches[ j ];
3233  
3234                  // Triggered event must either 1) be non-exclusive and have no namespace, or
3235                  // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
3236                  if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {
3237  
3238                      event.data = handleObj.data;
3239                      event.handleObj = handleObj;
3240  
3241                      ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
3242                              .apply( matched.elem, args );
3243  
3244                      if ( ret !== undefined ) {
3245                          event.result = ret;
3246                          if ( ret === false ) {
3247                              event.preventDefault();
3248                              event.stopPropagation();
3249                          }
3250                      }
3251                  }
3252              }
3253          }
3254  
3255          return event.result;
3256      },
3257  
3258      // Includes some event props shared by KeyEvent and MouseEvent
3259      // *** attrChange attrName relatedNode srcElement  are not normalized, non-W3C, deprecated, will be removed in 1.8 ***
3260      props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
3261  
3262      fixHooks: {},
3263  
3264      keyHooks: {
3265          props: "char charCode key keyCode".split(" "),
3266          filter: function( event, original ) {
3267  
3268              // Add which for key events
3269              if ( event.which == null ) {
3270                  event.which = original.charCode != null ? original.charCode : original.keyCode;
3271              }
3272  
3273              return event;
3274          }
3275      },
3276  
3277      mouseHooks: {
3278          props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
3279          filter: function( event, original ) {
3280              var eventDoc, doc, body,
3281                  button = original.button,
3282                  fromElement = original.fromElement;
3283  
3284              // Calculate pageX/Y if missing and clientX/Y available
3285              if ( event.pageX == null && original.clientX != null ) {
3286                  eventDoc = event.target.ownerDocument || document;
3287                  doc = eventDoc.documentElement;
3288                  body = eventDoc.body;
3289  
3290                  event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
3291                  event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
3292              }
3293  
3294              // Add relatedTarget, if necessary
3295              if ( !event.relatedTarget && fromElement ) {
3296                  event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
3297              }
3298  
3299              // Add which for click: 1 === left; 2 === middle; 3 === right
3300              // Note: button is not normalized, so don't use it
3301              if ( !event.which && button !== undefined ) {
3302                  event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
3303              }
3304  
3305              return event;
3306          }
3307      },
3308  
3309      fix: function( event ) {
3310          if ( event[ jQuery.expando ] ) {
3311              return event;
3312          }
3313  
3314          // Create a writable copy of the event object and normalize some properties
3315          var i, prop,
3316              originalEvent = event,
3317              fixHook = jQuery.event.fixHooks[ event.type ] || {},
3318              copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
3319  
3320          event = jQuery.Event( originalEvent );
3321  
3322          for ( i = copy.length; i; ) {
3323              prop = copy[ --i ];
3324              event[ prop ] = originalEvent[ prop ];
3325          }
3326  
3327          // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)
3328          if ( !event.target ) {
3329              event.target = originalEvent.srcElement || document;
3330          }
3331  
3332          // Target should not be a text node (#504, Safari)
3333          if ( event.target.nodeType === 3 ) {
3334              event.target = event.target.parentNode;
3335          }
3336  
3337          // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8)
3338          if ( event.metaKey === undefined ) {
3339              event.metaKey = event.ctrlKey;
3340          }
3341  
3342          return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
3343      },
3344  
3345      special: {
3346          ready: {
3347              // Make sure the ready event is setup
3348              setup: jQuery.bindReady
3349          },
3350  
3351          load: {
3352              // Prevent triggered image.load events from bubbling to window.load
3353              noBubble: true
3354          },
3355  
3356          focus: {
3357              delegateType: "focusin"
3358          },
3359          blur: {
3360              delegateType: "focusout"
3361          },
3362  
3363          beforeunload: {
3364              setup: function( data, namespaces, eventHandle ) {
3365                  // We only want to do this special case on windows
3366                  if ( jQuery.isWindow( this ) ) {
3367                      this.onbeforeunload = eventHandle;
3368                  }
3369              },
3370  
3371              teardown: function( namespaces, eventHandle ) {
3372                  if ( this.onbeforeunload === eventHandle ) {
3373                      this.onbeforeunload = null;
3374                  }
3375              }
3376          }
3377      },
3378  
3379      simulate: function( type, elem, event, bubble ) {
3380          // Piggyback on a donor event to simulate a different one.
3381          // Fake originalEvent to avoid donor's stopPropagation, but if the
3382          // simulated event prevents default then we do the same on the donor.
3383          var e = jQuery.extend(
3384              new jQuery.Event(),
3385              event,
3386              { type: type,
3387                  isSimulated: true,
3388                  originalEvent: {}
3389              }
3390          );
3391          if ( bubble ) {
3392              jQuery.event.trigger( e, null, elem );
3393          } else {
3394              jQuery.event.dispatch.call( elem, e );
3395          }
3396          if ( e.isDefaultPrevented() ) {
3397              event.preventDefault();
3398          }
3399      }
3400  };
3401  
3402  // Some plugins are using, but it's undocumented/deprecated and will be removed.
3403  // The 1.7 special event interface should provide all the hooks needed now.
3404  jQuery.event.handle = jQuery.event.dispatch;
3405  
3406  jQuery.removeEvent = document.removeEventListener ?
3407      function( elem, type, handle ) {
3408          if ( elem.removeEventListener ) {
3409              elem.removeEventListener( type, handle, false );
3410          }
3411      } :
3412      function( elem, type, handle ) {
3413          if ( elem.detachEvent ) {
3414              elem.detachEvent( "on" + type, handle );
3415          }
3416      };
3417  
3418  jQuery.Event = function( src, props ) {
3419      // Allow instantiation without the 'new' keyword
3420      if ( !(this instanceof jQuery.Event) ) {
3421          return new jQuery.Event( src, props );
3422      }
3423  
3424      // Event object
3425      if ( src && src.type ) {
3426          this.originalEvent = src;
3427          this.type = src.type;
3428  
3429          // Events bubbling up the document may have been marked as prevented
3430          // by a handler lower down the tree; reflect the correct value.
3431          this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
3432              src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
3433  
3434      // Event type
3435      } else {
3436          this.type = src;
3437      }
3438  
3439      // Put explicitly provided properties onto the event object
3440      if ( props ) {
3441          jQuery.extend( this, props );
3442      }
3443  
3444      // Create a timestamp if incoming event doesn't have one
3445      this.timeStamp = src && src.timeStamp || jQuery.now();
3446  
3447      // Mark it as fixed
3448      this[ jQuery.expando ] = true;
3449  };
3450  
3451  function returnFalse() {
3452      return false;
3453  }
3454  function returnTrue() {
3455      return true;
3456  }
3457  
3458  // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3459  // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3460  jQuery.Event.prototype = {
3461      preventDefault: function() {
3462          this.isDefaultPrevented = returnTrue;
3463  
3464          var e = this.originalEvent;
3465          if ( !e ) {
3466              return;
3467          }
3468  
3469          // if preventDefault exists run it on the original event
3470          if ( e.preventDefault ) {
3471              e.preventDefault();
3472  
3473          // otherwise set the returnValue property of the original event to false (IE)
3474          } else {
3475              e.returnValue = false;
3476          }
3477      },
3478      stopPropagation: function() {
3479          this.isPropagationStopped = returnTrue;
3480  
3481          var e = this.originalEvent;
3482          if ( !e ) {
3483              return;
3484          }
3485          // if stopPropagation exists run it on the original event
3486          if ( e.stopPropagation ) {
3487              e.stopPropagation();
3488          }
3489          // otherwise set the cancelBubble property of the original event to true (IE)
3490          e.cancelBubble = true;
3491      },
3492      stopImmediatePropagation: function() {
3493          this.isImmediatePropagationStopped = returnTrue;
3494          this.stopPropagation();
3495      },
3496      isDefaultPrevented: returnFalse,
3497      isPropagationStopped: returnFalse,
3498      isImmediatePropagationStopped: returnFalse
3499  };
3500  
3501  // Create mouseenter/leave events using mouseover/out and event-time checks
3502  jQuery.each({
3503      mouseenter: "mouseover",
3504      mouseleave: "mouseout"
3505  }, function( orig, fix ) {
3506      jQuery.event.special[ orig ] = {
3507          delegateType: fix,
3508          bindType: fix,
3509  
3510          handle: function( event ) {
3511              var target = this,
3512                  related = event.relatedTarget,
3513                  handleObj = event.handleObj,
3514                  selector = handleObj.selector,
3515                  ret;
3516  
3517              // For mousenter/leave call the handler if related is outside the target.
3518              // NB: No relatedTarget if the mouse left/entered the browser window
3519              if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
3520                  event.type = handleObj.origType;
3521                  ret = handleObj.handler.apply( this, arguments );
3522                  event.type = fix;
3523              }
3524              return ret;
3525          }
3526      };
3527  });
3528  
3529  // IE submit delegation
3530  if ( !jQuery.support.submitBubbles ) {
3531  
3532      jQuery.event.special.submit = {
3533          setup: function() {
3534              // Only need this for delegated form submit events
3535              if ( jQuery.nodeName( this, "form" ) ) {
3536                  return false;
3537              }
3538  
3539              // Lazy-add a submit handler when a descendant form may potentially be submitted
3540              jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
3541                  // Node name check avoids a VML-related crash in IE (#9807)
3542                  var elem = e.target,
3543                      form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
3544                  if ( form && !form._submit_attached ) {
3545                      jQuery.event.add( form, "submit._submit", function( event ) {
3546                          // If form was submitted by the user, bubble the event up the tree
3547                          if ( this.parentNode && !event.isTrigger ) {
3548                              jQuery.event.simulate( "submit", this.parentNode, event, true );
3549                          }
3550                      });
3551                      form._submit_attached = true;
3552                  }
3553              });
3554              // return undefined since we don't need an event listener
3555          },
3556  
3557          teardown: function() {
3558              // Only need this for delegated form submit events
3559              if ( jQuery.nodeName( this, "form" ) ) {
3560                  return false;
3561              }
3562  
3563              // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
3564              jQuery.event.remove( this, "._submit" );
3565          }
3566      };
3567  }
3568  
3569  // IE change delegation and checkbox/radio fix
3570  if ( !jQuery.support.changeBubbles ) {
3571  
3572      jQuery.event.special.change = {
3573  
3574          setup: function() {
3575  
3576              if ( rformElems.test( this.nodeName ) ) {
3577                  // IE doesn't fire change on a check/radio until blur; trigger it on click
3578                  // after a propertychange. Eat the blur-change in special.change.handle.
3579                  // This still fires onchange a second time for check/radio after blur.
3580                  if ( this.type === "checkbox" || this.type === "radio" ) {
3581                      jQuery.event.add( this, "propertychange._change", function( event ) {
3582                          if ( event.originalEvent.propertyName === "checked" ) {
3583                              this._just_changed = true;
3584                          }
3585                      });
3586                      jQuery.event.add( this, "click._change", function( event ) {
3587                          if ( this._just_changed && !event.isTrigger ) {
3588                              this._just_changed = false;
3589                              jQuery.event.simulate( "change", this, event, true );
3590                          }
3591                      });
3592                  }
3593                  return false;
3594              }
3595              // Delegated event; lazy-add a change handler on descendant inputs
3596              jQuery.event.add( this, "beforeactivate._change", function( e ) {
3597                  var elem = e.target;
3598  
3599                  if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) {
3600                      jQuery.event.add( elem, "change._change", function( event ) {
3601                          if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
3602                              jQuery.event.simulate( "change", this.parentNode, event, true );
3603                          }
3604                      });
3605                      elem._change_attached = true;
3606                  }
3607              });
3608          },
3609  
3610          handle: function( event ) {
3611              var elem = event.target;
3612  
3613              // Swallow native change events from checkbox/radio, we already triggered them above
3614              if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
3615                  return event.handleObj.handler.apply( this, arguments );
3616              }
3617          },
3618  
3619          teardown: function() {
3620              jQuery.event.remove( this, "._change" );
3621  
3622              return rformElems.test( this.nodeName );
3623          }
3624      };
3625  }
3626  
3627  // Create "bubbling" focus and blur events
3628  if ( !jQuery.support.focusinBubbles ) {
3629      jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3630  
3631          // Attach a single capturing handler while someone wants focusin/focusout
3632          var attaches = 0,
3633              handler = function( event ) {
3634                  jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
3635              };
3636  
3637          jQuery.event.special[ fix ] = {
3638              setup: function() {
3639                  if ( attaches++ === 0 ) {
3640                      document.addEventListener( orig, handler, true );
3641                  }
3642              },
3643              teardown: function() {
3644                  if ( --attaches === 0 ) {
3645                      document.removeEventListener( orig, handler, true );
3646                  }
3647              }
3648          };
3649      });
3650  }
3651  
3652  jQuery.fn.extend({
3653  
3654      on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
3655          var origFn, type;
3656  
3657          // Types can be a map of types/handlers
3658          if ( typeof types === "object" ) {
3659              // ( types-Object, selector, data )
3660              if ( typeof selector !== "string" ) {
3661                  // ( types-Object, data )
3662                  data = selector;
3663                  selector = undefined;
3664              }
3665              for ( type in types ) {
3666                  this.on( type, selector, data, types[ type ], one );
3667              }
3668              return this;
3669          }
3670  
3671          if ( data == null && fn == null ) {
3672              // ( types, fn )
3673              fn = selector;
3674              data = selector = undefined;
3675          } else if ( fn == null ) {
3676              if ( typeof selector === "string" ) {
3677                  // ( types, selector, fn )
3678                  fn = data;
3679                  data = undefined;
3680              } else {
3681                  // ( types, data, fn )
3682                  fn = data;
3683                  data = selector;
3684                  selector = undefined;
3685              }
3686          }
3687          if ( fn === false ) {
3688              fn = returnFalse;
3689          } else if ( !fn ) {
3690              return this;
3691          }
3692  
3693          if ( one === 1 ) {
3694              origFn = fn;
3695              fn = function( event ) {
3696                  // Can use an empty set, since event contains the info
3697                  jQuery().off( event );
3698                  return origFn.apply( this, arguments );
3699              };
3700              // Use same guid so caller can remove using origFn
3701              fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
3702          }
3703          return this.each( function() {
3704              jQuery.event.add( this, types, fn, data, selector );
3705          });
3706      },
3707      one: function( types, selector, data, fn ) {
3708          return this.on.call( this, types, selector, data, fn, 1 );
3709      },
3710      off: function( types, selector, fn ) {
3711          if ( types && types.preventDefault && types.handleObj ) {
3712              // ( event )  dispatched jQuery.Event
3713              var handleObj = types.handleObj;
3714              jQuery( types.delegateTarget ).off(
3715                  handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type,
3716                  handleObj.selector,
3717                  handleObj.handler
3718              );
3719              return this;
3720          }
3721          if ( typeof types === "object" ) {
3722              // ( types-object [, selector] )
3723              for ( var type in types ) {
3724                  this.off( type, selector, types[ type ] );
3725              }
3726              return this;
3727          }
3728          if ( selector === false || typeof selector === "function" ) {
3729              // ( types [, fn] )
3730              fn = selector;
3731              selector = undefined;
3732          }
3733          if ( fn === false ) {
3734              fn = returnFalse;
3735          }
3736          return this.each(function() {
3737              jQuery.event.remove( this, types, fn, selector );
3738          });
3739      },
3740  
3741      bind: function( types, data, fn ) {
3742          return this.on( types, null, data, fn );
3743      },
3744      unbind: function( types, fn ) {
3745          return this.off( types, null, fn );
3746      },
3747  
3748      live: function( types, data, fn ) {
3749          jQuery( this.context ).on( types, this.selector, data, fn );
3750          return this;
3751      },
3752      die: function( types, fn ) {
3753          jQuery( this.context ).off( types, this.selector || "**", fn );
3754          return this;
3755      },
3756  
3757      delegate: function( selector, types, data, fn ) {
3758          return this.on( types, selector, data, fn );
3759      },
3760      undelegate: function( selector, types, fn ) {
3761          // ( namespace ) or ( selector, types [, fn] )
3762          return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn );
3763      },
3764  
3765      trigger: function( type, data ) {
3766          return this.each(function() {
3767              jQuery.event.trigger( type, data, this );
3768          });
3769      },
3770      triggerHandler: function( type, data ) {
3771          if ( this[0] ) {
3772              return jQuery.event.trigger( type, data, this[0], true );
3773          }
3774      },
3775  
3776      toggle: function( fn ) {
3777          // Save reference to arguments for access in closure
3778          var args = arguments,
3779              guid = fn.guid || jQuery.guid++,
3780              i = 0,
3781              toggler = function( event ) {
3782                  // Figure out which function to execute
3783                  var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3784                  jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3785  
3786                  // Make sure that clicks stop
3787                  event.preventDefault();
3788  
3789                  // and execute the function
3790                  return args[ lastToggle ].apply( this, arguments ) || false;
3791              };
3792  
3793          // link all the functions, so any of them can unbind this click handler
3794          toggler.guid = guid;
3795          while ( i < args.length ) {
3796              args[ i++ ].guid = guid;
3797          }
3798  
3799          return this.click( toggler );
3800      },
3801  
3802      hover: function( fnOver, fnOut ) {
3803          return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3804      }
3805  });
3806  
3807  jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3808      "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3809      "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
3810  
3811      // Handle event binding
3812      jQuery.fn[ name ] = function( data, fn ) {
3813          if ( fn == null ) {
3814              fn = data;
3815              data = null;
3816          }
3817  
3818          return arguments.length > 0 ?
3819              this.on( name, null, data, fn ) :
3820              this.trigger( name );
3821      };
3822  
3823      if ( jQuery.attrFn ) {
3824          jQuery.attrFn[ name ] = true;
3825      }
3826  
3827      if ( rkeyEvent.test( name ) ) {
3828          jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;
3829      }
3830  
3831      if ( rmouseEvent.test( name ) ) {
3832          jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
3833      }
3834  });
3835  
3836  
3837  
3838  /*!
3839   * Sizzle CSS Selector Engine
3840   *  Copyright 2012, The Dojo Foundation
3841   *  Released under the MIT, BSD, and GPL Licenses.
3842   *  More information: http://sizzlejs.com/
3843   */
3844  (function(){
3845  
3846  var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3847      expando = "sizcache" + (Math.random() + '').replace('.', ''),
3848      done = 0,
3849      toString = Object.prototype.toString,
3850      hasDuplicate = false,
3851      baseHasDuplicate = true,
3852      rBackslash = /\\/g,
3853      rReturn = /\r\n/g,
3854      rNonWord = /\W/;
3855  
3856  // Here we check if the JavaScript engine is using some sort of
3857  // optimization where it does not always call our comparision
3858  // function. If that is the case, discard the hasDuplicate value.
3859  //   Thus far that includes Google Chrome.
3860  [0, 0].sort(function() {
3861      baseHasDuplicate = false;
3862      return 0;
3863  });
3864  
3865  var Sizzle = function( selector, context, results, seed ) {
3866      results = results || [];
3867      context = context || document;
3868  
3869      var origContext = context;
3870  
3871      if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3872          return [];
3873      }
3874  
3875      if ( !selector || typeof selector !== "string" ) {
3876          return results;
3877      }
3878  
3879      var m, set, checkSet, extra, ret, cur, pop, i,
3880          prune = true,
3881          contextXML = Sizzle.isXML( context ),
3882          parts = [],
3883          soFar = selector;
3884  
3885      // Reset the position of the chunker regexp (start from head)
3886      do {
3887          chunker.exec( "" );
3888          m = chunker.exec( soFar );
3889  
3890          if ( m ) {
3891              soFar = m[3];
3892  
3893              parts.push( m[1] );
3894  
3895              if ( m[2] ) {
3896                  extra = m[3];
3897                  break;
3898              }
3899          }
3900      } while ( m );
3901  
3902      if ( parts.length > 1 && origPOS.exec( selector ) ) {
3903  
3904          if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3905              set = posProcess( parts[0] + parts[1], context, seed );
3906  
3907          } else {
3908              set = Expr.relative[ parts[0] ] ?
3909                  [ context ] :
3910                  Sizzle( parts.shift(), context );
3911  
3912              while ( parts.length ) {
3913                  selector = parts.shift();
3914  
3915                  if ( Expr.relative[ selector ] ) {
3916                      selector += parts.shift();
3917                  }
3918  
3919                  set = posProcess( selector, set, seed );
3920              }
3921          }
3922  
3923      } else {
3924          // Take a shortcut and set the context if the root selector is an ID
3925          // (but not if it'll be faster if the inner selector is an ID)
3926          if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
3927                  Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
3928  
3929              ret = Sizzle.find( parts.shift(), context, contextXML );
3930              context = ret.expr ?
3931                  Sizzle.filter( ret.expr, ret.set )[0] :
3932                  ret.set[0];
3933          }
3934  
3935          if ( context ) {
3936              ret = seed ?
3937                  { expr: parts.pop(), set: makeArray(seed) } :
3938                  Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
3939  
3940              set = ret.expr ?
3941                  Sizzle.filter( ret.expr, ret.set ) :
3942                  ret.set;
3943  
3944              if ( parts.length > 0 ) {
3945                  checkSet = makeArray( set );
3946  
3947              } else {
3948                  prune = false;
3949              }
3950  
3951              while ( parts.length ) {
3952                  cur = parts.pop();
3953                  pop = cur;
3954  
3955                  if ( !Expr.relative[ cur ] ) {
3956                      cur = "";
3957                  } else {
3958                      pop = parts.pop();
3959                  }
3960  
3961                  if ( pop == null ) {
3962                      pop = context;
3963                  }
3964  
3965                  Expr.relative[ cur ]( checkSet, pop, contextXML );
3966              }
3967  
3968          } else {
3969              checkSet = parts = [];
3970          }
3971      }
3972  
3973      if ( !checkSet ) {
3974          checkSet = set;
3975      }
3976  
3977      if ( !checkSet ) {
3978          Sizzle.error( cur || selector );
3979      }
3980  
3981      if ( toString.call(checkSet) === "[object Array]" ) {
3982          if ( !prune ) {
3983              results.push.apply( results, checkSet );
3984  
3985          } else if ( context && context.nodeType === 1 ) {
3986              for ( i = 0; checkSet[i] != null; i++ ) {
3987                  if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
3988                      results.push( set[i] );
3989                  }
3990              }
3991  
3992          } else {
3993              for ( i = 0; checkSet[i] != null; i++ ) {
3994                  if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
3995                      results.push( set[i] );
3996                  }
3997              }
3998          }
3999  
4000      } else {
4001          makeArray( checkSet, results );
4002      }
4003  
4004      if ( extra ) {
4005          Sizzle( extra, origContext, results, seed );
4006          Sizzle.uniqueSort( results );
4007      }
4008  
4009      return results;
4010  };
4011  
4012  Sizzle.uniqueSort = function( results ) {
4013      if ( sortOrder ) {
4014          hasDuplicate = baseHasDuplicate;
4015          results.sort( sortOrder );
4016  
4017          if ( hasDuplicate ) {
4018              for ( var i = 1; i < results.length; i++ ) {
4019                  if ( results[i] === results[ i - 1 ] ) {
4020                      results.splice( i--, 1 );
4021                  }
4022              }
4023          }
4024      }
4025  
4026      return results;
4027  };
4028  
4029  Sizzle.matches = function( expr, set ) {
4030      return Sizzle( expr, null, null, set );
4031  };
4032  
4033  Sizzle.matchesSelector = function( node, expr ) {
4034      return Sizzle( expr, null, null, [node] ).length > 0;
4035  };
4036  
4037  Sizzle.find = function( expr, context, isXML ) {
4038      var set, i, len, match, type, left;
4039  
4040      if ( !expr ) {
4041          return [];
4042      }
4043  
4044      for ( i = 0, len = Expr.order.length; i < len; i++ ) {
4045          type = Expr.order[i];
4046  
4047          if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
4048              left = match[1];
4049              match.splice( 1, 1 );
4050  
4051              if ( left.substr( left.length - 1 ) !== "\\" ) {
4052                  match[1] = (match[1] || "").replace( rBackslash, "" );
4053                  set = Expr.find[ type ]( match, context, isXML );
4054  
4055                  if ( set != null ) {
4056                      expr = expr.replace( Expr.match[ type ], "" );
4057                      break;
4058                  }
4059              }
4060          }
4061      }
4062  
4063      if ( !set ) {
4064          set = typeof context.getElementsByTagName !== "undefined" ?
4065              context.getElementsByTagName( "*" ) :
4066              [];
4067      }
4068  
4069      return { set: set, expr: expr };
4070  };
4071  
4072  Sizzle.filter = function( expr, set, inplace, not ) {
4073      var match, anyFound,
4074          type, found, item, filter, left,
4075          i, pass,
4076          old = expr,
4077          result = [],
4078          curLoop = set,
4079          isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
4080  
4081      while ( expr && set.length ) {
4082          for ( type in Expr.filter ) {
4083              if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
4084                  filter = Expr.filter[ type ];
4085                  left = match[1];
4086  
4087                  anyFound = false;
4088  
4089                  match.splice(1,1);
4090  
4091                  if ( left.substr( left.length - 1 ) === "\\" ) {
4092                      continue;
4093                  }
4094  
4095                  if ( curLoop === result ) {
4096                      result = [];
4097                  }
4098  
4099                  if ( Expr.preFilter[ type ] ) {
4100                      match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
4101  
4102                      if ( !match ) {
4103                          anyFound = found = true;
4104  
4105                      } else if ( match === true ) {
4106                          continue;
4107                      }
4108                  }
4109  
4110                  if ( match ) {
4111                      for ( i = 0; (item = curLoop[i]) != null; i++ ) {
4112                          if ( item ) {
4113                              found = filter( item, match, i, curLoop );
4114                              pass = not ^ found;
4115  
4116                              if ( inplace && found != null ) {
4117                                  if ( pass ) {
4118                                      anyFound = true;
4119  
4120                                  } else {
4121                                      curLoop[i] = false;
4122                                  }
4123  
4124                              } else if ( pass ) {
4125                                  result.push( item );
4126                                  anyFound = true;
4127                              }
4128                          }
4129                      }
4130                  }
4131  
4132                  if ( found !== undefined ) {
4133                      if ( !inplace ) {
4134                          curLoop = result;
4135                      }
4136  
4137                      expr = expr.replace( Expr.match[ type ], "" );
4138  
4139                      if ( !anyFound ) {
4140                          return [];
4141                      }
4142  
4143                      break;
4144                  }
4145              }
4146          }
4147  
4148          // Improper expression
4149          if ( expr === old ) {
4150              if ( anyFound == null ) {
4151                  Sizzle.error( expr );
4152  
4153              } else {
4154                  break;
4155              }
4156          }
4157  
4158          old = expr;
4159      }
4160  
4161      return curLoop;
4162  };
4163  
4164  Sizzle.error = function( msg ) {
4165      throw new Error( "Syntax error, unrecognized expression: " + msg );
4166  };
4167  
4168  /**
4169   * Utility function for retreiving the text value of an array of DOM nodes
4170   * @param {Array|Element} elem
4171   */
4172  var getText = Sizzle.getText = function( elem ) {
4173      var i, node,
4174          nodeType = elem.nodeType,
4175          ret = "";
4176  
4177      if ( nodeType ) {
4178          if ( nodeType === 1 || nodeType === 9 ) {
4179              // Use textContent || innerText for elements
4180              if ( typeof elem.textContent === 'string' ) {
4181                  return elem.textContent;
4182              } else if ( typeof elem.innerText === 'string' ) {
4183                  // Replace IE's carriage returns
4184                  return elem.innerText.replace( rReturn, '' );
4185              } else {
4186                  // Traverse it's children
4187                  for ( elem = elem.firstChild; elem; elem = elem.nextSibling) {
4188                      ret += getText( elem );
4189                  }
4190              }
4191          } else if ( nodeType === 3 || nodeType === 4 ) {
4192              return elem.nodeValue;
4193          }
4194      } else {
4195  
4196          // If no nodeType, this is expected to be an array
4197          for ( i = 0; (node = elem[i]); i++ ) {
4198              // Do not traverse comment nodes
4199              if ( node.nodeType !== 8 ) {
4200                  ret += getText( node );
4201              }
4202          }
4203      }
4204      return ret;
4205  };
4206  
4207  var Expr = Sizzle.selectors = {
4208      order: [ "ID", "NAME", "TAG" ],
4209  
4210      match: {
4211          ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4212          CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4213          NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
4214          ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
4215          TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
4216          CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
4217          POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
4218          PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
4219      },
4220  
4221      leftMatch: {},
4222  
4223      attrMap: {
4224          "class": "className",
4225          "for": "htmlFor"
4226      },
4227  
4228      attrHandle: {
4229          href: function( elem ) {
4230              return elem.getAttribute( "href" );
4231          },
4232          type: function( elem ) {
4233              return elem.getAttribute( "type" );
4234          }
4235      },
4236  
4237      relative: {
4238          "+": function(checkSet, part){
4239              var isPartStr = typeof part === "string",
4240                  isTag = isPartStr && !rNonWord.test( part ),
4241                  isPartStrNotTag = isPartStr && !isTag;
4242  
4243              if ( isTag ) {
4244                  part = part.toLowerCase();
4245              }
4246  
4247              for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4248                  if ( (elem = checkSet[i]) ) {
4249                      while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4250  
4251                      checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4252                          elem || false :
4253                          elem === part;
4254                  }
4255              }
4256  
4257              if ( isPartStrNotTag ) {
4258                  Sizzle.filter( part, checkSet, true );
4259              }
4260          },
4261  
4262          ">": function( checkSet, part ) {
4263              var elem,
4264                  isPartStr = typeof part === "string",
4265                  i = 0,
4266                  l = checkSet.length;
4267  
4268              if ( isPartStr && !rNonWord.test( part ) ) {
4269                  part = part.toLowerCase();
4270  
4271                  for ( ; i < l; i++ ) {
4272                      elem = checkSet[i];
4273  
4274                      if ( elem ) {
4275                          var parent = elem.parentNode;
4276                          checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4277                      }
4278                  }
4279  
4280              } else {
4281                  for ( ; i < l; i++ ) {
4282                      elem = checkSet[i];
4283  
4284                      if ( elem ) {
4285                          checkSet[i] = isPartStr ?
4286                              elem.parentNode :
4287                              elem.parentNode === part;
4288                      }
4289                  }
4290  
4291                  if ( isPartStr ) {
4292                      Sizzle.filter( part, checkSet, true );
4293                  }
4294              }
4295          },
4296  
4297          "": function(checkSet, part, isXML){
4298              var nodeCheck,
4299                  doneName = done++,
4300                  checkFn = dirCheck;
4301  
4302              if ( typeof part === "string" && !rNonWord.test( part ) ) {
4303                  part = part.toLowerCase();
4304                  nodeCheck = part;
4305                  checkFn = dirNodeCheck;
4306              }
4307  
4308              checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4309          },
4310  
4311          "~": function( checkSet, part, isXML ) {
4312              var nodeCheck,
4313                  doneName = done++,
4314                  checkFn = dirCheck;
4315  
4316              if ( typeof part === "string" && !rNonWord.test( part ) ) {
4317                  part = part.toLowerCase();
4318                  nodeCheck = part;
4319                  checkFn = dirNodeCheck;
4320              }
4321  
4322              checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4323          }
4324      },
4325  
4326      find: {
4327          ID: function( match, context, isXML ) {
4328              if ( typeof context.getElementById !== "undefined" && !isXML ) {
4329                  var m = context.getElementById(match[1]);
4330                  // Check parentNode to catch when Blackberry 4.6 returns
4331                  // nodes that are no longer in the document #6963
4332                  return m && m.parentNode ? [m] : [];
4333              }
4334          },
4335  
4336          NAME: function( match, context ) {
4337              if ( typeof context.getElementsByName !== "undefined" ) {
4338                  var ret = [],
4339                      results = context.getElementsByName( match[1] );
4340  
4341                  for ( var i = 0, l = results.length; i < l; i++ ) {
4342                      if ( results[i].getAttribute("name") === match[1] ) {
4343                          ret.push( results[i] );
4344                      }
4345                  }
4346  
4347                  return ret.length === 0 ? null : ret;
4348              }
4349          },
4350  
4351          TAG: function( match, context ) {
4352              if ( typeof context.getElementsByTagName !== "undefined" ) {
4353                  return context.getElementsByTagName( match[1] );
4354              }
4355          }
4356      },
4357      preFilter: {
4358          CLASS: function( match, curLoop, inplace, result, not, isXML ) {
4359              match = " " + match[1].replace( rBackslash, "" ) + " ";
4360  
4361              if ( isXML ) {
4362                  return match;
4363              }
4364  
4365              for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4366                  if ( elem ) {
4367                      if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
4368                          if ( !inplace ) {
4369                              result.push( elem );
4370                          }
4371  
4372                      } else if ( inplace ) {
4373                          curLoop[i] = false;
4374                      }
4375                  }
4376              }
4377  
4378              return false;
4379          },
4380  
4381          ID: function( match ) {
4382              return match[1].replace( rBackslash, "" );
4383          },
4384  
4385          TAG: function( match, curLoop ) {
4386              return match[1].replace( rBackslash, "" ).toLowerCase();
4387          },
4388  
4389          CHILD: function( match ) {
4390              if ( match[1] === "nth" ) {
4391                  if ( !match[2] ) {
4392                      Sizzle.error( match[0] );
4393                  }
4394  
4395                  match[2] = match[2].replace(/^\+|\s*/g, '');
4396  
4397                  // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
4398                  var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
4399                      match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
4400                      !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4401  
4402                  // calculate the numbers (first)n+(last) including if they are negative
4403                  match[2] = (test[1] + (test[2] || 1)) - 0;
4404                  match[3] = test[3] - 0;
4405              }
4406              else if ( match[2] ) {
4407                  Sizzle.error( match[0] );
4408              }
4409  
4410              // TODO: Move to normal caching system
4411              match[0] = done++;
4412  
4413              return match;
4414          },
4415  
4416          ATTR: function( match, curLoop, inplace, result, not, isXML ) {
4417              var name = match[1] = match[1].replace( rBackslash, "" );
4418  
4419              if ( !isXML && Expr.attrMap[name] ) {
4420                  match[1] = Expr.attrMap[name];
4421              }
4422  
4423              // Handle if an un-quoted value was used
4424              match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4425  
4426              if ( match[2] === "~=" ) {
4427                  match[4] = " " + match[4] + " ";
4428              }
4429  
4430              return match;
4431          },
4432  
4433          PSEUDO: function( match, curLoop, inplace, result, not ) {
4434              if ( match[1] === "not" ) {
4435                  // If we're dealing with a complex expression, or a simple one
4436                  if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4437                      match[3] = Sizzle(match[3], null, null, curLoop);
4438  
4439                  } else {
4440                      var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4441  
4442                      if ( !inplace ) {
4443                          result.push.apply( result, ret );
4444                      }
4445  
4446                      return false;
4447                  }
4448  
4449              } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4450                  return true;
4451              }
4452  
4453              return match;
4454          },
4455  
4456          POS: function( match ) {
4457              match.unshift( true );
4458  
4459              return match;
4460          }
4461      },
4462  
4463      filters: {
4464          enabled: function( elem ) {
4465              return elem.disabled === false && elem.type !== "hidden";
4466          },
4467  
4468          disabled: function( elem ) {
4469              return elem.disabled === true;
4470          },
4471  
4472          checked: function( elem ) {
4473              return elem.checked === true;
4474          },
4475  
4476          selected: function( elem ) {
4477              // Accessing this property makes selected-by-default
4478              // options in Safari work properly
4479              if ( elem.parentNode ) {
4480                  elem.parentNode.selectedIndex;
4481              }
4482  
4483              return elem.selected === true;
4484          },
4485  
4486          parent: function( elem ) {
4487              return !!elem.firstChild;
4488          },
4489  
4490          empty: function( elem ) {
4491              return !elem.firstChild;
4492          },
4493  
4494          has: function( elem, i, match ) {
4495              return !!Sizzle( match[3], elem ).length;
4496          },
4497  
4498          header: function( elem ) {
4499              return (/h\d/i).test( elem.nodeName );
4500          },
4501  
4502          text: function( elem ) {
4503              var attr = elem.getAttribute( "type" ), type = elem.type;
4504              // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
4505              // use getAttribute instead to test this case
4506              return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
4507          },
4508  
4509          radio: function( elem ) {
4510              return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
4511          },
4512  
4513          checkbox: function( elem ) {
4514              return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
4515          },
4516  
4517          file: function( elem ) {
4518              return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
4519          },
4520  
4521          password: function( elem ) {
4522              return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
4523          },
4524  
4525          submit: function( elem ) {
4526              var name = elem.nodeName.toLowerCase();
4527              return (name === "input" || name === "button") && "submit" === elem.type;
4528          },
4529  
4530          image: function( elem ) {
4531              return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
4532          },
4533  
4534          reset: function( elem ) {
4535              var name = elem.nodeName.toLowerCase();
4536              return (name === "input" || name === "button") && "reset" === elem.type;
4537          },
4538  
4539          button: function( elem ) {
4540              var name = elem.nodeName.toLowerCase();
4541              return name === "input" && "button" === elem.type || name === "button";
4542          },
4543  
4544          input: function( elem ) {
4545              return (/input|select|textarea|button/i).test( elem.nodeName );
4546          },
4547  
4548          focus: function( elem ) {
4549              return elem === elem.ownerDocument.activeElement;
4550          }
4551      },
4552      setFilters: {
4553          first: function( elem, i ) {
4554              return i === 0;
4555          },
4556  
4557          last: function( elem, i, match, array ) {
4558              return i === array.length - 1;
4559          },
4560  
4561          even: function( elem, i ) {
4562              return i % 2 === 0;
4563          },
4564  
4565          odd: function( elem, i ) {
4566              return i % 2 === 1;
4567          },
4568  
4569          lt: function( elem, i, match ) {
4570              return i < match[3] - 0;
4571          },
4572  
4573          gt: function( elem, i, match ) {
4574              return i > match[3] - 0;
4575          },
4576  
4577          nth: function( elem, i, match ) {
4578              return match[3] - 0 === i;
4579          },
4580  
4581          eq: function( elem, i, match ) {
4582              return match[3] - 0 === i;
4583          }
4584      },
4585      filter: {
4586          PSEUDO: function( elem, match, i, array ) {
4587              var name = match[1],
4588                  filter = Expr.filters[ name ];
4589  
4590              if ( filter ) {
4591                  return filter( elem, i, match, array );
4592  
4593              } else if ( name === "contains" ) {
4594                  return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
4595  
4596              } else if ( name === "not" ) {
4597                  var not = match[3];
4598  
4599                  for ( var j = 0, l = not.length; j < l; j++ ) {
4600                      if ( not[j] === elem ) {
4601                          return false;
4602                      }
4603                  }
4604  
4605                  return true;
4606  
4607              } else {
4608                  Sizzle.error( name );
4609              }
4610          },
4611  
4612          CHILD: function( elem, match ) {
4613              var first, last,
4614                  doneName, parent, cache,
4615                  count, diff,
4616                  type = match[1],
4617                  node = elem;
4618  
4619              switch ( type ) {
4620                  case "only":
4621                  case "first":
4622                      while ( (node = node.previousSibling) )     {
4623                          if ( node.nodeType === 1 ) {
4624                              return false;
4625                          }
4626                      }
4627  
4628                      if ( type === "first" ) {
4629                          return true;
4630                      }
4631  
4632                      node = elem;
4633  
4634                  case "last":
4635                      while ( (node = node.nextSibling) )     {
4636                          if ( node.nodeType === 1 ) {
4637                              return false;
4638                          }
4639                      }
4640  
4641                      return true;
4642  
4643                  case "nth":
4644                      first = match[2];
4645                      last = match[3];
4646  
4647                      if ( first === 1 && last === 0 ) {
4648                          return true;
4649                      }
4650  
4651                      doneName = match[0];
4652                      parent = elem.parentNode;
4653  
4654                      if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) {
4655                          count = 0;
4656  
4657                          for ( node = parent.firstChild; node; node = node.nextSibling ) {
4658                              if ( node.nodeType === 1 ) {
4659                                  node.nodeIndex = ++count;
4660                              }
4661                          }
4662  
4663                          parent[ expando ] = doneName;
4664                      }
4665  
4666                      diff = elem.nodeIndex - last;
4667  
4668                      if ( first === 0 ) {
4669                          return diff === 0;
4670  
4671                      } else {
4672                          return ( diff % first === 0 && diff / first >= 0 );
4673                      }
4674              }
4675          },
4676  
4677          ID: function( elem, match ) {
4678              return elem.nodeType === 1 && elem.getAttribute("id") === match;
4679          },
4680  
4681          TAG: function( elem, match ) {
4682              return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match;
4683          },
4684  
4685          CLASS: function( elem, match ) {
4686              return (" " + (elem.className || elem.getAttribute("class")) + " ")
4687                  .indexOf( match ) > -1;
4688          },
4689  
4690          ATTR: function( elem, match ) {
4691              var name = match[1],
4692                  result = Sizzle.attr ?
4693                      Sizzle.attr( elem, name ) :
4694                      Expr.attrHandle[ name ] ?
4695                      Expr.attrHandle[ name ]( elem ) :
4696                      elem[ name ] != null ?
4697                          elem[ name ] :
4698                          elem.getAttribute( name ),
4699                  value = result + "",
4700                  type = match[2],
4701                  check = match[4];
4702  
4703              return result == null ?
4704                  type === "!=" :
4705                  !type && Sizzle.attr ?
4706                  result != null :
4707                  type === "=" ?
4708                  value === check :
4709                  type === "*=" ?
4710                  value.indexOf(check) >= 0 :
4711                  type === "~=" ?
4712                  (" " + value + " ").indexOf(check) >= 0 :
4713                  !check ?
4714                  value && result !== false :
4715                  type === "!=" ?
4716                  value !== check :
4717                  type === "^=" ?
4718                  value.indexOf(check) === 0 :
4719                  type === "$=" ?
4720                  value.substr(value.length - check.length) === check :
4721                  type === "|=" ?
4722                  value === check || value.substr(0, check.length + 1) === check + "-" :
4723                  false;
4724          },
4725  
4726          POS: function( elem, match, i, array ) {
4727              var name = match[2],
4728                  filter = Expr.setFilters[ name ];
4729  
4730              if ( filter ) {
4731                  return filter( elem, i, match, array );
4732              }
4733          }
4734      }
4735  };
4736  
4737  var origPOS = Expr.match.POS,
4738      fescape = function(all, num){
4739          return "\\" + (num - 0 + 1);
4740      };
4741  
4742  for ( var type in Expr.match ) {
4743      Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
4744      Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
4745  }
4746  
4747  var makeArray = function( array, results ) {
4748      array = Array.prototype.slice.call( array, 0 );
4749  
4750      if ( results ) {
4751          results.push.apply( results, array );
4752          return results;
4753      }
4754  
4755      return array;
4756  };
4757  
4758  // Perform a simple check to determine if the browser is capable of
4759  // converting a NodeList to an array using builtin methods.
4760  // Also verifies that the returned array holds DOM nodes
4761  // (which is not the case in the Blackberry browser)
4762  try {
4763      Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
4764  
4765  // Provide a fallback method if it does not work
4766  } catch( e ) {
4767      makeArray = function( array, results ) {
4768          var i = 0,
4769              ret = results || [];
4770  
4771          if ( toString.call(array) === "[object Array]" ) {
4772              Array.prototype.push.apply( ret, array );
4773  
4774          } else {
4775              if ( typeof array.length === "number" ) {
4776                  for ( var l = array.length; i < l; i++ ) {
4777                      ret.push( array[i] );
4778                  }
4779  
4780              } else {
4781                  for ( ; array[i]; i++ ) {
4782                      ret.push( array[i] );
4783                  }
4784              }
4785          }
4786  
4787          return ret;
4788      };
4789  }
4790  
4791  var sortOrder, siblingCheck;
4792  
4793  if ( document.documentElement.compareDocumentPosition ) {
4794      sortOrder = function( a, b ) {
4795          if ( a === b ) {
4796              hasDuplicate = true;
4797              return 0;
4798          }
4799  
4800          if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4801              return a.compareDocumentPosition ? -1 : 1;
4802          }
4803  
4804          return a.compareDocumentPosition(b) & 4 ? -1 : 1;
4805      };
4806  
4807  } else {
4808      sortOrder = function( a, b ) {
4809          // The nodes are identical, we can exit early
4810          if ( a === b ) {
4811              hasDuplicate = true;
4812              return 0;
4813  
4814          // Fallback to using sourceIndex (in IE) if it's available on both nodes
4815          } else if ( a.sourceIndex && b.sourceIndex ) {
4816              return a.sourceIndex - b.sourceIndex;
4817          }
4818  
4819          var al, bl,
4820              ap = [],
4821              bp = [],
4822              aup = a.parentNode,
4823              bup = b.parentNode,
4824              cur = aup;
4825  
4826          // If the nodes are siblings (or identical) we can do a quick check
4827          if ( aup === bup ) {
4828              return siblingCheck( a, b );
4829  
4830          // If no parents were found then the nodes are disconnected
4831          } else if ( !aup ) {
4832              return -1;
4833  
4834          } else if ( !bup ) {
4835              return 1;
4836          }
4837  
4838          // Otherwise they're somewhere else in the tree so we need
4839          // to build up a full list of the parentNodes for comparison
4840          while ( cur ) {
4841              ap.unshift( cur );
4842              cur = cur.parentNode;
4843          }
4844  
4845          cur = bup;
4846  
4847          while ( cur ) {
4848              bp.unshift( cur );
4849              cur = cur.parentNode;
4850          }
4851  
4852          al = ap.length;
4853          bl = bp.length;
4854  
4855          // Start walking down the tree looking for a discrepancy
4856          for ( var i = 0; i < al && i < bl; i++ ) {
4857              if ( ap[i] !== bp[i] ) {
4858                  return siblingCheck( ap[i], bp[i] );
4859              }
4860          }
4861  
4862          // We ended someplace up the tree so do a sibling check
4863          return i === al ?
4864              siblingCheck( a, bp[i], -1 ) :
4865              siblingCheck( ap[i], b, 1 );
4866      };
4867  
4868      siblingCheck = function( a, b, ret ) {
4869          if ( a === b ) {
4870              return ret;
4871  
4872          var cur = a.nextSibling;
4873          }
4874  
4875          while ( cur ) {
4876              if ( cur === b ) {
4877                  return -1;
4878              }
4879  
4880              cur = cur.nextSibling;
4881          }
4882  
4883          return 1;
4884      };
4885  }
4886  
4887  // Check to see if the browser returns elements by name when
4888  // querying by getElementById (and provide a workaround)
4889  (function(){
4890      // We're going to inject a fake input element with a specified name
4891      var form = document.createElement("div"),
4892          id = "script" + (new Date()).getTime(),
4893          root = document.documentElement;
4894  
4895      form.innerHTML = "<a name='" + id + "'/>";
4896  
4897      // Inject it into the root element, check its status, and remove it quickly
4898      root.insertBefore( form, root.firstChild );
4899  
4900      // The workaround has to do additional checks after a getElementById
4901      // Which slows things down for other browsers (hence the branching)
4902      if ( document.getElementById( id ) ) {
4903          Expr.find.ID = function( match, context, isXML ) {
4904              if ( typeof context.getElementById !== "undefined" && !isXML ) {
4905                  var m = context.getElementById(match[1]);
4906  
4907                  return m ?
4908                      m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
4909                          [m] :
4910                          undefined :
4911                      [];
4912              }
4913          };
4914  
4915          Expr.filter.ID = function( elem, match ) {
4916              var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4917  
4918              return elem.nodeType === 1 && node && node.nodeValue === match;
4919          };
4920      }
4921  
4922      root.removeChild( form );
4923  
4924      // release memory in IE
4925      root = form = null;
4926  })();
4927  
4928  (function(){
4929      // Check to see if the browser returns only elements
4930      // when doing getElementsByTagName("*")
4931  
4932      // Create a fake element
4933      var div = document.createElement("div");
4934      div.appendChild( document.createComment("") );
4935  
4936      // Make sure no comments are found
4937      if ( div.getElementsByTagName("*").length > 0 ) {
4938          Expr.find.TAG = function( match, context ) {
4939              var results = context.getElementsByTagName( match[1] );
4940  
4941              // Filter out possible comments
4942              if ( match[1] === "*" ) {
4943                  var tmp = [];
4944  
4945                  for ( var i = 0; results[i]; i++ ) {
4946                      if ( results[i].nodeType === 1 ) {
4947                          tmp.push( results[i] );
4948                      }
4949                  }
4950  
4951                  results = tmp;
4952              }
4953  
4954              return results;
4955          };
4956      }
4957  
4958      // Check to see if an attribute returns normalized href attributes
4959      div.innerHTML = "<a href='#'></a>";
4960  
4961      if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4962              div.firstChild.getAttribute("href") !== "#" ) {
4963  
4964          Expr.attrHandle.href = function( elem ) {
4965              return elem.getAttribute( "href", 2 );
4966          };
4967      }
4968  
4969      // release memory in IE
4970      div = null;
4971  })();
4972  
4973  if ( document.querySelectorAll ) {
4974      (function(){
4975          var oldSizzle = Sizzle,
4976              div = document.createElement("div"),
4977              id = "__sizzle__";
4978  
4979          div.innerHTML = "<p class='TEST'></p>";
4980  
4981          // Safari can't handle uppercase or unicode characters when
4982          // in quirks mode.
4983          if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4984              return;
4985          }
4986  
4987          Sizzle = function( query, context, extra, seed ) {
4988              context = context || document;
4989  
4990              // Only use querySelectorAll on non-XML documents
4991              // (ID selectors don't work in non-HTML documents)
4992              if ( !seed && !Sizzle.isXML(context) ) {
4993                  // See if we find a selector to speed up
4994                  var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
4995  
4996                  if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
4997                      // Speed-up: Sizzle("TAG")
4998                      if ( match[1] ) {
4999                          return makeArray( context.getElementsByTagName( query ), extra );
5000  
5001                      // Speed-up: Sizzle(".CLASS")
5002                      } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
5003                          return makeArray( context.getElementsByClassName( match[2] ), extra );
5004                      }
5005                  }
5006  
5007                  if ( context.nodeType === 9 ) {
5008                      // Speed-up: Sizzle("body")
5009                      // The body element only exists once, optimize finding it
5010                      if ( query === "body" && context.body ) {
5011                          return makeArray( [ context.body ], extra );
5012  
5013                      // Speed-up: Sizzle("#ID")
5014                      } else if ( match && match[3] ) {
5015                          var elem = context.getElementById( match[3] );
5016  
5017                          // Check parentNode to catch when Blackberry 4.6 returns
5018                          // nodes that are no longer in the document #6963
5019                          if ( elem && elem.parentNode ) {
5020                              // Handle the case where IE and Opera return items
5021                              // by name instead of ID
5022                              if ( elem.id === match[3] ) {
5023                                  return makeArray( [ elem ], extra );
5024                              }
5025  
5026                          } else {
5027                              return makeArray( [], extra );
5028                          }
5029                      }
5030  
5031                      try {
5032                          return makeArray( context.querySelectorAll(query), extra );
5033                      } catch(qsaError) {}
5034  
5035                  // qSA works strangely on Element-rooted queries
5036                  // We can work around this by specifying an extra ID on the root
5037                  // and working up from there (Thanks to Andrew Dupont for the technique)
5038                  // IE 8 doesn't work on object elements
5039                  } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
5040                      var oldContext = context,
5041                          old = context.getAttribute( "id" ),
5042                          nid = old || id,
5043                          hasParent = context.parentNode,
5044                          relativeHierarchySelector = /^\s*[+~]/.test( query );
5045  
5046                      if ( !old ) {
5047                          context.setAttribute( "id", nid );
5048                      } else {
5049                          nid = nid.replace( /'/g, "\\$&" );
5050                      }
5051                      if ( relativeHierarchySelector && hasParent ) {
5052                          context = context.parentNode;
5053                      }
5054  
5055                      try {
5056                          if ( !relativeHierarchySelector || hasParent ) {
5057                              return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
5058                          }
5059  
5060                      } catch(pseudoError) {
5061                      } finally {
5062                          if ( !old ) {
5063                              oldContext.removeAttribute( "id" );
5064                          }
5065                      }
5066                  }
5067              }
5068  
5069              return oldSizzle(query, context, extra, seed);
5070          };
5071  
5072          for ( var prop in oldSizzle ) {
5073              Sizzle[ prop ] = oldSizzle[ prop ];
5074          }
5075  
5076          // release memory in IE
5077          div = null;
5078      })();
5079  }
5080  
5081  (function(){
5082      var html = document.documentElement,
5083          matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
5084  
5085      if ( matches ) {
5086          // Check to see if it's possible to do matchesSelector
5087          // on a disconnected node (IE 9 fails this)
5088          var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
5089              pseudoWorks = false;
5090  
5091          try {
5092              // This should fail with an exception
5093              // Gecko does not error, returns false instead
5094              matches.call( document.documentElement, "[test!='']:sizzle" );
5095  
5096          } catch( pseudoError ) {
5097              pseudoWorks = true;
5098          }
5099  
5100          Sizzle.matchesSelector = function( node, expr ) {
5101              // Make sure that attribute selectors are quoted
5102              expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
5103  
5104              if ( !Sizzle.isXML( node ) ) {
5105                  try {
5106                      if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
5107                          var ret = matches.call( node, expr );
5108  
5109                          // IE 9's matchesSelector returns false on disconnected nodes
5110                          if ( ret || !disconnectedMatch ||
5111                                  // As well, disconnected nodes are said to be in a document
5112                                  // fragment in IE 9, so check for that
5113                                  node.document && node.document.nodeType !== 11 ) {
5114                              return ret;
5115                          }
5116                      }
5117                  } catch(e) {}
5118              }
5119  
5120              return Sizzle(expr, null, null, [node]).length > 0;
5121          };
5122      }
5123  })();
5124  
5125  (function(){
5126      var div = document.createElement("div");
5127  
5128      div.innerHTML = "<div class='test e'></div><div class='test'></div>";
5129  
5130      // Opera can't find a second classname (in 9.6)
5131      // Also, make sure that getElementsByClassName actually exists
5132      if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
5133          return;
5134      }
5135  
5136      // Safari caches class attributes, doesn't catch changes (in 3.2)
5137      div.lastChild.className = "e";
5138  
5139      if ( div.getElementsByClassName("e").length === 1 ) {
5140          return;
5141      }
5142  
5143      Expr.order.splice(1, 0, "CLASS");
5144      Expr.find.CLASS = function( match, context, isXML ) {
5145          if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
5146              return context.getElementsByClassName(match[1]);
5147          }
5148      };
5149  
5150      // release memory in IE
5151      div = null;
5152  })();
5153  
5154  function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5155      for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5156          var elem = checkSet[i];
5157  
5158          if ( elem ) {
5159              var match = false;
5160  
5161              elem = elem[dir];
5162  
5163              while ( elem ) {
5164                  if ( elem[ expando ] === doneName ) {
5165                      match = checkSet[elem.sizset];
5166                      break;
5167                  }
5168  
5169                  if ( elem.nodeType === 1 && !isXML ){
5170                      elem[ expando ] = doneName;
5171                      elem.sizset = i;
5172                  }
5173  
5174                  if ( elem.nodeName.toLowerCase() === cur ) {
5175                      match = elem;
5176                      break;
5177                  }
5178  
5179                  elem = elem[dir];
5180              }
5181  
5182              checkSet[i] = match;
5183          }
5184      }
5185  }
5186  
5187  function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5188      for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5189          var elem = checkSet[i];
5190  
5191          if ( elem ) {
5192              var match = false;
5193  
5194              elem = elem[dir];
5195  
5196              while ( elem ) {
5197                  if ( elem[ expando ] === doneName ) {
5198                      match = checkSet[elem.sizset];
5199                      break;
5200                  }
5201  
5202                  if ( elem.nodeType === 1 ) {
5203                      if ( !isXML ) {
5204                          elem[ expando ] = doneName;
5205                          elem.sizset = i;
5206                      }
5207  
5208                      if ( typeof cur !== "string" ) {
5209                          if ( elem === cur ) {
5210                              match = true;
5211                              break;
5212                          }
5213  
5214                      } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
5215                          match = elem;
5216                          break;
5217                      }
5218                  }
5219  
5220                  elem = elem[dir];
5221              }
5222  
5223              checkSet[i] = match;
5224          }
5225      }
5226  }
5227  
5228  if ( document.documentElement.contains ) {
5229      Sizzle.contains = function( a, b ) {
5230          return a !== b && (a.contains ? a.contains(b) : true);
5231      };
5232  
5233  } else if ( document.documentElement.compareDocumentPosition ) {
5234      Sizzle.contains = function( a, b ) {
5235          return !!(a.compareDocumentPosition(b) & 16);
5236      };
5237  
5238  } else {
5239      Sizzle.contains = function() {
5240          return false;
5241      };
5242  }
5243  
5244  Sizzle.isXML = function( elem ) {
5245      // documentElement is verified for cases where it doesn't yet exist
5246      // (such as loading iframes in IE - #4833)
5247      var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
5248  
5249      return documentElement ? documentElement.nodeName !== "HTML" : false;
5250  };
5251  
5252  var posProcess = function( selector, context, seed ) {
5253      var match,
5254          tmpSet = [],
5255          later = "",
5256          root = context.nodeType ? [context] : context;
5257  
5258      // Position selectors must be done after the filter
5259      // And so must :not(positional) so we move all PSEUDOs to the end
5260      while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
5261          later += match[0];
5262          selector = selector.replace( Expr.match.PSEUDO, "" );
5263      }
5264  
5265      selector = Expr.relative[selector] ? selector + "*" : selector;
5266  
5267      for ( var i = 0, l = root.length; i < l; i++ ) {
5268          Sizzle( selector, root[i], tmpSet, seed );
5269      }
5270  
5271      return Sizzle.filter( later, tmpSet );
5272  };
5273  
5274  // EXPOSE
5275  // Override sizzle attribute retrieval
5276  Sizzle.attr = jQuery.attr;
5277  Sizzle.selectors.attrMap = {};
5278  jQuery.find = Sizzle;
5279  jQuery.expr = Sizzle.selectors;
5280  jQuery.expr[":"] = jQuery.expr.filters;
5281  jQuery.unique = Sizzle.uniqueSort;
5282  jQuery.text = Sizzle.getText;
5283  jQuery.isXMLDoc = Sizzle.isXML;
5284  jQuery.contains = Sizzle.contains;
5285  
5286  
5287  })();
5288  
5289  
5290  var runtil = /Until$/,
5291      rparentsprev = /^(?:parents|prevUntil|prevAll)/,
5292      // Note: This RegExp should be improved, or likely pulled from Sizzle
5293      rmultiselector = /,/,
5294      isSimple = /^.[^:#\[\.,]*$/,
5295      slice = Array.prototype.slice,
5296      POS = jQuery.expr.match.POS,
5297      // methods guaranteed to produce a unique set when starting from a unique set
5298      guaranteedUnique = {
5299          children: true,
5300          contents: true,
5301          next: true,
5302          prev: true
5303      };
5304  
5305  jQuery.fn.extend({
5306      find: function( selector ) {
5307          var self = this,
5308              i, l;
5309  
5310          if ( typeof selector !== "string" ) {
5311              return jQuery( selector ).filter(function() {
5312                  for ( i = 0, l = self.length; i < l; i++ ) {
5313                      if ( jQuery.contains( self[ i ], this ) ) {
5314                          return true;
5315                      }
5316                  }
5317              });
5318          }
5319  
5320          var ret = this.pushStack( "", "find", selector ),
5321              length, n, r;
5322  
5323          for ( i = 0, l = this.length; i < l; i++ ) {
5324              length = ret.length;
5325              jQuery.find( selector, this[i], ret );
5326  
5327              if ( i > 0 ) {
5328                  // Make sure that the results are unique
5329                  for ( n = length; n < ret.length; n++ ) {
5330                      for ( r = 0; r < length; r++ ) {
5331                          if ( ret[r] === ret[n] ) {
5332                              ret.splice(n--, 1);
5333                              break;
5334                          }
5335                      }
5336                  }
5337              }
5338          }
5339  
5340          return ret;
5341      },
5342  
5343      has: function( target ) {
5344          var targets = jQuery( target );
5345          return this.filter(function() {
5346              for ( var i = 0, l = targets.length; i < l; i++ ) {
5347                  if ( jQuery.contains( this, targets[i] ) ) {
5348                      return true;
5349                  }
5350              }
5351          });
5352      },
5353  
5354      not: function( selector ) {
5355          return this.pushStack( winnow(this, selector, false), "not", selector);
5356      },
5357  
5358      filter: function( selector ) {
5359          return this.pushStack( winnow(this, selector, true), "filter", selector );
5360      },
5361  
5362      is: function( selector ) {
5363          return !!selector && (
5364              typeof selector === "string" ?
5365                  // If this is a positional selector, check membership in the returned set
5366                  // so $("p:first").is("p:last") won't return true for a doc with two "p".
5367                  POS.test( selector ) ?
5368                      jQuery( selector, this.context ).index( this[0] ) >= 0 :
5369                      jQuery.filter( selector, this ).length > 0 :
5370                  this.filter( selector ).length > 0 );
5371      },
5372  
5373      closest: function( selectors, context ) {
5374          var ret = [], i, l, cur = this[0];
5375  
5376          // Array (deprecated as of jQuery 1.7)
5377          if ( jQuery.isArray( selectors ) ) {
5378              var level = 1;
5379  
5380              while ( cur && cur.ownerDocument && cur !== context ) {
5381                  for ( i = 0; i < selectors.length; i++ ) {
5382  
5383                      if ( jQuery( cur ).is( selectors[ i ] ) ) {
5384                          ret.push({ selector: selectors[ i ], elem: cur, level: level });
5385                      }
5386                  }
5387  
5388                  cur = cur.parentNode;
5389                  level++;
5390              }
5391  
5392              return ret;
5393          }
5394  
5395          // String
5396          var pos = POS.test( selectors ) || typeof selectors !== "string" ?
5397                  jQuery( selectors, context || this.context ) :
5398                  0;
5399  
5400          for ( i = 0, l = this.length; i < l; i++ ) {
5401              cur = this[i];
5402  
5403              while ( cur ) {
5404                  if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5405                      ret.push( cur );
5406                      break;
5407  
5408                  } else {
5409                      cur = cur.parentNode;
5410                      if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
5411                          break;
5412                      }
5413                  }
5414              }
5415          }
5416  
5417          ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5418  
5419          return this.pushStack( ret, "closest", selectors );
5420      },
5421  
5422      // Determine the position of an element within
5423      // the matched set of elements
5424      index: function( elem ) {
5425  
5426          // No argument, return index in parent
5427          if ( !elem ) {
5428              return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;
5429          }
5430  
5431          // index in selector
5432          if ( typeof elem === "string" ) {
5433              return jQuery.inArray( this[0], jQuery( elem ) );
5434          }
5435  
5436          // Locate the position of the desired element
5437          return jQuery.inArray(
5438              // If it receives a jQuery object, the first element is used
5439              elem.jquery ? elem[0] : elem, this );
5440      },
5441  
5442      add: function( selector, context ) {
5443          var set = typeof selector === "string" ?
5444                  jQuery( selector, context ) :
5445                  jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5446              all = jQuery.merge( this.get(), set );
5447  
5448          return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5449              all :
5450              jQuery.unique( all ) );
5451      },
5452  
5453      andSelf: function() {
5454          return this.add( this.prevObject );
5455      }
5456  });
5457  
5458  // A painfully simple check to see if an element is disconnected
5459  // from a document (should be improved, where feasible).
5460  function isDisconnected( node ) {
5461      return !node || !node.parentNode || node.parentNode.nodeType === 11;
5462  }
5463  
5464  jQuery.each({
5465      parent: function( elem ) {
5466          var parent = elem.parentNode;
5467          return parent && parent.nodeType !== 11 ? parent : null;
5468      },
5469      parents: function( elem ) {
5470          return jQuery.dir( elem, "parentNode" );
5471      },
5472      parentsUntil: function( elem, i, until ) {
5473          return jQuery.dir( elem, "parentNode", until );
5474      },
5475      next: function( elem ) {
5476          return jQuery.nth( elem, 2, "nextSibling" );
5477      },
5478      prev: function( elem ) {
5479          return jQuery.nth( elem, 2, "previousSibling" );
5480      },
5481      nextAll: function( elem ) {
5482          return jQuery.dir( elem, "nextSibling" );
5483      },
5484      prevAll: function( elem ) {
5485          return jQuery.dir( elem, "previousSibling" );
5486      },
5487      nextUntil: function( elem, i, until ) {
5488          return jQuery.dir( elem, "nextSibling", until );
5489      },
5490      prevUntil: function( elem, i, until ) {
5491          return jQuery.dir( elem, "previousSibling", until );
5492      },
5493      siblings: function( elem ) {
5494          return jQuery.sibling( elem.parentNode.firstChild, elem );
5495      },
5496      children: function( elem ) {
5497          return jQuery.sibling( elem.firstChild );
5498      },
5499      contents: function( elem ) {
5500          return jQuery.nodeName( elem, "iframe" ) ?
5501              elem.contentDocument || elem.contentWindow.document :
5502              jQuery.makeArray( elem.childNodes );
5503      }
5504  }, function( name, fn ) {
5505      jQuery.fn[ name ] = function( until, selector ) {
5506          var ret = jQuery.map( this, fn, until );
5507  
5508          if ( !runtil.test( name ) ) {
5509              selector = until;
5510          }
5511  
5512          if ( selector && typeof selector === "string" ) {
5513              ret = jQuery.filter( selector, ret );
5514          }
5515  
5516          ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5517  
5518          if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
5519              ret = ret.reverse();
5520          }
5521  
5522          return this.pushStack( ret, name, slice.call( arguments ).join(",") );
5523      };
5524  });
5525  
5526  jQuery.extend({
5527      filter: function( expr, elems, not ) {
5528          if ( not ) {
5529              expr = ":not(" + expr + ")";
5530          }
5531  
5532          return elems.length === 1 ?
5533              jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5534              jQuery.find.matches(expr, elems);
5535      },
5536  
5537      dir: function( elem, dir, until ) {
5538          var matched = [],
5539              cur = elem[ dir ];
5540  
5541          while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5542              if ( cur.nodeType === 1 ) {
5543                  matched.push( cur );
5544              }
5545              cur = cur[dir];
5546          }
5547          return matched;
5548      },
5549  
5550      nth: function( cur, result, dir, elem ) {
5551          result = result || 1;
5552          var num = 0;
5553  
5554          for ( ; cur; cur = cur[dir] ) {
5555              if ( cur.nodeType === 1 && ++num === result ) {
5556                  break;
5557              }
5558          }
5559  
5560          return cur;
5561      },
5562  
5563      sibling: function( n, elem ) {
5564          var r = [];
5565  
5566          for ( ; n; n = n.nextSibling ) {
5567              if ( n.nodeType === 1 && n !== elem ) {
5568                  r.push( n );
5569              }
5570          }
5571  
5572          return r;
5573      }
5574  });
5575  
5576  // Implement the identical functionality for filter and not
5577  function winnow( elements, qualifier, keep ) {
5578  
5579      // Can't pass null or undefined to indexOf in Firefox 4
5580      // Set to 0 to skip string check
5581      qualifier = qualifier || 0;
5582  
5583      if ( jQuery.isFunction( qualifier ) ) {
5584          return jQuery.grep(elements, function( elem, i ) {
5585              var retVal = !!qualifier.call( elem, i, elem );
5586              return retVal === keep;
5587          });
5588  
5589      } else if ( qualifier.nodeType ) {
5590          return jQuery.grep(elements, function( elem, i ) {
5591              return ( elem === qualifier ) === keep;
5592          });
5593  
5594      } else if ( typeof qualifier === "string" ) {
5595          var filtered = jQuery.grep(elements, function( elem ) {
5596              return elem.nodeType === 1;
5597          });
5598  
5599          if ( isSimple.test( qualifier ) ) {
5600              return jQuery.filter(qualifier, filtered, !keep);
5601          } else {
5602              qualifier = jQuery.filter( qualifier, filtered );
5603          }
5604      }
5605  
5606      return jQuery.grep(elements, function( elem, i ) {
5607          return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
5608      });
5609  }
5610  
5611  
5612  
5613  
5614  function createSafeFragment( document ) {
5615      var list = nodeNames.split( "|" ),
5616      safeFrag = document.createDocumentFragment();
5617  
5618      if ( safeFrag.createElement ) {
5619          while ( list.length ) {
5620              safeFrag.createElement(
5621                  list.pop()
5622              );
5623          }
5624      }
5625      return safeFrag;
5626  }
5627  
5628  var nodeNames = "abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|" +
5629          "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
5630      rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
5631      rleadingWhitespace = /^\s+/,
5632      rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
5633      rtagName = /<([\w:]+)/,
5634      rtbody = /<tbody/i,
5635      rhtml = /<|&#?\w+;/,
5636      rnoInnerhtml = /<(?:script|style)/i,
5637      rnocache = /<(?:script|object|embed|option|style)/i,
5638      rnoshimcache = new RegExp("<(?:" + nodeNames + ")", "i"),
5639      // checked="checked" or checked
5640      rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5641      rscriptType = /\/(java|ecma)script/i,
5642      rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
5643      wrapMap = {
5644          option: [ 1, "<select multiple='multiple'>", "</select>" ],
5645          legend: [ 1, "<fieldset>", "</fieldset>" ],
5646          thead: [ 1, "<table>", "</table>" ],
5647          tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5648          td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5649          col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5650          area: [ 1, "<map>", "</map>" ],
5651          _default: [ 0, "", "" ]
5652      },
5653      safeFragment = createSafeFragment( document );
5654  
5655  wrapMap.optgroup = wrapMap.option;
5656  wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5657  wrapMap.th = wrapMap.td;
5658  
5659  // IE can't serialize <link> and <script> tags normally
5660  if ( !jQuery.support.htmlSerialize ) {
5661      wrapMap._default = [ 1, "div<div>", "</div>" ];
5662  }
5663  
5664  jQuery.fn.extend({
5665      text: function( text ) {
5666          if ( jQuery.isFunction(text) ) {
5667              return this.each(function(i) {
5668                  var self = jQuery( this );
5669  
5670                  self.text( text.call(this, i, self.text()) );
5671              });
5672          }
5673  
5674          if ( typeof text !== "object" && text !== undefined ) {
5675              return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
5676          }
5677  
5678          return jQuery.text( this );
5679      },
5680  
5681      wrapAll: function( html ) {
5682          if ( jQuery.isFunction( html ) ) {
5683              return this.each(function(i) {
5684                  jQuery(this).wrapAll( html.call(this, i) );
5685              });
5686          }
5687  
5688          if ( this[0] ) {
5689              // The elements to wrap the target around
5690              var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5691  
5692              if ( this[0].parentNode ) {
5693                  wrap.insertBefore( this[0] );
5694              }
5695  
5696              wrap.map(function() {
5697                  var elem = this;
5698  
5699                  while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5700                      elem = elem.firstChild;
5701                  }
5702  
5703                  return elem;
5704              }).append( this );
5705          }
5706  
5707          return this;
5708      },
5709  
5710      wrapInner: function( html ) {
5711          if ( jQuery.isFunction( html ) ) {
5712              return this.each(function(i) {
5713                  jQuery(this).wrapInner( html.call(this, i) );
5714              });
5715          }
5716  
5717          return this.each(function() {
5718              var self = jQuery( this ),
5719                  contents = self.contents();
5720  
5721              if ( contents.length ) {
5722                  contents.wrapAll( html );
5723  
5724              } else {
5725                  self.append( html );
5726              }
5727          });
5728      },
5729  
5730      wrap: function( html ) {
5731          var isFunction = jQuery.isFunction( html );
5732  
5733          return this.each(function(i) {
5734              jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
5735          });
5736      },
5737  
5738      unwrap: function() {
5739          return this.parent().each(function() {
5740              if ( !jQuery.nodeName( this, "body" ) ) {
5741                  jQuery( this ).replaceWith( this.childNodes );
5742              }
5743          }).end();
5744      },
5745  
5746      append: function() {
5747          return this.domManip(arguments, true, function( elem ) {
5748              if ( this.nodeType === 1 ) {
5749                  this.appendChild( elem );
5750              }
5751          });
5752      },
5753  
5754      prepend: function() {
5755          return this.domManip(arguments, true, function( elem ) {
5756              if ( this.nodeType === 1 ) {
5757                  this.insertBefore( elem, this.firstChild );
5758              }
5759          });
5760      },
5761  
5762      before: function() {
5763          if ( this[0] && this[0].parentNode ) {
5764              return this.domManip(arguments, false, function( elem ) {
5765                  this.parentNode.insertBefore( elem, this );
5766              });
5767          } else if ( arguments.length ) {
5768              var set = jQuery.clean( arguments );
5769              set.push.apply( set, this.toArray() );
5770              return this.pushStack( set, "before", arguments );
5771          }
5772      },
5773  
5774      after: function() {
5775          if ( this[0] && this[0].parentNode ) {
5776              return this.domManip(arguments, false, function( elem ) {
5777                  this.parentNode.insertBefore( elem, this.nextSibling );
5778              });
5779          } else if ( arguments.length ) {
5780              var set = this.pushStack( this, "after", arguments );
5781              set.push.apply( set, jQuery.clean(arguments) );
5782              return set;
5783          }
5784      },
5785  
5786      // keepData is for internal use only--do not document
5787      remove: function( selector, keepData ) {
5788          for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5789              if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5790                  if ( !keepData && elem.nodeType === 1 ) {
5791                      jQuery.cleanData( elem.getElementsByTagName("*") );
5792                      jQuery.cleanData( [ elem ] );
5793                  }
5794  
5795                  if ( elem.parentNode ) {
5796                      elem.parentNode.removeChild( elem );
5797                  }
5798              }
5799          }
5800  
5801          return this;
5802      },
5803  
5804      empty: function() {
5805          for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5806              // Remove element nodes and prevent memory leaks
5807              if ( elem.nodeType === 1 ) {
5808                  jQuery.cleanData( elem.getElementsByTagName("*") );
5809              }
5810  
5811              // Remove any remaining nodes
5812              while ( elem.firstChild ) {
5813                  elem.removeChild( elem.firstChild );
5814              }
5815          }
5816  
5817          return this;
5818      },
5819  
5820      clone: function( dataAndEvents, deepDataAndEvents ) {
5821          dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5822          deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5823  
5824          return this.map( function () {
5825              return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5826          });
5827      },
5828  
5829      html: function( value ) {
5830          if ( value === undefined ) {
5831              return this[0] && this[0].nodeType === 1 ?
5832                  this[0].innerHTML.replace(rinlinejQuery, "") :
5833                  null;
5834  
5835          // See if we can take a shortcut and just use innerHTML
5836          } else if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5837              (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
5838              !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
5839  
5840              value = value.replace(rxhtmlTag, "<$1></$2>");
5841  
5842              try {
5843                  for ( var i = 0, l = this.length; i < l; i++ ) {
5844                      // Remove element nodes and prevent memory leaks
5845                      if ( this[i].nodeType === 1 ) {
5846                          jQuery.cleanData( this[i].getElementsByTagName("*") );
5847                          this[i].innerHTML = value;
5848                      }
5849                  }
5850  
5851              // If using innerHTML throws an exception, use the fallback method
5852              } catch(e) {
5853                  this.empty().append( value );
5854              }
5855  
5856          } else if ( jQuery.isFunction( value ) ) {
5857              this.each(function(i){
5858                  var self = jQuery( this );
5859  
5860                  self.html( value.call(this, i, self.html()) );
5861              });
5862  
5863          } else {
5864              this.empty().append( value );
5865          }
5866  
5867          return this;
5868      },
5869  
5870      replaceWith: function( value ) {
5871          if ( this[0] && this[0].parentNode ) {
5872              // Make sure that the elements are removed from the DOM before they are inserted
5873              // this can help fix replacing a parent with child elements
5874              if ( jQuery.isFunction( value ) ) {
5875                  return this.each(function(i) {
5876                      var self = jQuery(this), old = self.html();
5877                      self.replaceWith( value.call( this, i, old ) );
5878                  });
5879              }
5880  
5881              if ( typeof value !== "string" ) {
5882                  value = jQuery( value ).detach();
5883              }
5884  
5885              return this.each(function() {
5886                  var next = this.nextSibling,
5887                      parent = this.parentNode;
5888  
5889                  jQuery( this ).remove();
5890  
5891                  if ( next ) {
5892                      jQuery(next).before( value );
5893                  } else {
5894                      jQuery(parent).append( value );
5895                  }
5896              });
5897          } else {
5898              return this.length ?
5899                  this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5900                  this;
5901          }
5902      },
5903  
5904      detach: function( selector ) {
5905          return this.remove( selector, true );
5906      },
5907  
5908      domManip: function( args, table, callback ) {
5909          var results, first, fragment, parent,
5910              value = args[0],
5911              scripts = [];
5912  
5913          // We can't cloneNode fragments that contain checked, in WebKit
5914          if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
5915              return this.each(function() {
5916                  jQuery(this).domManip( args, table, callback, true );
5917              });
5918          }
5919  
5920          if ( jQuery.isFunction(value) ) {
5921              return this.each(function(i) {
5922                  var self = jQuery(this);
5923                  args[0] = value.call(this, i, table ? self.html() : undefined);
5924                  self.domManip( args, table, callback );
5925              });
5926          }
5927  
5928          if ( this[0] ) {
5929              parent = value && value.parentNode;
5930  
5931              // If we're in a fragment, just use that instead of building a new one
5932              if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
5933                  results = { fragment: parent };
5934  
5935              } else {
5936                  results = jQuery.buildFragment( args, this, scripts );
5937              }
5938  
5939              fragment = results.fragment;
5940  
5941              if ( fragment.childNodes.length === 1 ) {
5942                  first = fragment = fragment.firstChild;
5943              } else {
5944                  first = fragment.firstChild;
5945              }
5946  
5947              if ( first ) {
5948                  table = table && jQuery.nodeName( first, "tr" );
5949  
5950                  for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
5951                      callback.call(
5952                          table ?
5953                              root(this[i], first) :
5954                              this[i],
5955                          // Make sure that we do not leak memory by inadvertently discarding
5956                          // the original fragment (which might have attached data) instead of
5957                          // using it; in addition, use the original fragment object for the last
5958                          // item instead of first because it can end up being emptied incorrectly
5959                          // in certain situations (Bug #8070).
5960                          // Fragments from the fragment cache must always be cloned and never used
5961                          // in place.
5962                          results.cacheable || ( l > 1 && i < lastIndex ) ?
5963                              jQuery.clone( fragment, true, true ) :
5964                              fragment
5965                      );
5966                  }
5967              }
5968  
5969              if ( scripts.length ) {
5970                  jQuery.each( scripts, evalScript );
5971              }
5972          }
5973  
5974          return this;
5975      }
5976  });
5977  
5978  function root( elem, cur ) {
5979      return jQuery.nodeName(elem, "table") ?
5980          (elem.getElementsByTagName("tbody")[0] ||
5981          elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
5982          elem;
5983  }
5984  
5985  function cloneCopyEvent( src, dest ) {
5986  
5987      if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5988          return;
5989      }
5990  
5991      var type, i, l,
5992          oldData = jQuery._data( src ),
5993          curData = jQuery._data( dest, oldData ),
5994          events = oldData.events;
5995  
5996      if ( events ) {
5997          delete curData.handle;
5998          curData.events = {};
5999  
6000          for ( type in events ) {
6001              for ( i = 0, l = events[ type ].length; i < l; i++ ) {
6002                  jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
6003              }
6004          }
6005      }
6006  
6007      // make the cloned public data object a copy from the original
6008      if ( curData.data ) {
6009          curData.data = jQuery.extend( {}, curData.data );
6010      }
6011  }
6012  
6013  function cloneFixAttributes( src, dest ) {
6014      var nodeName;
6015  
6016      // We do not need to do anything for non-Elements
6017      if ( dest.nodeType !== 1 ) {
6018          return;
6019      }
6020  
6021      // clearAttributes removes the attributes, which we don't want,
6022      // but also removes the attachEvent events, which we *do* want
6023      if ( dest.clearAttributes ) {
6024          dest.clearAttributes();
6025      }
6026  
6027      // mergeAttributes, in contrast, only merges back on the
6028      // original attributes, not the events
6029      if ( dest.mergeAttributes ) {
6030          dest.mergeAttributes( src );
6031      }
6032  
6033      nodeName = dest.nodeName.toLowerCase();
6034  
6035      // IE6-8 fail to clone children inside object elements that use
6036      // the proprietary classid attribute value (rather than the type
6037      // attribute) to identify the type of content to display
6038      if ( nodeName === "object" ) {
6039          dest.outerHTML = src.outerHTML;
6040  
6041      } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
6042          // IE6-8 fails to persist the checked state of a cloned checkbox
6043          // or radio button. Worse, IE6-7 fail to give the cloned element
6044          // a checked appearance if the defaultChecked value isn't also set
6045          if ( src.checked ) {
6046              dest.defaultChecked = dest.checked = src.checked;
6047          }
6048  
6049          // IE6-7 get confused and end up setting the value of a cloned
6050          // checkbox/radio button to an empty string instead of "on"
6051          if ( dest.value !== src.value ) {
6052              dest.value = src.value;
6053          }
6054  
6055      // IE6-8 fails to return the selected option to the default selected
6056      // state when cloning options
6057      } else if ( nodeName === "option" ) {
6058          dest.selected = src.defaultSelected;
6059  
6060      // IE6-8 fails to set the defaultValue to the correct value when
6061      // cloning other types of input fields
6062      } else if ( nodeName === "input" || nodeName === "textarea" ) {
6063          dest.defaultValue = src.defaultValue;
6064      }
6065  
6066      // Event data gets referenced instead of copied if the expando
6067      // gets copied too
6068      dest.removeAttribute( jQuery.expando );
6069  }
6070  
6071  jQuery.buildFragment = function( args, nodes, scripts ) {
6072      var fragment, cacheable, cacheresults, doc,
6073      first = args[ 0 ];
6074  
6075      // nodes may contain either an explicit document object,
6076      // a jQuery collection or context object.
6077      // If nodes[0] contains a valid object to assign to doc
6078      if ( nodes && nodes[0] ) {
6079          doc = nodes[0].ownerDocument || nodes[0];
6080      }
6081  
6082      // Ensure that an attr object doesn't incorrectly stand in as a document object
6083      // Chrome and Firefox seem to allow this to occur and will throw exception
6084      // Fixes #8950
6085      if ( !doc.createDocumentFragment ) {
6086          doc = document;
6087      }
6088  
6089      // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
6090      // Cloning options loses the selected state, so don't cache them
6091      // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
6092      // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
6093      // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501
6094      if ( args.length === 1 && typeof first === "string" && first.length < 512 && doc === document &&
6095          first.charAt(0) === "<" && !rnocache.test( first ) &&
6096          (jQuery.support.checkClone || !rchecked.test( first )) &&
6097          (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {
6098  
6099          cacheable = true;
6100  
6101          cacheresults = jQuery.fragments[ first ];
6102          if ( cacheresults && cacheresults !== 1 ) {
6103              fragment = cacheresults;
6104          }
6105      }
6106  
6107      if ( !fragment ) {
6108          fragment = doc.createDocumentFragment();
6109          jQuery.clean( args, doc, fragment, scripts );
6110      }
6111  
6112      if ( cacheable ) {
6113          jQuery.fragments[ first ] = cacheresults ? fragment : 1;
6114      }
6115  
6116      return { fragment: fragment, cacheable: cacheable };
6117  };
6118  
6119  jQuery.fragments = {};
6120  
6121  jQuery.each({
6122      appendTo: "append",
6123      prependTo: "prepend",
6124      insertBefore: "before",
6125      insertAfter: "after",
6126      replaceAll: "replaceWith"
6127  }, function( name, original ) {
6128      jQuery.fn[ name ] = function( selector ) {
6129          var ret = [],
6130              insert = jQuery( selector ),
6131              parent = this.length === 1 && this[0].parentNode;
6132  
6133          if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
6134              insert[ original ]( this[0] );
6135              return this;
6136  
6137          } else {
6138              for ( var i = 0, l = insert.length; i < l; i++ ) {
6139                  var elems = ( i > 0 ? this.clone(true) : this ).get();
6140                  jQuery( insert[i] )[ original ]( elems );
6141                  ret = ret.concat( elems );
6142              }
6143  
6144              return this.pushStack( ret, name, insert.selector );
6145          }
6146      };
6147  });
6148  
6149  function getAll( elem ) {
6150      if ( typeof elem.getElementsByTagName !== "undefined" ) {
6151          return elem.getElementsByTagName( "*" );
6152  
6153      } else if ( typeof elem.querySelectorAll !== "undefined" ) {
6154          return elem.querySelectorAll( "*" );
6155  
6156      } else {
6157          return [];
6158      }
6159  }
6160  
6161  // Used in clean, fixes the defaultChecked property
6162  function fixDefaultChecked( elem ) {
6163      if ( elem.type === "checkbox" || elem.type === "radio" ) {
6164          elem.defaultChecked = elem.checked;
6165      }
6166  }
6167  // Finds all inputs and passes them to fixDefaultChecked
6168  function findInputs( elem ) {
6169      var nodeName = ( elem.nodeName || "" ).toLowerCase();
6170      if ( nodeName === "input" ) {
6171          fixDefaultChecked( elem );
6172      // Skip scripts, get other children
6173      } else if ( nodeName !== "script" && typeof elem.getElementsByTagName !== "undefined" ) {
6174          jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
6175      }
6176  }
6177  
6178  // Derived From: http://www.iecss.com/shimprove/javascript/shimprove.1-0-1.js
6179  function shimCloneNode( elem ) {
6180      var div = document.createElement( "div" );
6181      safeFragment.appendChild( div );
6182  
6183      div.innerHTML = elem.outerHTML;
6184      return div.firstChild;
6185  }
6186  
6187  jQuery.extend({
6188      clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6189          var srcElements,
6190              destElements,
6191              i,
6192              // IE<=8 does not properly clone detached, unknown element nodes
6193              clone = jQuery.support.html5Clone || !rnoshimcache.test( "<" + elem.nodeName ) ?
6194                  elem.cloneNode( true ) :
6195                  shimCloneNode( elem );
6196  
6197          if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
6198                  (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
6199              // IE copies events bound via attachEvent when using cloneNode.
6200              // Calling detachEvent on the clone will also remove the events
6201              // from the original. In order to get around this, we use some
6202              // proprietary methods to clear the events. Thanks to MooTools
6203              // guys for this hotness.
6204  
6205              cloneFixAttributes( elem, clone );
6206  
6207              // Using Sizzle here is crazy slow, so we use getElementsByTagName instead
6208              srcElements = getAll( elem );
6209              destElements = getAll( clone );
6210  
6211              // Weird iteration because IE will replace the length property
6212              // with an element if you are cloning the body and one of the
6213              // elements on the page has a name or id of "length"
6214              for ( i = 0; srcElements[i]; ++i ) {
6215                  // Ensure that the destination node is not null; Fixes #9587
6216                  if ( destElements[i] ) {
6217                      cloneFixAttributes( srcElements[i], destElements[i] );
6218                  }
6219              }
6220          }
6221  
6222          // Copy the events from the original to the clone
6223          if ( dataAndEvents ) {
6224              cloneCopyEvent( elem, clone );
6225  
6226              if ( deepDataAndEvents ) {
6227                  srcElements = getAll( elem );
6228                  destElements = getAll( clone );
6229  
6230                  for ( i = 0; srcElements[i]; ++i ) {
6231                      cloneCopyEvent( srcElements[i], destElements[i] );
6232                  }
6233              }
6234          }
6235  
6236          srcElements = destElements = null;
6237  
6238          // Return the cloned set
6239          return clone;
6240      },
6241  
6242      clean: function( elems, context, fragment, scripts ) {
6243          var checkScriptType;
6244  
6245          context = context || document;
6246  
6247          // !context.createElement fails in IE with an error but returns typeof 'object'
6248          if ( typeof context.createElement === "undefined" ) {
6249              context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
6250          }
6251  
6252          var ret = [], j;
6253  
6254          for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6255              if ( typeof elem === "number" ) {
6256                  elem += "";
6257              }
6258  
6259              if ( !elem ) {
6260                  continue;
6261              }
6262  
6263              // Convert html string into DOM nodes
6264              if ( typeof elem === "string" ) {
6265                  if ( !rhtml.test( elem ) ) {
6266                      elem = context.createTextNode( elem );
6267                  } else {
6268                      // Fix "XHTML"-style tags in all browsers
6269                      elem = elem.replace(rxhtmlTag, "<$1></$2>");
6270  
6271                      // Trim whitespace, otherwise indexOf won't work as expected
6272                      var tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(),
6273                          wrap = wrapMap[ tag ] || wrapMap._default,
6274                          depth = wrap[0],
6275                          div = context.createElement("div");
6276  
6277                      // Append wrapper element to unknown element safe doc fragment
6278                      if ( context === document ) {
6279                          // Use the fragment we've already created for this document
6280                          safeFragment.appendChild( div );
6281                      } else {
6282                          // Use a fragment created with the owner document
6283                          createSafeFragment( context ).appendChild( div );
6284                      }
6285  
6286                      // Go to html and back, then peel off extra wrappers
6287                      div.innerHTML = wrap[1] + elem + wrap[2];
6288  
6289                      // Move to the right depth
6290                      while ( depth-- ) {
6291                          div = div.lastChild;
6292                      }
6293  
6294                      // Remove IE's autoinserted <tbody> from table fragments
6295                      if ( !jQuery.support.tbody ) {
6296  
6297                          // String was a <table>, *may* have spurious <tbody>
6298                          var hasBody = rtbody.test(elem),
6299                              tbody = tag === "table" && !hasBody ?
6300                                  div.firstChild && div.firstChild.childNodes :
6301  
6302                                  // String was a bare <thead> or <tfoot>
6303                                  wrap[1] === "<table>" && !hasBody ?
6304                                      div.childNodes :
6305                                      [];
6306  
6307                          for ( j = tbody.length - 1; j >= 0 ; --j ) {
6308                              if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6309                                  tbody[ j ].parentNode.removeChild( tbody[ j ] );
6310                              }
6311                          }
6312                      }
6313  
6314                      // IE completely kills leading whitespace when innerHTML is used
6315                      if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6316                          div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6317                      }
6318  
6319                      elem = div.childNodes;
6320                  }
6321              }
6322  
6323              // Resets defaultChecked for any radios and checkboxes
6324              // about to be appended to the DOM in IE 6/7 (#8060)
6325              var len;
6326              if ( !jQuery.support.appendChecked ) {
6327                  if ( elem[0] && typeof (len = elem.length) === "number" ) {
6328                      for ( j = 0; j < len; j++ ) {
6329                          findInputs( elem[j] );
6330                      }
6331                  } else {
6332                      findInputs( elem );
6333                  }
6334              }
6335  
6336              if ( elem.nodeType ) {
6337                  ret.push( elem );
6338              } else {
6339                  ret = jQuery.merge( ret, elem );
6340              }
6341          }
6342  
6343          if ( fragment ) {
6344              checkScriptType = function( elem ) {
6345                  return !elem.type || rscriptType.test( elem.type );
6346              };
6347              for ( i = 0; ret[i]; i++ ) {
6348                  if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
6349                      scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
6350  
6351                  } else {
6352                      if ( ret[i].nodeType === 1 ) {
6353                          var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
6354  
6355                          ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6356                      }
6357                      fragment.appendChild( ret[i] );
6358                  }
6359              }
6360          }
6361  
6362          return ret;
6363      },
6364  
6365      cleanData: function( elems ) {
6366          var data, id,
6367              cache = jQuery.cache,
6368              special = jQuery.event.special,
6369              deleteExpando = jQuery.support.deleteExpando;
6370  
6371          for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6372              if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
6373                  continue;
6374              }
6375  
6376              id = elem[ jQuery.expando ];
6377  
6378              if ( id ) {
6379                  data = cache[ id ];
6380  
6381                  if ( data && data.events ) {
6382                      for ( var type in data.events ) {
6383                          if ( special[ type ] ) {
6384                              jQuery.event.remove( elem, type );
6385  
6386                          // This is a shortcut to avoid jQuery.event.remove's overhead
6387                          } else {
6388                              jQuery.removeEvent( elem, type, data.handle );
6389                          }
6390                      }
6391  
6392                      // Null the DOM reference to avoid IE6/7/8 leak (#7054)
6393                      if ( data.handle ) {
6394                          data.handle.elem = null;
6395                      }
6396                  }
6397  
6398                  if ( deleteExpando ) {
6399                      delete elem[ jQuery.expando ];
6400  
6401                  } else if ( elem.removeAttribute ) {
6402                      elem.removeAttribute( jQuery.expando );
6403                  }
6404  
6405                  delete cache[ id ];
6406              }
6407          }
6408      }
6409  });
6410  
6411  function evalScript( i, elem ) {
6412      if ( elem.src ) {
6413          jQuery.ajax({
6414              url: elem.src,
6415              async: false,
6416              dataType: "script"
6417          });
6418      } else {
6419          jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
6420      }
6421  
6422      if ( elem.parentNode ) {
6423          elem.parentNode.removeChild( elem );
6424      }
6425  }
6426  
6427  
6428  
6429  
6430  var ralpha = /alpha\([^)]*\)/i,
6431      ropacity = /opacity=([^)]*)/,
6432      // fixed for IE9, see #8346
6433      rupper = /([A-Z]|^ms)/g,
6434      rnumpx = /^-?\d+(?:px)?$/i,
6435      rnum = /^-?\d/,
6436      rrelNum = /^([\-+])=([\-+.\de]+)/,
6437  
6438      cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6439      cssWidth = [ "Left", "Right" ],
6440      cssHeight = [ "Top", "Bottom" ],
6441      curCSS,
6442  
6443      getComputedStyle,
6444      currentStyle;
6445  
6446  jQuery.fn.css = function( name, value ) {
6447      // Setting 'undefined' is a no-op
6448      if ( arguments.length === 2 && value === undefined ) {
6449          return this;
6450      }
6451  
6452      return jQuery.access( this, name, value, true, function( elem, name, value ) {
6453          return value !== undefined ?
6454              jQuery.style( elem, name, value ) :
6455              jQuery.css( elem, name );
6456      });
6457  };
6458  
6459  jQuery.extend({
6460      // Add in style property hooks for overriding the default
6461      // behavior of getting and setting a style property
6462      cssHooks: {
6463          opacity: {
6464              get: function( elem, computed ) {
6465                  if ( computed ) {
6466                      // We should always get a number back from opacity
6467                      var ret = curCSS( elem, "opacity", "opacity" );
6468                      return ret === "" ? "1" : ret;
6469  
6470                  } else {
6471                      return elem.style.opacity;
6472                  }
6473              }
6474          }
6475      },
6476  
6477      // Exclude the following css properties to add px
6478      cssNumber: {
6479          "fillOpacity": true,
6480          "fontWeight": true,
6481          "lineHeight": true,
6482          "opacity": true,
6483          "orphans": true,
6484          "widows": true,
6485          "zIndex": true,
6486          "zoom": true
6487      },
6488  
6489      // Add in properties whose names you wish to fix before
6490      // setting or getting the value
6491      cssProps: {
6492          // normalize float css property
6493          "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6494      },
6495  
6496      // Get and set the style property on a DOM Node
6497      style: function( elem, name, value, extra ) {
6498          // Don't set styles on text and comment nodes
6499          if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6500              return;
6501          }
6502  
6503          // Make sure that we're working with the right name
6504          var ret, type, origName = jQuery.camelCase( name ),
6505              style = elem.style, hooks = jQuery.cssHooks[ origName ];
6506  
6507          name = jQuery.cssProps[ origName ] || origName;
6508  
6509          // Check if we're setting a value
6510          if ( value !== undefined ) {
6511              type = typeof value;
6512  
6513              // convert relative number strings (+= or -=) to relative numbers. #7345
6514              if ( type === "string" && (ret = rrelNum.exec( value )) ) {
6515                  value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );
6516                  // Fixes bug #9237
6517                  type = "number";
6518              }
6519  
6520              // Make sure that NaN and null values aren't set. See: #7116
6521              if ( value == null || type === "number" && isNaN( value ) ) {
6522                  return;
6523              }
6524  
6525              // If a number was passed in, add 'px' to the (except for certain CSS properties)
6526              if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6527                  value += "px";
6528              }
6529  
6530              // If a hook was provided, use that value, otherwise just set the specified value
6531              if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
6532                  // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6533                  // Fixes bug #5509
6534                  try {
6535                      style[ name ] = value;
6536                  } catch(e) {}
6537              }
6538  
6539          } else {
6540              // If a hook was provided get the non-computed value from there
6541              if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6542                  return ret;
6543              }
6544  
6545              // Otherwise just get the value from the style object
6546              return style[ name ];
6547          }
6548      },
6549  
6550      css: function( elem, name, extra ) {
6551          var ret, hooks;
6552  
6553          // Make sure that we're working with the right name
6554          name = jQuery.camelCase( name );
6555          hooks = jQuery.cssHooks[ name ];
6556          name = jQuery.cssProps[ name ] || name;
6557  
6558          // cssFloat needs a special treatment
6559          if ( name === "cssFloat" ) {
6560              name = "float";
6561          }
6562  
6563          // If a hook was provided get the computed value from there
6564          if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
6565              return ret;
6566  
6567          // Otherwise, if a way to get the computed value exists, use that
6568          } else if ( curCSS ) {
6569              return curCSS( elem, name );
6570          }
6571      },
6572  
6573      // A method for quickly swapping in/out CSS properties to get correct calculations
6574      swap: function( elem, options, callback ) {
6575          var old = {};
6576  
6577          // Remember the old values, and insert the new ones
6578          for ( var name in options ) {
6579              old[ name ] = elem.style[ name ];
6580              elem.style[ name ] = options[ name ];
6581          }
6582  
6583          callback.call( elem );
6584  
6585          // Revert the old values
6586          for ( name in options ) {
6587              elem.style[ name ] = old[ name ];
6588          }
6589      }
6590  });
6591  
6592  // DEPRECATED, Use jQuery.css() instead
6593  jQuery.curCSS = jQuery.css;
6594  
6595  jQuery.each(["height", "width"], function( i, name ) {
6596      jQuery.cssHooks[ name ] = {
6597          get: function( elem, computed, extra ) {
6598              var val;
6599  
6600              if ( computed ) {
6601                  if ( elem.offsetWidth !== 0 ) {
6602                      return getWH( elem, name, extra );
6603                  } else {
6604                      jQuery.swap( elem, cssShow, function() {
6605                          val = getWH( elem, name, extra );
6606                      });
6607                  }
6608  
6609                  return val;
6610              }
6611          },
6612  
6613          set: function( elem, value ) {
6614              if ( rnumpx.test( value ) ) {
6615                  // ignore negative width and height values #1599
6616                  value = parseFloat( value );
6617  
6618                  if ( value >= 0 ) {
6619                      return value + "px";
6620                  }
6621  
6622              } else {
6623                  return value;
6624              }
6625          }
6626      };
6627  });
6628  
6629  if ( !jQuery.support.opacity ) {
6630      jQuery.cssHooks.opacity = {
6631          get: function( elem, computed ) {
6632              // IE uses filters for opacity
6633              return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
6634                  ( parseFloat( RegExp.$1 ) / 100 ) + "" :
6635                  computed ? "1" : "";
6636          },
6637  
6638          set: function( elem, value ) {
6639              var style = elem.style,
6640                  currentStyle = elem.currentStyle,
6641                  opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
6642                  filter = currentStyle && currentStyle.filter || style.filter || "";
6643  
6644              // IE has trouble with opacity if it does not have layout
6645              // Force it by setting the zoom level
6646              style.zoom = 1;
6647  
6648              // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
6649              if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {
6650  
6651                  // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
6652                  // if "filter:" is present at all, clearType is disabled, we want to avoid this
6653                  // style.removeAttribute is IE Only, but so apparently is this code path...
6654                  style.removeAttribute( "filter" );
6655  
6656                  // if there there is no filter style applied in a css rule, we are done
6657                  if ( currentStyle && !currentStyle.filter ) {
6658                      return;
6659                  }
6660              }
6661  
6662              // otherwise, set new filter values
6663              style.filter = ralpha.test( filter ) ?
6664                  filter.replace( ralpha, opacity ) :
6665                  filter + " " + opacity;
6666          }
6667      };
6668  }
6669  
6670  jQuery(function() {
6671      // This hook cannot be added until DOM ready because the support test
6672      // for it is not run until after DOM ready
6673      if ( !jQuery.support.reliableMarginRight ) {
6674          jQuery.cssHooks.marginRight = {
6675              get: function( elem, computed ) {
6676                  // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6677                  // Work around by temporarily setting element display to inline-block
6678                  var ret;
6679                  jQuery.swap( elem, { "display": "inline-block" }, function() {
6680                      if ( computed ) {
6681                          ret = curCSS( elem, "margin-right", "marginRight" );
6682                      } else {
6683                          ret = elem.style.marginRight;
6684                      }
6685                  });
6686                  return ret;
6687              }
6688          };
6689      }
6690  });
6691  
6692  if ( document.defaultView && document.defaultView.getComputedStyle ) {
6693      getComputedStyle = function( elem, name ) {
6694          var ret, defaultView, computedStyle;
6695  
6696          name = name.replace( rupper, "-$1" ).toLowerCase();
6697  
6698          if ( (defaultView = elem.ownerDocument.defaultView) &&
6699                  (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
6700              ret = computedStyle.getPropertyValue( name );
6701              if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
6702                  ret = jQuery.style( elem, name );
6703              }
6704          }
6705  
6706          return ret;
6707      };
6708  }
6709  
6710  if ( document.documentElement.currentStyle ) {
6711      currentStyle = function( elem, name ) {
6712          var left, rsLeft, uncomputed,
6713              ret = elem.currentStyle && elem.currentStyle[ name ],
6714              style = elem.style;
6715  
6716          // Avoid setting ret to empty string here
6717          // so we don't default to auto
6718          if ( ret === null && style && (uncomputed = style[ name ]) ) {
6719              ret = uncomputed;
6720          }
6721  
6722          // From the awesome hack by Dean Edwards
6723          // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6724  
6725          // If we're not dealing with a regular pixel number
6726          // but a number that has a weird ending, we need to convert it to pixels
6727          if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
6728  
6729              // Remember the original values
6730              left = style.left;
6731              rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;
6732  
6733              // Put in the new values to get a computed value out
6734              if ( rsLeft ) {
6735                  elem.runtimeStyle.left = elem.currentStyle.left;
6736              }
6737              style.left = name === "fontSize" ? "1em" : ( ret || 0 );
6738              ret = style.pixelLeft + "px";
6739  
6740              // Revert the changed values
6741              style.left = left;
6742              if ( rsLeft ) {
6743                  elem.runtimeStyle.left = rsLeft;
6744              }
6745          }
6746  
6747          return ret === "" ? "auto" : ret;
6748      };
6749  }
6750  
6751  curCSS = getComputedStyle || currentStyle;
6752  
6753  function getWH( elem, name, extra ) {
6754  
6755      // Start with offset property
6756      var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6757          which = name === "width" ? cssWidth : cssHeight,
6758          i = 0,
6759          len = which.length;
6760  
6761      if ( val > 0 ) {
6762          if ( extra !== "border" ) {
6763              for ( ; i < len; i++ ) {
6764                  if ( !extra ) {
6765                      val -= parseFloat( jQuery.css( elem, "padding" + which[ i ] ) ) || 0;
6766                  }
6767                  if ( extra === "margin" ) {
6768                      val += parseFloat( jQuery.css( elem, extra + which[ i ] ) ) || 0;
6769                  } else {
6770                      val -= parseFloat( jQuery.css( elem, "border" + which[ i ] + "Width" ) ) || 0;
6771                  }
6772              }
6773          }
6774  
6775          return val + "px";
6776      }
6777  
6778      // Fall back to computed then uncomputed css if necessary
6779      val = curCSS( elem, name, name );
6780      if ( val < 0 || val == null ) {
6781          val = elem.style[ name ] || 0;
6782      }
6783      // Normalize "", auto, and prepare for extra
6784      val = parseFloat( val ) || 0;
6785  
6786      // Add padding, border, margin
6787      if ( extra ) {
6788          for ( ; i < len; i++ ) {
6789              val += parseFloat( jQuery.css( elem, "padding" + which[ i ] ) ) || 0;
6790              if ( extra !== "padding" ) {
6791                  val += parseFloat( jQuery.css( elem, "border" + which[ i ] + "Width" ) ) || 0;
6792              }
6793              if ( extra === "margin" ) {
6794                  val += parseFloat( jQuery.css( elem, extra + which[ i ] ) ) || 0;
6795              }
6796          }
6797      }
6798  
6799      return val + "px";
6800  }
6801  
6802  if ( jQuery.expr && jQuery.expr.filters ) {
6803      jQuery.expr.filters.hidden = function( elem ) {
6804          var width = elem.offsetWidth,
6805              height = elem.offsetHeight;
6806  
6807          return ( width === 0 && height === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
6808      };
6809  
6810      jQuery.expr.filters.visible = function( elem ) {
6811          return !jQuery.expr.filters.hidden( elem );
6812      };
6813  }
6814  
6815  
6816  
6817  
6818  var r20 = /%20/g,
6819      rbracket = /\[\]$/,
6820      rCRLF = /\r?\n/g,
6821      rhash = /#.*$/,
6822      rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
6823      rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
6824      // #7653, #8125, #8152: local protocol detection
6825      rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
6826      rnoContent = /^(?:GET|HEAD)$/,
6827      rprotocol = /^\/\//,
6828      rquery = /\?/,
6829      rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
6830      rselectTextarea = /^(?:select|textarea)/i,
6831      rspacesAjax = /\s+/,
6832      rts = /([?&])_=[^&]*/,
6833      rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
6834  
6835      // Keep a copy of the old load method
6836      _load = jQuery.fn.load,
6837  
6838      /* Prefilters
6839       * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
6840       * 2) These are called:
6841       *    - BEFORE asking for a transport
6842       *    - AFTER param serialization (s.data is a string if s.processData is true)
6843       * 3) key is the dataType
6844       * 4) the catchall symbol "*" can be used
6845       * 5) execution will start with transport dataType and THEN continue down to "*" if needed
6846       */
6847      prefilters = {},
6848  
6849      /* Transports bindings
6850       * 1) key is the dataType
6851       * 2) the catchall symbol "*" can be used
6852       * 3) selection will start with transport dataType and THEN go to "*" if needed
6853       */
6854      transports = {},
6855  
6856      // Document location
6857      ajaxLocation,
6858  
6859      // Document location segments
6860      ajaxLocParts,
6861  
6862      // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
6863      allTypes = ["*/"] + ["*"];
6864  
6865  // #8138, IE may throw an exception when accessing
6866  // a field from window.location if document.domain has been set
6867  try {
6868      ajaxLocation = location.href;
6869  } catch( e ) {
6870      // Use the href attribute of an A element
6871      // since IE will modify it given document.location
6872      ajaxLocation = document.createElement( "a" );
6873      ajaxLocation.href = "";
6874      ajaxLocation = ajaxLocation.href;
6875  }
6876  
6877  // Segment location into parts
6878  ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
6879  
6880  // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
6881  function addToPrefiltersOrTransports( structure ) {
6882  
6883      // dataTypeExpression is optional and defaults to "*"
6884      return function( dataTypeExpression, func ) {
6885  
6886          if ( typeof dataTypeExpression !== "string" ) {
6887              func = dataTypeExpression;
6888              dataTypeExpression = "*";
6889          }
6890  
6891          if ( jQuery.isFunction( func ) ) {
6892              var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
6893                  i = 0,
6894                  length = dataTypes.length,
6895                  dataType,
6896                  list,
6897                  placeBefore;
6898  
6899              // For each dataType in the dataTypeExpression
6900              for ( ; i < length; i++ ) {
6901                  dataType = dataTypes[ i ];
6902                  // We control if we're asked to add before
6903                  // any existing element
6904                  placeBefore = /^\+/.test( dataType );
6905                  if ( placeBefore ) {
6906                      dataType = dataType.substr( 1 ) || "*";
6907                  }
6908                  list = structure[ dataType ] = structure[ dataType ] || [];
6909                  // then we add to the structure accordingly
6910                  list[ placeBefore ? "unshift" : "push" ]( func );
6911              }
6912          }
6913      };
6914  }
6915  
6916  // Base inspection function for prefilters and transports
6917  function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
6918          dataType /* internal */, inspected /* internal */ ) {
6919  
6920      dataType = dataType || options.dataTypes[ 0 ];
6921      inspected = inspected || {};
6922  
6923      inspected[ dataType ] = true;
6924  
6925      var list = structure[ dataType ],
6926          i = 0,
6927          length = list ? list.length : 0,
6928          executeOnly = ( structure === prefilters ),
6929          selection;
6930  
6931      for ( ; i < length && ( executeOnly || !selection ); i++ ) {
6932          selection = list[ i ]( options, originalOptions, jqXHR );
6933          // If we got redirected to another dataType
6934          // we try there if executing only and not done already
6935          if ( typeof selection === "string" ) {
6936              if ( !executeOnly || inspected[ selection ] ) {
6937                  selection = undefined;
6938              } else {
6939                  options.dataTypes.unshift( selection );
6940                  selection = inspectPrefiltersOrTransports(
6941                          structure, options, originalOptions, jqXHR, selection, inspected );
6942              }
6943          }
6944      }
6945      // If we're only executing or nothing was selected
6946      // we try the catchall dataType if not done already
6947      if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
6948          selection = inspectPrefiltersOrTransports(
6949                  structure, options, originalOptions, jqXHR, "*", inspected );
6950      }
6951      // unnecessary when only executing (prefilters)
6952      // but it'll be ignored by the caller in that case
6953      return selection;
6954  }
6955  
6956  // A special extend for ajax options
6957  // that takes "flat" options (not to be deep extended)
6958  // Fixes #9887
6959  function ajaxExtend( target, src ) {
6960      var key, deep,
6961          flatOptions = jQuery.ajaxSettings.flatOptions || {};
6962      for ( key in src ) {
6963          if ( src[ key ] !== undefined ) {
6964              ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
6965          }
6966      }
6967      if ( deep ) {
6968          jQuery.extend( true, target, deep );
6969      }
6970  }
6971  
6972  jQuery.fn.extend({
6973      load: function( url, params, callback ) {
6974          if ( typeof url !== "string" && _load ) {
6975              return _load.apply( this, arguments );
6976  
6977          // Don't do a request if no elements are being requested
6978          } else if ( !this.length ) {
6979              return this;
6980          }
6981  
6982          var off = url.indexOf( " " );
6983          if ( off >= 0 ) {
6984              var selector = url.slice( off, url.length );
6985              url = url.slice( 0, off );
6986          }
6987  
6988          // Default to a GET request
6989          var type = "GET";
6990  
6991          // If the second parameter was provided
6992          if ( params ) {
6993              // If it's a function
6994              if ( jQuery.isFunction( params ) ) {
6995                  // We assume that it's the callback
6996                  callback = params;
6997                  params = undefined;
6998  
6999              // Otherwise, build a param string
7000              } else if ( typeof params === "object" ) {
7001                  params = jQuery.param( params, jQuery.ajaxSettings.traditional );
7002                  type = "POST";
7003              }
7004          }
7005  
7006          var self = this;
7007  
7008          // Request the remote document
7009          jQuery.ajax({
7010              url: url,
7011              type: type,
7012              dataType: "html",
7013              data: params,
7014              // Complete callback (responseText is used internally)
7015              complete: function( jqXHR, status, responseText ) {
7016                  // Store the response as specified by the jqXHR object
7017                  responseText = jqXHR.responseText;
7018                  // If successful, inject the HTML into all the matched elements
7019                  if ( jqXHR.isResolved() ) {
7020                      // #4825: Get the actual response in case
7021                      // a dataFilter is present in ajaxSettings
7022                      jqXHR.done(function( r ) {
7023                          responseText = r;
7024                      });
7025                      // See if a selector was specified
7026                      self.html( selector ?
7027                          // Create a dummy div to hold the results
7028                          jQuery("<div>")
7029                              // inject the contents of the document in, removing the scripts
7030                              // to avoid any 'Permission Denied' errors in IE
7031                              .append(responseText.replace(rscript, ""))
7032  
7033                              // Locate the specified elements
7034                              .find(selector) :
7035  
7036                          // If not, just inject the full result
7037                          responseText );
7038                  }
7039  
7040                  if ( callback ) {
7041                      self.each( callback, [ responseText, status, jqXHR ] );
7042                  }
7043              }
7044          });
7045  
7046          return this;
7047      },
7048  
7049      serialize: function() {
7050          return jQuery.param( this.serializeArray() );
7051      },
7052  
7053      serializeArray: function() {
7054          return this.map(function(){
7055              return this.elements ? jQuery.makeArray( this.elements ) : this;
7056          })
7057          .filter(function(){
7058              return this.name && !this.disabled &&
7059                  ( this.checked || rselectTextarea.test( this.nodeName ) ||
7060                      rinput.test( this.type ) );
7061          })
7062          .map(function( i, elem ){
7063              var val = jQuery( this ).val();
7064  
7065              return val == null ?
7066                  null :
7067                  jQuery.isArray( val ) ?
7068                      jQuery.map( val, function( val, i ){
7069                          return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7070                      }) :
7071                      { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7072          }).get();
7073      }
7074  });
7075  
7076  // Attach a bunch of functions for handling common AJAX events
7077  jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
7078      jQuery.fn[ o ] = function( f ){
7079          return this.on( o, f );
7080      };
7081  });
7082  
7083  jQuery.each( [ "get", "post" ], function( i, method ) {
7084      jQuery[ method ] = function( url, data, callback, type ) {
7085          // shift arguments if data argument was omitted
7086          if ( jQuery.isFunction( data ) ) {
7087              type = type || callback;
7088              callback = data;
7089              data = undefined;
7090          }
7091  
7092          return jQuery.ajax({
7093              type: method,
7094              url: url,
7095              data: data,
7096              success: callback,
7097              dataType: type
7098          });
7099      };
7100  });
7101  
7102  jQuery.extend({
7103  
7104      getScript: function( url, callback ) {
7105          return jQuery.get( url, undefined, callback, "script" );
7106      },
7107  
7108      getJSON: function( url, data, callback ) {
7109          return jQuery.get( url, data, callback, "json" );
7110      },
7111  
7112      // Creates a full fledged settings object into target
7113      // with both ajaxSettings and settings fields.
7114      // If target is omitted, writes into ajaxSettings.
7115      ajaxSetup: function( target, settings ) {
7116          if ( settings ) {
7117              // Building a settings object
7118              ajaxExtend( target, jQuery.ajaxSettings );
7119          } else {
7120              // Extending ajaxSettings
7121              settings = target;
7122              target = jQuery.ajaxSettings;
7123          }
7124          ajaxExtend( target, settings );
7125          return target;
7126      },
7127  
7128      ajaxSettings: {
7129          url: ajaxLocation,
7130          isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
7131          global: true,
7132          type: "GET",
7133          contentType: "application/x-www-form-urlencoded",
7134          processData: true,
7135          async: true,
7136          /*
7137          timeout: 0,
7138          data: null,
7139          dataType: null,
7140          username: null,
7141          password: null,
7142          cache: null,
7143          traditional: false,
7144          headers: {},
7145          */
7146  
7147          accepts: {
7148              xml: "application/xml, text/xml",
7149              html: "text/html",
7150              text: "text/plain",
7151              json: "application/json, text/javascript",
7152              "*": allTypes
7153          },
7154  
7155          contents: {
7156              xml: /xml/,
7157              html: /html/,
7158              json: /json/
7159          },
7160  
7161          responseFields: {
7162              xml: "responseXML",
7163              text: "responseText"
7164          },
7165  
7166          // List of data converters
7167          // 1) key format is "source_type destination_type" (a single space in-between)
7168          // 2) the catchall symbol "*" can be used for source_type
7169          converters: {
7170  
7171              // Convert anything to text
7172              "* text": window.String,
7173  
7174              // Text to html (true = no transformation)
7175              "text html": true,
7176  
7177              // Evaluate text as a json expression
7178              "text json": jQuery.parseJSON,
7179  
7180              // Parse text as xml
7181              "text xml": jQuery.parseXML
7182          },
7183  
7184          // For options that shouldn't be deep extended:
7185          // you can add your own custom options here if
7186          // and when you create one that shouldn't be
7187          // deep extended (see ajaxExtend)
7188          flatOptions: {
7189              context: true,
7190              url: true
7191          }
7192      },
7193  
7194      ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7195      ajaxTransport: addToPrefiltersOrTransports( transports ),
7196  
7197      // Main method
7198      ajax: function( url, options ) {
7199  
7200          // If url is an object, simulate pre-1.5 signature
7201          if ( typeof url === "object" ) {
7202              options = url;
7203              url = undefined;
7204          }
7205  
7206          // Force options to be an object
7207          options = options || {};
7208  
7209          var // Create the final options object
7210              s = jQuery.ajaxSetup( {}, options ),
7211              // Callbacks context
7212              callbackContext = s.context || s,
7213              // Context for global events
7214              // It's the callbackContext if one was provided in the options
7215              // and if it's a DOM node or a jQuery collection
7216              globalEventContext = callbackContext !== s &&
7217                  ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
7218                          jQuery( callbackContext ) : jQuery.event,
7219              // Deferreds
7220              deferred = jQuery.Deferred(),
7221              completeDeferred = jQuery.Callbacks( "once memory" ),
7222              // Status-dependent callbacks
7223              statusCode = s.statusCode || {},
7224              // ifModified key
7225              ifModifiedKey,
7226              // Headers (they are sent all at once)
7227              requestHeaders = {},
7228              requestHeadersNames = {},
7229              // Response headers
7230              responseHeadersString,
7231              responseHeaders,
7232              // transport
7233              transport,
7234              // timeout handle
7235              timeoutTimer,
7236              // Cross-domain detection vars
7237              parts,
7238              // The jqXHR state
7239              state = 0,
7240              // To know if global events are to be dispatched
7241              fireGlobals,
7242              // Loop variable
7243              i,
7244              // Fake xhr
7245              jqXHR = {
7246  
7247                  readyState: 0,
7248  
7249                  // Caches the header
7250                  setRequestHeader: function( name, value ) {
7251                      if ( !state ) {
7252                          var lname = name.toLowerCase();
7253                          name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7254                          requestHeaders[ name ] = value;
7255                      }
7256                      return this;
7257                  },
7258  
7259                  // Raw string
7260                  getAllResponseHeaders: function() {
7261                      return state === 2 ? responseHeadersString : null;
7262                  },
7263  
7264                  // Builds headers hashtable if needed
7265                  getResponseHeader: function( key ) {
7266                      var match;
7267                      if ( state === 2 ) {
7268                          if ( !responseHeaders ) {
7269                              responseHeaders = {};
7270                              while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7271                                  responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7272                              }
7273                          }
7274                          match = responseHeaders[ key.toLowerCase() ];
7275                      }
7276                      return match === undefined ? null : match;
7277                  },
7278  
7279                  // Overrides response content-type header
7280                  overrideMimeType: function( type ) {
7281                      if ( !state ) {
7282                          s.mimeType = type;
7283                      }
7284                      return this;
7285                  },
7286  
7287                  // Cancel the request
7288                  abort: function( statusText ) {
7289                      statusText = statusText || "abort";
7290                      if ( transport ) {
7291                          transport.abort( statusText );
7292                      }
7293                      done( 0, statusText );
7294                      return this;
7295                  }
7296              };
7297  
7298          // Callback for when everything is done
7299          // It is defined here because jslint complains if it is declared
7300          // at the end of the function (which would be more logical and readable)
7301  		function done( status, nativeStatusText, responses, headers ) {
7302  
7303              // Called once
7304              if ( state === 2 ) {
7305                  return;
7306              }
7307  
7308              // State is "done" now
7309              state = 2;
7310  
7311              // Clear timeout if it exists
7312              if ( timeoutTimer ) {
7313                  clearTimeout( timeoutTimer );
7314              }
7315  
7316              // Dereference transport for early garbage collection
7317              // (no matter how long the jqXHR object will be used)
7318              transport = undefined;
7319  
7320              // Cache response headers
7321              responseHeadersString = headers || "";
7322  
7323              // Set readyState
7324              jqXHR.readyState = status > 0 ? 4 : 0;
7325  
7326              var isSuccess,
7327                  success,
7328                  error,
7329                  statusText = nativeStatusText,
7330                  response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
7331                  lastModified,
7332                  etag;
7333  
7334              // If successful, handle type chaining
7335              if ( status >= 200 && status < 300 || status === 304 ) {
7336  
7337                  // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7338                  if ( s.ifModified ) {
7339  
7340                      if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
7341                          jQuery.lastModified[ ifModifiedKey ] = lastModified;
7342                      }
7343                      if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
7344                          jQuery.etag[ ifModifiedKey ] = etag;
7345                      }
7346                  }
7347  
7348                  // If not modified
7349                  if ( status === 304 ) {
7350  
7351                      statusText = "notmodified";
7352                      isSuccess = true;
7353  
7354                  // If we have data
7355                  } else {
7356  
7357                      try {
7358                          success = ajaxConvert( s, response );
7359                          statusText = "success";
7360                          isSuccess = true;
7361                      } catch(e) {
7362                          // We have a parsererror
7363                          statusText = "parsererror";
7364                          error = e;
7365                      }
7366                  }
7367              } else {
7368                  // We extract error from statusText
7369                  // then normalize statusText and status for non-aborts
7370                  error = statusText;
7371                  if ( !statusText || status ) {
7372                      statusText = "error";
7373                      if ( status < 0 ) {
7374                          status = 0;
7375                      }
7376                  }
7377              }
7378  
7379              // Set data for the fake xhr object
7380              jqXHR.status = status;
7381              jqXHR.statusText = "" + ( nativeStatusText || statusText );
7382  
7383              // Success/Error
7384              if ( isSuccess ) {
7385                  deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7386              } else {
7387                  deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7388              }
7389  
7390              // Status-dependent callbacks
7391              jqXHR.statusCode( statusCode );
7392              statusCode = undefined;
7393  
7394              if ( fireGlobals ) {
7395                  globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7396                          [ jqXHR, s, isSuccess ? success : error ] );
7397              }
7398  
7399              // Complete
7400              completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
7401  
7402              if ( fireGlobals ) {
7403                  globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
7404                  // Handle the global AJAX counter
7405                  if ( !( --jQuery.active ) ) {
7406                      jQuery.event.trigger( "ajaxStop" );
7407                  }
7408              }
7409          }
7410  
7411          // Attach deferreds
7412          deferred.promise( jqXHR );
7413          jqXHR.success = jqXHR.done;
7414          jqXHR.error = jqXHR.fail;
7415          jqXHR.complete = completeDeferred.add;
7416  
7417          // Status-dependent callbacks
7418          jqXHR.statusCode = function( map ) {
7419              if ( map ) {
7420                  var tmp;
7421                  if ( state < 2 ) {
7422                      for ( tmp in map ) {
7423                          statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7424                      }
7425                  } else {
7426                      tmp = map[ jqXHR.status ];
7427                      jqXHR.then( tmp, tmp );
7428                  }
7429              }
7430              return this;
7431          };
7432  
7433          // Remove hash character (#7531: and string promotion)
7434          // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7435          // We also use the url parameter if available
7436          s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7437  
7438          // Extract dataTypes list
7439          s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
7440  
7441          // Determine if a cross-domain request is in order
7442          if ( s.crossDomain == null ) {
7443              parts = rurl.exec( s.url.toLowerCase() );
7444              s.crossDomain = !!( parts &&
7445                  ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
7446                      ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7447                          ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7448              );
7449          }
7450  
7451          // Convert data if not already a string
7452          if ( s.data && s.processData && typeof s.data !== "string" ) {
7453              s.data = jQuery.param( s.data, s.traditional );
7454          }
7455  
7456          // Apply prefilters
7457          inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7458  
7459          // If request was aborted inside a prefiler, stop there
7460          if ( state === 2 ) {
7461              return false;
7462          }
7463  
7464          // We can fire global events as of now if asked to
7465          fireGlobals = s.global;
7466  
7467          // Uppercase the type
7468          s.type = s.type.toUpperCase();
7469  
7470          // Determine if request has content
7471          s.hasContent = !rnoContent.test( s.type );
7472  
7473          // Watch for a new set of requests
7474          if ( fireGlobals && jQuery.active++ === 0 ) {
7475              jQuery.event.trigger( "ajaxStart" );
7476          }
7477  
7478          // More options handling for requests with no content
7479          if ( !s.hasContent ) {
7480  
7481              // If data is available, append data to url
7482              if ( s.data ) {
7483                  s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7484                  // #9682: remove data so that it's not used in an eventual retry
7485                  delete s.data;
7486              }
7487  
7488              // Get ifModifiedKey before adding the anti-cache parameter
7489              ifModifiedKey = s.url;
7490  
7491              // Add anti-cache in url if needed
7492              if ( s.cache === false ) {
7493  
7494                  var ts = jQuery.now(),
7495                      // try replacing _= if it is there
7496                      ret = s.url.replace( rts, "$1_=" + ts );
7497  
7498                  // if nothing was replaced, add timestamp to the end
7499                  s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7500              }
7501          }
7502  
7503          // Set the correct header, if data is being sent
7504          if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7505              jqXHR.setRequestHeader( "Content-Type", s.contentType );
7506          }
7507  
7508          // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7509          if ( s.ifModified ) {
7510              ifModifiedKey = ifModifiedKey || s.url;
7511              if ( jQuery.lastModified[ ifModifiedKey ] ) {
7512                  jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7513              }
7514              if ( jQuery.etag[ ifModifiedKey ] ) {
7515                  jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7516              }
7517          }
7518  
7519          // Set the Accepts header for the server, depending on the dataType
7520          jqXHR.setRequestHeader(
7521              "Accept",
7522              s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7523                  s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
7524                  s.accepts[ "*" ]
7525          );
7526  
7527          // Check for headers option
7528          for ( i in s.headers ) {
7529              jqXHR.setRequestHeader( i, s.headers[ i ] );
7530          }
7531  
7532          // Allow custom headers/mimetypes and early abort
7533          if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7534                  // Abort if not done already
7535                  jqXHR.abort();
7536                  return false;
7537  
7538          }
7539  
7540          // Install callbacks on deferreds
7541          for ( i in { success: 1, error: 1, complete: 1 } ) {
7542              jqXHR[ i ]( s[ i ] );
7543          }
7544  
7545          // Get transport
7546          transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7547  
7548          // If no transport, we auto-abort
7549          if ( !transport ) {
7550              done( -1, "No Transport" );
7551          } else {
7552              jqXHR.readyState = 1;
7553              // Send global event
7554              if ( fireGlobals ) {
7555                  globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7556              }
7557              // Timeout
7558              if ( s.async && s.timeout > 0 ) {
7559                  timeoutTimer = setTimeout( function(){
7560                      jqXHR.abort( "timeout" );
7561                  }, s.timeout );
7562              }
7563  
7564              try {
7565                  state = 1;
7566                  transport.send( requestHeaders, done );
7567              } catch (e) {
7568                  // Propagate exception as error if not done
7569                  if ( state < 2 ) {
7570                      done( -1, e );
7571                  // Simply rethrow otherwise
7572                  } else {
7573                      throw e;
7574                  }
7575              }
7576          }
7577  
7578          return jqXHR;
7579      },
7580  
7581      // Serialize an array of form elements or a set of
7582      // key/values into a query string
7583      param: function( a, traditional ) {
7584          var s = [],
7585              add = function( key, value ) {
7586                  // If value is a function, invoke it and return its value
7587                  value = jQuery.isFunction( value ) ? value() : value;
7588                  s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7589              };
7590  
7591          // Set traditional to true for jQuery <= 1.3.2 behavior.
7592          if ( traditional === undefined ) {
7593              traditional = jQuery.ajaxSettings.traditional;
7594          }
7595  
7596          // If an array was passed in, assume that it is an array of form elements.
7597          if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7598              // Serialize the form elements
7599              jQuery.each( a, function() {
7600                  add( this.name, this.value );
7601              });
7602  
7603          } else {
7604              // If traditional, encode the "old" way (the way 1.3.2 or older
7605              // did it), otherwise encode params recursively.
7606              for ( var prefix in a ) {
7607                  buildParams( prefix, a[ prefix ], traditional, add );
7608              }
7609          }
7610  
7611          // Return the resulting serialization
7612          return s.join( "&" ).replace( r20, "+" );
7613      }
7614  });
7615  
7616  function buildParams( prefix, obj, traditional, add ) {
7617      if ( jQuery.isArray( obj ) ) {
7618          // Serialize array item.
7619          jQuery.each( obj, function( i, v ) {
7620              if ( traditional || rbracket.test( prefix ) ) {
7621                  // Treat each array item as a scalar.
7622                  add( prefix, v );
7623  
7624              } else {
7625                  // If array item is non-scalar (array or object), encode its
7626                  // numeric index to resolve deserialization ambiguity issues.
7627                  // Note that rack (as of 1.0.0) can't currently deserialize
7628                  // nested arrays properly, and attempting to do so may cause
7629                  // a server error. Possible fixes are to modify rack's
7630                  // deserialization algorithm or to provide an option or flag
7631                  // to force array serialization to be shallow.
7632                  buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
7633              }
7634          });
7635  
7636      } else if ( !traditional && obj != null && typeof obj === "object" ) {
7637          // Serialize object item.
7638          for ( var name in obj ) {
7639              buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7640          }
7641  
7642      } else {
7643          // Serialize scalar item.
7644          add( prefix, obj );
7645      }
7646  }
7647  
7648  // This is still on the jQuery object... for now
7649  // Want to move this to jQuery.ajax some day
7650  jQuery.extend({
7651  
7652      // Counter for holding the number of active queries
7653      active: 0,
7654  
7655      // Last-Modified header cache for next request
7656      lastModified: {},
7657      etag: {}
7658  
7659  });
7660  
7661  /* Handles responses to an ajax request:
7662   * - sets all responseXXX fields accordingly
7663   * - finds the right dataType (mediates between content-type and expected dataType)
7664   * - returns the corresponding response
7665   */
7666  function ajaxHandleResponses( s, jqXHR, responses ) {
7667  
7668      var contents = s.contents,
7669          dataTypes = s.dataTypes,
7670          responseFields = s.responseFields,
7671          ct,
7672          type,
7673          finalDataType,
7674          firstDataType;
7675  
7676      // Fill responseXXX fields
7677      for ( type in responseFields ) {
7678          if ( type in responses ) {
7679              jqXHR[ responseFields[type] ] = responses[ type ];
7680          }
7681      }
7682  
7683      // Remove auto dataType and get content-type in the process
7684      while( dataTypes[ 0 ] === "*" ) {
7685          dataTypes.shift();
7686          if ( ct === undefined ) {
7687              ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
7688          }
7689      }
7690  
7691      // Check if we're dealing with a known content-type
7692      if ( ct ) {
7693          for ( type in contents ) {
7694              if ( contents[ type ] && contents[ type ].test( ct ) ) {
7695                  dataTypes.unshift( type );
7696                  break;
7697              }
7698          }
7699      }
7700  
7701      // Check to see if we have a response for the expected dataType
7702      if ( dataTypes[ 0 ] in responses ) {
7703          finalDataType = dataTypes[ 0 ];
7704      } else {
7705          // Try convertible dataTypes
7706          for ( type in responses ) {
7707              if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7708                  finalDataType = type;
7709                  break;
7710              }
7711              if ( !firstDataType ) {
7712                  firstDataType = type;
7713              }
7714          }
7715          // Or just use first one
7716          finalDataType = finalDataType || firstDataType;
7717      }
7718  
7719      // If we found a dataType
7720      // We add the dataType to the list if needed
7721      // and return the corresponding response
7722      if ( finalDataType ) {
7723          if ( finalDataType !== dataTypes[ 0 ] ) {
7724              dataTypes.unshift( finalDataType );
7725          }
7726          return responses[ finalDataType ];
7727      }
7728  }
7729  
7730  // Chain conversions given the request and the original response
7731  function ajaxConvert( s, response ) {
7732  
7733      // Apply the dataFilter if provided
7734      if ( s.dataFilter ) {
7735          response = s.dataFilter( response, s.dataType );
7736      }
7737  
7738      var dataTypes = s.dataTypes,
7739          converters = {},
7740          i,
7741          key,
7742          length = dataTypes.length,
7743          tmp,
7744          // Current and previous dataTypes
7745          current = dataTypes[ 0 ],
7746          prev,
7747          // Conversion expression
7748          conversion,
7749          // Conversion function
7750          conv,
7751          // Conversion functions (transitive conversion)
7752          conv1,
7753          conv2;
7754  
7755      // For each dataType in the chain
7756      for ( i = 1; i < length; i++ ) {
7757  
7758          // Create converters map
7759          // with lowercased keys
7760          if ( i === 1 ) {
7761              for ( key in s.converters ) {
7762                  if ( typeof key === "string" ) {
7763                      converters[ key.toLowerCase() ] = s.converters[ key ];
7764                  }
7765              }
7766          }
7767  
7768          // Get the dataTypes
7769          prev = current;
7770          current = dataTypes[ i ];
7771  
7772          // If current is auto dataType, update it to prev
7773          if ( current === "*" ) {
7774              current = prev;
7775          // If no auto and dataTypes are actually different
7776          } else if ( prev !== "*" && prev !== current ) {
7777  
7778              // Get the converter
7779              conversion = prev + " " + current;
7780              conv = converters[ conversion ] || converters[ "* " + current ];
7781  
7782              // If there is no direct converter, search transitively
7783              if ( !conv ) {
7784                  conv2 = undefined;
7785                  for ( conv1 in converters ) {
7786                      tmp = conv1.split( " " );
7787                      if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
7788                          conv2 = converters[ tmp[1] + " " + current ];
7789                          if ( conv2 ) {
7790                              conv1 = converters[ conv1 ];
7791                              if ( conv1 === true ) {
7792                                  conv = conv2;
7793                              } else if ( conv2 === true ) {
7794                                  conv = conv1;
7795                              }
7796                              break;
7797                          }
7798                      }
7799                  }
7800              }
7801              // If we found no converter, dispatch an error
7802              if ( !( conv || conv2 ) ) {
7803                  jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
7804              }
7805              // If found converter is not an equivalence
7806              if ( conv !== true ) {
7807                  // Convert with 1 or 2 converters accordingly
7808                  response = conv ? conv( response ) : conv2( conv1(response) );
7809              }
7810          }
7811      }
7812      return response;
7813  }
7814  
7815  
7816  
7817  
7818  var jsc = jQuery.now(),
7819      jsre = /(\=)\?(&|$)|\?\?/i;
7820  
7821  // Default jsonp settings
7822  jQuery.ajaxSetup({
7823      jsonp: "callback",
7824      jsonpCallback: function() {
7825          return jQuery.expando + "_" + ( jsc++ );
7826      }
7827  });
7828  
7829  // Detect, normalize options and install callbacks for jsonp requests
7830  jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
7831  
7832      var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
7833          ( typeof s.data === "string" );
7834  
7835      if ( s.dataTypes[ 0 ] === "jsonp" ||
7836          s.jsonp !== false && ( jsre.test( s.url ) ||
7837                  inspectData && jsre.test( s.data ) ) ) {
7838  
7839          var responseContainer,
7840              jsonpCallback = s.jsonpCallback =
7841                  jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
7842              previous = window[ jsonpCallback ],
7843              url = s.url,
7844              data = s.data,
7845              replace = "$1" + jsonpCallback + "$2";
7846  
7847          if ( s.jsonp !== false ) {
7848              url = url.replace( jsre, replace );
7849              if ( s.url === url ) {
7850                  if ( inspectData ) {
7851                      data = data.replace( jsre, replace );
7852                  }
7853                  if ( s.data === data ) {
7854                      // Add callback manually
7855                      url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
7856                  }
7857              }
7858          }
7859  
7860          s.url = url;
7861          s.data = data;
7862  
7863          // Install callback
7864          window[ jsonpCallback ] = function( response ) {
7865              responseContainer = [ response ];
7866          };
7867  
7868          // Clean-up function
7869          jqXHR.always(function() {
7870              // Set callback back to previous value
7871              window[ jsonpCallback ] = previous;
7872              // Call if it was a function and we have a response
7873              if ( responseContainer && jQuery.isFunction( previous ) ) {
7874                  window[ jsonpCallback ]( responseContainer[ 0 ] );
7875              }
7876          });
7877  
7878          // Use data converter to retrieve json after script execution
7879          s.converters["script json"] = function() {
7880              if ( !responseContainer ) {
7881                  jQuery.error( jsonpCallback + " was not called" );
7882              }
7883              return responseContainer[ 0 ];
7884          };
7885  
7886          // force json dataType
7887          s.dataTypes[ 0 ] = "json";
7888  
7889          // Delegate to script
7890          return "script";
7891      }
7892  });
7893  
7894  
7895  
7896  
7897  // Install script dataType
7898  jQuery.ajaxSetup({
7899      accepts: {
7900          script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
7901      },
7902      contents: {
7903          script: /javascript|ecmascript/
7904      },
7905      converters: {
7906          "text script": function( text ) {
7907              jQuery.globalEval( text );
7908              return text;
7909          }
7910      }
7911  });
7912  
7913  // Handle cache's special case and global
7914  jQuery.ajaxPrefilter( "script", function( s ) {
7915      if ( s.cache === undefined ) {
7916          s.cache = false;
7917      }
7918      if ( s.crossDomain ) {
7919          s.type = "GET";
7920          s.global = false;
7921      }
7922  });
7923  
7924  // Bind script tag hack transport
7925  jQuery.ajaxTransport( "script", function(s) {
7926  
7927      // This transport only deals with cross domain requests
7928      if ( s.crossDomain ) {
7929  
7930          var script,
7931              head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
7932  
7933          return {
7934  
7935              send: function( _, callback ) {
7936  
7937                  script = document.createElement( "script" );
7938  
7939                  script.async = "async";
7940  
7941                  if ( s.scriptCharset ) {
7942                      script.charset = s.scriptCharset;
7943                  }
7944  
7945                  script.src = s.url;
7946  
7947                  // Attach handlers for all browsers
7948                  script.onload = script.onreadystatechange = function( _, isAbort ) {
7949  
7950                      if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
7951  
7952                          // Handle memory leak in IE
7953                          script.onload = script.onreadystatechange = null;
7954  
7955                          // Remove the script
7956                          if ( head && script.parentNode ) {
7957                              head.removeChild( script );
7958                          }
7959  
7960                          // Dereference the script
7961                          script = undefined;
7962  
7963                          // Callback if not abort
7964                          if ( !isAbort ) {
7965                              callback( 200, "success" );
7966                          }
7967                      }
7968                  };
7969                  // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
7970                  // This arises when a base node is used (#2709 and #4378).
7971                  head.insertBefore( script, head.firstChild );
7972              },
7973  
7974              abort: function() {
7975                  if ( script ) {
7976                      script.onload( 0, 1 );
7977                  }
7978              }
7979          };
7980      }
7981  });
7982  
7983  
7984  
7985  
7986  var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
7987      xhrOnUnloadAbort = window.ActiveXObject ? function() {
7988          // Abort all pending requests
7989          for ( var key in xhrCallbacks ) {
7990              xhrCallbacks[ key ]( 0, 1 );
7991          }
7992      } : false,
7993      xhrId = 0,
7994      xhrCallbacks;
7995  
7996  // Functions to create xhrs
7997  function createStandardXHR() {
7998      try {
7999          return new window.XMLHttpRequest();
8000      } catch( e ) {}
8001  }
8002  
8003  function createActiveXHR() {
8004      try {
8005          return new window.ActiveXObject( "Microsoft.XMLHTTP" );
8006      } catch( e ) {}
8007  }
8008  
8009  // Create the request object
8010  // (This is still attached to ajaxSettings for backward compatibility)
8011  jQuery.ajaxSettings.xhr = window.ActiveXObject ?
8012      /* Microsoft failed to properly
8013       * implement the XMLHttpRequest in IE7 (can't request local files),
8014       * so we use the ActiveXObject when it is available
8015       * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
8016       * we need a fallback.
8017       */
8018      function() {
8019          return !this.isLocal && createStandardXHR() || createActiveXHR();
8020      } :
8021      // For all other browsers, use the standard XMLHttpRequest object
8022      createStandardXHR;
8023  
8024  // Determine support properties
8025  (function( xhr ) {
8026      jQuery.extend( jQuery.support, {
8027          ajax: !!xhr,
8028          cors: !!xhr && ( "withCredentials" in xhr )
8029      });
8030  })( jQuery.ajaxSettings.xhr() );
8031  
8032  // Create transport if the browser can provide an xhr
8033  if ( jQuery.support.ajax ) {
8034  
8035      jQuery.ajaxTransport(function( s ) {
8036          // Cross domain only allowed if supported through XMLHttpRequest
8037          if ( !s.crossDomain || jQuery.support.cors ) {
8038  
8039              var callback;
8040  
8041              return {
8042                  send: function( headers, complete ) {
8043  
8044                      // Get a new xhr
8045                      var xhr = s.xhr(),
8046                          handle,
8047                          i;
8048  
8049                      // Open the socket
8050                      // Passing null username, generates a login popup on Opera (#2865)
8051                      if ( s.username ) {
8052                          xhr.open( s.type, s.url, s.async, s.username, s.password );
8053                      } else {
8054                          xhr.open( s.type, s.url, s.async );
8055                      }
8056  
8057                      // Apply custom fields if provided
8058                      if ( s.xhrFields ) {
8059                          for ( i in s.xhrFields ) {
8060                              xhr[ i ] = s.xhrFields[ i ];
8061                          }
8062                      }
8063  
8064                      // Override mime type if needed
8065                      if ( s.mimeType && xhr.overrideMimeType ) {
8066                          xhr.overrideMimeType( s.mimeType );
8067                      }
8068  
8069                      // X-Requested-With header
8070                      // For cross-domain requests, seeing as conditions for a preflight are
8071                      // akin to a jigsaw puzzle, we simply never set it to be sure.
8072                      // (it can always be set on a per-request basis or even using ajaxSetup)
8073                      // For same-domain requests, won't change header if already provided.
8074                      if ( !s.crossDomain && !headers["X-Requested-With"] ) {
8075                          headers[ "X-Requested-With" ] = "XMLHttpRequest";
8076                      }
8077  
8078                      // Need an extra try/catch for cross domain requests in Firefox 3
8079                      try {
8080                          for ( i in headers ) {
8081                              xhr.setRequestHeader( i, headers[ i ] );
8082                          }
8083                      } catch( _ ) {}
8084  
8085                      // Do send the request
8086                      // This may raise an exception which is actually
8087                      // handled in jQuery.ajax (so no try/catch here)
8088                      xhr.send( ( s.hasContent && s.data ) || null );
8089  
8090                      // Listener
8091                      callback = function( _, isAbort ) {
8092  
8093                          var status,
8094                              statusText,
8095                              responseHeaders,
8096                              responses,
8097                              xml;
8098  
8099                          // Firefox throws exceptions when accessing properties
8100                          // of an xhr when a network error occured
8101                          // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
8102                          try {
8103  
8104                              // Was never called and is aborted or complete
8105                              if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
8106  
8107                                  // Only called once
8108                                  callback = undefined;
8109  
8110                                  // Do not keep as active anymore
8111                                  if ( handle ) {
8112                                      xhr.onreadystatechange = jQuery.noop;
8113                                      if ( xhrOnUnloadAbort ) {
8114                                          delete xhrCallbacks[ handle ];
8115                                      }
8116                                  }
8117  
8118                                  // If it's an abort
8119                                  if ( isAbort ) {
8120                                      // Abort it manually if needed
8121                                      if ( xhr.readyState !== 4 ) {
8122                                          xhr.abort();
8123                                      }
8124                                  } else {
8125                                      status = xhr.status;
8126                                      responseHeaders = xhr.getAllResponseHeaders();
8127                                      responses = {};
8128                                      xml = xhr.responseXML;
8129  
8130                                      // Construct response list
8131                                      if ( xml && xml.documentElement /* #4958 */ ) {
8132                                          responses.xml = xml;
8133                                      }
8134                                      responses.text = xhr.responseText;
8135  
8136                                      // Firefox throws an exception when accessing
8137                                      // statusText for faulty cross-domain requests
8138                                      try {
8139                                          statusText = xhr.statusText;
8140                                      } catch( e ) {
8141                                          // We normalize with Webkit giving an empty statusText
8142                                          statusText = "";
8143                                      }
8144  
8145                                      // Filter status for non standard behaviors
8146  
8147                                      // If the request is local and we have data: assume a success
8148                                      // (success with no data won't get notified, that's the best we
8149                                      // can do given current implementations)
8150                                      if ( !status && s.isLocal && !s.crossDomain ) {
8151                                          status = responses.text ? 200 : 404;
8152                                      // IE - #1450: sometimes returns 1223 when it should be 204
8153                                      } else if ( status === 1223 ) {
8154                                          status = 204;
8155                                      }
8156                                  }
8157                              }
8158                          } catch( firefoxAccessException ) {
8159                              if ( !isAbort ) {
8160                                  complete( -1, firefoxAccessException );
8161                              }
8162                          }
8163  
8164                          // Call complete if needed
8165                          if ( responses ) {
8166                              complete( status, statusText, responses, responseHeaders );
8167                          }
8168                      };
8169  
8170                      // if we're in sync mode or it's in cache
8171                      // and has been retrieved directly (IE6 & IE7)
8172                      // we need to manually fire the callback
8173                      if ( !s.async || xhr.readyState === 4 ) {
8174                          callback();
8175                      } else {
8176                          handle = ++xhrId;
8177                          if ( xhrOnUnloadAbort ) {
8178                              // Create the active xhrs callbacks list if needed
8179                              // and attach the unload handler
8180                              if ( !xhrCallbacks ) {
8181                                  xhrCallbacks = {};
8182                                  jQuery( window ).unload( xhrOnUnloadAbort );
8183                              }
8184                              // Add to list of active xhrs callbacks
8185                              xhrCallbacks[ handle ] = callback;
8186                          }
8187                          xhr.onreadystatechange = callback;
8188                      }
8189                  },
8190  
8191                  abort: function() {
8192                      if ( callback ) {
8193                          callback(0,1);
8194                      }
8195                  }
8196              };
8197          }
8198      });
8199  }
8200  
8201  
8202  
8203  
8204  var elemdisplay = {},
8205      iframe, iframeDoc,
8206      rfxtypes = /^(?:toggle|show|hide)$/,
8207      rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
8208      timerId,
8209      fxAttrs = [
8210          // height animations
8211          [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
8212          // width animations
8213          [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
8214          // opacity animations
8215          [ "opacity" ]
8216      ],
8217      fxNow;
8218  
8219  jQuery.fn.extend({
8220      show: function( speed, easing, callback ) {
8221          var elem, display;
8222  
8223          if ( speed || speed === 0 ) {
8224              return this.animate( genFx("show", 3), speed, easing, callback );
8225  
8226          } else {
8227              for ( var i = 0, j = this.length; i < j; i++ ) {
8228                  elem = this[ i ];
8229  
8230                  if ( elem.style ) {
8231                      display = elem.style.display;
8232  
8233                      // Reset the inline display of this element to learn if it is
8234                      // being hidden by cascaded rules or not
8235                      if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
8236                          display = elem.style.display = "";
8237                      }
8238  
8239                      // Set elements which have been overridden with display: none
8240                      // in a stylesheet to whatever the default browser style is
8241                      // for such an element
8242                      if ( display === "" && jQuery.css(elem, "display") === "none" ) {
8243                          jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
8244                      }
8245                  }
8246              }
8247  
8248              // Set the display of most of the elements in a second loop
8249              // to avoid the constant reflow
8250              for ( i = 0; i < j; i++ ) {
8251                  elem = this[ i ];
8252  
8253                  if ( elem.style ) {
8254                      display = elem.style.display;
8255  
8256                      if ( display === "" || display === "none" ) {
8257                          elem.style.display = jQuery._data( elem, "olddisplay" ) || "";
8258                      }
8259                  }
8260              }
8261  
8262              return this;
8263          }
8264      },
8265  
8266      hide: function( speed, easing, callback ) {
8267          if ( speed || speed === 0 ) {
8268              return this.animate( genFx("hide", 3), speed, easing, callback);
8269  
8270          } else {
8271              var elem, display,
8272                  i = 0,
8273                  j = this.length;
8274  
8275              for ( ; i < j; i++ ) {
8276                  elem = this[i];
8277                  if ( elem.style ) {
8278                      display = jQuery.css( elem, "display" );
8279  
8280                      if ( display !== "none" && !jQuery._data( elem, "olddisplay" ) ) {
8281                          jQuery._data( elem, "olddisplay", display );
8282                      }
8283                  }
8284              }
8285  
8286              // Set the display of the elements in a second loop
8287              // to avoid the constant reflow
8288              for ( i = 0; i < j; i++ ) {
8289                  if ( this[i].style ) {
8290                      this[i].style.display = "none";
8291                  }
8292              }
8293  
8294              return this;
8295          }
8296      },
8297  
8298      // Save the old toggle function
8299      _toggle: jQuery.fn.toggle,
8300  
8301      toggle: function( fn, fn2, callback ) {
8302          var bool = typeof fn === "boolean";
8303  
8304          if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
8305              this._toggle.apply( this, arguments );
8306  
8307          } else if ( fn == null || bool ) {
8308              this.each(function() {
8309                  var state = bool ? fn : jQuery(this).is(":hidden");
8310                  jQuery(this)[ state ? "show" : "hide" ]();
8311              });
8312  
8313          } else {
8314              this.animate(genFx("toggle", 3), fn, fn2, callback);
8315          }
8316  
8317          return this;
8318      },
8319  
8320      fadeTo: function( speed, to, easing, callback ) {
8321          return this.filter(":hidden").css("opacity", 0).show().end()
8322                      .animate({opacity: to}, speed, easing, callback);
8323      },
8324  
8325      animate: function( prop, speed, easing, callback ) {
8326          var optall = jQuery.speed( speed, easing, callback );
8327  
8328          if ( jQuery.isEmptyObject( prop ) ) {
8329              return this.each( optall.complete, [ false ] );
8330          }
8331  
8332          // Do not change referenced properties as per-property easing will be lost
8333          prop = jQuery.extend( {}, prop );
8334  
8335  		function doAnimation() {
8336              // XXX 'this' does not always have a nodeName when running the
8337              // test suite
8338  
8339              if ( optall.queue === false ) {
8340                  jQuery._mark( this );
8341              }
8342  
8343              var opt = jQuery.extend( {}, optall ),
8344                  isElement = this.nodeType === 1,
8345                  hidden = isElement && jQuery(this).is(":hidden"),
8346                  name, val, p, e,
8347                  parts, start, end, unit,
8348                  method;
8349  
8350              // will store per property easing and be used to determine when an animation is complete
8351              opt.animatedProperties = {};
8352  
8353              for ( p in prop ) {
8354  
8355                  // property name normalization
8356                  name = jQuery.camelCase( p );
8357                  if ( p !== name ) {
8358                      prop[ name ] = prop[ p ];
8359                      delete prop[ p ];
8360                  }
8361  
8362                  val = prop[ name ];
8363  
8364                  // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8365                  if ( jQuery.isArray( val ) ) {
8366                      opt.animatedProperties[ name ] = val[ 1 ];
8367                      val = prop[ name ] = val[ 0 ];
8368                  } else {
8369                      opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
8370                  }
8371  
8372                  if ( val === "hide" && hidden || val === "show" && !hidden ) {
8373                      return opt.complete.call( this );
8374                  }
8375  
8376                  if ( isElement && ( name === "height" || name === "width" ) ) {
8377                      // Make sure that nothing sneaks out
8378                      // Record all 3 overflow attributes because IE does not
8379                      // change the overflow attribute when overflowX and
8380                      // overflowY are set to the same value
8381                      opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
8382  
8383                      // Set display property to inline-block for height/width
8384                      // animations on inline elements that are having width/height animated
8385                      if ( jQuery.css( this, "display" ) === "inline" &&
8386                              jQuery.css( this, "float" ) === "none" ) {
8387  
8388                          // inline-level elements accept inline-block;
8389                          // block-level elements need to be inline with layout
8390                          if ( !jQuery.support.inlineBlockNeedsLayout || defaultDisplay( this.nodeName ) === "inline" ) {
8391                              this.style.display = "inline-block";
8392  
8393                          } else {
8394                              this.style.zoom = 1;
8395                          }
8396                      }
8397                  }
8398              }
8399  
8400              if ( opt.overflow != null ) {
8401                  this.style.overflow = "hidden";
8402              }
8403  
8404              for ( p in prop ) {
8405                  e = new jQuery.fx( this, opt, p );
8406                  val = prop[ p ];
8407  
8408                  if ( rfxtypes.test( val ) ) {
8409  
8410                      // Tracks whether to show or hide based on private
8411                      // data attached to the element
8412                      method = jQuery._data( this, "toggle" + p ) || ( val === "toggle" ? hidden ? "show" : "hide" : 0 );
8413                      if ( method ) {
8414                          jQuery._data( this, "toggle" + p, method === "show" ? "hide" : "show" );
8415                          e[ method ]();
8416                      } else {
8417                          e[ val ]();
8418                      }
8419  
8420                  } else {
8421                      parts = rfxnum.exec( val );
8422                      start = e.cur();
8423  
8424                      if ( parts ) {
8425                          end = parseFloat( parts[2] );
8426                          unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
8427  
8428                          // We need to compute starting value
8429                          if ( unit !== "px" ) {
8430                              jQuery.style( this, p, (end || 1) + unit);
8431                              start = ( (end || 1) / e.cur() ) * start;
8432                              jQuery.style( this, p, start + unit);
8433                          }
8434  
8435                          // If a +=/-= token was provided, we're doing a relative animation
8436                          if ( parts[1] ) {
8437                              end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
8438                          }
8439  
8440                          e.custom( start, end, unit );
8441  
8442                      } else {
8443                          e.custom( start, val, "" );
8444                      }
8445                  }
8446              }
8447  
8448              // For JS strict compliance
8449              return true;
8450          }
8451  
8452          return optall.queue === false ?
8453              this.each( doAnimation ) :
8454              this.queue( optall.queue, doAnimation );
8455      },
8456  
8457      stop: function( type, clearQueue, gotoEnd ) {
8458          if ( typeof type !== "string" ) {
8459              gotoEnd = clearQueue;
8460              clearQueue = type;
8461              type = undefined;
8462          }
8463          if ( clearQueue && type !== false ) {
8464              this.queue( type || "fx", [] );
8465          }
8466  
8467          return this.each(function() {
8468              var index,
8469                  hadTimers = false,
8470                  timers = jQuery.timers,
8471                  data = jQuery._data( this );
8472  
8473              // clear marker counters if we know they won't be
8474              if ( !gotoEnd ) {
8475                  jQuery._unmark( true, this );
8476              }
8477  
8478  			function stopQueue( elem, data, index ) {
8479                  var hooks = data[ index ];
8480                  jQuery.removeData( elem, index, true );
8481                  hooks.stop( gotoEnd );
8482              }
8483  
8484              if ( type == null ) {
8485                  for ( index in data ) {
8486                      if ( data[ index ] && data[ index ].stop && index.indexOf(".run") === index.length - 4 ) {
8487                          stopQueue( this, data, index );
8488                      }
8489                  }
8490              } else if ( data[ index = type + ".run" ] && data[ index ].stop ){
8491                  stopQueue( this, data, index );
8492              }
8493  
8494              for ( index = timers.length; index--; ) {
8495                  if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
8496                      if ( gotoEnd ) {
8497  
8498                          // force the next step to be the last
8499                          timers[ index ]( true );
8500                      } else {
8501                          timers[ index ].saveState();
8502                      }
8503                      hadTimers = true;
8504                      timers.splice( index, 1 );
8505                  }
8506              }
8507  
8508              // start the next in the queue if the last step wasn't forced
8509              // timers currently will call their complete callbacks, which will dequeue
8510              // but only if they were gotoEnd
8511              if ( !( gotoEnd && hadTimers ) ) {
8512                  jQuery.dequeue( this, type );
8513              }
8514          });
8515      }
8516  
8517  });
8518  
8519  // Animations created synchronously will run synchronously
8520  function createFxNow() {
8521      setTimeout( clearFxNow, 0 );
8522      return ( fxNow = jQuery.now() );
8523  }
8524  
8525  function clearFxNow() {
8526      fxNow = undefined;
8527  }
8528  
8529  // Generate parameters to create a standard animation
8530  function genFx( type, num ) {
8531      var obj = {};
8532  
8533      jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice( 0, num )), function() {
8534          obj[ this ] = type;
8535      });
8536  
8537      return obj;
8538  }
8539  
8540  // Generate shortcuts for custom animations
8541  jQuery.each({
8542      slideDown: genFx( "show", 1 ),
8543      slideUp: genFx( "hide", 1 ),
8544      slideToggle: genFx( "toggle", 1 ),
8545      fadeIn: { opacity: "show" },
8546      fadeOut: { opacity: "hide" },
8547      fadeToggle: { opacity: "toggle" }
8548  }, function( name, props ) {
8549      jQuery.fn[ name ] = function( speed, easing, callback ) {
8550          return this.animate( props, speed, easing, callback );
8551      };
8552  });
8553  
8554  jQuery.extend({
8555      speed: function( speed, easing, fn ) {
8556          var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
8557              complete: fn || !fn && easing ||
8558                  jQuery.isFunction( speed ) && speed,
8559              duration: speed,
8560              easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
8561          };
8562  
8563          opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8564              opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
8565  
8566          // normalize opt.queue - true/undefined/null -> "fx"
8567          if ( opt.queue == null || opt.queue === true ) {
8568              opt.queue = "fx";
8569          }
8570  
8571          // Queueing
8572          opt.old = opt.complete;
8573  
8574          opt.complete = function( noUnmark ) {
8575              if ( jQuery.isFunction( opt.old ) ) {
8576                  opt.old.call( this );
8577              }
8578  
8579              if ( opt.queue ) {
8580                  jQuery.dequeue( this, opt.queue );
8581              } else if ( noUnmark !== false ) {
8582                  jQuery._unmark( this );
8583              }
8584          };
8585  
8586          return opt;
8587      },
8588  
8589      easing: {
8590          linear: function( p, n, firstNum, diff ) {
8591              return firstNum + diff * p;
8592          },
8593          swing: function( p, n, firstNum, diff ) {
8594              return ( ( -Math.cos( p*Math.PI ) / 2 ) + 0.5 ) * diff + firstNum;
8595          }
8596      },
8597  
8598      timers: [],
8599  
8600      fx: function( elem, options, prop ) {
8601          this.options = options;
8602          this.elem = elem;
8603          this.prop = prop;
8604  
8605          options.orig = options.orig || {};
8606      }
8607  
8608  });
8609  
8610  jQuery.fx.prototype = {
8611      // Simple function for setting a style value
8612      update: function() {
8613          if ( this.options.step ) {
8614              this.options.step.call( this.elem, this.now, this );
8615          }
8616  
8617          ( jQuery.fx.step[ this.prop ] || jQuery.fx.step._default )( this );
8618      },
8619  
8620      // Get the current size
8621      cur: function() {
8622          if ( this.elem[ this.prop ] != null && (!this.elem.style || this.elem.style[ this.prop ] == null) ) {
8623              return this.elem[ this.prop ];
8624          }
8625  
8626          var parsed,
8627              r = jQuery.css( this.elem, this.prop );
8628          // Empty strings, null, undefined and "auto" are converted to 0,
8629          // complex values such as "rotate(1rad)" are returned as is,
8630          // simple values such as "10px" are parsed to Float.
8631          return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
8632      },
8633  
8634      // Start an animation from one number to another
8635      custom: function( from, to, unit ) {
8636          var self = this,
8637              fx = jQuery.fx;
8638  
8639          this.startTime = fxNow || createFxNow();
8640          this.end = to;
8641          this.now = this.start = from;
8642          this.pos = this.state = 0;
8643          this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
8644  
8645          function t( gotoEnd ) {
8646              return self.step( gotoEnd );
8647          }
8648  
8649          t.queue = this.options.queue;
8650          t.elem = this.elem;
8651          t.saveState = function() {
8652              if ( self.options.hide && jQuery._data( self.elem, "fxshow" + self.prop ) === undefined ) {
8653                  jQuery._data( self.elem, "fxshow" + self.prop, self.start );
8654              }
8655          };
8656  
8657          if ( t() && jQuery.timers.push(t) && !timerId ) {
8658              timerId = setInterval( fx.tick, fx.interval );
8659          }
8660      },
8661  
8662      // Simple 'show' function
8663      show: function() {
8664          var dataShow = jQuery._data( this.elem, "fxshow" + this.prop );
8665  
8666          // Remember where we started, so that we can go back to it later
8667          this.options.orig[ this.prop ] = dataShow || jQuery.style( this.elem, this.prop );
8668          this.options.show = true;
8669  
8670          // Begin the animation
8671          // Make sure that we start at a small width/height to avoid any flash of content
8672          if ( dataShow !== undefined ) {
8673              // This show is picking up where a previous hide or show left off
8674              this.custom( this.cur(), dataShow );
8675          } else {
8676              this.custom( this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur() );
8677          }
8678  
8679          // Start by showing the element
8680          jQuery( this.elem ).show();
8681      },
8682  
8683      // Simple 'hide' function
8684      hide: function() {
8685          // Remember where we started, so that we can go back to it later
8686          this.options.orig[ this.prop ] = jQuery._data( this.elem, "fxshow" + this.prop ) || jQuery.style( this.elem, this.prop );
8687          this.options.hide = true;
8688  
8689          // Begin the animation
8690          this.custom( this.cur(), 0 );
8691      },
8692  
8693      // Each step of an animation
8694      step: function( gotoEnd ) {
8695          var p, n, complete,
8696              t = fxNow || createFxNow(),
8697              done = true,
8698              elem = this.elem,
8699              options = this.options;
8700  
8701          if ( gotoEnd || t >= options.duration + this.startTime ) {
8702              this.now = this.end;
8703              this.pos = this.state = 1;
8704              this.update();
8705  
8706              options.animatedProperties[ this.prop ] = true;
8707  
8708              for ( p in options.animatedProperties ) {
8709                  if ( options.animatedProperties[ p ] !== true ) {
8710                      done = false;
8711                  }
8712              }
8713  
8714              if ( done ) {
8715                  // Reset the overflow
8716                  if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
8717  
8718                      jQuery.each( [ "", "X", "Y" ], function( index, value ) {
8719                          elem.style[ "overflow" + value ] = options.overflow[ index ];
8720                      });
8721                  }
8722  
8723                  // Hide the element if the "hide" operation was done
8724                  if ( options.hide ) {
8725                      jQuery( elem ).hide();
8726                  }
8727  
8728                  // Reset the properties, if the item has been hidden or shown
8729                  if ( options.hide || options.show ) {
8730                      for ( p in options.animatedProperties ) {
8731                          jQuery.style( elem, p, options.orig[ p ] );
8732                          jQuery.removeData( elem, "fxshow" + p, true );
8733                          // Toggle data is no longer needed
8734                          jQuery.removeData( elem, "toggle" + p, true );
8735                      }
8736                  }
8737  
8738                  // Execute the complete function
8739                  // in the event that the complete function throws an exception
8740                  // we must ensure it won't be called twice. #5684
8741  
8742                  complete = options.complete;
8743                  if ( complete ) {
8744  
8745                      options.complete = false;
8746                      complete.call( elem );
8747                  }
8748              }
8749  
8750              return false;
8751  
8752          } else {
8753              // classical easing cannot be used with an Infinity duration
8754              if ( options.duration == Infinity ) {
8755                  this.now = t;
8756              } else {
8757                  n = t - this.startTime;
8758                  this.state = n / options.duration;
8759  
8760                  // Perform the easing function, defaults to swing
8761                  this.pos = jQuery.easing[ options.animatedProperties[this.prop] ]( this.state, n, 0, 1, options.duration );
8762                  this.now = this.start + ( (this.end - this.start) * this.pos );
8763              }
8764              // Perform the next step of the animation
8765              this.update();
8766          }
8767  
8768          return true;
8769      }
8770  };
8771  
8772  jQuery.extend( jQuery.fx, {
8773      tick: function() {
8774          var timer,
8775              timers = jQuery.timers,
8776              i = 0;
8777  
8778          for ( ; i < timers.length; i++ ) {
8779              timer = timers[ i ];
8780              // Checks the timer has not already been removed
8781              if ( !timer() && timers[ i ] === timer ) {
8782                  timers.splice( i--, 1 );
8783              }
8784          }
8785  
8786          if ( !timers.length ) {
8787              jQuery.fx.stop();
8788          }
8789      },
8790  
8791      interval: 13,
8792  
8793      stop: function() {
8794          clearInterval( timerId );
8795          timerId = null;
8796      },
8797  
8798      speeds: {
8799          slow: 600,
8800          fast: 200,
8801          // Default speed
8802          _default: 400
8803      },
8804  
8805      step: {
8806          opacity: function( fx ) {
8807              jQuery.style( fx.elem, "opacity", fx.now );
8808          },
8809  
8810          _default: function( fx ) {
8811              if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
8812                  fx.elem.style[ fx.prop ] = fx.now + fx.unit;
8813              } else {
8814                  fx.elem[ fx.prop ] = fx.now;
8815              }
8816          }
8817      }
8818  });
8819  
8820  // Adds width/height step functions
8821  // Do not set anything below 0
8822  jQuery.each([ "width", "height" ], function( i, prop ) {
8823      jQuery.fx.step[ prop ] = function( fx ) {
8824          jQuery.style( fx.elem, prop, Math.max(0, fx.now) + fx.unit );
8825      };
8826  });
8827  
8828  if ( jQuery.expr && jQuery.expr.filters ) {
8829      jQuery.expr.filters.animated = function( elem ) {
8830          return jQuery.grep(jQuery.timers, function( fn ) {
8831              return elem === fn.elem;
8832          }).length;
8833      };
8834  }
8835  
8836  // Try to restore the default display value of an element
8837  function defaultDisplay( nodeName ) {
8838  
8839      if ( !elemdisplay[ nodeName ] ) {
8840  
8841          var body = document.body,
8842              elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),
8843              display = elem.css( "display" );
8844          elem.remove();
8845  
8846          // If the simple way fails,
8847          // get element's real default display by attaching it to a temp iframe
8848          if ( display === "none" || display === "" ) {
8849              // No iframe to use yet, so create it
8850              if ( !iframe ) {
8851                  iframe = document.createElement( "iframe" );
8852                  iframe.frameBorder = iframe.width = iframe.height = 0;
8853              }
8854  
8855              body.appendChild( iframe );
8856  
8857              // Create a cacheable copy of the iframe document on first call.
8858              // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
8859              // document to it; WebKit & Firefox won't allow reusing the iframe document.
8860              if ( !iframeDoc || !iframe.createElement ) {
8861                  iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
8862                  iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "<!doctype html>" : "" ) + "<html><body>" );
8863                  iframeDoc.close();
8864              }
8865  
8866              elem = iframeDoc.createElement( nodeName );
8867  
8868              iframeDoc.body.appendChild( elem );
8869  
8870              display = jQuery.css( elem, "display" );
8871              body.removeChild( iframe );
8872          }
8873  
8874          // Store the correct default display
8875          elemdisplay[ nodeName ] = display;
8876      }
8877  
8878      return elemdisplay[ nodeName ];
8879  }
8880  
8881  
8882  
8883  
8884  var rtable = /^t(?:able|d|h)$/i,
8885      rroot = /^(?:body|html)$/i;
8886  
8887  if ( "getBoundingClientRect" in document.documentElement ) {
8888      jQuery.fn.offset = function( options ) {
8889          var elem = this[0], box;
8890  
8891          if ( options ) {
8892              return this.each(function( i ) {
8893                  jQuery.offset.setOffset( this, options, i );
8894              });
8895          }
8896  
8897          if ( !elem || !elem.ownerDocument ) {
8898              return null;
8899          }
8900  
8901          if ( elem === elem.ownerDocument.body ) {
8902              return jQuery.offset.bodyOffset( elem );
8903          }
8904  
8905          try {
8906              box = elem.getBoundingClientRect();
8907          } catch(e) {}
8908  
8909          var doc = elem.ownerDocument,
8910              docElem = doc.documentElement;
8911  
8912          // Make sure we're not dealing with a disconnected DOM node
8913          if ( !box || !jQuery.contains( docElem, elem ) ) {
8914              return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
8915          }
8916  
8917          var body = doc.body,
8918              win = getWindow(doc),
8919              clientTop  = docElem.clientTop  || body.clientTop  || 0,
8920              clientLeft = docElem.clientLeft || body.clientLeft || 0,
8921              scrollTop  = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop,
8922              scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
8923              top  = box.top  + scrollTop  - clientTop,
8924              left = box.left + scrollLeft - clientLeft;
8925  
8926          return { top: top, left: left };
8927      };
8928  
8929  } else {
8930      jQuery.fn.offset = function( options ) {
8931          var elem = this[0];
8932  
8933          if ( options ) {
8934              return this.each(function( i ) {
8935                  jQuery.offset.setOffset( this, options, i );
8936              });
8937          }
8938  
8939          if ( !elem || !elem.ownerDocument ) {
8940              return null;
8941          }
8942  
8943          if ( elem === elem.ownerDocument.body ) {
8944              return jQuery.offset.bodyOffset( elem );
8945          }
8946  
8947          var computedStyle,
8948              offsetParent = elem.offsetParent,
8949              prevOffsetParent = elem,
8950              doc = elem.ownerDocument,
8951              docElem = doc.documentElement,
8952              body = doc.body,
8953              defaultView = doc.defaultView,
8954              prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
8955              top = elem.offsetTop,
8956              left = elem.offsetLeft;
8957  
8958          while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
8959              if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {
8960                  break;
8961              }
8962  
8963              computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
8964              top  -= elem.scrollTop;
8965              left -= elem.scrollLeft;
8966  
8967              if ( elem === offsetParent ) {
8968                  top  += elem.offsetTop;
8969                  left += elem.offsetLeft;
8970  
8971                  if ( jQuery.support.doesNotAddBorder && !(jQuery.support.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
8972                      top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
8973                      left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8974                  }
8975  
8976                  prevOffsetParent = offsetParent;
8977                  offsetParent = elem.offsetParent;
8978              }
8979  
8980              if ( jQuery.support.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
8981                  top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
8982                  left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8983              }
8984  
8985              prevComputedStyle = computedStyle;
8986          }
8987  
8988          if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
8989              top  += body.offsetTop;
8990              left += body.offsetLeft;
8991          }
8992  
8993          if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {
8994              top  += Math.max( docElem.scrollTop, body.scrollTop );
8995              left += Math.max( docElem.scrollLeft, body.scrollLeft );
8996          }
8997  
8998          return { top: top, left: left };
8999      };
9000  }
9001  
9002  jQuery.offset = {
9003  
9004      bodyOffset: function( body ) {
9005          var top = body.offsetTop,
9006              left = body.offsetLeft;
9007  
9008          if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {
9009              top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
9010              left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
9011          }
9012  
9013          return { top: top, left: left };
9014      },
9015  
9016      setOffset: function( elem, options, i ) {
9017          var position = jQuery.css( elem, "position" );
9018  
9019          // set position first, in-case top/left are set even on static elem
9020          if ( position === "static" ) {
9021              elem.style.position = "relative";
9022          }
9023  
9024          var curElem = jQuery( elem ),
9025              curOffset = curElem.offset(),
9026              curCSSTop = jQuery.css( elem, "top" ),
9027              curCSSLeft = jQuery.css( elem, "left" ),
9028              calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
9029              props = {}, curPosition = {}, curTop, curLeft;
9030  
9031          // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
9032          if ( calculatePosition ) {
9033              curPosition = curElem.position();
9034              curTop = curPosition.top;
9035              curLeft = curPosition.left;
9036          } else {
9037              curTop = parseFloat( curCSSTop ) || 0;
9038              curLeft = parseFloat( curCSSLeft ) || 0;
9039          }
9040  
9041          if ( jQuery.isFunction( options ) ) {
9042              options = options.call( elem, i, curOffset );
9043          }
9044  
9045          if ( options.top != null ) {
9046              props.top = ( options.top - curOffset.top ) + curTop;
9047          }
9048          if ( options.left != null ) {
9049              props.left = ( options.left - curOffset.left ) + curLeft;
9050          }
9051  
9052          if ( "using" in options ) {
9053              options.using.call( elem, props );
9054          } else {
9055              curElem.css( props );
9056          }
9057      }
9058  };
9059  
9060  
9061  jQuery.fn.extend({
9062  
9063      position: function() {
9064          if ( !this[0] ) {
9065              return null;
9066          }
9067  
9068          var elem = this[0],
9069  
9070          // Get *real* offsetParent
9071          offsetParent = this.offsetParent(),
9072  
9073          // Get correct offsets
9074          offset       = this.offset(),
9075          parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
9076  
9077          // Subtract element margins
9078          // note: when an element has margin: auto the offsetLeft and marginLeft
9079          // are the same in Safari causing offset.left to incorrectly be 0
9080          offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
9081          offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
9082  
9083          // Add offsetParent borders
9084          parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
9085          parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
9086  
9087          // Subtract the two offsets
9088          return {
9089              top:  offset.top  - parentOffset.top,
9090              left: offset.left - parentOffset.left
9091          };
9092      },
9093  
9094      offsetParent: function() {
9095          return this.map(function() {
9096              var offsetParent = this.offsetParent || document.body;
9097              while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
9098                  offsetParent = offsetParent.offsetParent;
9099              }
9100              return offsetParent;
9101          });
9102      }
9103  });
9104  
9105  
9106  // Create scrollLeft and scrollTop methods
9107  jQuery.each( ["Left", "Top"], function( i, name ) {
9108      var method = "scroll" + name;
9109  
9110      jQuery.fn[ method ] = function( val ) {
9111          var elem, win;
9112  
9113          if ( val === undefined ) {
9114              elem = this[ 0 ];
9115  
9116              if ( !elem ) {
9117                  return null;
9118              }
9119  
9120              win = getWindow( elem );
9121  
9122              // Return the scroll offset
9123              return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
9124                  jQuery.support.boxModel && win.document.documentElement[ method ] ||
9125                      win.document.body[ method ] :
9126                  elem[ method ];
9127          }
9128  
9129          // Set the scroll offset
9130          return this.each(function() {
9131              win = getWindow( this );
9132  
9133              if ( win ) {
9134                  win.scrollTo(
9135                      !i ? val : jQuery( win ).scrollLeft(),
9136                       i ? val : jQuery( win ).scrollTop()
9137                  );
9138  
9139              } else {
9140                  this[ method ] = val;
9141              }
9142          });
9143      };
9144  });
9145  
9146  function getWindow( elem ) {
9147      return jQuery.isWindow( elem ) ?
9148          elem :
9149          elem.nodeType === 9 ?
9150              elem.defaultView || elem.parentWindow :
9151              false;
9152  }
9153  
9154  
9155  
9156  
9157  // Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods
9158  jQuery.each([ "Height", "Width" ], function( i, name ) {
9159  
9160      var type = name.toLowerCase();
9161  
9162      // innerHeight and innerWidth
9163      jQuery.fn[ "inner" + name ] = function() {
9164          var elem = this[0];
9165          return elem ?
9166              elem.style ?
9167              parseFloat( jQuery.css( elem, type, "padding" ) ) :
9168              this[ type ]() :
9169              null;
9170      };
9171  
9172      // outerHeight and outerWidth
9173      jQuery.fn[ "outer" + name ] = function( margin ) {
9174          var elem = this[0];
9175          return elem ?
9176              elem.style ?
9177              parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :
9178              this[ type ]() :
9179              null;
9180      };
9181  
9182      jQuery.fn[ type ] = function( size ) {
9183          // Get window width or height
9184          var elem = this[0];
9185          if ( !elem ) {
9186              return size == null ? null : this;
9187          }
9188  
9189          if ( jQuery.isFunction( size ) ) {
9190              return this.each(function( i ) {
9191                  var self = jQuery( this );
9192                  self[ type ]( size.call( this, i, self[ type ]() ) );
9193              });
9194          }
9195  
9196          if ( jQuery.isWindow( elem ) ) {
9197              // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
9198              // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
9199              var docElemProp = elem.document.documentElement[ "client" + name ],
9200                  body = elem.document.body;
9201              return elem.document.compatMode === "CSS1Compat" && docElemProp ||
9202                  body && body[ "client" + name ] || docElemProp;
9203  
9204          // Get document width or height
9205          } else if ( elem.nodeType === 9 ) {
9206              // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
9207              return Math.max(
9208                  elem.documentElement["client" + name],
9209                  elem.body["scroll" + name], elem.documentElement["scroll" + name],
9210                  elem.body["offset" + name], elem.documentElement["offset" + name]
9211              );
9212  
9213          // Get or set width or height on the element
9214          } else if ( size === undefined ) {
9215              var orig = jQuery.css( elem, type ),
9216                  ret = parseFloat( orig );
9217  
9218              return jQuery.isNumeric( ret ) ? ret : orig;
9219  
9220          // Set the width or height on the element (default to pixels if value is unitless)
9221          } else {
9222              return this.css( type, typeof size === "string" ? size : size + "px" );
9223          }
9224      };
9225  
9226  });
9227  
9228  
9229  
9230  
9231  // Expose jQuery to the global object
9232  window.jQuery = window.$ = jQuery;
9233  
9234  // Expose jQuery as an AMD module, but only for AMD loaders that
9235  // understand the issues with loading multiple versions of jQuery
9236  // in a page that all might call define(). The loader will indicate
9237  // they have special allowances for multiple jQuery versions by
9238  // specifying define.amd.jQuery = true. Register as a named module,
9239  // since jQuery can be concatenated with other files that may use define,
9240  // but not use a proper concatenation script that understands anonymous
9241  // AMD modules. A named AMD is safest and most robust way to register.
9242  // Lowercase jquery is used because AMD module names are derived from
9243  // file names, and jQuery is normally delivered in a lowercase file name.
9244  // Do this after creating the global so that if an AMD module wants to call
9245  // noConflict to hide this version of jQuery, it will work.
9246  if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
9247      define( "jquery", [], function () { return jQuery; } );
9248  }
9249  
9250  
9251  
9252  })( window );


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