source: drbl-virt/web/js/jquery-1.4.4.js @ 236

Last change on this file since 236 was 226, checked in by rock, 14 years ago

Add: jQuery-1.4.4

File size: 178.9 KB
Line 
1/*!
2 * jQuery JavaScript Library v1.4.4
3 * http://jquery.com/
4 *
5 * Copyright 2010, John Resig
6 * Dual licensed under the MIT or GPL Version 2 licenses.
7 * http://jquery.org/license
8 *
9 * Includes Sizzle.js
10 * http://sizzlejs.com/
11 * Copyright 2010, The Dojo Foundation
12 * Released under the MIT, BSD, and GPL Licenses.
13 *
14 * Date: Thu Nov 11 19:04:53 2010 -0500
15 */
16(function( window, undefined ) {
17
18// Use the correct document accordingly with window argument (sandbox)
19var document = window.document;
20var jQuery = (function() {
21
22// Define a local copy of jQuery
23var jQuery = function( selector, context ) {
24    // The jQuery object is actually just the init constructor 'enhanced'
25    return new jQuery.fn.init( selector, context );
26  },
27
28  // Map over jQuery in case of overwrite
29  _jQuery = window.jQuery,
30
31  // Map over the $ in case of overwrite
32  _$ = window.$,
33
34  // A central reference to the root jQuery(document)
35  rootjQuery,
36
37  // A simple way to check for HTML strings or ID strings
38  // (both of which we optimize for)
39  quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,
40
41  // Is it a simple selector
42  isSimple = /^.[^:#\[\.,]*$/,
43
44  // Check if a string has a non-whitespace character in it
45  rnotwhite = /\S/,
46  rwhite = /\s/,
47
48  // Used for trimming whitespace
49  trimLeft = /^\s+/,
50  trimRight = /\s+$/,
51
52  // Check for non-word characters
53  rnonword = /\W/,
54
55  // Check for digits
56  rdigit = /\d/,
57
58  // Match a standalone tag
59  rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
60
61  // JSON RegExp
62  rvalidchars = /^[\],:{}\s]*$/,
63  rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
64  rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
65  rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
66
67  // Useragent RegExp
68  rwebkit = /(webkit)[ \/]([\w.]+)/,
69  ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
70  rmsie = /(msie) ([\w.]+)/,
71  rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
72
73  // Keep a UserAgent string for use with jQuery.browser
74  userAgent = navigator.userAgent,
75
76  // For matching the engine and version of the browser
77  browserMatch,
78 
79  // Has the ready events already been bound?
80  readyBound = false,
81 
82  // The functions to execute on DOM ready
83  readyList = [],
84
85  // The ready event handler
86  DOMContentLoaded,
87
88  // Save a reference to some core methods
89  toString = Object.prototype.toString,
90  hasOwn = Object.prototype.hasOwnProperty,
91  push = Array.prototype.push,
92  slice = Array.prototype.slice,
93  trim = String.prototype.trim,
94  indexOf = Array.prototype.indexOf,
95 
96  // [[Class]] -> type pairs
97  class2type = {};
98
99jQuery.fn = jQuery.prototype = {
100  init: function( selector, context ) {
101    var match, elem, ret, doc;
102
103    // Handle $(""), $(null), or $(undefined)
104    if ( !selector ) {
105      return this;
106    }
107
108    // Handle $(DOMElement)
109    if ( selector.nodeType ) {
110      this.context = this[0] = selector;
111      this.length = 1;
112      return this;
113    }
114   
115    // The body element only exists once, optimize finding it
116    if ( selector === "body" && !context && document.body ) {
117      this.context = document;
118      this[0] = document.body;
119      this.selector = "body";
120      this.length = 1;
121      return this;
122    }
123
124    // Handle HTML strings
125    if ( typeof selector === "string" ) {
126      // Are we dealing with HTML string or an ID?
127      match = quickExpr.exec( selector );
128
129      // Verify a match, and that no context was specified for #id
130      if ( match && (match[1] || !context) ) {
131
132        // HANDLE: $(html) -> $(array)
133        if ( match[1] ) {
134          doc = (context ? context.ownerDocument || context : document);
135
136          // If a single string is passed in and it's a single tag
137          // just do a createElement and skip the rest
138          ret = rsingleTag.exec( selector );
139
140          if ( ret ) {
141            if ( jQuery.isPlainObject( context ) ) {
142              selector = [ document.createElement( ret[1] ) ];
143              jQuery.fn.attr.call( selector, context, true );
144
145            } else {
146              selector = [ doc.createElement( ret[1] ) ];
147            }
148
149          } else {
150            ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
151            selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
152          }
153         
154          return jQuery.merge( this, selector );
155         
156        // HANDLE: $("#id")
157        } else {
158          elem = document.getElementById( match[2] );
159
160          // Check parentNode to catch when Blackberry 4.6 returns
161          // nodes that are no longer in the document #6963
162          if ( elem && elem.parentNode ) {
163            // Handle the case where IE and Opera return items
164            // by name instead of ID
165            if ( elem.id !== match[2] ) {
166              return rootjQuery.find( selector );
167            }
168
169            // Otherwise, we inject the element directly into the jQuery object
170            this.length = 1;
171            this[0] = elem;
172          }
173
174          this.context = document;
175          this.selector = selector;
176          return this;
177        }
178
179      // HANDLE: $("TAG")
180      } else if ( !context && !rnonword.test( selector ) ) {
181        this.selector = selector;
182        this.context = document;
183        selector = document.getElementsByTagName( selector );
184        return jQuery.merge( this, selector );
185
186      // HANDLE: $(expr, $(...))
187      } else if ( !context || context.jquery ) {
188        return (context || rootjQuery).find( selector );
189
190      // HANDLE: $(expr, context)
191      // (which is just equivalent to: $(context).find(expr)
192      } else {
193        return jQuery( context ).find( selector );
194      }
195
196    // HANDLE: $(function)
197    // Shortcut for document ready
198    } else if ( jQuery.isFunction( selector ) ) {
199      return rootjQuery.ready( selector );
200    }
201
202    if (selector.selector !== undefined) {
203      this.selector = selector.selector;
204      this.context = selector.context;
205    }
206
207    return jQuery.makeArray( selector, this );
208  },
209
210  // Start with an empty selector
211  selector: "",
212
213  // The current version of jQuery being used
214  jquery: "1.4.4",
215
216  // The default length of a jQuery object is 0
217  length: 0,
218
219  // The number of elements contained in the matched element set
220  size: function() {
221    return this.length;
222  },
223
224  toArray: function() {
225    return slice.call( this, 0 );
226  },
227
228  // Get the Nth element in the matched element set OR
229  // Get the whole matched element set as a clean array
230  get: function( num ) {
231    return num == null ?
232
233      // Return a 'clean' array
234      this.toArray() :
235
236      // Return just the object
237      ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
238  },
239
240  // Take an array of elements and push it onto the stack
241  // (returning the new matched element set)
242  pushStack: function( elems, name, selector ) {
243    // Build a new jQuery matched element set
244    var ret = jQuery();
245
246    if ( jQuery.isArray( elems ) ) {
247      push.apply( ret, elems );
248   
249    } else {
250      jQuery.merge( ret, elems );
251    }
252
253    // Add the old object onto the stack (as a reference)
254    ret.prevObject = this;
255
256    ret.context = this.context;
257
258    if ( name === "find" ) {
259      ret.selector = this.selector + (this.selector ? " " : "") + selector;
260    } else if ( name ) {
261      ret.selector = this.selector + "." + name + "(" + selector + ")";
262    }
263
264    // Return the newly-formed element set
265    return ret;
266  },
267
268  // Execute a callback for every element in the matched set.
269  // (You can seed the arguments with an array of args, but this is
270  // only used internally.)
271  each: function( callback, args ) {
272    return jQuery.each( this, callback, args );
273  },
274 
275  ready: function( fn ) {
276    // Attach the listeners
277    jQuery.bindReady();
278
279    // If the DOM is already ready
280    if ( jQuery.isReady ) {
281      // Execute the function immediately
282      fn.call( document, jQuery );
283
284    // Otherwise, remember the function for later
285    } else if ( readyList ) {
286      // Add the function to the wait list
287      readyList.push( fn );
288    }
289
290    return this;
291  },
292 
293  eq: function( i ) {
294    return i === -1 ?
295      this.slice( i ) :
296      this.slice( i, +i + 1 );
297  },
298
299  first: function() {
300    return this.eq( 0 );
301  },
302
303  last: function() {
304    return this.eq( -1 );
305  },
306
307  slice: function() {
308    return this.pushStack( slice.apply( this, arguments ),
309      "slice", slice.call(arguments).join(",") );
310  },
311
312  map: function( callback ) {
313    return this.pushStack( jQuery.map(this, function( elem, i ) {
314      return callback.call( elem, i, elem );
315    }));
316  },
317 
318  end: function() {
319    return this.prevObject || jQuery(null);
320  },
321
322  // For internal use only.
323  // Behaves like an Array's method, not like a jQuery method.
324  push: push,
325  sort: [].sort,
326  splice: [].splice
327};
328
329// Give the init function the jQuery prototype for later instantiation
330jQuery.fn.init.prototype = jQuery.fn;
331
332jQuery.extend = jQuery.fn.extend = function() {
333   var options, name, src, copy, copyIsArray, clone,
334    target = arguments[0] || {},
335    i = 1,
336    length = arguments.length,
337    deep = false;
338
339  // Handle a deep copy situation
340  if ( typeof target === "boolean" ) {
341    deep = target;
342    target = arguments[1] || {};
343    // skip the boolean and the target
344    i = 2;
345  }
346
347  // Handle case when target is a string or something (possible in deep copy)
348  if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
349    target = {};
350  }
351
352  // extend jQuery itself if only one argument is passed
353  if ( length === i ) {
354    target = this;
355    --i;
356  }
357
358  for ( ; i < length; i++ ) {
359    // Only deal with non-null/undefined values
360    if ( (options = arguments[ i ]) != null ) {
361      // Extend the base object
362      for ( name in options ) {
363        src = target[ name ];
364        copy = options[ name ];
365
366        // Prevent never-ending loop
367        if ( target === copy ) {
368          continue;
369        }
370
371        // Recurse if we're merging plain objects or arrays
372        if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
373          if ( copyIsArray ) {
374            copyIsArray = false;
375            clone = src && jQuery.isArray(src) ? src : [];
376
377          } else {
378            clone = src && jQuery.isPlainObject(src) ? src : {};
379          }
380
381          // Never move original objects, clone them
382          target[ name ] = jQuery.extend( deep, clone, copy );
383
384        // Don't bring in undefined values
385        } else if ( copy !== undefined ) {
386          target[ name ] = copy;
387        }
388      }
389    }
390  }
391
392  // Return the modified object
393  return target;
394};
395
396jQuery.extend({
397  noConflict: function( deep ) {
398    window.$ = _$;
399
400    if ( deep ) {
401      window.jQuery = _jQuery;
402    }
403
404    return jQuery;
405  },
406 
407  // Is the DOM ready to be used? Set to true once it occurs.
408  isReady: false,
409
410  // A counter to track how many items to wait for before
411  // the ready event fires. See #6781
412  readyWait: 1,
413 
414  // Handle when the DOM is ready
415  ready: function( wait ) {
416    // A third-party is pushing the ready event forwards
417    if ( wait === true ) {
418      jQuery.readyWait--;
419    }
420
421    // Make sure that the DOM is not already loaded
422    if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) {
423      // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
424      if ( !document.body ) {
425        return setTimeout( jQuery.ready, 1 );
426      }
427
428      // Remember that the DOM is ready
429      jQuery.isReady = true;
430
431      // If a normal DOM Ready event fired, decrement, and wait if need be
432      if ( wait !== true && --jQuery.readyWait > 0 ) {
433        return;
434      }
435
436      // If there are functions bound, to execute
437      if ( readyList ) {
438        // Execute all of them
439        var fn,
440          i = 0,
441          ready = readyList;
442
443        // Reset the list of functions
444        readyList = null;
445
446        while ( (fn = ready[ i++ ]) ) {
447          fn.call( document, jQuery );
448        }
449
450        // Trigger any bound ready events
451        if ( jQuery.fn.trigger ) {
452          jQuery( document ).trigger( "ready" ).unbind( "ready" );
453        }
454      }
455    }
456  },
457 
458  bindReady: function() {
459    if ( readyBound ) {
460      return;
461    }
462
463    readyBound = true;
464
465    // Catch cases where $(document).ready() is called after the
466    // browser event has already occurred.
467    if ( document.readyState === "complete" ) {
468      // Handle it asynchronously to allow scripts the opportunity to delay ready
469      return setTimeout( jQuery.ready, 1 );
470    }
471
472    // Mozilla, Opera and webkit nightlies currently support this event
473    if ( document.addEventListener ) {
474      // Use the handy event callback
475      document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
476     
477      // A fallback to window.onload, that will always work
478      window.addEventListener( "load", jQuery.ready, false );
479
480    // If IE event model is used
481    } else if ( document.attachEvent ) {
482      // ensure firing before onload,
483      // maybe late but safe also for iframes
484      document.attachEvent("onreadystatechange", DOMContentLoaded);
485     
486      // A fallback to window.onload, that will always work
487      window.attachEvent( "onload", jQuery.ready );
488
489      // If IE and not a frame
490      // continually check to see if the document is ready
491      var toplevel = false;
492
493      try {
494        toplevel = window.frameElement == null;
495      } catch(e) {}
496
497      if ( document.documentElement.doScroll && toplevel ) {
498        doScrollCheck();
499      }
500    }
501  },
502
503  // See test/unit/core.js for details concerning isFunction.
504  // Since version 1.3, DOM methods and functions like alert
505  // aren't supported. They return false on IE (#2968).
506  isFunction: function( obj ) {
507    return jQuery.type(obj) === "function";
508  },
509
510  isArray: Array.isArray || function( obj ) {
511    return jQuery.type(obj) === "array";
512  },
513
514  // A crude way of determining if an object is a window
515  isWindow: function( obj ) {
516    return obj && typeof obj === "object" && "setInterval" in obj;
517  },
518
519  isNaN: function( obj ) {
520    return obj == null || !rdigit.test( obj ) || isNaN( obj );
521  },
522
523  type: function( obj ) {
524    return obj == null ?
525      String( obj ) :
526      class2type[ toString.call(obj) ] || "object";
527  },
528
529  isPlainObject: function( obj ) {
530    // Must be an Object.
531    // Because of IE, we also have to check the presence of the constructor property.
532    // Make sure that DOM nodes and window objects don't pass through, as well
533    if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
534      return false;
535    }
536   
537    // Not own constructor property must be Object
538    if ( obj.constructor &&
539      !hasOwn.call(obj, "constructor") &&
540      !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
541      return false;
542    }
543   
544    // Own properties are enumerated firstly, so to speed up,
545    // if last one is own, then all properties are own.
546 
547    var key;
548    for ( key in obj ) {}
549   
550    return key === undefined || hasOwn.call( obj, key );
551  },
552
553  isEmptyObject: function( obj ) {
554    for ( var name in obj ) {
555      return false;
556    }
557    return true;
558  },
559 
560  error: function( msg ) {
561    throw msg;
562  },
563 
564  parseJSON: function( data ) {
565    if ( typeof data !== "string" || !data ) {
566      return null;
567    }
568
569    // Make sure leading/trailing whitespace is removed (IE can't handle it)
570    data = jQuery.trim( data );
571   
572    // Make sure the incoming data is actual JSON
573    // Logic borrowed from http://json.org/json2.js
574    if ( rvalidchars.test(data.replace(rvalidescape, "@")
575      .replace(rvalidtokens, "]")
576      .replace(rvalidbraces, "")) ) {
577
578      // Try to use the native JSON parser first
579      return window.JSON && window.JSON.parse ?
580        window.JSON.parse( data ) :
581        (new Function("return " + data))();
582
583    } else {
584      jQuery.error( "Invalid JSON: " + data );
585    }
586  },
587
588  noop: function() {},
589
590  // Evalulates a script in a global context
591  globalEval: function( data ) {
592    if ( data && rnotwhite.test(data) ) {
593      // Inspired by code by Andrea Giammarchi
594      // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
595      var head = document.getElementsByTagName("head")[0] || document.documentElement,
596        script = document.createElement("script");
597
598      script.type = "text/javascript";
599
600      if ( jQuery.support.scriptEval ) {
601        script.appendChild( document.createTextNode( data ) );
602      } else {
603        script.text = data;
604      }
605
606      // Use insertBefore instead of appendChild to circumvent an IE6 bug.
607      // This arises when a base node is used (#2709).
608      head.insertBefore( script, head.firstChild );
609      head.removeChild( script );
610    }
611  },
612
613  nodeName: function( elem, name ) {
614    return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
615  },
616
617  // args is for internal usage only
618  each: function( object, callback, args ) {
619    var name, i = 0,
620      length = object.length,
621      isObj = length === undefined || jQuery.isFunction(object);
622
623    if ( args ) {
624      if ( isObj ) {
625        for ( name in object ) {
626          if ( callback.apply( object[ name ], args ) === false ) {
627            break;
628          }
629        }
630      } else {
631        for ( ; i < length; ) {
632          if ( callback.apply( object[ i++ ], args ) === false ) {
633            break;
634          }
635        }
636      }
637
638    // A special, fast, case for the most common use of each
639    } else {
640      if ( isObj ) {
641        for ( name in object ) {
642          if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
643            break;
644          }
645        }
646      } else {
647        for ( var value = object[0];
648          i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
649      }
650    }
651
652    return object;
653  },
654
655  // Use native String.trim function wherever possible
656  trim: trim ?
657    function( text ) {
658      return text == null ?
659        "" :
660        trim.call( text );
661    } :
662
663    // Otherwise use our own trimming functionality
664    function( text ) {
665      return text == null ?
666        "" :
667        text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
668    },
669
670  // results is for internal usage only
671  makeArray: function( array, results ) {
672    var ret = results || [];
673
674    if ( array != null ) {
675      // The window, strings (and functions) also have 'length'
676      // The extra typeof function check is to prevent crashes
677      // in Safari 2 (See: #3039)
678      // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
679      var type = jQuery.type(array);
680
681      if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
682        push.call( ret, array );
683      } else {
684        jQuery.merge( ret, array );
685      }
686    }
687
688    return ret;
689  },
690
691  inArray: function( elem, array ) {
692    if ( array.indexOf ) {
693      return array.indexOf( elem );
694    }
695
696    for ( var i = 0, length = array.length; i < length; i++ ) {
697      if ( array[ i ] === elem ) {
698        return i;
699      }
700    }
701
702    return -1;
703  },
704
705  merge: function( first, second ) {
706    var i = first.length,
707      j = 0;
708
709    if ( typeof second.length === "number" ) {
710      for ( var l = second.length; j < l; j++ ) {
711        first[ i++ ] = second[ j ];
712      }
713   
714    } else {
715      while ( second[j] !== undefined ) {
716        first[ i++ ] = second[ j++ ];
717      }
718    }
719
720    first.length = i;
721
722    return first;
723  },
724
725  grep: function( elems, callback, inv ) {
726    var ret = [], retVal;
727    inv = !!inv;
728
729    // Go through the array, only saving the items
730    // that pass the validator function
731    for ( var i = 0, length = elems.length; i < length; i++ ) {
732      retVal = !!callback( elems[ i ], i );
733      if ( inv !== retVal ) {
734        ret.push( elems[ i ] );
735      }
736    }
737
738    return ret;
739  },
740
741  // arg is for internal usage only
742  map: function( elems, callback, arg ) {
743    var ret = [], value;
744
745    // Go through the array, translating each of the items to their
746    // new value (or values).
747    for ( var i = 0, length = elems.length; i < length; i++ ) {
748      value = callback( elems[ i ], i, arg );
749
750      if ( value != null ) {
751        ret[ ret.length ] = value;
752      }
753    }
754
755    return ret.concat.apply( [], ret );
756  },
757
758  // A global GUID counter for objects
759  guid: 1,
760
761  proxy: function( fn, proxy, thisObject ) {
762    if ( arguments.length === 2 ) {
763      if ( typeof proxy === "string" ) {
764        thisObject = fn;
765        fn = thisObject[ proxy ];
766        proxy = undefined;
767
768      } else if ( proxy && !jQuery.isFunction( proxy ) ) {
769        thisObject = proxy;
770        proxy = undefined;
771      }
772    }
773
774    if ( !proxy && fn ) {
775      proxy = function() {
776        return fn.apply( thisObject || this, arguments );
777      };
778    }
779
780    // Set the guid of unique handler to the same of original handler, so it can be removed
781    if ( fn ) {
782      proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
783    }
784
785    // So proxy can be declared as an argument
786    return proxy;
787  },
788
789  // Mutifunctional method to get and set values to a collection
790  // The value/s can be optionally by executed if its a function
791  access: function( elems, key, value, exec, fn, pass ) {
792    var length = elems.length;
793 
794    // Setting many attributes
795    if ( typeof key === "object" ) {
796      for ( var k in key ) {
797        jQuery.access( elems, k, key[k], exec, fn, value );
798      }
799      return elems;
800    }
801 
802    // Setting one attribute
803    if ( value !== undefined ) {
804      // Optionally, function values get executed if exec is true
805      exec = !pass && exec && jQuery.isFunction(value);
806   
807      for ( var i = 0; i < length; i++ ) {
808        fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
809      }
810   
811      return elems;
812    }
813 
814    // Getting an attribute
815    return length ? fn( elems[0], key ) : undefined;
816  },
817
818  now: function() {
819    return (new Date()).getTime();
820  },
821
822  // Use of jQuery.browser is frowned upon.
823  // More details: http://docs.jquery.com/Utilities/jQuery.browser
824  uaMatch: function( ua ) {
825    ua = ua.toLowerCase();
826
827    var match = rwebkit.exec( ua ) ||
828      ropera.exec( ua ) ||
829      rmsie.exec( ua ) ||
830      ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
831      [];
832
833    return { browser: match[1] || "", version: match[2] || "0" };
834  },
835
836  browser: {}
837});
838
839// Populate the class2type map
840jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
841  class2type[ "[object " + name + "]" ] = name.toLowerCase();
842});
843
844browserMatch = jQuery.uaMatch( userAgent );
845if ( browserMatch.browser ) {
846  jQuery.browser[ browserMatch.browser ] = true;
847  jQuery.browser.version = browserMatch.version;
848}
849
850// Deprecated, use jQuery.browser.webkit instead
851if ( jQuery.browser.webkit ) {
852  jQuery.browser.safari = true;
853}
854
855if ( indexOf ) {
856  jQuery.inArray = function( elem, array ) {
857    return indexOf.call( array, elem );
858  };
859}
860
861// Verify that \s matches non-breaking spaces
862// (IE fails on this test)
863if ( !rwhite.test( "\xA0" ) ) {
864  trimLeft = /^[\s\xA0]+/;
865  trimRight = /[\s\xA0]+$/;
866}
867
868// All jQuery objects should point back to these
869rootjQuery = jQuery(document);
870
871// Cleanup functions for the document ready method
872if ( document.addEventListener ) {
873  DOMContentLoaded = function() {
874    document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
875    jQuery.ready();
876  };
877
878} else if ( document.attachEvent ) {
879  DOMContentLoaded = function() {
880    // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
881    if ( document.readyState === "complete" ) {
882      document.detachEvent( "onreadystatechange", DOMContentLoaded );
883      jQuery.ready();
884    }
885  };
886}
887
888// The DOM ready check for Internet Explorer
889function doScrollCheck() {
890  if ( jQuery.isReady ) {
891    return;
892  }
893
894  try {
895    // If IE is used, use the trick by Diego Perini
896    // http://javascript.nwbox.com/IEContentLoaded/
897    document.documentElement.doScroll("left");
898  } catch(e) {
899    setTimeout( doScrollCheck, 1 );
900    return;
901  }
902
903  // and execute any waiting functions
904  jQuery.ready();
905}
906
907// Expose jQuery to the global object
908return (window.jQuery = window.$ = jQuery);
909
910})();
911
912
913(function() {
914
915  jQuery.support = {};
916
917  var root = document.documentElement,
918    script = document.createElement("script"),
919    div = document.createElement("div"),
920    id = "script" + jQuery.now();
921
922  div.style.display = "none";
923  div.innerHTML = "   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
924
925  var all = div.getElementsByTagName("*"),
926    a = div.getElementsByTagName("a")[0],
927    select = document.createElement("select"),
928    opt = select.appendChild( document.createElement("option") );
929
930  // Can't get basic test support
931  if ( !all || !all.length || !a ) {
932    return;
933  }
934
935  jQuery.support = {
936    // IE strips leading whitespace when .innerHTML is used
937    leadingWhitespace: div.firstChild.nodeType === 3,
938
939    // Make sure that tbody elements aren't automatically inserted
940    // IE will insert them into empty tables
941    tbody: !div.getElementsByTagName("tbody").length,
942
943    // Make sure that link elements get serialized correctly by innerHTML
944    // This requires a wrapper element in IE
945    htmlSerialize: !!div.getElementsByTagName("link").length,
946
947    // Get the style information from getAttribute
948    // (IE uses .cssText insted)
949    style: /red/.test( a.getAttribute("style") ),
950
951    // Make sure that URLs aren't manipulated
952    // (IE normalizes it by default)
953    hrefNormalized: a.getAttribute("href") === "/a",
954
955    // Make sure that element opacity exists
956    // (IE uses filter instead)
957    // Use a regex to work around a WebKit issue. See #5145
958    opacity: /^0.55$/.test( a.style.opacity ),
959
960    // Verify style float existence
961    // (IE uses styleFloat instead of cssFloat)
962    cssFloat: !!a.style.cssFloat,
963
964    // Make sure that if no value is specified for a checkbox
965    // that it defaults to "on".
966    // (WebKit defaults to "" instead)
967    checkOn: div.getElementsByTagName("input")[0].value === "on",
968
969    // Make sure that a selected-by-default option has a working selected property.
970    // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
971    optSelected: opt.selected,
972
973    // Will be defined later
974    deleteExpando: true,
975    optDisabled: false,
976    checkClone: false,
977    scriptEval: false,
978    noCloneEvent: true,
979    boxModel: null,
980    inlineBlockNeedsLayout: false,
981    shrinkWrapBlocks: false,
982    reliableHiddenOffsets: true
983  };
984
985  // Make sure that the options inside disabled selects aren't marked as disabled
986  // (WebKit marks them as diabled)
987  select.disabled = true;
988  jQuery.support.optDisabled = !opt.disabled;
989
990  script.type = "text/javascript";
991  try {
992    script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
993  } catch(e) {}
994
995  root.insertBefore( script, root.firstChild );
996
997  // Make sure that the execution of code works by injecting a script
998  // tag with appendChild/createTextNode
999  // (IE doesn't support this, fails, and uses .text instead)
1000  if ( window[ id ] ) {
1001    jQuery.support.scriptEval = true;
1002    delete window[ id ];
1003  }
1004
1005  // Test to see if it's possible to delete an expando from an element
1006  // Fails in Internet Explorer
1007  try {
1008    delete script.test;
1009
1010  } catch(e) {
1011    jQuery.support.deleteExpando = false;
1012  }
1013
1014  root.removeChild( script );
1015
1016  if ( div.attachEvent && div.fireEvent ) {
1017    div.attachEvent("onclick", function click() {
1018      // Cloning a node shouldn't copy over any
1019      // bound event handlers (IE does this)
1020      jQuery.support.noCloneEvent = false;
1021      div.detachEvent("onclick", click);
1022    });
1023    div.cloneNode(true).fireEvent("onclick");
1024  }
1025
1026  div = document.createElement("div");
1027  div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
1028
1029  var fragment = document.createDocumentFragment();
1030  fragment.appendChild( div.firstChild );
1031
1032  // WebKit doesn't clone checked state correctly in fragments
1033  jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
1034
1035  // Figure out if the W3C box model works as expected
1036  // document.body must exist before we can do this
1037  jQuery(function() {
1038    var div = document.createElement("div");
1039    div.style.width = div.style.paddingLeft = "1px";
1040
1041    document.body.appendChild( div );
1042    jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
1043
1044    if ( "zoom" in div.style ) {
1045      // Check if natively block-level elements act like inline-block
1046      // elements when setting their display to 'inline' and giving
1047      // them layout
1048      // (IE < 8 does this)
1049      div.style.display = "inline";
1050      div.style.zoom = 1;
1051      jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;
1052
1053      // Check if elements with layout shrink-wrap their children
1054      // (IE 6 does this)
1055      div.style.display = "";
1056      div.innerHTML = "<div style='width:4px;'></div>";
1057      jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
1058    }
1059
1060    div.innerHTML = "<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";
1061    var tds = div.getElementsByTagName("td");
1062
1063    // Check if table cells still have offsetWidth/Height when they are set
1064    // to display:none and there are still other visible table cells in a
1065    // table row; if so, offsetWidth/Height are not reliable for use when
1066    // determining if an element has been hidden directly using
1067    // display:none (it is still safe to use offsets if a parent element is
1068    // hidden; don safety goggles and see bug #4512 for more information).
1069    // (only IE 8 fails this test)
1070    jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;
1071
1072    tds[0].style.display = "";
1073    tds[1].style.display = "none";
1074
1075    // Check if empty table cells still have offsetWidth/Height
1076    // (IE < 8 fail this test)
1077    jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
1078    div.innerHTML = "";
1079
1080    document.body.removeChild( div ).style.display = "none";
1081    div = tds = null;
1082  });
1083
1084  // Technique from Juriy Zaytsev
1085  // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1086  var eventSupported = function( eventName ) {
1087    var el = document.createElement("div");
1088    eventName = "on" + eventName;
1089
1090    var isSupported = (eventName in el);
1091    if ( !isSupported ) {
1092      el.setAttribute(eventName, "return;");
1093      isSupported = typeof el[eventName] === "function";
1094    }
1095    el = null;
1096
1097    return isSupported;
1098  };
1099
1100  jQuery.support.submitBubbles = eventSupported("submit");
1101  jQuery.support.changeBubbles = eventSupported("change");
1102
1103  // release memory in IE
1104  root = script = div = all = a = null;
1105})();
1106
1107
1108
1109var windowData = {},
1110  rbrace = /^(?:\{.*\}|\[.*\])$/;
1111
1112jQuery.extend({
1113  cache: {},
1114
1115  // Please use with caution
1116  uuid: 0,
1117
1118  // Unique for each copy of jQuery on the page
1119  expando: "jQuery" + jQuery.now(),
1120
1121  // The following elements throw uncatchable exceptions if you
1122  // attempt to add expando properties to them.
1123  noData: {
1124    "embed": true,
1125    // Ban all objects except for Flash (which handle expandos)
1126    "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1127    "applet": true
1128  },
1129
1130  data: function( elem, name, data ) {
1131    if ( !jQuery.acceptData( elem ) ) {
1132      return;
1133    }
1134
1135    elem = elem == window ?
1136      windowData :
1137      elem;
1138
1139    var isNode = elem.nodeType,
1140      id = isNode ? elem[ jQuery.expando ] : null,
1141      cache = jQuery.cache, thisCache;
1142
1143    if ( isNode && !id && typeof name === "string" && data === undefined ) {
1144      return;
1145    }
1146
1147    // Get the data from the object directly
1148    if ( !isNode ) {
1149      cache = elem;
1150
1151    // Compute a unique ID for the element
1152    } else if ( !id ) {
1153      elem[ jQuery.expando ] = id = ++jQuery.uuid;
1154    }
1155
1156    // Avoid generating a new cache unless none exists and we
1157    // want to manipulate it.
1158    if ( typeof name === "object" ) {
1159      if ( isNode ) {
1160        cache[ id ] = jQuery.extend(cache[ id ], name);
1161
1162      } else {
1163        jQuery.extend( cache, name );
1164      }
1165
1166    } else if ( isNode && !cache[ id ] ) {
1167      cache[ id ] = {};
1168    }
1169
1170    thisCache = isNode ? cache[ id ] : cache;
1171
1172    // Prevent overriding the named cache with undefined values
1173    if ( data !== undefined ) {
1174      thisCache[ name ] = data;
1175    }
1176
1177    return typeof name === "string" ? thisCache[ name ] : thisCache;
1178  },
1179
1180  removeData: function( elem, name ) {
1181    if ( !jQuery.acceptData( elem ) ) {
1182      return;
1183    }
1184
1185    elem = elem == window ?
1186      windowData :
1187      elem;
1188
1189    var isNode = elem.nodeType,
1190      id = isNode ? elem[ jQuery.expando ] : elem,
1191      cache = jQuery.cache,
1192      thisCache = isNode ? cache[ id ] : id;
1193
1194    // If we want to remove a specific section of the element's data
1195    if ( name ) {
1196      if ( thisCache ) {
1197        // Remove the section of cache data
1198        delete thisCache[ name ];
1199
1200        // If we've removed all the data, remove the element's cache
1201        if ( isNode && jQuery.isEmptyObject(thisCache) ) {
1202          jQuery.removeData( elem );
1203        }
1204      }
1205
1206    // Otherwise, we want to remove all of the element's data
1207    } else {
1208      if ( isNode && jQuery.support.deleteExpando ) {
1209        delete elem[ jQuery.expando ];
1210
1211      } else if ( elem.removeAttribute ) {
1212        elem.removeAttribute( jQuery.expando );
1213
1214      // Completely remove the data cache
1215      } else if ( isNode ) {
1216        delete cache[ id ];
1217
1218      // Remove all fields from the object
1219      } else {
1220        for ( var n in elem ) {
1221          delete elem[ n ];
1222        }
1223      }
1224    }
1225  },
1226
1227  // A method for determining if a DOM node can handle the data expando
1228  acceptData: function( elem ) {
1229    if ( elem.nodeName ) {
1230      var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1231
1232      if ( match ) {
1233        return !(match === true || elem.getAttribute("classid") !== match);
1234      }
1235    }
1236
1237    return true;
1238  }
1239});
1240
1241jQuery.fn.extend({
1242  data: function( key, value ) {
1243    var data = null;
1244
1245    if ( typeof key === "undefined" ) {
1246      if ( this.length ) {
1247        var attr = this[0].attributes, name;
1248        data = jQuery.data( this[0] );
1249
1250        for ( var i = 0, l = attr.length; i < l; i++ ) {
1251          name = attr[i].name;
1252
1253          if ( name.indexOf( "data-" ) === 0 ) {
1254            name = name.substr( 5 );
1255            dataAttr( this[0], name, data[ name ] );
1256          }
1257        }
1258      }
1259
1260      return data;
1261
1262    } else if ( typeof key === "object" ) {
1263      return this.each(function() {
1264        jQuery.data( this, key );
1265      });
1266    }
1267
1268    var parts = key.split(".");
1269    parts[1] = parts[1] ? "." + parts[1] : "";
1270
1271    if ( value === undefined ) {
1272      data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1273
1274      // Try to fetch any internally stored data first
1275      if ( data === undefined && this.length ) {
1276        data = jQuery.data( this[0], key );
1277        data = dataAttr( this[0], key, data );
1278      }
1279
1280      return data === undefined && parts[1] ?
1281        this.data( parts[0] ) :
1282        data;
1283
1284    } else {
1285      return this.each(function() {
1286        var $this = jQuery( this ),
1287          args = [ parts[0], value ];
1288
1289        $this.triggerHandler( "setData" + parts[1] + "!", args );
1290        jQuery.data( this, key, value );
1291        $this.triggerHandler( "changeData" + parts[1] + "!", args );
1292      });
1293    }
1294  },
1295
1296  removeData: function( key ) {
1297    return this.each(function() {
1298      jQuery.removeData( this, key );
1299    });
1300  }
1301});
1302
1303function dataAttr( elem, key, data ) {
1304  // If nothing was found internally, try to fetch any
1305  // data from the HTML5 data-* attribute
1306  if ( data === undefined && elem.nodeType === 1 ) {
1307    data = elem.getAttribute( "data-" + key );
1308
1309    if ( typeof data === "string" ) {
1310      try {
1311        data = data === "true" ? true :
1312        data === "false" ? false :
1313        data === "null" ? null :
1314        !jQuery.isNaN( data ) ? parseFloat( data ) :
1315          rbrace.test( data ) ? jQuery.parseJSON( data ) :
1316          data;
1317      } catch( e ) {}
1318
1319      // Make sure we set the data so it isn't changed later
1320      jQuery.data( elem, key, data );
1321
1322    } else {
1323      data = undefined;
1324    }
1325  }
1326
1327  return data;
1328}
1329
1330
1331
1332
1333jQuery.extend({
1334  queue: function( elem, type, data ) {
1335    if ( !elem ) {
1336      return;
1337    }
1338
1339    type = (type || "fx") + "queue";
1340    var q = jQuery.data( elem, type );
1341
1342    // Speed up dequeue by getting out quickly if this is just a lookup
1343    if ( !data ) {
1344      return q || [];
1345    }
1346
1347    if ( !q || jQuery.isArray(data) ) {
1348      q = jQuery.data( elem, type, jQuery.makeArray(data) );
1349
1350    } else {
1351      q.push( data );
1352    }
1353
1354    return q;
1355  },
1356
1357  dequeue: function( elem, type ) {
1358    type = type || "fx";
1359
1360    var queue = jQuery.queue( elem, type ),
1361      fn = queue.shift();
1362
1363    // If the fx queue is dequeued, always remove the progress sentinel
1364    if ( fn === "inprogress" ) {
1365      fn = queue.shift();
1366    }
1367
1368    if ( fn ) {
1369      // Add a progress sentinel to prevent the fx queue from being
1370      // automatically dequeued
1371      if ( type === "fx" ) {
1372        queue.unshift("inprogress");
1373      }
1374
1375      fn.call(elem, function() {
1376        jQuery.dequeue(elem, type);
1377      });
1378    }
1379  }
1380});
1381
1382jQuery.fn.extend({
1383  queue: function( type, data ) {
1384    if ( typeof type !== "string" ) {
1385      data = type;
1386      type = "fx";
1387    }
1388
1389    if ( data === undefined ) {
1390      return jQuery.queue( this[0], type );
1391    }
1392    return this.each(function( i ) {
1393      var queue = jQuery.queue( this, type, data );
1394
1395      if ( type === "fx" && queue[0] !== "inprogress" ) {
1396        jQuery.dequeue( this, type );
1397      }
1398    });
1399  },
1400  dequeue: function( type ) {
1401    return this.each(function() {
1402      jQuery.dequeue( this, type );
1403    });
1404  },
1405
1406  // Based off of the plugin by Clint Helfers, with permission.
1407  // http://blindsignals.com/index.php/2009/07/jquery-delay/
1408  delay: function( time, type ) {
1409    time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1410    type = type || "fx";
1411
1412    return this.queue( type, function() {
1413      var elem = this;
1414      setTimeout(function() {
1415        jQuery.dequeue( elem, type );
1416      }, time );
1417    });
1418  },
1419
1420  clearQueue: function( type ) {
1421    return this.queue( type || "fx", [] );
1422  }
1423});
1424
1425
1426
1427
1428var rclass = /[\n\t]/g,
1429  rspaces = /\s+/,
1430  rreturn = /\r/g,
1431  rspecialurl = /^(?:href|src|style)$/,
1432  rtype = /^(?:button|input)$/i,
1433  rfocusable = /^(?:button|input|object|select|textarea)$/i,
1434  rclickable = /^a(?:rea)?$/i,
1435  rradiocheck = /^(?:radio|checkbox)$/i;
1436
1437jQuery.props = {
1438  "for": "htmlFor",
1439  "class": "className",
1440  readonly: "readOnly",
1441  maxlength: "maxLength",
1442  cellspacing: "cellSpacing",
1443  rowspan: "rowSpan",
1444  colspan: "colSpan",
1445  tabindex: "tabIndex",
1446  usemap: "useMap",
1447  frameborder: "frameBorder"
1448};
1449
1450jQuery.fn.extend({
1451  attr: function( name, value ) {
1452    return jQuery.access( this, name, value, true, jQuery.attr );
1453  },
1454
1455  removeAttr: function( name, fn ) {
1456    return this.each(function(){
1457      jQuery.attr( this, name, "" );
1458      if ( this.nodeType === 1 ) {
1459        this.removeAttribute( name );
1460      }
1461    });
1462  },
1463
1464  addClass: function( value ) {
1465    if ( jQuery.isFunction(value) ) {
1466      return this.each(function(i) {
1467        var self = jQuery(this);
1468        self.addClass( value.call(this, i, self.attr("class")) );
1469      });
1470    }
1471
1472    if ( value && typeof value === "string" ) {
1473      var classNames = (value || "").split( rspaces );
1474
1475      for ( var i = 0, l = this.length; i < l; i++ ) {
1476        var elem = this[i];
1477
1478        if ( elem.nodeType === 1 ) {
1479          if ( !elem.className ) {
1480            elem.className = value;
1481
1482          } else {
1483            var className = " " + elem.className + " ",
1484              setClass = elem.className;
1485
1486            for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1487              if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
1488                setClass += " " + classNames[c];
1489              }
1490            }
1491            elem.className = jQuery.trim( setClass );
1492          }
1493        }
1494      }
1495    }
1496
1497    return this;
1498  },
1499
1500  removeClass: function( value ) {
1501    if ( jQuery.isFunction(value) ) {
1502      return this.each(function(i) {
1503        var self = jQuery(this);
1504        self.removeClass( value.call(this, i, self.attr("class")) );
1505      });
1506    }
1507
1508    if ( (value && typeof value === "string") || value === undefined ) {
1509      var classNames = (value || "").split( rspaces );
1510
1511      for ( var i = 0, l = this.length; i < l; i++ ) {
1512        var elem = this[i];
1513
1514        if ( elem.nodeType === 1 && elem.className ) {
1515          if ( value ) {
1516            var className = (" " + elem.className + " ").replace(rclass, " ");
1517            for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1518              className = className.replace(" " + classNames[c] + " ", " ");
1519            }
1520            elem.className = jQuery.trim( className );
1521
1522          } else {
1523            elem.className = "";
1524          }
1525        }
1526      }
1527    }
1528
1529    return this;
1530  },
1531
1532  toggleClass: function( value, stateVal ) {
1533    var type = typeof value,
1534      isBool = typeof stateVal === "boolean";
1535
1536    if ( jQuery.isFunction( value ) ) {
1537      return this.each(function(i) {
1538        var self = jQuery(this);
1539        self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
1540      });
1541    }
1542
1543    return this.each(function() {
1544      if ( type === "string" ) {
1545        // toggle individual class names
1546        var className,
1547          i = 0,
1548          self = jQuery( this ),
1549          state = stateVal,
1550          classNames = value.split( rspaces );
1551
1552        while ( (className = classNames[ i++ ]) ) {
1553          // check each className given, space seperated list
1554          state = isBool ? state : !self.hasClass( className );
1555          self[ state ? "addClass" : "removeClass" ]( className );
1556        }
1557
1558      } else if ( type === "undefined" || type === "boolean" ) {
1559        if ( this.className ) {
1560          // store className if set
1561          jQuery.data( this, "__className__", this.className );
1562        }
1563
1564        // toggle whole className
1565        this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
1566      }
1567    });
1568  },
1569
1570  hasClass: function( selector ) {
1571    var className = " " + selector + " ";
1572    for ( var i = 0, l = this.length; i < l; i++ ) {
1573      if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
1574        return true;
1575      }
1576    }
1577
1578    return false;
1579  },
1580
1581  val: function( value ) {
1582    if ( !arguments.length ) {
1583      var elem = this[0];
1584
1585      if ( elem ) {
1586        if ( jQuery.nodeName( elem, "option" ) ) {
1587          // attributes.value is undefined in Blackberry 4.7 but
1588          // uses .value. See #6932
1589          var val = elem.attributes.value;
1590          return !val || val.specified ? elem.value : elem.text;
1591        }
1592
1593        // We need to handle select boxes special
1594        if ( jQuery.nodeName( elem, "select" ) ) {
1595          var index = elem.selectedIndex,
1596            values = [],
1597            options = elem.options,
1598            one = elem.type === "select-one";
1599
1600          // Nothing was selected
1601          if ( index < 0 ) {
1602            return null;
1603          }
1604
1605          // Loop through all the selected options
1606          for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
1607            var option = options[ i ];
1608
1609            // Don't return options that are disabled or in a disabled optgroup
1610            if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && 
1611                (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
1612
1613              // Get the specific value for the option
1614              value = jQuery(option).val();
1615
1616              // We don't need an array for one selects
1617              if ( one ) {
1618                return value;
1619              }
1620
1621              // Multi-Selects return an array
1622              values.push( value );
1623            }
1624          }
1625
1626          return values;
1627        }
1628
1629        // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
1630        if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
1631          return elem.getAttribute("value") === null ? "on" : elem.value;
1632        }
1633       
1634
1635        // Everything else, we just grab the value
1636        return (elem.value || "").replace(rreturn, "");
1637
1638      }
1639
1640      return undefined;
1641    }
1642
1643    var isFunction = jQuery.isFunction(value);
1644
1645    return this.each(function(i) {
1646      var self = jQuery(this), val = value;
1647
1648      if ( this.nodeType !== 1 ) {
1649        return;
1650      }
1651
1652      if ( isFunction ) {
1653        val = value.call(this, i, self.val());
1654      }
1655
1656      // Treat null/undefined as ""; convert numbers to string
1657      if ( val == null ) {
1658        val = "";
1659      } else if ( typeof val === "number" ) {
1660        val += "";
1661      } else if ( jQuery.isArray(val) ) {
1662        val = jQuery.map(val, function (value) {
1663          return value == null ? "" : value + "";
1664        });
1665      }
1666
1667      if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
1668        this.checked = jQuery.inArray( self.val(), val ) >= 0;
1669
1670      } else if ( jQuery.nodeName( this, "select" ) ) {
1671        var values = jQuery.makeArray(val);
1672
1673        jQuery( "option", this ).each(function() {
1674          this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
1675        });
1676
1677        if ( !values.length ) {
1678          this.selectedIndex = -1;
1679        }
1680
1681      } else {
1682        this.value = val;
1683      }
1684    });
1685  }
1686});
1687
1688jQuery.extend({
1689  attrFn: {
1690    val: true,
1691    css: true,
1692    html: true,
1693    text: true,
1694    data: true,
1695    width: true,
1696    height: true,
1697    offset: true
1698  },
1699   
1700  attr: function( elem, name, value, pass ) {
1701    // don't set attributes on text and comment nodes
1702    if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
1703      return undefined;
1704    }
1705
1706    if ( pass && name in jQuery.attrFn ) {
1707      return jQuery(elem)[name](value);
1708    }
1709
1710    var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
1711      // Whether we are setting (or getting)
1712      set = value !== undefined;
1713
1714    // Try to normalize/fix the name
1715    name = notxml && jQuery.props[ name ] || name;
1716
1717    // These attributes require special treatment
1718    var special = rspecialurl.test( name );
1719
1720    // Safari mis-reports the default selected property of an option
1721    // Accessing the parent's selectedIndex property fixes it
1722    if ( name === "selected" && !jQuery.support.optSelected ) {
1723      var parent = elem.parentNode;
1724      if ( parent ) {
1725        parent.selectedIndex;
1726
1727        // Make sure that it also works with optgroups, see #5701
1728        if ( parent.parentNode ) {
1729          parent.parentNode.selectedIndex;
1730        }
1731      }
1732    }
1733
1734    // If applicable, access the attribute via the DOM 0 way
1735    // 'in' checks fail in Blackberry 4.7 #6931
1736    if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
1737      if ( set ) {
1738        // We can't allow the type property to be changed (since it causes problems in IE)
1739        if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
1740          jQuery.error( "type property can't be changed" );
1741        }
1742
1743        if ( value === null ) {
1744          if ( elem.nodeType === 1 ) {
1745            elem.removeAttribute( name );
1746          }
1747
1748        } else {
1749          elem[ name ] = value;
1750        }
1751      }
1752
1753      // browsers index elements by id/name on forms, give priority to attributes.
1754      if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
1755        return elem.getAttributeNode( name ).nodeValue;
1756      }
1757
1758      // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1759      // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1760      if ( name === "tabIndex" ) {
1761        var attributeNode = elem.getAttributeNode( "tabIndex" );
1762
1763        return attributeNode && attributeNode.specified ?
1764          attributeNode.value :
1765          rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
1766            0 :
1767            undefined;
1768      }
1769
1770      return elem[ name ];
1771    }
1772
1773    if ( !jQuery.support.style && notxml && name === "style" ) {
1774      if ( set ) {
1775        elem.style.cssText = "" + value;
1776      }
1777
1778      return elem.style.cssText;
1779    }
1780
1781    if ( set ) {
1782      // convert the value to a string (all browsers do this but IE) see #1070
1783      elem.setAttribute( name, "" + value );
1784    }
1785
1786    // Ensure that missing attributes return undefined
1787    // Blackberry 4.7 returns "" from getAttribute #6938
1788    if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
1789      return undefined;
1790    }
1791
1792    var attr = !jQuery.support.hrefNormalized && notxml && special ?
1793        // Some attributes require a special call on IE
1794        elem.getAttribute( name, 2 ) :
1795        elem.getAttribute( name );
1796
1797    // Non-existent attributes return null, we normalize to undefined
1798    return attr === null ? undefined : attr;
1799  }
1800});
1801
1802
1803
1804
1805var rnamespaces = /\.(.*)$/,
1806  rformElems = /^(?:textarea|input|select)$/i,
1807  rperiod = /\./g,
1808  rspace = / /g,
1809  rescape = /[^\w\s.|`]/g,
1810  fcleanup = function( nm ) {
1811    return nm.replace(rescape, "\\$&");
1812  },
1813  focusCounts = { focusin: 0, focusout: 0 };
1814
1815/*
1816 * A number of helper functions used for managing events.
1817 * Many of the ideas behind this code originated from
1818 * Dean Edwards' addEvent library.
1819 */
1820jQuery.event = {
1821
1822  // Bind an event to an element
1823  // Original by Dean Edwards
1824  add: function( elem, types, handler, data ) {
1825    if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
1826      return;
1827    }
1828
1829    // For whatever reason, IE has trouble passing the window object
1830    // around, causing it to be cloned in the process
1831    if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) {
1832      elem = window;
1833    }
1834
1835    if ( handler === false ) {
1836      handler = returnFalse;
1837    } else if ( !handler ) {
1838      // Fixes bug #7229. Fix recommended by jdalton
1839      return;
1840    }
1841
1842    var handleObjIn, handleObj;
1843
1844    if ( handler.handler ) {
1845      handleObjIn = handler;
1846      handler = handleObjIn.handler;
1847    }
1848
1849    // Make sure that the function being executed has a unique ID
1850    if ( !handler.guid ) {
1851      handler.guid = jQuery.guid++;
1852    }
1853
1854    // Init the element's event structure
1855    var elemData = jQuery.data( elem );
1856
1857    // If no elemData is found then we must be trying to bind to one of the
1858    // banned noData elements
1859    if ( !elemData ) {
1860      return;
1861    }
1862
1863    // Use a key less likely to result in collisions for plain JS objects.
1864    // Fixes bug #7150.
1865    var eventKey = elem.nodeType ? "events" : "__events__",
1866      events = elemData[ eventKey ],
1867      eventHandle = elemData.handle;
1868     
1869    if ( typeof events === "function" ) {
1870      // On plain objects events is a fn that holds the the data
1871      // which prevents this data from being JSON serialized
1872      // the function does not need to be called, it just contains the data
1873      eventHandle = events.handle;
1874      events = events.events;
1875
1876    } else if ( !events ) {
1877      if ( !elem.nodeType ) {
1878        // On plain objects, create a fn that acts as the holder
1879        // of the values to avoid JSON serialization of event data
1880        elemData[ eventKey ] = elemData = function(){};
1881      }
1882
1883      elemData.events = events = {};
1884    }
1885
1886    if ( !eventHandle ) {
1887      elemData.handle = eventHandle = function() {
1888        // Handle the second event of a trigger and when
1889        // an event is called after a page has unloaded
1890        return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
1891          jQuery.event.handle.apply( eventHandle.elem, arguments ) :
1892          undefined;
1893      };
1894    }
1895
1896    // Add elem as a property of the handle function
1897    // This is to prevent a memory leak with non-native events in IE.
1898    eventHandle.elem = elem;
1899
1900    // Handle multiple events separated by a space
1901    // jQuery(...).bind("mouseover mouseout", fn);
1902    types = types.split(" ");
1903
1904    var type, i = 0, namespaces;
1905
1906    while ( (type = types[ i++ ]) ) {
1907      handleObj = handleObjIn ?
1908        jQuery.extend({}, handleObjIn) :
1909        { handler: handler, data: data };
1910
1911      // Namespaced event handlers
1912      if ( type.indexOf(".") > -1 ) {
1913        namespaces = type.split(".");
1914        type = namespaces.shift();
1915        handleObj.namespace = namespaces.slice(0).sort().join(".");
1916
1917      } else {
1918        namespaces = [];
1919        handleObj.namespace = "";
1920      }
1921
1922      handleObj.type = type;
1923      if ( !handleObj.guid ) {
1924        handleObj.guid = handler.guid;
1925      }
1926
1927      // Get the current list of functions bound to this event
1928      var handlers = events[ type ],
1929        special = jQuery.event.special[ type ] || {};
1930
1931      // Init the event handler queue
1932      if ( !handlers ) {
1933        handlers = events[ type ] = [];
1934
1935        // Check for a special event handler
1936        // Only use addEventListener/attachEvent if the special
1937        // events handler returns false
1938        if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
1939          // Bind the global event handler to the element
1940          if ( elem.addEventListener ) {
1941            elem.addEventListener( type, eventHandle, false );
1942
1943          } else if ( elem.attachEvent ) {
1944            elem.attachEvent( "on" + type, eventHandle );
1945          }
1946        }
1947      }
1948     
1949      if ( special.add ) { 
1950        special.add.call( elem, handleObj ); 
1951
1952        if ( !handleObj.handler.guid ) {
1953          handleObj.handler.guid = handler.guid;
1954        }
1955      }
1956
1957      // Add the function to the element's handler list
1958      handlers.push( handleObj );
1959
1960      // Keep track of which events have been used, for global triggering
1961      jQuery.event.global[ type ] = true;
1962    }
1963
1964    // Nullify elem to prevent memory leaks in IE
1965    elem = null;
1966  },
1967
1968  global: {},
1969
1970  // Detach an event or set of events from an element
1971  remove: function( elem, types, handler, pos ) {
1972    // don't do events on text and comment nodes
1973    if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
1974      return;
1975    }
1976
1977    if ( handler === false ) {
1978      handler = returnFalse;
1979    }
1980
1981    var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
1982      eventKey = elem.nodeType ? "events" : "__events__",
1983      elemData = jQuery.data( elem ),
1984      events = elemData && elemData[ eventKey ];
1985
1986    if ( !elemData || !events ) {
1987      return;
1988    }
1989   
1990    if ( typeof events === "function" ) {
1991      elemData = events;
1992      events = events.events;
1993    }
1994
1995    // types is actually an event object here
1996    if ( types && types.type ) {
1997      handler = types.handler;
1998      types = types.type;
1999    }
2000
2001    // Unbind all events for the element
2002    if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
2003      types = types || "";
2004
2005      for ( type in events ) {
2006        jQuery.event.remove( elem, type + types );
2007      }
2008
2009      return;
2010    }
2011
2012    // Handle multiple events separated by a space
2013    // jQuery(...).unbind("mouseover mouseout", fn);
2014    types = types.split(" ");
2015
2016    while ( (type = types[ i++ ]) ) {
2017      origType = type;
2018      handleObj = null;
2019      all = type.indexOf(".") < 0;
2020      namespaces = [];
2021
2022      if ( !all ) {
2023        // Namespaced event handlers
2024        namespaces = type.split(".");
2025        type = namespaces.shift();
2026
2027        namespace = new RegExp("(^|\\.)" + 
2028          jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2029      }
2030
2031      eventType = events[ type ];
2032
2033      if ( !eventType ) {
2034        continue;
2035      }
2036
2037      if ( !handler ) {
2038        for ( j = 0; j < eventType.length; j++ ) {
2039          handleObj = eventType[ j ];
2040
2041          if ( all || namespace.test( handleObj.namespace ) ) {
2042            jQuery.event.remove( elem, origType, handleObj.handler, j );
2043            eventType.splice( j--, 1 );
2044          }
2045        }
2046
2047        continue;
2048      }
2049
2050      special = jQuery.event.special[ type ] || {};
2051
2052      for ( j = pos || 0; j < eventType.length; j++ ) {
2053        handleObj = eventType[ j ];
2054
2055        if ( handler.guid === handleObj.guid ) {
2056          // remove the given handler for the given type
2057          if ( all || namespace.test( handleObj.namespace ) ) {
2058            if ( pos == null ) {
2059              eventType.splice( j--, 1 );
2060            }
2061
2062            if ( special.remove ) {
2063              special.remove.call( elem, handleObj );
2064            }
2065          }
2066
2067          if ( pos != null ) {
2068            break;
2069          }
2070        }
2071      }
2072
2073      // remove generic event handler if no more handlers exist
2074      if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
2075        if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2076          jQuery.removeEvent( elem, type, elemData.handle );
2077        }
2078
2079        ret = null;
2080        delete events[ type ];
2081      }
2082    }
2083
2084    // Remove the expando if it's no longer used
2085    if ( jQuery.isEmptyObject( events ) ) {
2086      var handle = elemData.handle;
2087      if ( handle ) {
2088        handle.elem = null;
2089      }
2090
2091      delete elemData.events;
2092      delete elemData.handle;
2093
2094      if ( typeof elemData === "function" ) {
2095        jQuery.removeData( elem, eventKey );
2096
2097      } else if ( jQuery.isEmptyObject( elemData ) ) {
2098        jQuery.removeData( elem );
2099      }
2100    }
2101  },
2102
2103  // bubbling is internal
2104  trigger: function( event, data, elem /*, bubbling */ ) {
2105    // Event object or event type
2106    var type = event.type || event,
2107      bubbling = arguments[3];
2108
2109    if ( !bubbling ) {
2110      event = typeof event === "object" ?
2111        // jQuery.Event object
2112        event[ jQuery.expando ] ? event :
2113        // Object literal
2114        jQuery.extend( jQuery.Event(type), event ) :
2115        // Just the event type (string)
2116        jQuery.Event(type);
2117
2118      if ( type.indexOf("!") >= 0 ) {
2119        event.type = type = type.slice(0, -1);
2120        event.exclusive = true;
2121      }
2122
2123      // Handle a global trigger
2124      if ( !elem ) {
2125        // Don't bubble custom events when global (to avoid too much overhead)
2126        event.stopPropagation();
2127
2128        // Only trigger if we've ever bound an event for it
2129        if ( jQuery.event.global[ type ] ) {
2130          jQuery.each( jQuery.cache, function() {
2131            if ( this.events && this.events[type] ) {
2132              jQuery.event.trigger( event, data, this.handle.elem );
2133            }
2134          });
2135        }
2136      }
2137
2138      // Handle triggering a single element
2139
2140      // don't do events on text and comment nodes
2141      if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
2142        return undefined;
2143      }
2144
2145      // Clean up in case it is reused
2146      event.result = undefined;
2147      event.target = elem;
2148
2149      // Clone the incoming data, if any
2150      data = jQuery.makeArray( data );
2151      data.unshift( event );
2152    }
2153
2154    event.currentTarget = elem;
2155
2156    // Trigger the event, it is assumed that "handle" is a function
2157    var handle = elem.nodeType ?
2158      jQuery.data( elem, "handle" ) :
2159      (jQuery.data( elem, "__events__" ) || {}).handle;
2160
2161    if ( handle ) {
2162      handle.apply( elem, data );
2163    }
2164
2165    var parent = elem.parentNode || elem.ownerDocument;
2166
2167    // Trigger an inline bound script
2168    try {
2169      if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
2170        if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
2171          event.result = false;
2172          event.preventDefault();
2173        }
2174      }
2175
2176    // prevent IE from throwing an error for some elements with some event types, see #3533
2177    } catch (inlineError) {}
2178
2179    if ( !event.isPropagationStopped() && parent ) {
2180      jQuery.event.trigger( event, data, parent, true );
2181
2182    } else if ( !event.isDefaultPrevented() ) {
2183      var old,
2184        target = event.target,
2185        targetType = type.replace( rnamespaces, "" ),
2186        isClick = jQuery.nodeName( target, "a" ) && targetType === "click",
2187        special = jQuery.event.special[ targetType ] || {};
2188
2189      if ( (!special._default || special._default.call( elem, event ) === false) && 
2190        !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
2191
2192        try {
2193          if ( target[ targetType ] ) {
2194            // Make sure that we don't accidentally re-trigger the onFOO events
2195            old = target[ "on" + targetType ];
2196
2197            if ( old ) {
2198              target[ "on" + targetType ] = null;
2199            }
2200
2201            jQuery.event.triggered = true;
2202            target[ targetType ]();
2203          }
2204
2205        // prevent IE from throwing an error for some elements with some event types, see #3533
2206        } catch (triggerError) {}
2207
2208        if ( old ) {
2209          target[ "on" + targetType ] = old;
2210        }
2211
2212        jQuery.event.triggered = false;
2213      }
2214    }
2215  },
2216
2217  handle: function( event ) {
2218    var all, handlers, namespaces, namespace_re, events,
2219      namespace_sort = [],
2220      args = jQuery.makeArray( arguments );
2221
2222    event = args[0] = jQuery.event.fix( event || window.event );
2223    event.currentTarget = this;
2224
2225    // Namespaced event handlers
2226    all = event.type.indexOf(".") < 0 && !event.exclusive;
2227
2228    if ( !all ) {
2229      namespaces = event.type.split(".");
2230      event.type = namespaces.shift();
2231      namespace_sort = namespaces.slice(0).sort();
2232      namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
2233    }
2234
2235    event.namespace = event.namespace || namespace_sort.join(".");
2236
2237    events = jQuery.data(this, this.nodeType ? "events" : "__events__");
2238
2239    if ( typeof events === "function" ) {
2240      events = events.events;
2241    }
2242
2243    handlers = (events || {})[ event.type ];
2244
2245    if ( events && handlers ) {
2246      // Clone the handlers to prevent manipulation
2247      handlers = handlers.slice(0);
2248
2249      for ( var j = 0, l = handlers.length; j < l; j++ ) {
2250        var handleObj = handlers[ j ];
2251
2252        // Filter the functions by class
2253        if ( all || namespace_re.test( handleObj.namespace ) ) {
2254          // Pass in a reference to the handler function itself
2255          // So that we can later remove it
2256          event.handler = handleObj.handler;
2257          event.data = handleObj.data;
2258          event.handleObj = handleObj;
2259 
2260          var ret = handleObj.handler.apply( this, args );
2261
2262          if ( ret !== undefined ) {
2263            event.result = ret;
2264            if ( ret === false ) {
2265              event.preventDefault();
2266              event.stopPropagation();
2267            }
2268          }
2269
2270          if ( event.isImmediatePropagationStopped() ) {
2271            break;
2272          }
2273        }
2274      }
2275    }
2276
2277    return event.result;
2278  },
2279
2280  props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
2281
2282  fix: function( event ) {
2283    if ( event[ jQuery.expando ] ) {
2284      return event;
2285    }
2286
2287    // store a copy of the original event object
2288    // and "clone" to set read-only properties
2289    var originalEvent = event;
2290    event = jQuery.Event( originalEvent );
2291
2292    for ( var i = this.props.length, prop; i; ) {
2293      prop = this.props[ --i ];
2294      event[ prop ] = originalEvent[ prop ];
2295    }
2296
2297    // Fix target property, if necessary
2298    if ( !event.target ) {
2299      // Fixes #1925 where srcElement might not be defined either
2300      event.target = event.srcElement || document;
2301    }
2302
2303    // check if target is a textnode (safari)
2304    if ( event.target.nodeType === 3 ) {
2305      event.target = event.target.parentNode;
2306    }
2307
2308    // Add relatedTarget, if necessary
2309    if ( !event.relatedTarget && event.fromElement ) {
2310      event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
2311    }
2312
2313    // Calculate pageX/Y if missing and clientX/Y available
2314    if ( event.pageX == null && event.clientX != null ) {
2315      var doc = document.documentElement,
2316        body = document.body;
2317
2318      event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
2319      event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
2320    }
2321
2322    // Add which for key events
2323    if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
2324      event.which = event.charCode != null ? event.charCode : event.keyCode;
2325    }
2326
2327    // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2328    if ( !event.metaKey && event.ctrlKey ) {
2329      event.metaKey = event.ctrlKey;
2330    }
2331
2332    // Add which for click: 1 === left; 2 === middle; 3 === right
2333    // Note: button is not normalized, so don't use it
2334    if ( !event.which && event.button !== undefined ) {
2335      event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2336    }
2337
2338    return event;
2339  },
2340
2341  // Deprecated, use jQuery.guid instead
2342  guid: 1E8,
2343
2344  // Deprecated, use jQuery.proxy instead
2345  proxy: jQuery.proxy,
2346
2347  special: {
2348    ready: {
2349      // Make sure the ready event is setup
2350      setup: jQuery.bindReady,
2351      teardown: jQuery.noop
2352    },
2353
2354    live: {
2355      add: function( handleObj ) {
2356        jQuery.event.add( this,
2357          liveConvert( handleObj.origType, handleObj.selector ),
2358          jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) ); 
2359      },
2360
2361      remove: function( handleObj ) {
2362        jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
2363      }
2364    },
2365
2366    beforeunload: {
2367      setup: function( data, namespaces, eventHandle ) {
2368        // We only want to do this special case on windows
2369        if ( jQuery.isWindow( this ) ) {
2370          this.onbeforeunload = eventHandle;
2371        }
2372      },
2373
2374      teardown: function( namespaces, eventHandle ) {
2375        if ( this.onbeforeunload === eventHandle ) {
2376          this.onbeforeunload = null;
2377        }
2378      }
2379    }
2380  }
2381};
2382
2383jQuery.removeEvent = document.removeEventListener ?
2384  function( elem, type, handle ) {
2385    if ( elem.removeEventListener ) {
2386      elem.removeEventListener( type, handle, false );
2387    }
2388  } : 
2389  function( elem, type, handle ) {
2390    if ( elem.detachEvent ) {
2391      elem.detachEvent( "on" + type, handle );
2392    }
2393  };
2394
2395jQuery.Event = function( src ) {
2396  // Allow instantiation without the 'new' keyword
2397  if ( !this.preventDefault ) {
2398    return new jQuery.Event( src );
2399  }
2400
2401  // Event object
2402  if ( src && src.type ) {
2403    this.originalEvent = src;
2404    this.type = src.type;
2405  // Event type
2406  } else {
2407    this.type = src;
2408  }
2409
2410  // timeStamp is buggy for some events on Firefox(#3843)
2411  // So we won't rely on the native value
2412  this.timeStamp = jQuery.now();
2413
2414  // Mark it as fixed
2415  this[ jQuery.expando ] = true;
2416};
2417
2418function returnFalse() {
2419  return false;
2420}
2421function returnTrue() {
2422  return true;
2423}
2424
2425// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2426// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2427jQuery.Event.prototype = {
2428  preventDefault: function() {
2429    this.isDefaultPrevented = returnTrue;
2430
2431    var e = this.originalEvent;
2432    if ( !e ) {
2433      return;
2434    }
2435   
2436    // if preventDefault exists run it on the original event
2437    if ( e.preventDefault ) {
2438      e.preventDefault();
2439
2440    // otherwise set the returnValue property of the original event to false (IE)
2441    } else {
2442      e.returnValue = false;
2443    }
2444  },
2445  stopPropagation: function() {
2446    this.isPropagationStopped = returnTrue;
2447
2448    var e = this.originalEvent;
2449    if ( !e ) {
2450      return;
2451    }
2452    // if stopPropagation exists run it on the original event
2453    if ( e.stopPropagation ) {
2454      e.stopPropagation();
2455    }
2456    // otherwise set the cancelBubble property of the original event to true (IE)
2457    e.cancelBubble = true;
2458  },
2459  stopImmediatePropagation: function() {
2460    this.isImmediatePropagationStopped = returnTrue;
2461    this.stopPropagation();
2462  },
2463  isDefaultPrevented: returnFalse,
2464  isPropagationStopped: returnFalse,
2465  isImmediatePropagationStopped: returnFalse
2466};
2467
2468// Checks if an event happened on an element within another element
2469// Used in jQuery.event.special.mouseenter and mouseleave handlers
2470var withinElement = function( event ) {
2471  // Check if mouse(over|out) are still within the same parent element
2472  var parent = event.relatedTarget;
2473
2474  // Firefox sometimes assigns relatedTarget a XUL element
2475  // which we cannot access the parentNode property of
2476  try {
2477    // Traverse up the tree
2478    while ( parent && parent !== this ) {
2479      parent = parent.parentNode;
2480    }
2481
2482    if ( parent !== this ) {
2483      // set the correct event type
2484      event.type = event.data;
2485
2486      // handle event if we actually just moused on to a non sub-element
2487      jQuery.event.handle.apply( this, arguments );
2488    }
2489
2490  // assuming we've left the element since we most likely mousedover a xul element
2491  } catch(e) { }
2492},
2493
2494// In case of event delegation, we only need to rename the event.type,
2495// liveHandler will take care of the rest.
2496delegate = function( event ) {
2497  event.type = event.data;
2498  jQuery.event.handle.apply( this, arguments );
2499};
2500
2501// Create mouseenter and mouseleave events
2502jQuery.each({
2503  mouseenter: "mouseover",
2504  mouseleave: "mouseout"
2505}, function( orig, fix ) {
2506  jQuery.event.special[ orig ] = {
2507    setup: function( data ) {
2508      jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
2509    },
2510    teardown: function( data ) {
2511      jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
2512    }
2513  };
2514});
2515
2516// submit delegation
2517if ( !jQuery.support.submitBubbles ) {
2518
2519  jQuery.event.special.submit = {
2520    setup: function( data, namespaces ) {
2521      if ( this.nodeName.toLowerCase() !== "form" ) {
2522        jQuery.event.add(this, "click.specialSubmit", function( e ) {
2523          var elem = e.target,
2524            type = elem.type;
2525
2526          if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
2527            e.liveFired = undefined;
2528            return trigger( "submit", this, arguments );
2529          }
2530        });
2531   
2532        jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
2533          var elem = e.target,
2534            type = elem.type;
2535
2536          if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
2537            e.liveFired = undefined;
2538            return trigger( "submit", this, arguments );
2539          }
2540        });
2541
2542      } else {
2543        return false;
2544      }
2545    },
2546
2547    teardown: function( namespaces ) {
2548      jQuery.event.remove( this, ".specialSubmit" );
2549    }
2550  };
2551
2552}
2553
2554// change delegation, happens here so we have bind.
2555if ( !jQuery.support.changeBubbles ) {
2556
2557  var changeFilters,
2558
2559  getVal = function( elem ) {
2560    var type = elem.type, val = elem.value;
2561
2562    if ( type === "radio" || type === "checkbox" ) {
2563      val = elem.checked;
2564
2565    } else if ( type === "select-multiple" ) {
2566      val = elem.selectedIndex > -1 ?
2567        jQuery.map( elem.options, function( elem ) {
2568          return elem.selected;
2569        }).join("-") :
2570        "";
2571
2572    } else if ( elem.nodeName.toLowerCase() === "select" ) {
2573      val = elem.selectedIndex;
2574    }
2575
2576    return val;
2577  },
2578
2579  testChange = function testChange( e ) {
2580    var elem = e.target, data, val;
2581
2582    if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
2583      return;
2584    }
2585
2586    data = jQuery.data( elem, "_change_data" );
2587    val = getVal(elem);
2588
2589    // the current data will be also retrieved by beforeactivate
2590    if ( e.type !== "focusout" || elem.type !== "radio" ) {
2591      jQuery.data( elem, "_change_data", val );
2592    }
2593   
2594    if ( data === undefined || val === data ) {
2595      return;
2596    }
2597
2598    if ( data != null || val ) {
2599      e.type = "change";
2600      e.liveFired = undefined;
2601      return jQuery.event.trigger( e, arguments[1], elem );
2602    }
2603  };
2604
2605  jQuery.event.special.change = {
2606    filters: {
2607      focusout: testChange, 
2608
2609      beforedeactivate: testChange,
2610
2611      click: function( e ) {
2612        var elem = e.target, type = elem.type;
2613
2614        if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
2615          return testChange.call( this, e );
2616        }
2617      },
2618
2619      // Change has to be called before submit
2620      // Keydown will be called before keypress, which is used in submit-event delegation
2621      keydown: function( e ) {
2622        var elem = e.target, type = elem.type;
2623
2624        if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
2625          (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
2626          type === "select-multiple" ) {
2627          return testChange.call( this, e );
2628        }
2629      },
2630
2631      // Beforeactivate happens also before the previous element is blurred
2632      // with this event you can't trigger a change event, but you can store
2633      // information
2634      beforeactivate: function( e ) {
2635        var elem = e.target;
2636        jQuery.data( elem, "_change_data", getVal(elem) );
2637      }
2638    },
2639
2640    setup: function( data, namespaces ) {
2641      if ( this.type === "file" ) {
2642        return false;
2643      }
2644
2645      for ( var type in changeFilters ) {
2646        jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
2647      }
2648
2649      return rformElems.test( this.nodeName );
2650    },
2651
2652    teardown: function( namespaces ) {
2653      jQuery.event.remove( this, ".specialChange" );
2654
2655      return rformElems.test( this.nodeName );
2656    }
2657  };
2658
2659  changeFilters = jQuery.event.special.change.filters;
2660
2661  // Handle when the input is .focus()'d
2662  changeFilters.focus = changeFilters.beforeactivate;
2663}
2664
2665function trigger( type, elem, args ) {
2666  args[0].type = type;
2667  return jQuery.event.handle.apply( elem, args );
2668}
2669
2670// Create "bubbling" focus and blur events
2671if ( document.addEventListener ) {
2672  jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
2673    jQuery.event.special[ fix ] = {
2674      setup: function() {
2675        if ( focusCounts[fix]++ === 0 ) {
2676          document.addEventListener( orig, handler, true );
2677        }
2678      }, 
2679      teardown: function() { 
2680        if ( --focusCounts[fix] === 0 ) {
2681          document.removeEventListener( orig, handler, true );
2682        }
2683      }
2684    };
2685
2686    function handler( e ) { 
2687      e = jQuery.event.fix( e );
2688      e.type = fix;
2689      return jQuery.event.trigger( e, null, e.target );
2690    }
2691  });
2692}
2693
2694jQuery.each(["bind", "one"], function( i, name ) {
2695  jQuery.fn[ name ] = function( type, data, fn ) {
2696    // Handle object literals
2697    if ( typeof type === "object" ) {
2698      for ( var key in type ) {
2699        this[ name ](key, data, type[key], fn);
2700      }
2701      return this;
2702    }
2703   
2704    if ( jQuery.isFunction( data ) || data === false ) {
2705      fn = data;
2706      data = undefined;
2707    }
2708
2709    var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
2710      jQuery( this ).unbind( event, handler );
2711      return fn.apply( this, arguments );
2712    }) : fn;
2713
2714    if ( type === "unload" && name !== "one" ) {
2715      this.one( type, data, fn );
2716
2717    } else {
2718      for ( var i = 0, l = this.length; i < l; i++ ) {
2719        jQuery.event.add( this[i], type, handler, data );
2720      }
2721    }
2722
2723    return this;
2724  };
2725});
2726
2727jQuery.fn.extend({
2728  unbind: function( type, fn ) {
2729    // Handle object literals
2730    if ( typeof type === "object" && !type.preventDefault ) {
2731      for ( var key in type ) {
2732        this.unbind(key, type[key]);
2733      }
2734
2735    } else {
2736      for ( var i = 0, l = this.length; i < l; i++ ) {
2737        jQuery.event.remove( this[i], type, fn );
2738      }
2739    }
2740
2741    return this;
2742  },
2743 
2744  delegate: function( selector, types, data, fn ) {
2745    return this.live( types, data, fn, selector );
2746  },
2747 
2748  undelegate: function( selector, types, fn ) {
2749    if ( arguments.length === 0 ) {
2750        return this.unbind( "live" );
2751   
2752    } else {
2753      return this.die( types, null, fn, selector );
2754    }
2755  },
2756 
2757  trigger: function( type, data ) {
2758    return this.each(function() {
2759      jQuery.event.trigger( type, data, this );
2760    });
2761  },
2762
2763  triggerHandler: function( type, data ) {
2764    if ( this[0] ) {
2765      var event = jQuery.Event( type );
2766      event.preventDefault();
2767      event.stopPropagation();
2768      jQuery.event.trigger( event, data, this[0] );
2769      return event.result;
2770    }
2771  },
2772
2773  toggle: function( fn ) {
2774    // Save reference to arguments for access in closure
2775    var args = arguments,
2776      i = 1;
2777
2778    // link all the functions, so any of them can unbind this click handler
2779    while ( i < args.length ) {
2780      jQuery.proxy( fn, args[ i++ ] );
2781    }
2782
2783    return this.click( jQuery.proxy( fn, function( event ) {
2784      // Figure out which function to execute
2785      var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
2786      jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
2787
2788      // Make sure that clicks stop
2789      event.preventDefault();
2790
2791      // and execute the function
2792      return args[ lastToggle ].apply( this, arguments ) || false;
2793    }));
2794  },
2795
2796  hover: function( fnOver, fnOut ) {
2797    return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
2798  }
2799});
2800
2801var liveMap = {
2802  focus: "focusin",
2803  blur: "focusout",
2804  mouseenter: "mouseover",
2805  mouseleave: "mouseout"
2806};
2807
2808jQuery.each(["live", "die"], function( i, name ) {
2809  jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
2810    var type, i = 0, match, namespaces, preType,
2811      selector = origSelector || this.selector,
2812      context = origSelector ? this : jQuery( this.context );
2813   
2814    if ( typeof types === "object" && !types.preventDefault ) {
2815      for ( var key in types ) {
2816        context[ name ]( key, data, types[key], selector );
2817      }
2818     
2819      return this;
2820    }
2821
2822    if ( jQuery.isFunction( data ) ) {
2823      fn = data;
2824      data = undefined;
2825    }
2826
2827    types = (types || "").split(" ");
2828
2829    while ( (type = types[ i++ ]) != null ) {
2830      match = rnamespaces.exec( type );
2831      namespaces = "";
2832
2833      if ( match )  {
2834        namespaces = match[0];
2835        type = type.replace( rnamespaces, "" );
2836      }
2837
2838      if ( type === "hover" ) {
2839        types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
2840        continue;
2841      }
2842
2843      preType = type;
2844
2845      if ( type === "focus" || type === "blur" ) {
2846        types.push( liveMap[ type ] + namespaces );
2847        type = type + namespaces;
2848
2849      } else {
2850        type = (liveMap[ type ] || type) + namespaces;
2851      }
2852
2853      if ( name === "live" ) {
2854        // bind live handler
2855        for ( var j = 0, l = context.length; j < l; j++ ) {
2856          jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
2857            { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
2858        }
2859
2860      } else {
2861        // unbind live handler
2862        context.unbind( "live." + liveConvert( type, selector ), fn );
2863      }
2864    }
2865   
2866    return this;
2867  };
2868});
2869
2870function liveHandler( event ) {
2871  var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
2872    elems = [],
2873    selectors = [],
2874    events = jQuery.data( this, this.nodeType ? "events" : "__events__" );
2875
2876  if ( typeof events === "function" ) {
2877    events = events.events;
2878  }
2879
2880  // Make sure we avoid non-left-click bubbling in Firefox (#3861)
2881  if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
2882    return;
2883  }
2884 
2885  if ( event.namespace ) {
2886    namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
2887  }
2888
2889  event.liveFired = this;
2890
2891  var live = events.live.slice(0);
2892
2893  for ( j = 0; j < live.length; j++ ) {
2894    handleObj = live[j];
2895
2896    if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
2897      selectors.push( handleObj.selector );
2898
2899    } else {
2900      live.splice( j--, 1 );
2901    }
2902  }
2903
2904  match = jQuery( event.target ).closest( selectors, event.currentTarget );
2905
2906  for ( i = 0, l = match.length; i < l; i++ ) {
2907    close = match[i];
2908
2909    for ( j = 0; j < live.length; j++ ) {
2910      handleObj = live[j];
2911
2912      if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) {
2913        elem = close.elem;
2914        related = null;
2915
2916        // Those two events require additional checking
2917        if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
2918          event.type = handleObj.preType;
2919          related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
2920        }
2921
2922        if ( !related || related !== elem ) {
2923          elems.push({ elem: elem, handleObj: handleObj, level: close.level });
2924        }
2925      }
2926    }
2927  }
2928
2929  for ( i = 0, l = elems.length; i < l; i++ ) {
2930    match = elems[i];
2931
2932    if ( maxLevel && match.level > maxLevel ) {
2933      break;
2934    }
2935
2936    event.currentTarget = match.elem;
2937    event.data = match.handleObj.data;
2938    event.handleObj = match.handleObj;
2939
2940    ret = match.handleObj.origHandler.apply( match.elem, arguments );
2941
2942    if ( ret === false || event.isPropagationStopped() ) {
2943      maxLevel = match.level;
2944
2945      if ( ret === false ) {
2946        stop = false;
2947      }
2948      if ( event.isImmediatePropagationStopped() ) {
2949        break;
2950      }
2951    }
2952  }
2953
2954  return stop;
2955}
2956
2957function liveConvert( type, selector ) {
2958  return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&");
2959}
2960
2961jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
2962  "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
2963  "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
2964
2965  // Handle event binding
2966  jQuery.fn[ name ] = function( data, fn ) {
2967    if ( fn == null ) {
2968      fn = data;
2969      data = null;
2970    }
2971
2972    return arguments.length > 0 ?
2973      this.bind( name, data, fn ) :
2974      this.trigger( name );
2975  };
2976
2977  if ( jQuery.attrFn ) {
2978    jQuery.attrFn[ name ] = true;
2979  }
2980});
2981
2982// Prevent memory leaks in IE
2983// Window isn't included so as not to unbind existing unload events
2984// More info:
2985//  - http://isaacschlueter.com/2006/10/msie-memory-leaks/
2986if ( window.attachEvent && !window.addEventListener ) {
2987  jQuery(window).bind("unload", function() {
2988    for ( var id in jQuery.cache ) {
2989      if ( jQuery.cache[ id ].handle ) {
2990        // Try/Catch is to handle iframes being unloaded, see #4280
2991        try {
2992          jQuery.event.remove( jQuery.cache[ id ].handle.elem );
2993        } catch(e) {}
2994      }
2995    }
2996  });
2997}
2998
2999
3000/*!
3001 * Sizzle CSS Selector Engine - v1.0
3002 *  Copyright 2009, The Dojo Foundation
3003 *  Released under the MIT, BSD, and GPL Licenses.
3004 *  More information: http://sizzlejs.com/
3005 */
3006(function(){
3007
3008var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3009  done = 0,
3010  toString = Object.prototype.toString,
3011  hasDuplicate = false,
3012  baseHasDuplicate = true;
3013
3014// Here we check if the JavaScript engine is using some sort of
3015// optimization where it does not always call our comparision
3016// function. If that is the case, discard the hasDuplicate value.
3017//   Thus far that includes Google Chrome.
3018[0, 0].sort(function() {
3019  baseHasDuplicate = false;
3020  return 0;
3021});
3022
3023var Sizzle = function( selector, context, results, seed ) {
3024  results = results || [];
3025  context = context || document;
3026
3027  var origContext = context;
3028
3029  if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3030    return [];
3031  }
3032 
3033  if ( !selector || typeof selector !== "string" ) {
3034    return results;
3035  }
3036
3037  var m, set, checkSet, extra, ret, cur, pop, i,
3038    prune = true,
3039    contextXML = Sizzle.isXML( context ),
3040    parts = [],
3041    soFar = selector;
3042 
3043  // Reset the position of the chunker regexp (start from head)
3044  do {
3045    chunker.exec( "" );
3046    m = chunker.exec( soFar );
3047
3048    if ( m ) {
3049      soFar = m[3];
3050   
3051      parts.push( m[1] );
3052   
3053      if ( m[2] ) {
3054        extra = m[3];
3055        break;
3056      }
3057    }
3058  } while ( m );
3059
3060  if ( parts.length > 1 && origPOS.exec( selector ) ) {
3061
3062    if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3063      set = posProcess( parts[0] + parts[1], context );
3064
3065    } else {
3066      set = Expr.relative[ parts[0] ] ?
3067        [ context ] :
3068        Sizzle( parts.shift(), context );
3069
3070      while ( parts.length ) {
3071        selector = parts.shift();
3072
3073        if ( Expr.relative[ selector ] ) {
3074          selector += parts.shift();
3075        }
3076       
3077        set = posProcess( selector, set );
3078      }
3079    }
3080
3081  } else {
3082    // Take a shortcut and set the context if the root selector is an ID
3083    // (but not if it'll be faster if the inner selector is an ID)
3084    if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
3085        Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
3086
3087      ret = Sizzle.find( parts.shift(), context, contextXML );
3088      context = ret.expr ?
3089        Sizzle.filter( ret.expr, ret.set )[0] :
3090        ret.set[0];
3091    }
3092
3093    if ( context ) {
3094      ret = seed ?
3095        { expr: parts.pop(), set: makeArray(seed) } :
3096        Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
3097
3098      set = ret.expr ?
3099        Sizzle.filter( ret.expr, ret.set ) :
3100        ret.set;
3101
3102      if ( parts.length > 0 ) {
3103        checkSet = makeArray( set );
3104
3105      } else {
3106        prune = false;
3107      }
3108
3109      while ( parts.length ) {
3110        cur = parts.pop();
3111        pop = cur;
3112
3113        if ( !Expr.relative[ cur ] ) {
3114          cur = "";
3115        } else {
3116          pop = parts.pop();
3117        }
3118
3119        if ( pop == null ) {
3120          pop = context;
3121        }
3122
3123        Expr.relative[ cur ]( checkSet, pop, contextXML );
3124      }
3125
3126    } else {
3127      checkSet = parts = [];
3128    }
3129  }
3130
3131  if ( !checkSet ) {
3132    checkSet = set;
3133  }
3134
3135  if ( !checkSet ) {
3136    Sizzle.error( cur || selector );
3137  }
3138
3139  if ( toString.call(checkSet) === "[object Array]" ) {
3140    if ( !prune ) {
3141      results.push.apply( results, checkSet );
3142
3143    } else if ( context && context.nodeType === 1 ) {
3144      for ( i = 0; checkSet[i] != null; i++ ) {
3145        if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
3146          results.push( set[i] );
3147        }
3148      }
3149
3150    } else {
3151      for ( i = 0; checkSet[i] != null; i++ ) {
3152        if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
3153          results.push( set[i] );
3154        }
3155      }
3156    }
3157
3158  } else {
3159    makeArray( checkSet, results );
3160  }
3161
3162  if ( extra ) {
3163    Sizzle( extra, origContext, results, seed );
3164    Sizzle.uniqueSort( results );
3165  }
3166
3167  return results;
3168};
3169
3170Sizzle.uniqueSort = function( results ) {
3171  if ( sortOrder ) {
3172    hasDuplicate = baseHasDuplicate;
3173    results.sort( sortOrder );
3174
3175    if ( hasDuplicate ) {
3176      for ( var i = 1; i < results.length; i++ ) {
3177        if ( results[i] === results[ i - 1 ] ) {
3178          results.splice( i--, 1 );
3179        }
3180      }
3181    }
3182  }
3183
3184  return results;
3185};
3186
3187Sizzle.matches = function( expr, set ) {
3188  return Sizzle( expr, null, null, set );
3189};
3190
3191Sizzle.matchesSelector = function( node, expr ) {
3192  return Sizzle( expr, null, null, [node] ).length > 0;
3193};
3194
3195Sizzle.find = function( expr, context, isXML ) {
3196  var set;
3197
3198  if ( !expr ) {
3199    return [];
3200  }
3201
3202  for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
3203    var match,
3204      type = Expr.order[i];
3205   
3206    if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
3207      var left = match[1];
3208      match.splice( 1, 1 );
3209
3210      if ( left.substr( left.length - 1 ) !== "\\" ) {
3211        match[1] = (match[1] || "").replace(/\\/g, "");
3212        set = Expr.find[ type ]( match, context, isXML );
3213
3214        if ( set != null ) {
3215          expr = expr.replace( Expr.match[ type ], "" );
3216          break;
3217        }
3218      }
3219    }
3220  }
3221
3222  if ( !set ) {
3223    set = context.getElementsByTagName( "*" );
3224  }
3225
3226  return { set: set, expr: expr };
3227};
3228
3229Sizzle.filter = function( expr, set, inplace, not ) {
3230  var match, anyFound,
3231    old = expr,
3232    result = [],
3233    curLoop = set,
3234    isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
3235
3236  while ( expr && set.length ) {
3237    for ( var type in Expr.filter ) {
3238      if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
3239        var found, item,
3240          filter = Expr.filter[ type ],
3241          left = match[1];
3242
3243        anyFound = false;
3244
3245        match.splice(1,1);
3246
3247        if ( left.substr( left.length - 1 ) === "\\" ) {
3248          continue;
3249        }
3250
3251        if ( curLoop === result ) {
3252          result = [];
3253        }
3254
3255        if ( Expr.preFilter[ type ] ) {
3256          match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
3257
3258          if ( !match ) {
3259            anyFound = found = true;
3260
3261          } else if ( match === true ) {
3262            continue;
3263          }
3264        }
3265
3266        if ( match ) {
3267          for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
3268            if ( item ) {
3269              found = filter( item, match, i, curLoop );
3270              var pass = not ^ !!found;
3271
3272              if ( inplace && found != null ) {
3273                if ( pass ) {
3274                  anyFound = true;
3275
3276                } else {
3277                  curLoop[i] = false;
3278                }
3279
3280              } else if ( pass ) {
3281                result.push( item );
3282                anyFound = true;
3283              }
3284            }
3285          }
3286        }
3287
3288        if ( found !== undefined ) {
3289          if ( !inplace ) {
3290            curLoop = result;
3291          }
3292
3293          expr = expr.replace( Expr.match[ type ], "" );
3294
3295          if ( !anyFound ) {
3296            return [];
3297          }
3298
3299          break;
3300        }
3301      }
3302    }
3303
3304    // Improper expression
3305    if ( expr === old ) {
3306      if ( anyFound == null ) {
3307        Sizzle.error( expr );
3308
3309      } else {
3310        break;
3311      }
3312    }
3313
3314    old = expr;
3315  }
3316
3317  return curLoop;
3318};
3319
3320Sizzle.error = function( msg ) {
3321  throw "Syntax error, unrecognized expression: " + msg;
3322};
3323
3324var Expr = Sizzle.selectors = {
3325  order: [ "ID", "NAME", "TAG" ],
3326
3327  match: {
3328    ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3329    CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3330    NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
3331    ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
3332    TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
3333    CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
3334    POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
3335    PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
3336  },
3337
3338  leftMatch: {},
3339
3340  attrMap: {
3341    "class": "className",
3342    "for": "htmlFor"
3343  },
3344
3345  attrHandle: {
3346    href: function( elem ) {
3347      return elem.getAttribute( "href" );
3348    }
3349  },
3350
3351  relative: {
3352    "+": function(checkSet, part){
3353      var isPartStr = typeof part === "string",
3354        isTag = isPartStr && !/\W/.test( part ),
3355        isPartStrNotTag = isPartStr && !isTag;
3356
3357      if ( isTag ) {
3358        part = part.toLowerCase();
3359      }
3360
3361      for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
3362        if ( (elem = checkSet[i]) ) {
3363          while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
3364
3365          checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
3366            elem || false :
3367            elem === part;
3368        }
3369      }
3370
3371      if ( isPartStrNotTag ) {
3372        Sizzle.filter( part, checkSet, true );
3373      }
3374    },
3375
3376    ">": function( checkSet, part ) {
3377      var elem,
3378        isPartStr = typeof part === "string",
3379        i = 0,
3380        l = checkSet.length;
3381
3382      if ( isPartStr && !/\W/.test( part ) ) {
3383        part = part.toLowerCase();
3384
3385        for ( ; i < l; i++ ) {
3386          elem = checkSet[i];
3387
3388          if ( elem ) {
3389            var parent = elem.parentNode;
3390            checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
3391          }
3392        }
3393
3394      } else {
3395        for ( ; i < l; i++ ) {
3396          elem = checkSet[i];
3397
3398          if ( elem ) {
3399            checkSet[i] = isPartStr ?
3400              elem.parentNode :
3401              elem.parentNode === part;
3402          }
3403        }
3404
3405        if ( isPartStr ) {
3406          Sizzle.filter( part, checkSet, true );
3407        }
3408      }
3409    },
3410
3411    "": function(checkSet, part, isXML){
3412      var nodeCheck,
3413        doneName = done++,
3414        checkFn = dirCheck;
3415
3416      if ( typeof part === "string" && !/\W/.test(part) ) {
3417        part = part.toLowerCase();
3418        nodeCheck = part;
3419        checkFn = dirNodeCheck;
3420      }
3421
3422      checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
3423    },
3424
3425    "~": function( checkSet, part, isXML ) {
3426      var nodeCheck,
3427        doneName = done++,
3428        checkFn = dirCheck;
3429
3430      if ( typeof part === "string" && !/\W/.test( part ) ) {
3431        part = part.toLowerCase();
3432        nodeCheck = part;
3433        checkFn = dirNodeCheck;
3434      }
3435
3436      checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
3437    }
3438  },
3439
3440  find: {
3441    ID: function( match, context, isXML ) {
3442      if ( typeof context.getElementById !== "undefined" && !isXML ) {
3443        var m = context.getElementById(match[1]);
3444        // Check parentNode to catch when Blackberry 4.6 returns
3445        // nodes that are no longer in the document #6963
3446        return m && m.parentNode ? [m] : [];
3447      }
3448    },
3449
3450    NAME: function( match, context ) {
3451      if ( typeof context.getElementsByName !== "undefined" ) {
3452        var ret = [],
3453          results = context.getElementsByName( match[1] );
3454
3455        for ( var i = 0, l = results.length; i < l; i++ ) {
3456          if ( results[i].getAttribute("name") === match[1] ) {
3457            ret.push( results[i] );
3458          }
3459        }
3460
3461        return ret.length === 0 ? null : ret;
3462      }
3463    },
3464
3465    TAG: function( match, context ) {
3466      return context.getElementsByTagName( match[1] );
3467    }
3468  },
3469  preFilter: {
3470    CLASS: function( match, curLoop, inplace, result, not, isXML ) {
3471      match = " " + match[1].replace(/\\/g, "") + " ";
3472
3473      if ( isXML ) {
3474        return match;
3475      }
3476
3477      for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
3478        if ( elem ) {
3479          if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
3480            if ( !inplace ) {
3481              result.push( elem );
3482            }
3483
3484          } else if ( inplace ) {
3485            curLoop[i] = false;
3486          }
3487        }
3488      }
3489
3490      return false;
3491    },
3492
3493    ID: function( match ) {
3494      return match[1].replace(/\\/g, "");
3495    },
3496
3497    TAG: function( match, curLoop ) {
3498      return match[1].toLowerCase();
3499    },
3500
3501    CHILD: function( match ) {
3502      if ( match[1] === "nth" ) {
3503        // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
3504        var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
3505          match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
3506          !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
3507
3508        // calculate the numbers (first)n+(last) including if they are negative
3509        match[2] = (test[1] + (test[2] || 1)) - 0;
3510        match[3] = test[3] - 0;
3511      }
3512
3513      // TODO: Move to normal caching system
3514      match[0] = done++;
3515
3516      return match;
3517    },
3518
3519    ATTR: function( match, curLoop, inplace, result, not, isXML ) {
3520      var name = match[1].replace(/\\/g, "");
3521     
3522      if ( !isXML && Expr.attrMap[name] ) {
3523        match[1] = Expr.attrMap[name];
3524      }
3525
3526      if ( match[2] === "~=" ) {
3527        match[4] = " " + match[4] + " ";
3528      }
3529
3530      return match;
3531    },
3532
3533    PSEUDO: function( match, curLoop, inplace, result, not ) {
3534      if ( match[1] === "not" ) {
3535        // If we're dealing with a complex expression, or a simple one
3536        if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
3537          match[3] = Sizzle(match[3], null, null, curLoop);
3538
3539        } else {
3540          var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
3541
3542          if ( !inplace ) {
3543            result.push.apply( result, ret );
3544          }
3545
3546          return false;
3547        }
3548
3549      } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
3550        return true;
3551      }
3552     
3553      return match;
3554    },
3555
3556    POS: function( match ) {
3557      match.unshift( true );
3558
3559      return match;
3560    }
3561  },
3562 
3563  filters: {
3564    enabled: function( elem ) {
3565      return elem.disabled === false && elem.type !== "hidden";
3566    },
3567
3568    disabled: function( elem ) {
3569      return elem.disabled === true;
3570    },
3571
3572    checked: function( elem ) {
3573      return elem.checked === true;
3574    },
3575   
3576    selected: function( elem ) {
3577      // Accessing this property makes selected-by-default
3578      // options in Safari work properly
3579      elem.parentNode.selectedIndex;
3580     
3581      return elem.selected === true;
3582    },
3583
3584    parent: function( elem ) {
3585      return !!elem.firstChild;
3586    },
3587
3588    empty: function( elem ) {
3589      return !elem.firstChild;
3590    },
3591
3592    has: function( elem, i, match ) {
3593      return !!Sizzle( match[3], elem ).length;
3594    },
3595
3596    header: function( elem ) {
3597      return (/h\d/i).test( elem.nodeName );
3598    },
3599
3600    text: function( elem ) {
3601      return "text" === elem.type;
3602    },
3603    radio: function( elem ) {
3604      return "radio" === elem.type;
3605    },
3606
3607    checkbox: function( elem ) {
3608      return "checkbox" === elem.type;
3609    },
3610
3611    file: function( elem ) {
3612      return "file" === elem.type;
3613    },
3614    password: function( elem ) {
3615      return "password" === elem.type;
3616    },
3617
3618    submit: function( elem ) {
3619      return "submit" === elem.type;
3620    },
3621
3622    image: function( elem ) {
3623      return "image" === elem.type;
3624    },
3625
3626    reset: function( elem ) {
3627      return "reset" === elem.type;
3628    },
3629
3630    button: function( elem ) {
3631      return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
3632    },
3633
3634    input: function( elem ) {
3635      return (/input|select|textarea|button/i).test( elem.nodeName );
3636    }
3637  },
3638  setFilters: {
3639    first: function( elem, i ) {
3640      return i === 0;
3641    },
3642
3643    last: function( elem, i, match, array ) {
3644      return i === array.length - 1;
3645    },
3646
3647    even: function( elem, i ) {
3648      return i % 2 === 0;
3649    },
3650
3651    odd: function( elem, i ) {
3652      return i % 2 === 1;
3653    },
3654
3655    lt: function( elem, i, match ) {
3656      return i < match[3] - 0;
3657    },
3658
3659    gt: function( elem, i, match ) {
3660      return i > match[3] - 0;
3661    },
3662
3663    nth: function( elem, i, match ) {
3664      return match[3] - 0 === i;
3665    },
3666
3667    eq: function( elem, i, match ) {
3668      return match[3] - 0 === i;
3669    }
3670  },
3671  filter: {
3672    PSEUDO: function( elem, match, i, array ) {
3673      var name = match[1],
3674        filter = Expr.filters[ name ];
3675
3676      if ( filter ) {
3677        return filter( elem, i, match, array );
3678
3679      } else if ( name === "contains" ) {
3680        return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
3681
3682      } else if ( name === "not" ) {
3683        var not = match[3];
3684
3685        for ( var j = 0, l = not.length; j < l; j++ ) {
3686          if ( not[j] === elem ) {
3687            return false;
3688          }
3689        }
3690
3691        return true;
3692
3693      } else {
3694        Sizzle.error( "Syntax error, unrecognized expression: " + name );
3695      }
3696    },
3697
3698    CHILD: function( elem, match ) {
3699      var type = match[1],
3700        node = elem;
3701
3702      switch ( type ) {
3703        case "only":
3704        case "first":
3705          while ( (node = node.previousSibling) )  {
3706            if ( node.nodeType === 1 ) { 
3707              return false; 
3708            }
3709          }
3710
3711          if ( type === "first" ) { 
3712            return true; 
3713          }
3714
3715          node = elem;
3716
3717        case "last":
3718          while ( (node = node.nextSibling) )  {
3719            if ( node.nodeType === 1 ) { 
3720              return false; 
3721            }
3722          }
3723
3724          return true;
3725
3726        case "nth":
3727          var first = match[2],
3728            last = match[3];
3729
3730          if ( first === 1 && last === 0 ) {
3731            return true;
3732          }
3733         
3734          var doneName = match[0],
3735            parent = elem.parentNode;
3736 
3737          if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
3738            var count = 0;
3739           
3740            for ( node = parent.firstChild; node; node = node.nextSibling ) {
3741              if ( node.nodeType === 1 ) {
3742                node.nodeIndex = ++count;
3743              }
3744            } 
3745
3746            parent.sizcache = doneName;
3747          }
3748         
3749          var diff = elem.nodeIndex - last;
3750
3751          if ( first === 0 ) {
3752            return diff === 0;
3753
3754          } else {
3755            return ( diff % first === 0 && diff / first >= 0 );
3756          }
3757      }
3758    },
3759
3760    ID: function( elem, match ) {
3761      return elem.nodeType === 1 && elem.getAttribute("id") === match;
3762    },
3763
3764    TAG: function( elem, match ) {
3765      return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
3766    },
3767   
3768    CLASS: function( elem, match ) {
3769      return (" " + (elem.className || elem.getAttribute("class")) + " ")
3770        .indexOf( match ) > -1;
3771    },
3772
3773    ATTR: function( elem, match ) {
3774      var name = match[1],
3775        result = Expr.attrHandle[ name ] ?
3776          Expr.attrHandle[ name ]( elem ) :
3777          elem[ name ] != null ?
3778            elem[ name ] :
3779            elem.getAttribute( name ),
3780        value = result + "",
3781        type = match[2],
3782        check = match[4];
3783
3784      return result == null ?
3785        type === "!=" :
3786        type === "=" ?
3787        value === check :
3788        type === "*=" ?
3789        value.indexOf(check) >= 0 :
3790        type === "~=" ?
3791        (" " + value + " ").indexOf(check) >= 0 :
3792        !check ?
3793        value && result !== false :
3794        type === "!=" ?
3795        value !== check :
3796        type === "^=" ?
3797        value.indexOf(check) === 0 :
3798        type === "$=" ?
3799        value.substr(value.length - check.length) === check :
3800        type === "|=" ?
3801        value === check || value.substr(0, check.length + 1) === check + "-" :
3802        false;
3803    },
3804
3805    POS: function( elem, match, i, array ) {
3806      var name = match[2],
3807        filter = Expr.setFilters[ name ];
3808
3809      if ( filter ) {
3810        return filter( elem, i, match, array );
3811      }
3812    }
3813  }
3814};
3815
3816var origPOS = Expr.match.POS,
3817  fescape = function(all, num){
3818    return "\\" + (num - 0 + 1);
3819  };
3820
3821for ( var type in Expr.match ) {
3822  Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
3823  Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
3824}
3825
3826var makeArray = function( array, results ) {
3827  array = Array.prototype.slice.call( array, 0 );
3828
3829  if ( results ) {
3830    results.push.apply( results, array );
3831    return results;
3832  }
3833 
3834  return array;
3835};
3836
3837// Perform a simple check to determine if the browser is capable of
3838// converting a NodeList to an array using builtin methods.
3839// Also verifies that the returned array holds DOM nodes
3840// (which is not the case in the Blackberry browser)
3841try {
3842  Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
3843
3844// Provide a fallback method if it does not work
3845} catch( e ) {
3846  makeArray = function( array, results ) {
3847    var i = 0,
3848      ret = results || [];
3849
3850    if ( toString.call(array) === "[object Array]" ) {
3851      Array.prototype.push.apply( ret, array );
3852
3853    } else {
3854      if ( typeof array.length === "number" ) {
3855        for ( var l = array.length; i < l; i++ ) {
3856          ret.push( array[i] );
3857        }
3858
3859      } else {
3860        for ( ; array[i]; i++ ) {
3861          ret.push( array[i] );
3862        }
3863      }
3864    }
3865
3866    return ret;
3867  };
3868}
3869
3870var sortOrder, siblingCheck;
3871
3872if ( document.documentElement.compareDocumentPosition ) {
3873  sortOrder = function( a, b ) {
3874    if ( a === b ) {
3875      hasDuplicate = true;
3876      return 0;
3877    }
3878
3879    if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
3880      return a.compareDocumentPosition ? -1 : 1;
3881    }
3882
3883    return a.compareDocumentPosition(b) & 4 ? -1 : 1;
3884  };
3885
3886} else {
3887  sortOrder = function( a, b ) {
3888    var al, bl,
3889      ap = [],
3890      bp = [],
3891      aup = a.parentNode,
3892      bup = b.parentNode,
3893      cur = aup;
3894
3895    // The nodes are identical, we can exit early
3896    if ( a === b ) {
3897      hasDuplicate = true;
3898      return 0;
3899
3900    // If the nodes are siblings (or identical) we can do a quick check
3901    } else if ( aup === bup ) {
3902      return siblingCheck( a, b );
3903
3904    // If no parents were found then the nodes are disconnected
3905    } else if ( !aup ) {
3906      return -1;
3907
3908    } else if ( !bup ) {
3909      return 1;
3910    }
3911
3912    // Otherwise they're somewhere else in the tree so we need
3913    // to build up a full list of the parentNodes for comparison
3914    while ( cur ) {
3915      ap.unshift( cur );
3916      cur = cur.parentNode;
3917    }
3918
3919    cur = bup;
3920
3921    while ( cur ) {
3922      bp.unshift( cur );
3923      cur = cur.parentNode;
3924    }
3925
3926    al = ap.length;
3927    bl = bp.length;
3928
3929    // Start walking down the tree looking for a discrepancy
3930    for ( var i = 0; i < al && i < bl; i++ ) {
3931      if ( ap[i] !== bp[i] ) {
3932        return siblingCheck( ap[i], bp[i] );
3933      }
3934    }
3935
3936    // We ended someplace up the tree so do a sibling check
3937    return i === al ?
3938      siblingCheck( a, bp[i], -1 ) :
3939      siblingCheck( ap[i], b, 1 );
3940  };
3941
3942  siblingCheck = function( a, b, ret ) {
3943    if ( a === b ) {
3944      return ret;
3945    }
3946
3947    var cur = a.nextSibling;
3948
3949    while ( cur ) {
3950      if ( cur === b ) {
3951        return -1;
3952      }
3953
3954      cur = cur.nextSibling;
3955    }
3956
3957    return 1;
3958  };
3959}
3960
3961// Utility function for retreiving the text value of an array of DOM nodes
3962Sizzle.getText = function( elems ) {
3963  var ret = "", elem;
3964
3965  for ( var i = 0; elems[i]; i++ ) {
3966    elem = elems[i];
3967
3968    // Get the text from text nodes and CDATA nodes
3969    if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
3970      ret += elem.nodeValue;
3971
3972    // Traverse everything else, except comment nodes
3973    } else if ( elem.nodeType !== 8 ) {
3974      ret += Sizzle.getText( elem.childNodes );
3975    }
3976  }
3977
3978  return ret;
3979};
3980
3981// Check to see if the browser returns elements by name when
3982// querying by getElementById (and provide a workaround)
3983(function(){
3984  // We're going to inject a fake input element with a specified name
3985  var form = document.createElement("div"),
3986    id = "script" + (new Date()).getTime(),
3987    root = document.documentElement;
3988
3989  form.innerHTML = "<a name='" + id + "'/>";
3990
3991  // Inject it into the root element, check its status, and remove it quickly
3992  root.insertBefore( form, root.firstChild );
3993
3994  // The workaround has to do additional checks after a getElementById
3995  // Which slows things down for other browsers (hence the branching)
3996  if ( document.getElementById( id ) ) {
3997    Expr.find.ID = function( match, context, isXML ) {
3998      if ( typeof context.getElementById !== "undefined" && !isXML ) {
3999        var m = context.getElementById(match[1]);
4000
4001        return m ?
4002          m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
4003            [m] :
4004            undefined :
4005          [];
4006      }
4007    };
4008
4009    Expr.filter.ID = function( elem, match ) {
4010      var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4011
4012      return elem.nodeType === 1 && node && node.nodeValue === match;
4013    };
4014  }
4015
4016  root.removeChild( form );
4017
4018  // release memory in IE
4019  root = form = null;
4020})();
4021
4022(function(){
4023  // Check to see if the browser returns only elements
4024  // when doing getElementsByTagName("*")
4025
4026  // Create a fake element
4027  var div = document.createElement("div");
4028  div.appendChild( document.createComment("") );
4029
4030  // Make sure no comments are found
4031  if ( div.getElementsByTagName("*").length > 0 ) {
4032    Expr.find.TAG = function( match, context ) {
4033      var results = context.getElementsByTagName( match[1] );
4034
4035      // Filter out possible comments
4036      if ( match[1] === "*" ) {
4037        var tmp = [];
4038
4039        for ( var i = 0; results[i]; i++ ) {
4040          if ( results[i].nodeType === 1 ) {
4041            tmp.push( results[i] );
4042          }
4043        }
4044
4045        results = tmp;
4046      }
4047
4048      return results;
4049    };
4050  }
4051
4052  // Check to see if an attribute returns normalized href attributes
4053  div.innerHTML = "<a href='#'></a>";
4054
4055  if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4056      div.firstChild.getAttribute("href") !== "#" ) {
4057
4058    Expr.attrHandle.href = function( elem ) {
4059      return elem.getAttribute( "href", 2 );
4060    };
4061  }
4062
4063  // release memory in IE
4064  div = null;
4065})();
4066
4067if ( document.querySelectorAll ) {
4068  (function(){
4069    var oldSizzle = Sizzle,
4070      div = document.createElement("div"),
4071      id = "__sizzle__";
4072
4073    div.innerHTML = "<p class='TEST'></p>";
4074
4075    // Safari can't handle uppercase or unicode characters when
4076    // in quirks mode.
4077    if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4078      return;
4079    }
4080 
4081    Sizzle = function( query, context, extra, seed ) {
4082      context = context || document;
4083
4084      // Make sure that attribute selectors are quoted
4085      query = query.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4086
4087      // Only use querySelectorAll on non-XML documents
4088      // (ID selectors don't work in non-HTML documents)
4089      if ( !seed && !Sizzle.isXML(context) ) {
4090        if ( context.nodeType === 9 ) {
4091          try {
4092            return makeArray( context.querySelectorAll(query), extra );
4093          } catch(qsaError) {}
4094
4095        // qSA works strangely on Element-rooted queries
4096        // We can work around this by specifying an extra ID on the root
4097        // and working up from there (Thanks to Andrew Dupont for the technique)
4098        // IE 8 doesn't work on object elements
4099        } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
4100          var old = context.getAttribute( "id" ),
4101            nid = old || id;
4102
4103          if ( !old ) {
4104            context.setAttribute( "id", nid );
4105          }
4106
4107          try {
4108            return makeArray( context.querySelectorAll( "#" + nid + " " + query ), extra );
4109
4110          } catch(pseudoError) {
4111          } finally {
4112            if ( !old ) {
4113              context.removeAttribute( "id" );
4114            }
4115          }
4116        }
4117      }
4118   
4119      return oldSizzle(query, context, extra, seed);
4120    };
4121
4122    for ( var prop in oldSizzle ) {
4123      Sizzle[ prop ] = oldSizzle[ prop ];
4124    }
4125
4126    // release memory in IE
4127    div = null;
4128  })();
4129}
4130
4131(function(){
4132  var html = document.documentElement,
4133    matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector,
4134    pseudoWorks = false;
4135
4136  try {
4137    // This should fail with an exception
4138    // Gecko does not error, returns false instead
4139    matches.call( document.documentElement, "[test!='']:sizzle" );
4140 
4141  } catch( pseudoError ) {
4142    pseudoWorks = true;
4143  }
4144
4145  if ( matches ) {
4146    Sizzle.matchesSelector = function( node, expr ) {
4147      // Make sure that attribute selectors are quoted
4148      expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4149
4150      if ( !Sizzle.isXML( node ) ) {
4151        try { 
4152          if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
4153            return matches.call( node, expr );
4154          }
4155        } catch(e) {}
4156      }
4157
4158      return Sizzle(expr, null, null, [node]).length > 0;
4159    };
4160  }
4161})();
4162
4163(function(){
4164  var div = document.createElement("div");
4165
4166  div.innerHTML = "<div class='test e'></div><div class='test'></div>";
4167
4168  // Opera can't find a second classname (in 9.6)
4169  // Also, make sure that getElementsByClassName actually exists
4170  if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
4171    return;
4172  }
4173
4174  // Safari caches class attributes, doesn't catch changes (in 3.2)
4175  div.lastChild.className = "e";
4176
4177  if ( div.getElementsByClassName("e").length === 1 ) {
4178    return;
4179  }
4180 
4181  Expr.order.splice(1, 0, "CLASS");
4182  Expr.find.CLASS = function( match, context, isXML ) {
4183    if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
4184      return context.getElementsByClassName(match[1]);
4185    }
4186  };
4187
4188  // release memory in IE
4189  div = null;
4190})();
4191
4192function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4193  for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4194    var elem = checkSet[i];
4195
4196    if ( elem ) {
4197      var match = false;
4198
4199      elem = elem[dir];
4200
4201      while ( elem ) {
4202        if ( elem.sizcache === doneName ) {
4203          match = checkSet[elem.sizset];
4204          break;
4205        }
4206
4207        if ( elem.nodeType === 1 && !isXML ){
4208          elem.sizcache = doneName;
4209          elem.sizset = i;
4210        }
4211
4212        if ( elem.nodeName.toLowerCase() === cur ) {
4213          match = elem;
4214          break;
4215        }
4216
4217        elem = elem[dir];
4218      }
4219
4220      checkSet[i] = match;
4221    }
4222  }
4223}
4224
4225function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4226  for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4227    var elem = checkSet[i];
4228
4229    if ( elem ) {
4230      var match = false;
4231     
4232      elem = elem[dir];
4233
4234      while ( elem ) {
4235        if ( elem.sizcache === doneName ) {
4236          match = checkSet[elem.sizset];
4237          break;
4238        }
4239
4240        if ( elem.nodeType === 1 ) {
4241          if ( !isXML ) {
4242            elem.sizcache = doneName;
4243            elem.sizset = i;
4244          }
4245
4246          if ( typeof cur !== "string" ) {
4247            if ( elem === cur ) {
4248              match = true;
4249              break;
4250            }
4251
4252          } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
4253            match = elem;
4254            break;
4255          }
4256        }
4257
4258        elem = elem[dir];
4259      }
4260
4261      checkSet[i] = match;
4262    }
4263  }
4264}
4265
4266if ( document.documentElement.contains ) {
4267  Sizzle.contains = function( a, b ) {
4268    return a !== b && (a.contains ? a.contains(b) : true);
4269  };
4270
4271} else if ( document.documentElement.compareDocumentPosition ) {
4272  Sizzle.contains = function( a, b ) {
4273    return !!(a.compareDocumentPosition(b) & 16);
4274  };
4275
4276} else {
4277  Sizzle.contains = function() {
4278    return false;
4279  };
4280}
4281
4282Sizzle.isXML = function( elem ) {
4283  // documentElement is verified for cases where it doesn't yet exist
4284  // (such as loading iframes in IE - #4833)
4285  var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
4286
4287  return documentElement ? documentElement.nodeName !== "HTML" : false;
4288};
4289
4290var posProcess = function( selector, context ) {
4291  var match,
4292    tmpSet = [],
4293    later = "",
4294    root = context.nodeType ? [context] : context;
4295
4296  // Position selectors must be done after the filter
4297  // And so must :not(positional) so we move all PSEUDOs to the end
4298  while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
4299    later += match[0];
4300    selector = selector.replace( Expr.match.PSEUDO, "" );
4301  }
4302
4303  selector = Expr.relative[selector] ? selector + "*" : selector;
4304
4305  for ( var i = 0, l = root.length; i < l; i++ ) {
4306    Sizzle( selector, root[i], tmpSet );
4307  }
4308
4309  return Sizzle.filter( later, tmpSet );
4310};
4311
4312// EXPOSE
4313jQuery.find = Sizzle;
4314jQuery.expr = Sizzle.selectors;
4315jQuery.expr[":"] = jQuery.expr.filters;
4316jQuery.unique = Sizzle.uniqueSort;
4317jQuery.text = Sizzle.getText;
4318jQuery.isXMLDoc = Sizzle.isXML;
4319jQuery.contains = Sizzle.contains;
4320
4321
4322})();
4323
4324
4325var runtil = /Until$/,
4326  rparentsprev = /^(?:parents|prevUntil|prevAll)/,
4327  // Note: This RegExp should be improved, or likely pulled from Sizzle
4328  rmultiselector = /,/,
4329  isSimple = /^.[^:#\[\.,]*$/,
4330  slice = Array.prototype.slice,
4331  POS = jQuery.expr.match.POS;
4332
4333jQuery.fn.extend({
4334  find: function( selector ) {
4335    var ret = this.pushStack( "", "find", selector ),
4336      length = 0;
4337
4338    for ( var i = 0, l = this.length; i < l; i++ ) {
4339      length = ret.length;
4340      jQuery.find( selector, this[i], ret );
4341
4342      if ( i > 0 ) {
4343        // Make sure that the results are unique
4344        for ( var n = length; n < ret.length; n++ ) {
4345          for ( var r = 0; r < length; r++ ) {
4346            if ( ret[r] === ret[n] ) {
4347              ret.splice(n--, 1);
4348              break;
4349            }
4350          }
4351        }
4352      }
4353    }
4354
4355    return ret;
4356  },
4357
4358  has: function( target ) {
4359    var targets = jQuery( target );
4360    return this.filter(function() {
4361      for ( var i = 0, l = targets.length; i < l; i++ ) {
4362        if ( jQuery.contains( this, targets[i] ) ) {
4363          return true;
4364        }
4365      }
4366    });
4367  },
4368
4369  not: function( selector ) {
4370    return this.pushStack( winnow(this, selector, false), "not", selector);
4371  },
4372
4373  filter: function( selector ) {
4374    return this.pushStack( winnow(this, selector, true), "filter", selector );
4375  },
4376 
4377  is: function( selector ) {
4378    return !!selector && jQuery.filter( selector, this ).length > 0;
4379  },
4380
4381  closest: function( selectors, context ) {
4382    var ret = [], i, l, cur = this[0];
4383
4384    if ( jQuery.isArray( selectors ) ) {
4385      var match, selector,
4386        matches = {},
4387        level = 1;
4388
4389      if ( cur && selectors.length ) {
4390        for ( i = 0, l = selectors.length; i < l; i++ ) {
4391          selector = selectors[i];
4392
4393          if ( !matches[selector] ) {
4394            matches[selector] = jQuery.expr.match.POS.test( selector ) ? 
4395              jQuery( selector, context || this.context ) :
4396              selector;
4397          }
4398        }
4399
4400        while ( cur && cur.ownerDocument && cur !== context ) {
4401          for ( selector in matches ) {
4402            match = matches[selector];
4403
4404            if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
4405              ret.push({ selector: selector, elem: cur, level: level });
4406            }
4407          }
4408
4409          cur = cur.parentNode;
4410          level++;
4411        }
4412      }
4413
4414      return ret;
4415    }
4416
4417    var pos = POS.test( selectors ) ? 
4418      jQuery( selectors, context || this.context ) : null;
4419
4420    for ( i = 0, l = this.length; i < l; i++ ) {
4421      cur = this[i];
4422
4423      while ( cur ) {
4424        if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
4425          ret.push( cur );
4426          break;
4427
4428        } else {
4429          cur = cur.parentNode;
4430          if ( !cur || !cur.ownerDocument || cur === context ) {
4431            break;
4432          }
4433        }
4434      }
4435    }
4436
4437    ret = ret.length > 1 ? jQuery.unique(ret) : ret;
4438   
4439    return this.pushStack( ret, "closest", selectors );
4440  },
4441 
4442  // Determine the position of an element within
4443  // the matched set of elements
4444  index: function( elem ) {
4445    if ( !elem || typeof elem === "string" ) {
4446      return jQuery.inArray( this[0],
4447        // If it receives a string, the selector is used
4448        // If it receives nothing, the siblings are used
4449        elem ? jQuery( elem ) : this.parent().children() );
4450    }
4451    // Locate the position of the desired element
4452    return jQuery.inArray(
4453      // If it receives a jQuery object, the first element is used
4454      elem.jquery ? elem[0] : elem, this );
4455  },
4456
4457  add: function( selector, context ) {
4458    var set = typeof selector === "string" ?
4459        jQuery( selector, context || this.context ) :
4460        jQuery.makeArray( selector ),
4461      all = jQuery.merge( this.get(), set );
4462
4463    return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
4464      all :
4465      jQuery.unique( all ) );
4466  },
4467
4468  andSelf: function() {
4469    return this.add( this.prevObject );
4470  }
4471});
4472
4473// A painfully simple check to see if an element is disconnected
4474// from a document (should be improved, where feasible).
4475function isDisconnected( node ) {
4476  return !node || !node.parentNode || node.parentNode.nodeType === 11;
4477}
4478
4479jQuery.each({
4480  parent: function( elem ) {
4481    var parent = elem.parentNode;
4482    return parent && parent.nodeType !== 11 ? parent : null;
4483  },
4484  parents: function( elem ) {
4485    return jQuery.dir( elem, "parentNode" );
4486  },
4487  parentsUntil: function( elem, i, until ) {
4488    return jQuery.dir( elem, "parentNode", until );
4489  },
4490  next: function( elem ) {
4491    return jQuery.nth( elem, 2, "nextSibling" );
4492  },
4493  prev: function( elem ) {
4494    return jQuery.nth( elem, 2, "previousSibling" );
4495  },
4496  nextAll: function( elem ) {
4497    return jQuery.dir( elem, "nextSibling" );
4498  },
4499  prevAll: function( elem ) {
4500    return jQuery.dir( elem, "previousSibling" );
4501  },
4502  nextUntil: function( elem, i, until ) {
4503    return jQuery.dir( elem, "nextSibling", until );
4504  },
4505  prevUntil: function( elem, i, until ) {
4506    return jQuery.dir( elem, "previousSibling", until );
4507  },
4508  siblings: function( elem ) {
4509    return jQuery.sibling( elem.parentNode.firstChild, elem );
4510  },
4511  children: function( elem ) {
4512    return jQuery.sibling( elem.firstChild );
4513  },
4514  contents: function( elem ) {
4515    return jQuery.nodeName( elem, "iframe" ) ?
4516      elem.contentDocument || elem.contentWindow.document :
4517      jQuery.makeArray( elem.childNodes );
4518  }
4519}, function( name, fn ) {
4520  jQuery.fn[ name ] = function( until, selector ) {
4521    var ret = jQuery.map( this, fn, until );
4522   
4523    if ( !runtil.test( name ) ) {
4524      selector = until;
4525    }
4526
4527    if ( selector && typeof selector === "string" ) {
4528      ret = jQuery.filter( selector, ret );
4529    }
4530
4531    ret = this.length > 1 ? jQuery.unique( ret ) : ret;
4532
4533    if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
4534      ret = ret.reverse();
4535    }
4536
4537    return this.pushStack( ret, name, slice.call(arguments).join(",") );
4538  };
4539});
4540
4541jQuery.extend({
4542  filter: function( expr, elems, not ) {
4543    if ( not ) {
4544      expr = ":not(" + expr + ")";
4545    }
4546
4547    return elems.length === 1 ?
4548      jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
4549      jQuery.find.matches(expr, elems);
4550  },
4551 
4552  dir: function( elem, dir, until ) {
4553    var matched = [],
4554      cur = elem[ dir ];
4555
4556    while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
4557      if ( cur.nodeType === 1 ) {
4558        matched.push( cur );
4559      }
4560      cur = cur[dir];
4561    }
4562    return matched;
4563  },
4564
4565  nth: function( cur, result, dir, elem ) {
4566    result = result || 1;
4567    var num = 0;
4568
4569    for ( ; cur; cur = cur[dir] ) {
4570      if ( cur.nodeType === 1 && ++num === result ) {
4571        break;
4572      }
4573    }
4574
4575    return cur;
4576  },
4577
4578  sibling: function( n, elem ) {
4579    var r = [];
4580
4581    for ( ; n; n = n.nextSibling ) {
4582      if ( n.nodeType === 1 && n !== elem ) {
4583        r.push( n );
4584      }
4585    }
4586
4587    return r;
4588  }
4589});
4590
4591// Implement the identical functionality for filter and not
4592function winnow( elements, qualifier, keep ) {
4593  if ( jQuery.isFunction( qualifier ) ) {
4594    return jQuery.grep(elements, function( elem, i ) {
4595      var retVal = !!qualifier.call( elem, i, elem );
4596      return retVal === keep;
4597    });
4598
4599  } else if ( qualifier.nodeType ) {
4600    return jQuery.grep(elements, function( elem, i ) {
4601      return (elem === qualifier) === keep;
4602    });
4603
4604  } else if ( typeof qualifier === "string" ) {
4605    var filtered = jQuery.grep(elements, function( elem ) {
4606      return elem.nodeType === 1;
4607    });
4608
4609    if ( isSimple.test( qualifier ) ) {
4610      return jQuery.filter(qualifier, filtered, !keep);
4611    } else {
4612      qualifier = jQuery.filter( qualifier, filtered );
4613    }
4614  }
4615
4616  return jQuery.grep(elements, function( elem, i ) {
4617    return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
4618  });
4619}
4620
4621
4622
4623
4624var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
4625  rleadingWhitespace = /^\s+/,
4626  rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
4627  rtagName = /<([\w:]+)/,
4628  rtbody = /<tbody/i,
4629  rhtml = /<|&#?\w+;/,
4630  rnocache = /<(?:script|object|embed|option|style)/i,
4631  // checked="checked" or checked (html5)
4632  rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
4633  raction = /\=([^="'>\s]+\/)>/g,
4634  wrapMap = {
4635    option: [ 1, "<select multiple='multiple'>", "</select>" ],
4636    legend: [ 1, "<fieldset>", "</fieldset>" ],
4637    thead: [ 1, "<table>", "</table>" ],
4638    tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4639    td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4640    col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
4641    area: [ 1, "<map>", "</map>" ],
4642    _default: [ 0, "", "" ]
4643  };
4644
4645wrapMap.optgroup = wrapMap.option;
4646wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4647wrapMap.th = wrapMap.td;
4648
4649// IE can't serialize <link> and <script> tags normally
4650if ( !jQuery.support.htmlSerialize ) {
4651  wrapMap._default = [ 1, "div<div>", "</div>" ];
4652}
4653
4654jQuery.fn.extend({
4655  text: function( text ) {
4656    if ( jQuery.isFunction(text) ) {
4657      return this.each(function(i) {
4658        var self = jQuery( this );
4659
4660        self.text( text.call(this, i, self.text()) );
4661      });
4662    }
4663
4664    if ( typeof text !== "object" && text !== undefined ) {
4665      return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
4666    }
4667
4668    return jQuery.text( this );
4669  },
4670
4671  wrapAll: function( html ) {
4672    if ( jQuery.isFunction( html ) ) {
4673      return this.each(function(i) {
4674        jQuery(this).wrapAll( html.call(this, i) );
4675      });
4676    }
4677
4678    if ( this[0] ) {
4679      // The elements to wrap the target around
4680      var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
4681
4682      if ( this[0].parentNode ) {
4683        wrap.insertBefore( this[0] );
4684      }
4685
4686      wrap.map(function() {
4687        var elem = this;
4688
4689        while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
4690          elem = elem.firstChild;
4691        }
4692
4693        return elem;
4694      }).append(this);
4695    }
4696
4697    return this;
4698  },
4699
4700  wrapInner: function( html ) {
4701    if ( jQuery.isFunction( html ) ) {
4702      return this.each(function(i) {
4703        jQuery(this).wrapInner( html.call(this, i) );
4704      });
4705    }
4706
4707    return this.each(function() {
4708      var self = jQuery( this ),
4709        contents = self.contents();
4710
4711      if ( contents.length ) {
4712        contents.wrapAll( html );
4713
4714      } else {
4715        self.append( html );
4716      }
4717    });
4718  },
4719
4720  wrap: function( html ) {
4721    return this.each(function() {
4722      jQuery( this ).wrapAll( html );
4723    });
4724  },
4725
4726  unwrap: function() {
4727    return this.parent().each(function() {
4728      if ( !jQuery.nodeName( this, "body" ) ) {
4729        jQuery( this ).replaceWith( this.childNodes );
4730      }
4731    }).end();
4732  },
4733
4734  append: function() {
4735    return this.domManip(arguments, true, function( elem ) {
4736      if ( this.nodeType === 1 ) {
4737        this.appendChild( elem );
4738      }
4739    });
4740  },
4741
4742  prepend: function() {
4743    return this.domManip(arguments, true, function( elem ) {
4744      if ( this.nodeType === 1 ) {
4745        this.insertBefore( elem, this.firstChild );
4746      }
4747    });
4748  },
4749
4750  before: function() {
4751    if ( this[0] && this[0].parentNode ) {
4752      return this.domManip(arguments, false, function( elem ) {
4753        this.parentNode.insertBefore( elem, this );
4754      });
4755    } else if ( arguments.length ) {
4756      var set = jQuery(arguments[0]);
4757      set.push.apply( set, this.toArray() );
4758      return this.pushStack( set, "before", arguments );
4759    }
4760  },
4761
4762  after: function() {
4763    if ( this[0] && this[0].parentNode ) {
4764      return this.domManip(arguments, false, function( elem ) {
4765        this.parentNode.insertBefore( elem, this.nextSibling );
4766      });
4767    } else if ( arguments.length ) {
4768      var set = this.pushStack( this, "after", arguments );
4769      set.push.apply( set, jQuery(arguments[0]).toArray() );
4770      return set;
4771    }
4772  },
4773 
4774  // keepData is for internal use only--do not document
4775  remove: function( selector, keepData ) {
4776    for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
4777      if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
4778        if ( !keepData && elem.nodeType === 1 ) {
4779          jQuery.cleanData( elem.getElementsByTagName("*") );
4780          jQuery.cleanData( [ elem ] );
4781        }
4782
4783        if ( elem.parentNode ) {
4784           elem.parentNode.removeChild( elem );
4785        }
4786      }
4787    }
4788   
4789    return this;
4790  },
4791
4792  empty: function() {
4793    for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
4794      // Remove element nodes and prevent memory leaks
4795      if ( elem.nodeType === 1 ) {
4796        jQuery.cleanData( elem.getElementsByTagName("*") );
4797      }
4798
4799      // Remove any remaining nodes
4800      while ( elem.firstChild ) {
4801        elem.removeChild( elem.firstChild );
4802      }
4803    }
4804   
4805    return this;
4806  },
4807
4808  clone: function( events ) {
4809    // Do the clone
4810    var ret = this.map(function() {
4811      if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
4812        // IE copies events bound via attachEvent when
4813        // using cloneNode. Calling detachEvent on the
4814        // clone will also remove the events from the orignal
4815        // In order to get around this, we use innerHTML.
4816        // Unfortunately, this means some modifications to
4817        // attributes in IE that are actually only stored
4818        // as properties will not be copied (such as the
4819        // the name attribute on an input).
4820        var html = this.outerHTML,
4821          ownerDocument = this.ownerDocument;
4822
4823        if ( !html ) {
4824          var div = ownerDocument.createElement("div");
4825          div.appendChild( this.cloneNode(true) );
4826          html = div.innerHTML;
4827        }
4828
4829        return jQuery.clean([html.replace(rinlinejQuery, "")
4830          // Handle the case in IE 8 where action=/test/> self-closes a tag
4831          .replace(raction, '="$1">')
4832          .replace(rleadingWhitespace, "")], ownerDocument)[0];
4833      } else {
4834        return this.cloneNode(true);
4835      }
4836    });
4837
4838    // Copy the events from the original to the clone
4839    if ( events === true ) {
4840      cloneCopyEvent( this, ret );
4841      cloneCopyEvent( this.find("*"), ret.find("*") );
4842    }
4843
4844    // Return the cloned set
4845    return ret;
4846  },
4847
4848  html: function( value ) {
4849    if ( value === undefined ) {
4850      return this[0] && this[0].nodeType === 1 ?
4851        this[0].innerHTML.replace(rinlinejQuery, "") :
4852        null;
4853
4854    // See if we can take a shortcut and just use innerHTML
4855    } else if ( typeof value === "string" && !rnocache.test( value ) &&
4856      (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
4857      !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
4858
4859      value = value.replace(rxhtmlTag, "<$1></$2>");
4860
4861      try {
4862        for ( var i = 0, l = this.length; i < l; i++ ) {
4863          // Remove element nodes and prevent memory leaks
4864          if ( this[i].nodeType === 1 ) {
4865            jQuery.cleanData( this[i].getElementsByTagName("*") );
4866            this[i].innerHTML = value;
4867          }
4868        }
4869
4870      // If using innerHTML throws an exception, use the fallback method
4871      } catch(e) {
4872        this.empty().append( value );
4873      }
4874
4875    } else if ( jQuery.isFunction( value ) ) {
4876      this.each(function(i){
4877        var self = jQuery( this );
4878
4879        self.html( value.call(this, i, self.html()) );
4880      });
4881
4882    } else {
4883      this.empty().append( value );
4884    }
4885
4886    return this;
4887  },
4888
4889  replaceWith: function( value ) {
4890    if ( this[0] && this[0].parentNode ) {
4891      // Make sure that the elements are removed from the DOM before they are inserted
4892      // this can help fix replacing a parent with child elements
4893      if ( jQuery.isFunction( value ) ) {
4894        return this.each(function(i) {
4895          var self = jQuery(this), old = self.html();
4896          self.replaceWith( value.call( this, i, old ) );
4897        });
4898      }
4899
4900      if ( typeof value !== "string" ) {
4901        value = jQuery( value ).detach();
4902      }
4903
4904      return this.each(function() {
4905        var next = this.nextSibling,
4906          parent = this.parentNode;
4907
4908        jQuery( this ).remove();
4909
4910        if ( next ) {
4911          jQuery(next).before( value );
4912        } else {
4913          jQuery(parent).append( value );
4914        }
4915      });
4916    } else {
4917      return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
4918    }
4919  },
4920
4921  detach: function( selector ) {
4922    return this.remove( selector, true );
4923  },
4924
4925  domManip: function( args, table, callback ) {
4926    var results, first, fragment, parent,
4927      value = args[0],
4928      scripts = [];
4929
4930    // We can't cloneNode fragments that contain checked, in WebKit
4931    if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
4932      return this.each(function() {
4933        jQuery(this).domManip( args, table, callback, true );
4934      });
4935    }
4936
4937    if ( jQuery.isFunction(value) ) {
4938      return this.each(function(i) {
4939        var self = jQuery(this);
4940        args[0] = value.call(this, i, table ? self.html() : undefined);
4941        self.domManip( args, table, callback );
4942      });
4943    }
4944
4945    if ( this[0] ) {
4946      parent = value && value.parentNode;
4947
4948      // If we're in a fragment, just use that instead of building a new one
4949      if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
4950        results = { fragment: parent };
4951
4952      } else {
4953        results = jQuery.buildFragment( args, this, scripts );
4954      }
4955     
4956      fragment = results.fragment;
4957     
4958      if ( fragment.childNodes.length === 1 ) {
4959        first = fragment = fragment.firstChild;
4960      } else {
4961        first = fragment.firstChild;
4962      }
4963
4964      if ( first ) {
4965        table = table && jQuery.nodeName( first, "tr" );
4966
4967        for ( var i = 0, l = this.length; i < l; i++ ) {
4968          callback.call(
4969            table ?
4970              root(this[i], first) :
4971              this[i],
4972            i > 0 || results.cacheable || this.length > 1  ?
4973              fragment.cloneNode(true) :
4974              fragment
4975          );
4976        }
4977      }
4978
4979      if ( scripts.length ) {
4980        jQuery.each( scripts, evalScript );
4981      }
4982    }
4983
4984    return this;
4985  }
4986});
4987
4988function root( elem, cur ) {
4989  return jQuery.nodeName(elem, "table") ?
4990    (elem.getElementsByTagName("tbody")[0] ||
4991    elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
4992    elem;
4993}
4994
4995function cloneCopyEvent(orig, ret) {
4996  var i = 0;
4997
4998  ret.each(function() {
4999    if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
5000      return;
5001    }
5002
5003    var oldData = jQuery.data( orig[i++] ),
5004      curData = jQuery.data( this, oldData ),
5005      events = oldData && oldData.events;
5006
5007    if ( events ) {
5008      delete curData.handle;
5009      curData.events = {};
5010
5011      for ( var type in events ) {
5012        for ( var handler in events[ type ] ) {
5013          jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
5014        }
5015      }
5016    }
5017  });
5018}
5019
5020jQuery.buildFragment = function( args, nodes, scripts ) {
5021  var fragment, cacheable, cacheresults,
5022    doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
5023
5024  // Only cache "small" (1/2 KB) strings that are associated with the main document
5025  // Cloning options loses the selected state, so don't cache them
5026  // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
5027  // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
5028  if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
5029    !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
5030
5031    cacheable = true;
5032    cacheresults = jQuery.fragments[ args[0] ];
5033    if ( cacheresults ) {
5034      if ( cacheresults !== 1 ) {
5035        fragment = cacheresults;
5036      }
5037    }
5038  }
5039
5040  if ( !fragment ) {
5041    fragment = doc.createDocumentFragment();
5042    jQuery.clean( args, doc, fragment, scripts );
5043  }
5044
5045  if ( cacheable ) {
5046    jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
5047  }
5048
5049  return { fragment: fragment, cacheable: cacheable };
5050};
5051
5052jQuery.fragments = {};
5053
5054jQuery.each({
5055  appendTo: "append",
5056  prependTo: "prepend",
5057  insertBefore: "before",
5058  insertAfter: "after",
5059  replaceAll: "replaceWith"
5060}, function( name, original ) {
5061  jQuery.fn[ name ] = function( selector ) {
5062    var ret = [],
5063      insert = jQuery( selector ),
5064      parent = this.length === 1 && this[0].parentNode;
5065   
5066    if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
5067      insert[ original ]( this[0] );
5068      return this;
5069     
5070    } else {
5071      for ( var i = 0, l = insert.length; i < l; i++ ) {
5072        var elems = (i > 0 ? this.clone(true) : this).get();
5073        jQuery( insert[i] )[ original ]( elems );
5074        ret = ret.concat( elems );
5075      }
5076   
5077      return this.pushStack( ret, name, insert.selector );
5078    }
5079  };
5080});
5081
5082jQuery.extend({
5083  clean: function( elems, context, fragment, scripts ) {
5084    context = context || document;
5085
5086    // !context.createElement fails in IE with an error but returns typeof 'object'
5087    if ( typeof context.createElement === "undefined" ) {
5088      context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
5089    }
5090
5091    var ret = [];
5092
5093    for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
5094      if ( typeof elem === "number" ) {
5095        elem += "";
5096      }
5097
5098      if ( !elem ) {
5099        continue;
5100      }
5101
5102      // Convert html string into DOM nodes
5103      if ( typeof elem === "string" && !rhtml.test( elem ) ) {
5104        elem = context.createTextNode( elem );
5105
5106      } else if ( typeof elem === "string" ) {
5107        // Fix "XHTML"-style tags in all browsers
5108        elem = elem.replace(rxhtmlTag, "<$1></$2>");
5109
5110        // Trim whitespace, otherwise indexOf won't work as expected
5111        var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
5112          wrap = wrapMap[ tag ] || wrapMap._default,
5113          depth = wrap[0],
5114          div = context.createElement("div");
5115
5116        // Go to html and back, then peel off extra wrappers
5117        div.innerHTML = wrap[1] + elem + wrap[2];
5118
5119        // Move to the right depth
5120        while ( depth-- ) {
5121          div = div.lastChild;
5122        }
5123
5124        // Remove IE's autoinserted <tbody> from table fragments
5125        if ( !jQuery.support.tbody ) {
5126
5127          // String was a <table>, *may* have spurious <tbody>
5128          var hasBody = rtbody.test(elem),
5129            tbody = tag === "table" && !hasBody ?
5130              div.firstChild && div.firstChild.childNodes :
5131
5132              // String was a bare <thead> or <tfoot>
5133              wrap[1] === "<table>" && !hasBody ?
5134                div.childNodes :
5135                [];
5136
5137          for ( var j = tbody.length - 1; j >= 0 ; --j ) {
5138            if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
5139              tbody[ j ].parentNode.removeChild( tbody[ j ] );
5140            }
5141          }
5142
5143        }
5144
5145        // IE completely kills leading whitespace when innerHTML is used
5146        if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
5147          div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
5148        }
5149
5150        elem = div.childNodes;
5151      }
5152
5153      if ( elem.nodeType ) {
5154        ret.push( elem );
5155      } else {
5156        ret = jQuery.merge( ret, elem );
5157      }
5158    }
5159
5160    if ( fragment ) {
5161      for ( i = 0; ret[i]; i++ ) {
5162        if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
5163          scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
5164       
5165        } else {
5166          if ( ret[i].nodeType === 1 ) {
5167            ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
5168          }
5169          fragment.appendChild( ret[i] );
5170        }
5171      }
5172    }
5173
5174    return ret;
5175  },
5176 
5177  cleanData: function( elems ) {
5178    var data, id, cache = jQuery.cache,
5179      special = jQuery.event.special,
5180      deleteExpando = jQuery.support.deleteExpando;
5181   
5182    for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
5183      if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
5184        continue;
5185      }
5186
5187      id = elem[ jQuery.expando ];
5188     
5189      if ( id ) {
5190        data = cache[ id ];
5191       
5192        if ( data && data.events ) {
5193          for ( var type in data.events ) {
5194            if ( special[ type ] ) {
5195              jQuery.event.remove( elem, type );
5196
5197            } else {
5198              jQuery.removeEvent( elem, type, data.handle );
5199            }
5200          }
5201        }
5202       
5203        if ( deleteExpando ) {
5204          delete elem[ jQuery.expando ];
5205
5206        } else if ( elem.removeAttribute ) {
5207          elem.removeAttribute( jQuery.expando );
5208        }
5209       
5210        delete cache[ id ];
5211      }
5212    }
5213  }
5214});
5215
5216function evalScript( i, elem ) {
5217  if ( elem.src ) {
5218    jQuery.ajax({
5219      url: elem.src,
5220      async: false,
5221      dataType: "script"
5222    });
5223  } else {
5224    jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
5225  }
5226
5227  if ( elem.parentNode ) {
5228    elem.parentNode.removeChild( elem );
5229  }
5230}
5231
5232
5233
5234
5235var ralpha = /alpha\([^)]*\)/i,
5236  ropacity = /opacity=([^)]*)/,
5237  rdashAlpha = /-([a-z])/ig,
5238  rupper = /([A-Z])/g,
5239  rnumpx = /^-?\d+(?:px)?$/i,
5240  rnum = /^-?\d/,
5241
5242  cssShow = { position: "absolute", visibility: "hidden", display: "block" },
5243  cssWidth = [ "Left", "Right" ],
5244  cssHeight = [ "Top", "Bottom" ],
5245  curCSS,
5246
5247  getComputedStyle,
5248  currentStyle,
5249
5250  fcamelCase = function( all, letter ) {
5251    return letter.toUpperCase();
5252  };
5253
5254jQuery.fn.css = function( name, value ) {
5255  // Setting 'undefined' is a no-op
5256  if ( arguments.length === 2 && value === undefined ) {
5257    return this;
5258  }
5259
5260  return jQuery.access( this, name, value, true, function( elem, name, value ) {
5261    return value !== undefined ?
5262      jQuery.style( elem, name, value ) :
5263      jQuery.css( elem, name );
5264  });
5265};
5266
5267jQuery.extend({
5268  // Add in style property hooks for overriding the default
5269  // behavior of getting and setting a style property
5270  cssHooks: {
5271    opacity: {
5272      get: function( elem, computed ) {
5273        if ( computed ) {
5274          // We should always get a number back from opacity
5275          var ret = curCSS( elem, "opacity", "opacity" );
5276          return ret === "" ? "1" : ret;
5277
5278        } else {
5279          return elem.style.opacity;
5280        }
5281      }
5282    }
5283  },
5284
5285  // Exclude the following css properties to add px
5286  cssNumber: {
5287    "zIndex": true,
5288    "fontWeight": true,
5289    "opacity": true,
5290    "zoom": true,
5291    "lineHeight": true
5292  },
5293
5294  // Add in properties whose names you wish to fix before
5295  // setting or getting the value
5296  cssProps: {
5297    // normalize float css property
5298    "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
5299  },
5300
5301  // Get and set the style property on a DOM Node
5302  style: function( elem, name, value, extra ) {
5303    // Don't set styles on text and comment nodes
5304    if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
5305      return;
5306    }
5307
5308    // Make sure that we're working with the right name
5309    var ret, origName = jQuery.camelCase( name ),
5310      style = elem.style, hooks = jQuery.cssHooks[ origName ];
5311
5312    name = jQuery.cssProps[ origName ] || origName;
5313
5314    // Check if we're setting a value
5315    if ( value !== undefined ) {
5316      // Make sure that NaN and null values aren't set. See: #7116
5317      if ( typeof value === "number" && isNaN( value ) || value == null ) {
5318        return;
5319      }
5320
5321      // If a number was passed in, add 'px' to the (except for certain CSS properties)
5322      if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) {
5323        value += "px";
5324      }
5325
5326      // If a hook was provided, use that value, otherwise just set the specified value
5327      if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
5328        // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
5329        // Fixes bug #5509
5330        try {
5331          style[ name ] = value;
5332        } catch(e) {}
5333      }
5334
5335    } else {
5336      // If a hook was provided get the non-computed value from there
5337      if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
5338        return ret;
5339      }
5340
5341      // Otherwise just get the value from the style object
5342      return style[ name ];
5343    }
5344  },
5345
5346  css: function( elem, name, extra ) {
5347    // Make sure that we're working with the right name
5348    var ret, origName = jQuery.camelCase( name ),
5349      hooks = jQuery.cssHooks[ origName ];
5350
5351    name = jQuery.cssProps[ origName ] || origName;
5352
5353    // If a hook was provided get the computed value from there
5354    if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
5355      return ret;
5356
5357    // Otherwise, if a way to get the computed value exists, use that
5358    } else if ( curCSS ) {
5359      return curCSS( elem, name, origName );
5360    }
5361  },
5362
5363  // A method for quickly swapping in/out CSS properties to get correct calculations
5364  swap: function( elem, options, callback ) {
5365    var old = {};
5366
5367    // Remember the old values, and insert the new ones
5368    for ( var name in options ) {
5369      old[ name ] = elem.style[ name ];
5370      elem.style[ name ] = options[ name ];
5371    }
5372
5373    callback.call( elem );
5374
5375    // Revert the old values
5376    for ( name in options ) {
5377      elem.style[ name ] = old[ name ];
5378    }
5379  },
5380
5381  camelCase: function( string ) {
5382    return string.replace( rdashAlpha, fcamelCase );
5383  }
5384});
5385
5386// DEPRECATED, Use jQuery.css() instead
5387jQuery.curCSS = jQuery.css;
5388
5389jQuery.each(["height", "width"], function( i, name ) {
5390  jQuery.cssHooks[ name ] = {
5391    get: function( elem, computed, extra ) {
5392      var val;
5393
5394      if ( computed ) {
5395        if ( elem.offsetWidth !== 0 ) {
5396          val = getWH( elem, name, extra );
5397
5398        } else {
5399          jQuery.swap( elem, cssShow, function() {
5400            val = getWH( elem, name, extra );
5401          });
5402        }
5403
5404        if ( val <= 0 ) {
5405          val = curCSS( elem, name, name );
5406
5407          if ( val === "0px" && currentStyle ) {
5408            val = currentStyle( elem, name, name );
5409          }
5410
5411          if ( val != null ) {
5412            // Should return "auto" instead of 0, use 0 for
5413            // temporary backwards-compat
5414            return val === "" || val === "auto" ? "0px" : val;
5415          }
5416        }
5417
5418        if ( val < 0 || val == null ) {
5419          val = elem.style[ name ];
5420
5421          // Should return "auto" instead of 0, use 0 for
5422          // temporary backwards-compat
5423          return val === "" || val === "auto" ? "0px" : val;
5424        }
5425
5426        return typeof val === "string" ? val : val + "px";
5427      }
5428    },
5429
5430    set: function( elem, value ) {
5431      if ( rnumpx.test( value ) ) {
5432        // ignore negative width and height values #1599
5433        value = parseFloat(value);
5434
5435        if ( value >= 0 ) {
5436          return value + "px";
5437        }
5438
5439      } else {
5440        return value;
5441      }
5442    }
5443  };
5444});
5445
5446if ( !jQuery.support.opacity ) {
5447  jQuery.cssHooks.opacity = {
5448    get: function( elem, computed ) {
5449      // IE uses filters for opacity
5450      return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ?
5451        (parseFloat(RegExp.$1) / 100) + "" :
5452        computed ? "1" : "";
5453    },
5454
5455    set: function( elem, value ) {
5456      var style = elem.style;
5457
5458      // IE has trouble with opacity if it does not have layout
5459      // Force it by setting the zoom level
5460      style.zoom = 1;
5461
5462      // Set the alpha filter to set the opacity
5463      var opacity = jQuery.isNaN(value) ?
5464        "" :
5465        "alpha(opacity=" + value * 100 + ")",
5466        filter = style.filter || "";
5467
5468      style.filter = ralpha.test(filter) ?
5469        filter.replace(ralpha, opacity) :
5470        style.filter + ' ' + opacity;
5471    }
5472  };
5473}
5474
5475if ( document.defaultView && document.defaultView.getComputedStyle ) {
5476  getComputedStyle = function( elem, newName, name ) {
5477    var ret, defaultView, computedStyle;
5478
5479    name = name.replace( rupper, "-$1" ).toLowerCase();
5480
5481    if ( !(defaultView = elem.ownerDocument.defaultView) ) {
5482      return undefined;
5483    }
5484
5485    if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
5486      ret = computedStyle.getPropertyValue( name );
5487      if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
5488        ret = jQuery.style( elem, name );
5489      }
5490    }
5491
5492    return ret;
5493  };
5494}
5495
5496if ( document.documentElement.currentStyle ) {
5497  currentStyle = function( elem, name ) {
5498    var left, rsLeft,
5499      ret = elem.currentStyle && elem.currentStyle[ name ],
5500      style = elem.style;
5501
5502    // From the awesome hack by Dean Edwards
5503    // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
5504
5505    // If we're not dealing with a regular pixel number
5506    // but a number that has a weird ending, we need to convert it to pixels
5507    if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
5508      // Remember the original values
5509      left = style.left;
5510      rsLeft = elem.runtimeStyle.left;
5511
5512      // Put in the new values to get a computed value out
5513      elem.runtimeStyle.left = elem.currentStyle.left;
5514      style.left = name === "fontSize" ? "1em" : (ret || 0);
5515      ret = style.pixelLeft + "px";
5516
5517      // Revert the changed values
5518      style.left = left;
5519      elem.runtimeStyle.left = rsLeft;
5520    }
5521
5522    return ret === "" ? "auto" : ret;
5523  };
5524}
5525
5526curCSS = getComputedStyle || currentStyle;
5527
5528function getWH( elem, name, extra ) {
5529  var which = name === "width" ? cssWidth : cssHeight,
5530    val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
5531
5532  if ( extra === "border" ) {
5533    return val;
5534  }
5535
5536  jQuery.each( which, function() {
5537    if ( !extra ) {
5538      val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
5539    }
5540
5541    if ( extra === "margin" ) {
5542      val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
5543
5544    } else {
5545      val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
5546    }
5547  });
5548
5549  return val;
5550}
5551
5552if ( jQuery.expr && jQuery.expr.filters ) {
5553  jQuery.expr.filters.hidden = function( elem ) {
5554    var width = elem.offsetWidth,
5555      height = elem.offsetHeight;
5556
5557    return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
5558  };
5559
5560  jQuery.expr.filters.visible = function( elem ) {
5561    return !jQuery.expr.filters.hidden( elem );
5562  };
5563}
5564
5565
5566
5567
5568var jsc = jQuery.now(),
5569  rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
5570  rselectTextarea = /^(?:select|textarea)/i,
5571  rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
5572  rnoContent = /^(?:GET|HEAD)$/,
5573  rbracket = /\[\]$/,
5574  jsre = /\=\?(&|$)/,
5575  rquery = /\?/,
5576  rts = /([?&])_=[^&]*/,
5577  rurl = /^(\w+:)?\/\/([^\/?#]+)/,
5578  r20 = /%20/g,
5579  rhash = /#.*$/,
5580
5581  // Keep a copy of the old load method
5582  _load = jQuery.fn.load;
5583
5584jQuery.fn.extend({
5585  load: function( url, params, callback ) {
5586    if ( typeof url !== "string" && _load ) {
5587      return _load.apply( this, arguments );
5588
5589    // Don't do a request if no elements are being requested
5590    } else if ( !this.length ) {
5591      return this;
5592    }
5593
5594    var off = url.indexOf(" ");
5595    if ( off >= 0 ) {
5596      var selector = url.slice(off, url.length);
5597      url = url.slice(0, off);
5598    }
5599
5600    // Default to a GET request
5601    var type = "GET";
5602
5603    // If the second parameter was provided
5604    if ( params ) {
5605      // If it's a function
5606      if ( jQuery.isFunction( params ) ) {
5607        // We assume that it's the callback
5608        callback = params;
5609        params = null;
5610
5611      // Otherwise, build a param string
5612      } else if ( typeof params === "object" ) {
5613        params = jQuery.param( params, jQuery.ajaxSettings.traditional );
5614        type = "POST";
5615      }
5616    }
5617
5618    var self = this;
5619
5620    // Request the remote document
5621    jQuery.ajax({
5622      url: url,
5623      type: type,
5624      dataType: "html",
5625      data: params,
5626      complete: function( res, status ) {
5627        // If successful, inject the HTML into all the matched elements
5628        if ( status === "success" || status === "notmodified" ) {
5629          // See if a selector was specified
5630          self.html( selector ?
5631            // Create a dummy div to hold the results
5632            jQuery("<div>")
5633              // inject the contents of the document in, removing the scripts
5634              // to avoid any 'Permission Denied' errors in IE
5635              .append(res.responseText.replace(rscript, ""))
5636
5637              // Locate the specified elements
5638              .find(selector) :
5639
5640            // If not, just inject the full result
5641            res.responseText );
5642        }
5643
5644        if ( callback ) {
5645          self.each( callback, [res.responseText, status, res] );
5646        }
5647      }
5648    });
5649
5650    return this;
5651  },
5652
5653  serialize: function() {
5654    return jQuery.param(this.serializeArray());
5655  },
5656
5657  serializeArray: function() {
5658    return this.map(function() {
5659      return this.elements ? jQuery.makeArray(this.elements) : this;
5660    })
5661    .filter(function() {
5662      return this.name && !this.disabled &&
5663        (this.checked || rselectTextarea.test(this.nodeName) ||
5664          rinput.test(this.type));
5665    })
5666    .map(function( i, elem ) {
5667      var val = jQuery(this).val();
5668
5669      return val == null ?
5670        null :
5671        jQuery.isArray(val) ?
5672          jQuery.map( val, function( val, i ) {
5673            return { name: elem.name, value: val };
5674          }) :
5675          { name: elem.name, value: val };
5676    }).get();
5677  }
5678});
5679
5680// Attach a bunch of functions for handling common AJAX events
5681jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
5682  jQuery.fn[o] = function( f ) {
5683    return this.bind(o, f);
5684  };
5685});
5686
5687jQuery.extend({
5688  get: function( url, data, callback, type ) {
5689    // shift arguments if data argument was omited
5690    if ( jQuery.isFunction( data ) ) {
5691      type = type || callback;
5692      callback = data;
5693      data = null;
5694    }
5695
5696    return jQuery.ajax({
5697      type: "GET",
5698      url: url,
5699      data: data,
5700      success: callback,
5701      dataType: type
5702    });
5703  },
5704
5705  getScript: function( url, callback ) {
5706    return jQuery.get(url, null, callback, "script");
5707  },
5708
5709  getJSON: function( url, data, callback ) {
5710    return jQuery.get(url, data, callback, "json");
5711  },
5712
5713  post: function( url, data, callback, type ) {
5714    // shift arguments if data argument was omited
5715    if ( jQuery.isFunction( data ) ) {
5716      type = type || callback;
5717      callback = data;
5718      data = {};
5719    }
5720
5721    return jQuery.ajax({
5722      type: "POST",
5723      url: url,
5724      data: data,
5725      success: callback,
5726      dataType: type
5727    });
5728  },
5729
5730  ajaxSetup: function( settings ) {
5731    jQuery.extend( jQuery.ajaxSettings, settings );
5732  },
5733
5734  ajaxSettings: {
5735    url: location.href,
5736    global: true,
5737    type: "GET",
5738    contentType: "application/x-www-form-urlencoded",
5739    processData: true,
5740    async: true,
5741    /*
5742    timeout: 0,
5743    data: null,
5744    username: null,
5745    password: null,
5746    traditional: false,
5747    */
5748    // This function can be overriden by calling jQuery.ajaxSetup
5749    xhr: function() {
5750      return new window.XMLHttpRequest();
5751    },
5752    accepts: {
5753      xml: "application/xml, text/xml",
5754      html: "text/html",
5755      script: "text/javascript, application/javascript",
5756      json: "application/json, text/javascript",
5757      text: "text/plain",
5758      _default: "*/*"
5759    }
5760  },
5761
5762  ajax: function( origSettings ) {
5763    var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings),
5764      jsonp, status, data, type = s.type.toUpperCase(), noContent = rnoContent.test(type);
5765
5766    s.url = s.url.replace( rhash, "" );
5767
5768    // Use original (not extended) context object if it was provided
5769    s.context = origSettings && origSettings.context != null ? origSettings.context : s;
5770
5771    // convert data if not already a string
5772    if ( s.data && s.processData && typeof s.data !== "string" ) {
5773      s.data = jQuery.param( s.data, s.traditional );
5774    }
5775
5776    // Handle JSONP Parameter Callbacks
5777    if ( s.dataType === "jsonp" ) {
5778      if ( type === "GET" ) {
5779        if ( !jsre.test( s.url ) ) {
5780          s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
5781        }
5782      } else if ( !s.data || !jsre.test(s.data) ) {
5783        s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
5784      }
5785      s.dataType = "json";
5786    }
5787
5788    // Build temporary JSONP function
5789    if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
5790      jsonp = s.jsonpCallback || ("jsonp" + jsc++);
5791
5792      // Replace the =? sequence both in the query string and the data
5793      if ( s.data ) {
5794        s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
5795      }
5796
5797      s.url = s.url.replace(jsre, "=" + jsonp + "$1");
5798
5799      // We need to make sure
5800      // that a JSONP style response is executed properly
5801      s.dataType = "script";
5802
5803      // Handle JSONP-style loading
5804      var customJsonp = window[ jsonp ];
5805
5806      window[ jsonp ] = function( tmp ) {
5807        if ( jQuery.isFunction( customJsonp ) ) {
5808          customJsonp( tmp );
5809
5810        } else {
5811          // Garbage collect
5812          window[ jsonp ] = undefined;
5813
5814          try {
5815            delete window[ jsonp ];
5816          } catch( jsonpError ) {}
5817        }
5818
5819        data = tmp;
5820        jQuery.handleSuccess( s, xhr, status, data );
5821        jQuery.handleComplete( s, xhr, status, data );
5822       
5823        if ( head ) {
5824          head.removeChild( script );
5825        }
5826      };
5827    }
5828
5829    if ( s.dataType === "script" && s.cache === null ) {
5830      s.cache = false;
5831    }
5832
5833    if ( s.cache === false && noContent ) {
5834      var ts = jQuery.now();
5835
5836      // try replacing _= if it is there
5837      var ret = s.url.replace(rts, "$1_=" + ts);
5838
5839      // if nothing was replaced, add timestamp to the end
5840      s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
5841    }
5842
5843    // If data is available, append data to url for GET/HEAD requests
5844    if ( s.data && noContent ) {
5845      s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
5846    }
5847
5848    // Watch for a new set of requests
5849    if ( s.global && jQuery.active++ === 0 ) {
5850      jQuery.event.trigger( "ajaxStart" );
5851    }
5852
5853    // Matches an absolute URL, and saves the domain
5854    var parts = rurl.exec( s.url ),
5855      remote = parts && (parts[1] && parts[1].toLowerCase() !== location.protocol || parts[2].toLowerCase() !== location.host);
5856
5857    // If we're requesting a remote document
5858    // and trying to load JSON or Script with a GET
5859    if ( s.dataType === "script" && type === "GET" && remote ) {
5860      var head = document.getElementsByTagName("head")[0] || document.documentElement;
5861      var script = document.createElement("script");
5862      if ( s.scriptCharset ) {
5863        script.charset = s.scriptCharset;
5864      }
5865      script.src = s.url;
5866
5867      // Handle Script loading
5868      if ( !jsonp ) {
5869        var done = false;
5870
5871        // Attach handlers for all browsers
5872        script.onload = script.onreadystatechange = function() {
5873          if ( !done && (!this.readyState ||
5874              this.readyState === "loaded" || this.readyState === "complete") ) {
5875            done = true;
5876            jQuery.handleSuccess( s, xhr, status, data );
5877            jQuery.handleComplete( s, xhr, status, data );
5878
5879            // Handle memory leak in IE
5880            script.onload = script.onreadystatechange = null;
5881            if ( head && script.parentNode ) {
5882              head.removeChild( script );
5883            }
5884          }
5885        };
5886      }
5887
5888      // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
5889      // This arises when a base node is used (#2709 and #4378).
5890      head.insertBefore( script, head.firstChild );
5891
5892      // We handle everything using the script element injection
5893      return undefined;
5894    }
5895
5896    var requestDone = false;
5897
5898    // Create the request object
5899    var xhr = s.xhr();
5900
5901    if ( !xhr ) {
5902      return;
5903    }
5904
5905    // Open the socket
5906    // Passing null username, generates a login popup on Opera (#2865)
5907    if ( s.username ) {
5908      xhr.open(type, s.url, s.async, s.username, s.password);
5909    } else {
5910      xhr.open(type, s.url, s.async);
5911    }
5912
5913    // Need an extra try/catch for cross domain requests in Firefox 3
5914    try {
5915      // Set content-type if data specified and content-body is valid for this type
5916      if ( (s.data != null && !noContent) || (origSettings && origSettings.contentType) ) {
5917        xhr.setRequestHeader("Content-Type", s.contentType);
5918      }
5919
5920      // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
5921      if ( s.ifModified ) {
5922        if ( jQuery.lastModified[s.url] ) {
5923          xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
5924        }
5925
5926        if ( jQuery.etag[s.url] ) {
5927          xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
5928        }
5929      }
5930
5931      // Set header so the called script knows that it's an XMLHttpRequest
5932      // Only send the header if it's not a remote XHR
5933      if ( !remote ) {
5934        xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
5935      }
5936
5937      // Set the Accepts header for the server, depending on the dataType
5938      xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
5939        s.accepts[ s.dataType ] + ", */*; q=0.01" :
5940        s.accepts._default );
5941    } catch( headerError ) {}
5942
5943    // Allow custom headers/mimetypes and early abort
5944    if ( s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false ) {
5945      // Handle the global AJAX counter
5946      if ( s.global && jQuery.active-- === 1 ) {
5947        jQuery.event.trigger( "ajaxStop" );
5948      }
5949
5950      // close opended socket
5951      xhr.abort();
5952      return false;
5953    }
5954
5955    if ( s.global ) {
5956      jQuery.triggerGlobal( s, "ajaxSend", [xhr, s] );
5957    }
5958
5959    // Wait for a response to come back
5960    var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
5961      // The request was aborted
5962      if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
5963        // Opera doesn't call onreadystatechange before this point
5964        // so we simulate the call
5965        if ( !requestDone ) {
5966          jQuery.handleComplete( s, xhr, status, data );
5967        }
5968
5969        requestDone = true;
5970        if ( xhr ) {
5971          xhr.onreadystatechange = jQuery.noop;
5972        }
5973
5974      // The transfer is complete and the data is available, or the request timed out
5975      } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
5976        requestDone = true;
5977        xhr.onreadystatechange = jQuery.noop;
5978
5979        status = isTimeout === "timeout" ?
5980          "timeout" :
5981          !jQuery.httpSuccess( xhr ) ?
5982            "error" :
5983            s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
5984              "notmodified" :
5985              "success";
5986
5987        var errMsg;
5988
5989        if ( status === "success" ) {
5990          // Watch for, and catch, XML document parse errors
5991          try {
5992            // process the data (runs the xml through httpData regardless of callback)
5993            data = jQuery.httpData( xhr, s.dataType, s );
5994          } catch( parserError ) {
5995            status = "parsererror";
5996            errMsg = parserError;
5997          }
5998        }
5999
6000        // Make sure that the request was successful or notmodified
6001        if ( status === "success" || status === "notmodified" ) {
6002          // JSONP handles its own success callback
6003          if ( !jsonp ) {
6004            jQuery.handleSuccess( s, xhr, status, data );
6005          }
6006        } else {
6007          jQuery.handleError( s, xhr, status, errMsg );
6008        }
6009
6010        // Fire the complete handlers
6011        if ( !jsonp ) {
6012          jQuery.handleComplete( s, xhr, status, data );
6013        }
6014
6015        if ( isTimeout === "timeout" ) {
6016          xhr.abort();
6017        }
6018
6019        // Stop memory leaks
6020        if ( s.async ) {
6021          xhr = null;
6022        }
6023      }
6024    };
6025
6026    // Override the abort handler, if we can (IE 6 doesn't allow it, but that's OK)
6027    // Opera doesn't fire onreadystatechange at all on abort
6028    try {
6029      var oldAbort = xhr.abort;
6030      xhr.abort = function() {
6031        if ( xhr ) {
6032          // oldAbort has no call property in IE7 so
6033          // just do it this way, which works in all
6034          // browsers
6035          Function.prototype.call.call( oldAbort, xhr );
6036        }
6037
6038        onreadystatechange( "abort" );
6039      };
6040    } catch( abortError ) {}
6041
6042    // Timeout checker
6043    if ( s.async && s.timeout > 0 ) {
6044      setTimeout(function() {
6045        // Check to see if the request is still happening
6046        if ( xhr && !requestDone ) {
6047          onreadystatechange( "timeout" );
6048        }
6049      }, s.timeout);
6050    }
6051
6052    // Send the data
6053    try {
6054      xhr.send( noContent || s.data == null ? null : s.data );
6055
6056    } catch( sendError ) {
6057      jQuery.handleError( s, xhr, null, sendError );
6058
6059      // Fire the complete handlers
6060      jQuery.handleComplete( s, xhr, status, data );
6061    }
6062
6063    // firefox 1.5 doesn't fire statechange for sync requests
6064    if ( !s.async ) {
6065      onreadystatechange();
6066    }
6067
6068    // return XMLHttpRequest to allow aborting the request etc.
6069    return xhr;
6070  },
6071
6072  // Serialize an array of form elements or a set of
6073  // key/values into a query string
6074  param: function( a, traditional ) {
6075    var s = [],
6076      add = function( key, value ) {
6077        // If value is a function, invoke it and return its value
6078        value = jQuery.isFunction(value) ? value() : value;
6079        s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
6080      };
6081   
6082    // Set traditional to true for jQuery <= 1.3.2 behavior.
6083    if ( traditional === undefined ) {
6084      traditional = jQuery.ajaxSettings.traditional;
6085    }
6086   
6087    // If an array was passed in, assume that it is an array of form elements.
6088    if ( jQuery.isArray(a) || a.jquery ) {
6089      // Serialize the form elements
6090      jQuery.each( a, function() {
6091        add( this.name, this.value );
6092      });
6093     
6094    } else {
6095      // If traditional, encode the "old" way (the way 1.3.2 or older
6096      // did it), otherwise encode params recursively.
6097      for ( var prefix in a ) {
6098        buildParams( prefix, a[prefix], traditional, add );
6099      }
6100    }
6101
6102    // Return the resulting serialization
6103    return s.join("&").replace(r20, "+");
6104  }
6105});
6106
6107function buildParams( prefix, obj, traditional, add ) {
6108  if ( jQuery.isArray(obj) && obj.length ) {
6109    // Serialize array item.
6110    jQuery.each( obj, function( i, v ) {
6111      if ( traditional || rbracket.test( prefix ) ) {
6112        // Treat each array item as a scalar.
6113        add( prefix, v );
6114
6115      } else {
6116        // If array item is non-scalar (array or object), encode its
6117        // numeric index to resolve deserialization ambiguity issues.
6118        // Note that rack (as of 1.0.0) can't currently deserialize
6119        // nested arrays properly, and attempting to do so may cause
6120        // a server error. Possible fixes are to modify rack's
6121        // deserialization algorithm or to provide an option or flag
6122        // to force array serialization to be shallow.
6123        buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
6124      }
6125    });
6126     
6127  } else if ( !traditional && obj != null && typeof obj === "object" ) {
6128    if ( jQuery.isEmptyObject( obj ) ) {
6129      add( prefix, "" );
6130
6131    // Serialize object item.
6132    } else {
6133      jQuery.each( obj, function( k, v ) {
6134        buildParams( prefix + "[" + k + "]", v, traditional, add );
6135      });
6136    }
6137         
6138  } else {
6139    // Serialize scalar item.
6140    add( prefix, obj );
6141  }
6142}
6143
6144// This is still on the jQuery object... for now
6145// Want to move this to jQuery.ajax some day
6146jQuery.extend({
6147
6148  // Counter for holding the number of active queries
6149  active: 0,
6150
6151  // Last-Modified header cache for next request
6152  lastModified: {},
6153  etag: {},
6154
6155  handleError: function( s, xhr, status, e ) {
6156    // If a local callback was specified, fire it
6157    if ( s.error ) {
6158      s.error.call( s.context, xhr, status, e );
6159    }
6160
6161    // Fire the global callback
6162    if ( s.global ) {
6163      jQuery.triggerGlobal( s, "ajaxError", [xhr, s, e] );
6164    }
6165  },
6166
6167  handleSuccess: function( s, xhr, status, data ) {
6168    // If a local callback was specified, fire it and pass it the data
6169    if ( s.success ) {
6170      s.success.call( s.context, data, status, xhr );
6171    }
6172
6173    // Fire the global callback
6174    if ( s.global ) {
6175      jQuery.triggerGlobal( s, "ajaxSuccess", [xhr, s] );
6176    }
6177  },
6178
6179  handleComplete: function( s, xhr, status ) {
6180    // Process result
6181    if ( s.complete ) {
6182      s.complete.call( s.context, xhr, status );
6183    }
6184
6185    // The request was completed
6186    if ( s.global ) {
6187      jQuery.triggerGlobal( s, "ajaxComplete", [xhr, s] );
6188    }
6189
6190    // Handle the global AJAX counter
6191    if ( s.global && jQuery.active-- === 1 ) {
6192      jQuery.event.trigger( "ajaxStop" );
6193    }
6194  },
6195   
6196  triggerGlobal: function( s, type, args ) {
6197    (s.context && s.context.url == null ? jQuery(s.context) : jQuery.event).trigger(type, args);
6198  },
6199
6200  // Determines if an XMLHttpRequest was successful or not
6201  httpSuccess: function( xhr ) {
6202    try {
6203      // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
6204      return !xhr.status && location.protocol === "file:" ||
6205        xhr.status >= 200 && xhr.status < 300 ||
6206        xhr.status === 304 || xhr.status === 1223;
6207    } catch(e) {}
6208
6209    return false;
6210  },
6211
6212  // Determines if an XMLHttpRequest returns NotModified
6213  httpNotModified: function( xhr, url ) {
6214    var lastModified = xhr.getResponseHeader("Last-Modified"),
6215      etag = xhr.getResponseHeader("Etag");
6216
6217    if ( lastModified ) {
6218      jQuery.lastModified[url] = lastModified;
6219    }
6220
6221    if ( etag ) {
6222      jQuery.etag[url] = etag;
6223    }
6224
6225    return xhr.status === 304;
6226  },
6227
6228  httpData: function( xhr, type, s ) {
6229    var ct = xhr.getResponseHeader("content-type") || "",
6230      xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
6231      data = xml ? xhr.responseXML : xhr.responseText;
6232
6233    if ( xml && data.documentElement.nodeName === "parsererror" ) {
6234      jQuery.error( "parsererror" );
6235    }
6236
6237    // Allow a pre-filtering function to sanitize the response
6238    // s is checked to keep backwards compatibility
6239    if ( s && s.dataFilter ) {
6240      data = s.dataFilter( data, type );
6241    }
6242
6243    // The filter can actually parse the response
6244    if ( typeof data === "string" ) {
6245      // Get the JavaScript object, if JSON is used.
6246      if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
6247        data = jQuery.parseJSON( data );
6248
6249      // If the type is "script", eval it in global context
6250      } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
6251        jQuery.globalEval( data );
6252      }
6253    }
6254
6255    return data;
6256  }
6257
6258});
6259
6260/*
6261 * Create the request object; Microsoft failed to properly
6262 * implement the XMLHttpRequest in IE7 (can't request local files),
6263 * so we use the ActiveXObject when it is available
6264 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
6265 * we need a fallback.
6266 */
6267if ( window.ActiveXObject ) {
6268  jQuery.ajaxSettings.xhr = function() {
6269    if ( window.location.protocol !== "file:" ) {
6270      try {
6271        return new window.XMLHttpRequest();
6272      } catch(xhrError) {}
6273    }
6274
6275    try {
6276      return new window.ActiveXObject("Microsoft.XMLHTTP");
6277    } catch(activeError) {}
6278  };
6279}
6280
6281// Does this browser support XHR requests?
6282jQuery.support.ajax = !!jQuery.ajaxSettings.xhr();
6283
6284
6285
6286
6287var elemdisplay = {},
6288  rfxtypes = /^(?:toggle|show|hide)$/,
6289  rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/,
6290  timerId,
6291  fxAttrs = [
6292    // height animations
6293    [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
6294    // width animations
6295    [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
6296    // opacity animations
6297    [ "opacity" ]
6298  ];
6299
6300jQuery.fn.extend({
6301  show: function( speed, easing, callback ) {
6302    var elem, display;
6303
6304    if ( speed || speed === 0 ) {
6305      return this.animate( genFx("show", 3), speed, easing, callback);
6306
6307    } else {
6308      for ( var i = 0, j = this.length; i < j; i++ ) {
6309        elem = this[i];
6310        display = elem.style.display;
6311
6312        // Reset the inline display of this element to learn if it is
6313        // being hidden by cascaded rules or not
6314        if ( !jQuery.data(elem, "olddisplay") && display === "none" ) {
6315          display = elem.style.display = "";
6316        }
6317
6318        // Set elements which have been overridden with display: none
6319        // in a stylesheet to whatever the default browser style is
6320        // for such an element
6321        if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
6322          jQuery.data(elem, "olddisplay", defaultDisplay(elem.nodeName));
6323        }
6324      }
6325
6326      // Set the display of most of the elements in a second loop
6327      // to avoid the constant reflow
6328      for ( i = 0; i < j; i++ ) {
6329        elem = this[i];
6330        display = elem.style.display;
6331
6332        if ( display === "" || display === "none" ) {
6333          elem.style.display = jQuery.data(elem, "olddisplay") || "";
6334        }
6335      }
6336
6337      return this;
6338    }
6339  },
6340
6341  hide: function( speed, easing, callback ) {
6342    if ( speed || speed === 0 ) {
6343      return this.animate( genFx("hide", 3), speed, easing, callback);
6344
6345    } else {
6346      for ( var i = 0, j = this.length; i < j; i++ ) {
6347        var display = jQuery.css( this[i], "display" );
6348
6349        if ( display !== "none" ) {
6350          jQuery.data( this[i], "olddisplay", display );
6351        }
6352      }
6353
6354      // Set the display of the elements in a second loop
6355      // to avoid the constant reflow
6356      for ( i = 0; i < j; i++ ) {
6357        this[i].style.display = "none";
6358      }
6359
6360      return this;
6361    }
6362  },
6363
6364  // Save the old toggle function
6365  _toggle: jQuery.fn.toggle,
6366
6367  toggle: function( fn, fn2, callback ) {
6368    var bool = typeof fn === "boolean";
6369
6370    if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
6371      this._toggle.apply( this, arguments );
6372
6373    } else if ( fn == null || bool ) {
6374      this.each(function() {
6375        var state = bool ? fn : jQuery(this).is(":hidden");
6376        jQuery(this)[ state ? "show" : "hide" ]();
6377      });
6378
6379    } else {
6380      this.animate(genFx("toggle", 3), fn, fn2, callback);
6381    }
6382
6383    return this;
6384  },
6385
6386  fadeTo: function( speed, to, easing, callback ) {
6387    return this.filter(":hidden").css("opacity", 0).show().end()
6388          .animate({opacity: to}, speed, easing, callback);
6389  },
6390
6391  animate: function( prop, speed, easing, callback ) {
6392    var optall = jQuery.speed(speed, easing, callback);
6393
6394    if ( jQuery.isEmptyObject( prop ) ) {
6395      return this.each( optall.complete );
6396    }
6397
6398    return this[ optall.queue === false ? "each" : "queue" ](function() {
6399      // XXX 'this' does not always have a nodeName when running the
6400      // test suite
6401
6402      var opt = jQuery.extend({}, optall), p,
6403        isElement = this.nodeType === 1,
6404        hidden = isElement && jQuery(this).is(":hidden"),
6405        self = this;
6406
6407      for ( p in prop ) {
6408        var name = jQuery.camelCase( p );
6409
6410        if ( p !== name ) {
6411          prop[ name ] = prop[ p ];
6412          delete prop[ p ];
6413          p = name;
6414        }
6415
6416        if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
6417          return opt.complete.call(this);
6418        }
6419
6420        if ( isElement && ( p === "height" || p === "width" ) ) {
6421          // Make sure that nothing sneaks out
6422          // Record all 3 overflow attributes because IE does not
6423          // change the overflow attribute when overflowX and
6424          // overflowY are set to the same value
6425          opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
6426
6427          // Set display property to inline-block for height/width
6428          // animations on inline elements that are having width/height
6429          // animated
6430          if ( jQuery.css( this, "display" ) === "inline" &&
6431              jQuery.css( this, "float" ) === "none" ) {
6432            if ( !jQuery.support.inlineBlockNeedsLayout ) {
6433              this.style.display = "inline-block";
6434
6435            } else {
6436              var display = defaultDisplay(this.nodeName);
6437
6438              // inline-level elements accept inline-block;
6439              // block-level elements need to be inline with layout
6440              if ( display === "inline" ) {
6441                this.style.display = "inline-block";
6442
6443              } else {
6444                this.style.display = "inline";
6445                this.style.zoom = 1;
6446              }
6447            }
6448          }
6449        }
6450
6451        if ( jQuery.isArray( prop[p] ) ) {
6452          // Create (if needed) and add to specialEasing
6453          (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
6454          prop[p] = prop[p][0];
6455        }
6456      }
6457
6458      if ( opt.overflow != null ) {
6459        this.style.overflow = "hidden";
6460      }
6461
6462      opt.curAnim = jQuery.extend({}, prop);
6463
6464      jQuery.each( prop, function( name, val ) {
6465        var e = new jQuery.fx( self, opt, name );
6466
6467        if ( rfxtypes.test(val) ) {
6468          e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
6469
6470        } else {
6471          var parts = rfxnum.exec(val),
6472            start = e.cur() || 0;
6473
6474          if ( parts ) {
6475            var end = parseFloat( parts[2] ),
6476              unit = parts[3] || "px";
6477
6478            // We need to compute starting value
6479            if ( unit !== "px" ) {
6480              jQuery.style( self, name, (end || 1) + unit);
6481              start = ((end || 1) / e.cur()) * start;
6482              jQuery.style( self, name, start + unit);
6483            }
6484
6485            // If a +=/-= token was provided, we're doing a relative animation
6486            if ( parts[1] ) {
6487              end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
6488            }
6489
6490            e.custom( start, end, unit );
6491
6492          } else {
6493            e.custom( start, val, "" );
6494          }
6495        }
6496      });
6497
6498      // For JS strict compliance
6499      return true;
6500    });
6501  },
6502
6503  stop: function( clearQueue, gotoEnd ) {
6504    var timers = jQuery.timers;
6505
6506    if ( clearQueue ) {
6507      this.queue([]);
6508    }
6509
6510    this.each(function() {
6511      // go in reverse order so anything added to the queue during the loop is ignored
6512      for ( var i = timers.length - 1; i >= 0; i-- ) {
6513        if ( timers[i].elem === this ) {
6514          if (gotoEnd) {
6515            // force the next step to be the last
6516            timers[i](true);
6517          }
6518
6519          timers.splice(i, 1);
6520        }
6521      }
6522    });
6523
6524    // start the next in the queue if the last step wasn't forced
6525    if ( !gotoEnd ) {
6526      this.dequeue();
6527    }
6528
6529    return this;
6530  }
6531
6532});
6533
6534function genFx( type, num ) {
6535  var obj = {};
6536
6537  jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
6538    obj[ this ] = type;
6539  });
6540
6541  return obj;
6542}
6543
6544// Generate shortcuts for custom animations
6545jQuery.each({
6546  slideDown: genFx("show", 1),
6547  slideUp: genFx("hide", 1),
6548  slideToggle: genFx("toggle", 1),
6549  fadeIn: { opacity: "show" },
6550  fadeOut: { opacity: "hide" },
6551  fadeToggle: { opacity: "toggle" }
6552}, function( name, props ) {
6553  jQuery.fn[ name ] = function( speed, easing, callback ) {
6554    return this.animate( props, speed, easing, callback );
6555  };
6556});
6557
6558jQuery.extend({
6559  speed: function( speed, easing, fn ) {
6560    var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
6561      complete: fn || !fn && easing ||
6562        jQuery.isFunction( speed ) && speed,
6563      duration: speed,
6564      easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
6565    };
6566
6567    opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
6568      opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
6569
6570    // Queueing
6571    opt.old = opt.complete;
6572    opt.complete = function() {
6573      if ( opt.queue !== false ) {
6574        jQuery(this).dequeue();
6575      }
6576      if ( jQuery.isFunction( opt.old ) ) {
6577        opt.old.call( this );
6578      }
6579    };
6580
6581    return opt;
6582  },
6583
6584  easing: {
6585    linear: function( p, n, firstNum, diff ) {
6586      return firstNum + diff * p;
6587    },
6588    swing: function( p, n, firstNum, diff ) {
6589      return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
6590    }
6591  },
6592
6593  timers: [],
6594
6595  fx: function( elem, options, prop ) {
6596    this.options = options;
6597    this.elem = elem;
6598    this.prop = prop;
6599
6600    if ( !options.orig ) {
6601      options.orig = {};
6602    }
6603  }
6604
6605});
6606
6607jQuery.fx.prototype = {
6608  // Simple function for setting a style value
6609  update: function() {
6610    if ( this.options.step ) {
6611      this.options.step.call( this.elem, this.now, this );
6612    }
6613
6614    (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
6615  },
6616
6617  // Get the current size
6618  cur: function() {
6619    if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
6620      return this.elem[ this.prop ];
6621    }
6622
6623    var r = parseFloat( jQuery.css( this.elem, this.prop ) );
6624    return r && r > -10000 ? r : 0;
6625  },
6626
6627  // Start an animation from one number to another
6628  custom: function( from, to, unit ) {
6629    var self = this,
6630      fx = jQuery.fx;
6631
6632    this.startTime = jQuery.now();
6633    this.start = from;
6634    this.end = to;
6635    this.unit = unit || this.unit || "px";
6636    this.now = this.start;
6637    this.pos = this.state = 0;
6638
6639    function t( gotoEnd ) {
6640      return self.step(gotoEnd);
6641    }
6642
6643    t.elem = this.elem;
6644
6645    if ( t() && jQuery.timers.push(t) && !timerId ) {
6646      timerId = setInterval(fx.tick, fx.interval);
6647    }
6648  },
6649
6650  // Simple 'show' function
6651  show: function() {
6652    // Remember where we started, so that we can go back to it later
6653    this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
6654    this.options.show = true;
6655
6656    // Begin the animation
6657    // Make sure that we start at a small width/height to avoid any
6658    // flash of content
6659    this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
6660
6661    // Start by showing the element
6662    jQuery( this.elem ).show();
6663  },
6664
6665  // Simple 'hide' function
6666  hide: function() {
6667    // Remember where we started, so that we can go back to it later
6668    this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
6669    this.options.hide = true;
6670
6671    // Begin the animation
6672    this.custom(this.cur(), 0);
6673  },
6674
6675  // Each step of an animation
6676  step: function( gotoEnd ) {
6677    var t = jQuery.now(), done = true;
6678
6679    if ( gotoEnd || t >= this.options.duration + this.startTime ) {
6680      this.now = this.end;
6681      this.pos = this.state = 1;
6682      this.update();
6683
6684      this.options.curAnim[ this.prop ] = true;
6685
6686      for ( var i in this.options.curAnim ) {
6687        if ( this.options.curAnim[i] !== true ) {
6688          done = false;
6689        }
6690      }
6691
6692      if ( done ) {
6693        // Reset the overflow
6694        if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
6695          var elem = this.elem,
6696            options = this.options;
6697
6698          jQuery.each( [ "", "X", "Y" ], function (index, value) {
6699            elem.style[ "overflow" + value ] = options.overflow[index];
6700          } );
6701        }
6702
6703        // Hide the element if the "hide" operation was done
6704        if ( this.options.hide ) {
6705          jQuery(this.elem).hide();
6706        }
6707
6708        // Reset the properties, if the item has been hidden or shown
6709        if ( this.options.hide || this.options.show ) {
6710          for ( var p in this.options.curAnim ) {
6711            jQuery.style( this.elem, p, this.options.orig[p] );
6712          }
6713        }
6714
6715        // Execute the complete function
6716        this.options.complete.call( this.elem );
6717      }
6718
6719      return false;
6720
6721    } else {
6722      var n = t - this.startTime;
6723      this.state = n / this.options.duration;
6724
6725      // Perform the easing function, defaults to swing
6726      var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
6727      var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
6728      this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
6729      this.now = this.start + ((this.end - this.start) * this.pos);
6730
6731      // Perform the next step of the animation
6732      this.update();
6733    }
6734
6735    return true;
6736  }
6737};
6738
6739jQuery.extend( jQuery.fx, {
6740  tick: function() {
6741    var timers = jQuery.timers;
6742
6743    for ( var i = 0; i < timers.length; i++ ) {
6744      if ( !timers[i]() ) {
6745        timers.splice(i--, 1);
6746      }
6747    }
6748
6749    if ( !timers.length ) {
6750      jQuery.fx.stop();
6751    }
6752  },
6753
6754  interval: 13,
6755
6756  stop: function() {
6757    clearInterval( timerId );
6758    timerId = null;
6759  },
6760
6761  speeds: {
6762    slow: 600,
6763    fast: 200,
6764    // Default speed
6765    _default: 400
6766  },
6767
6768  step: {
6769    opacity: function( fx ) {
6770      jQuery.style( fx.elem, "opacity", fx.now );
6771    },
6772
6773    _default: function( fx ) {
6774      if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
6775        fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
6776      } else {
6777        fx.elem[ fx.prop ] = fx.now;
6778      }
6779    }
6780  }
6781});
6782
6783if ( jQuery.expr && jQuery.expr.filters ) {
6784  jQuery.expr.filters.animated = function( elem ) {
6785    return jQuery.grep(jQuery.timers, function( fn ) {
6786      return elem === fn.elem;
6787    }).length;
6788  };
6789}
6790
6791function defaultDisplay( nodeName ) {
6792  if ( !elemdisplay[ nodeName ] ) {
6793    var elem = jQuery("<" + nodeName + ">").appendTo("body"),
6794      display = elem.css("display");
6795
6796    elem.remove();
6797
6798    if ( display === "none" || display === "" ) {
6799      display = "block";
6800    }
6801
6802    elemdisplay[ nodeName ] = display;
6803  }
6804
6805  return elemdisplay[ nodeName ];
6806}
6807
6808
6809
6810
6811var rtable = /^t(?:able|d|h)$/i,
6812  rroot = /^(?:body|html)$/i;
6813
6814if ( "getBoundingClientRect" in document.documentElement ) {
6815  jQuery.fn.offset = function( options ) {
6816    var elem = this[0], box;
6817
6818    if ( options ) { 
6819      return this.each(function( i ) {
6820        jQuery.offset.setOffset( this, options, i );
6821      });
6822    }
6823
6824    if ( !elem || !elem.ownerDocument ) {
6825      return null;
6826    }
6827
6828    if ( elem === elem.ownerDocument.body ) {
6829      return jQuery.offset.bodyOffset( elem );
6830    }
6831
6832    try {
6833      box = elem.getBoundingClientRect();
6834    } catch(e) {}
6835
6836    var doc = elem.ownerDocument,
6837      docElem = doc.documentElement;
6838
6839    // Make sure we're not dealing with a disconnected DOM node
6840    if ( !box || !jQuery.contains( docElem, elem ) ) {
6841      return box || { top: 0, left: 0 };
6842    }
6843
6844    var body = doc.body,
6845      win = getWindow(doc),
6846      clientTop  = docElem.clientTop  || body.clientTop  || 0,
6847      clientLeft = docElem.clientLeft || body.clientLeft || 0,
6848      scrollTop  = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop ),
6849      scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft),
6850      top  = box.top  + scrollTop  - clientTop,
6851      left = box.left + scrollLeft - clientLeft;
6852
6853    return { top: top, left: left };
6854  };
6855
6856} else {
6857  jQuery.fn.offset = function( options ) {
6858    var elem = this[0];
6859
6860    if ( options ) { 
6861      return this.each(function( i ) {
6862        jQuery.offset.setOffset( this, options, i );
6863      });
6864    }
6865
6866    if ( !elem || !elem.ownerDocument ) {
6867      return null;
6868    }
6869
6870    if ( elem === elem.ownerDocument.body ) {
6871      return jQuery.offset.bodyOffset( elem );
6872    }
6873
6874    jQuery.offset.initialize();
6875
6876    var computedStyle,
6877      offsetParent = elem.offsetParent,
6878      prevOffsetParent = elem,
6879      doc = elem.ownerDocument,
6880      docElem = doc.documentElement,
6881      body = doc.body,
6882      defaultView = doc.defaultView,
6883      prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
6884      top = elem.offsetTop,
6885      left = elem.offsetLeft;
6886
6887    while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
6888      if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
6889        break;
6890      }
6891
6892      computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
6893      top  -= elem.scrollTop;
6894      left -= elem.scrollLeft;
6895
6896      if ( elem === offsetParent ) {
6897        top  += elem.offsetTop;
6898        left += elem.offsetLeft;
6899
6900        if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
6901          top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
6902          left += parseFloat( computedStyle.borderLeftWidth ) || 0;
6903        }
6904
6905        prevOffsetParent = offsetParent;
6906        offsetParent = elem.offsetParent;
6907      }
6908
6909      if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
6910        top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
6911        left += parseFloat( computedStyle.borderLeftWidth ) || 0;
6912      }
6913
6914      prevComputedStyle = computedStyle;
6915    }
6916
6917    if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
6918      top  += body.offsetTop;
6919      left += body.offsetLeft;
6920    }
6921
6922    if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
6923      top  += Math.max( docElem.scrollTop, body.scrollTop );
6924      left += Math.max( docElem.scrollLeft, body.scrollLeft );
6925    }
6926
6927    return { top: top, left: left };
6928  };
6929}
6930
6931jQuery.offset = {
6932  initialize: function() {
6933    var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
6934      html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
6935
6936    jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
6937
6938    container.innerHTML = html;
6939    body.insertBefore( container, body.firstChild );
6940    innerDiv = container.firstChild;
6941    checkDiv = innerDiv.firstChild;
6942    td = innerDiv.nextSibling.firstChild.firstChild;
6943
6944    this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
6945    this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
6946
6947    checkDiv.style.position = "fixed";
6948    checkDiv.style.top = "20px";
6949
6950    // safari subtracts parent border width here which is 5px
6951    this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
6952    checkDiv.style.position = checkDiv.style.top = "";
6953
6954    innerDiv.style.overflow = "hidden";
6955    innerDiv.style.position = "relative";
6956
6957    this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
6958
6959    this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
6960
6961    body.removeChild( container );
6962    body = container = innerDiv = checkDiv = table = td = null;
6963    jQuery.offset.initialize = jQuery.noop;
6964  },
6965
6966  bodyOffset: function( body ) {
6967    var top = body.offsetTop,
6968      left = body.offsetLeft;
6969
6970    jQuery.offset.initialize();
6971
6972    if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
6973      top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
6974      left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
6975    }
6976
6977    return { top: top, left: left };
6978  },
6979 
6980  setOffset: function( elem, options, i ) {
6981    var position = jQuery.css( elem, "position" );
6982
6983    // set position first, in-case top/left are set even on static elem
6984    if ( position === "static" ) {
6985      elem.style.position = "relative";
6986    }
6987
6988    var curElem = jQuery( elem ),
6989      curOffset = curElem.offset(),
6990      curCSSTop = jQuery.css( elem, "top" ),
6991      curCSSLeft = jQuery.css( elem, "left" ),
6992      calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1),
6993      props = {}, curPosition = {}, curTop, curLeft;
6994
6995    // need to be able to calculate position if either top or left is auto and position is absolute
6996    if ( calculatePosition ) {
6997      curPosition = curElem.position();
6998    }
6999
7000    curTop  = calculatePosition ? curPosition.top  : parseInt( curCSSTop,  10 ) || 0;
7001    curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0;
7002
7003    if ( jQuery.isFunction( options ) ) {
7004      options = options.call( elem, i, curOffset );
7005    }
7006
7007    if (options.top != null) {
7008      props.top = (options.top - curOffset.top) + curTop;
7009    }
7010    if (options.left != null) {
7011      props.left = (options.left - curOffset.left) + curLeft;
7012    }
7013   
7014    if ( "using" in options ) {
7015      options.using.call( elem, props );
7016    } else {
7017      curElem.css( props );
7018    }
7019  }
7020};
7021
7022
7023jQuery.fn.extend({
7024  position: function() {
7025    if ( !this[0] ) {
7026      return null;
7027    }
7028
7029    var elem = this[0],
7030
7031    // Get *real* offsetParent
7032    offsetParent = this.offsetParent(),
7033
7034    // Get correct offsets
7035    offset       = this.offset(),
7036    parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
7037
7038    // Subtract element margins
7039    // note: when an element has margin: auto the offsetLeft and marginLeft
7040    // are the same in Safari causing offset.left to incorrectly be 0
7041    offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
7042    offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
7043
7044    // Add offsetParent borders
7045    parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
7046    parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
7047
7048    // Subtract the two offsets
7049    return {
7050      top:  offset.top  - parentOffset.top,
7051      left: offset.left - parentOffset.left
7052    };
7053  },
7054
7055  offsetParent: function() {
7056    return this.map(function() {
7057      var offsetParent = this.offsetParent || document.body;
7058      while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
7059        offsetParent = offsetParent.offsetParent;
7060      }
7061      return offsetParent;
7062    });
7063  }
7064});
7065
7066
7067// Create scrollLeft and scrollTop methods
7068jQuery.each( ["Left", "Top"], function( i, name ) {
7069  var method = "scroll" + name;
7070
7071  jQuery.fn[ method ] = function(val) {
7072    var elem = this[0], win;
7073   
7074    if ( !elem ) {
7075      return null;
7076    }
7077
7078    if ( val !== undefined ) {
7079      // Set the scroll offset
7080      return this.each(function() {
7081        win = getWindow( this );
7082
7083        if ( win ) {
7084          win.scrollTo(
7085            !i ? val : jQuery(win).scrollLeft(),
7086             i ? val : jQuery(win).scrollTop()
7087          );
7088
7089        } else {
7090          this[ method ] = val;
7091        }
7092      });
7093    } else {
7094      win = getWindow( elem );
7095
7096      // Return the scroll offset
7097      return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
7098        jQuery.support.boxModel && win.document.documentElement[ method ] ||
7099          win.document.body[ method ] :
7100        elem[ method ];
7101    }
7102  };
7103});
7104
7105function getWindow( elem ) {
7106  return jQuery.isWindow( elem ) ?
7107    elem :
7108    elem.nodeType === 9 ?
7109      elem.defaultView || elem.parentWindow :
7110      false;
7111}
7112
7113
7114
7115
7116// Create innerHeight, innerWidth, outerHeight and outerWidth methods
7117jQuery.each([ "Height", "Width" ], function( i, name ) {
7118
7119  var type = name.toLowerCase();
7120
7121  // innerHeight and innerWidth
7122  jQuery.fn["inner" + name] = function() {
7123    return this[0] ?
7124      parseFloat( jQuery.css( this[0], type, "padding" ) ) :
7125      null;
7126  };
7127
7128  // outerHeight and outerWidth
7129  jQuery.fn["outer" + name] = function( margin ) {
7130    return this[0] ?
7131      parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
7132      null;
7133  };
7134
7135  jQuery.fn[ type ] = function( size ) {
7136    // Get window width or height
7137    var elem = this[0];
7138    if ( !elem ) {
7139      return size == null ? null : this;
7140    }
7141   
7142    if ( jQuery.isFunction( size ) ) {
7143      return this.each(function( i ) {
7144        var self = jQuery( this );
7145        self[ type ]( size.call( this, i, self[ type ]() ) );
7146      });
7147    }
7148
7149    if ( jQuery.isWindow( elem ) ) {
7150      // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
7151      return elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
7152        elem.document.body[ "client" + name ];
7153
7154    // Get document width or height
7155    } else if ( elem.nodeType === 9 ) {
7156      // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
7157      return Math.max(
7158        elem.documentElement["client" + name],
7159        elem.body["scroll" + name], elem.documentElement["scroll" + name],
7160        elem.body["offset" + name], elem.documentElement["offset" + name]
7161      );
7162
7163    // Get or set width or height on the element
7164    } else if ( size === undefined ) {
7165      var orig = jQuery.css( elem, type ),
7166        ret = parseFloat( orig );
7167
7168      return jQuery.isNaN( ret ) ? orig : ret;
7169
7170    // Set the width or height on the element (default to pixels if value is unitless)
7171    } else {
7172      return this.css( type, typeof size === "string" ? size : size + "px" );
7173    }
7174  };
7175
7176});
7177
7178
7179})(window);
Note: See TracBrowser for help on using the repository browser.