1    (function(){
2    /*
3     * jQuery 1.2.6 - New Wave Javascript
4     *
5     * Copyright (c) 2008 John Resig (jquery.com)
6     * Dual licensed under the MIT (MIT-LICENSE.txt)
7     * and GPL (GPL-LICENSE.txt) licenses.
8     *
9     * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
10    * $Rev: 5685 $
11    */
12   
13   // Map over jQuery in case of overwrite 
14   var _jQuery = window.jQuery,
15   // Map over the $ in case of overwrite 
16       _$ = window.$;
17   
18   var jQuery = window.jQuery = window.$ = function( selector, context ) {
19       // The jQuery object is actually just the init constructor 'enhanced' 
20       returnnew jQuery.fn.init( selector, context );
21   };
22   
23   // A simple way to check for HTML strings or ID strings 
24   // (both of which we optimize for) 
25   var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,
26   
27   // Is it a simple selector 
28       isSimple = /^.[^:#\[\.]*$/,
29   
30   // Will speed up references to undefined, and allows munging its name. 
31       undefined;
32   
33   jQuery.fn = jQuery.prototype = {
34       init: function( selector, context ) {
35           // Make sure that a selection was provided 
36           selector = selector || document;
37   
38           // Handle $(DOMElement) 
39           if ( selector.nodeType ) {
40               this[0] = selector;
41               this.length = 1;
42               returnthis;
43           }
44           // Handle HTML strings 
45           if ( typeof selector == "string" ) {
46               // Are we dealing with HTML string or an ID? 
47               var match = quickExpr.exec( selector );
48   
49               // Verify a match, and that no context was specified for #id 
50               if ( match && (match[1] || !context) ) {
51   
52                   // HANDLE: $(html) -> $(array) 
53                   if ( match[1] )
54                       selector = jQuery.clean( [ match[1] ], context );
55   
56                   // HANDLE: $("#id") 
57                   else {
58                       var elem = document.getElementById( match[3] );
59   
60                       // Make sure an element was located 
61                       if ( elem ){
62                           // Handle the case where IE and Opera return items 
63                           // by name instead of ID 
64                           if ( elem.id != match[3] )
65                               return jQuery().find( selector );
66   
67                           // Otherwise, we inject the element directly into the jQuery object 
68                           return jQuery( elem );
69                       }
70                       selector = [];
71                   }
72   
73               // HANDLE: $(expr, [context]) 
74               // (which is just equivalent to: $(content).find(expr) 
75               } else
76                   return jQuery( context ).find( selector );
77   
78           // HANDLE: $(function) 
79           // Shortcut for document ready 
80           } elseif ( jQuery.isFunction( selector ) )
81               return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
82   
83           returnthis.setArray(jQuery.makeArray(selector));
84       },
85   
86       // The current version of jQuery being used 
87       jquery: "1.2.6",
88   
89       // The number of elements contained in the matched element set 
90       size: function() {
91           returnthis.length;
92       },
93   
94       // The number of elements contained in the matched element set 
95       length: 0,
96   
97       // Get the Nth element in the matched element set OR 
98       // Get the whole matched element set as a clean array 
99       get: function( num ) {
100          return num == undefined ?
101  
102              // Return a 'clean' array 
103              jQuery.makeArray( this ) :
104  
105              // Return just the object 
106              this[ num ];
107      },
108  
109      // Take an array of elements and push it onto the stack 
110      // (returning the new matched element set) 
111      pushStack: function( elems ) {
112          // Build a new jQuery matched element set 
113          var ret = jQuery( elems );
114  
115          // Add the old object onto the stack (as a reference) 
116          ret.prevObject = this;
117  
118          // Return the newly-formed element set 
119          return ret;
120      },
121  
122      // Force the current matched set of elements to become 
123      // the specified array of elements (destroying the stack in the process) 
124      // You should use pushStack() in order to do this, but maintain the stack 
125      setArray: function( elems ) {
126          // Resetting the length to 0, then using the native Array push 
127          // is a super-fast way to populate an object with array-like properties 
128          this.length = 0;
129          Array.prototype.push.apply( this, elems );
130  
131          returnthis;
132      },
133  
134      // Execute a callback for every element in the matched set. 
135      // (You can seed the arguments with an array of args, but this is 
136      // only used internally.) 
137      each: function( callback, args ) {
138          return jQuery.each( this, callback, args );
139      },
140  
141      // Determine the position of an element within 
142      // the matched set of elements 
143      index: function( elem ) {
144          var ret = -1;
145  
146          // Locate the position of the desired element 
147          return jQuery.inArray(
148              // If it receives a jQuery object, the first element is used 
149              elem && elem.jquery ? elem[0] : elem
150          , this );
151      },
152  
153      attr: function( name, value, type ) {
154          var options = name;
155  
156          // Look for the case where we're accessing a style value 
157          if ( name.constructor == String )
158              if ( value === undefined )
159                  returnthis[0] && jQuery[ type || "attr" ]( this[0], name );
160  
161              else {
162                  options = {};
163                  options[ name ] = value;
164              }
165  
166          // Check to see if we're setting style values 
167          returnthis.each(function(i){
168              // Set all the styles 
169              for ( name in options )
170                  jQuery.attr(
171                      type ?
172                          this.style :
173                          this,
174                      name, jQuery.prop( this, options[ name ], type, i, name )
175                  );
176          });
177      },
178  
179      css: function( key, value ) {
180          // ignore negative width and height values 
181          if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
182              value = undefined;
183          returnthis.attr( key, value, "curCSS" );
184      },
185  
186      text: function( text ) {
187          if ( typeof text != "object" && text != null )
188              returnthis.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
189  
190          var ret = "";
191  
192          jQuery.each( text || this, function(){
193              jQuery.each( this.childNodes, function(){
194                  if ( this.nodeType != 8 )
195                      ret += this.nodeType != 1 ?
196                          this.nodeValue :
197                          jQuery.fn.text( [ this ] );
198              });
199          });
200  
201          return ret;
202      },
203  
204      wrapAll: function( html ) {
205          if ( this[0] )
206              // The elements to wrap the target around 
207              jQuery( html, this[0].ownerDocument )
208                  .clone()
209                  .insertBefore( this[0] )
210                  .map(function(){
211                      var elem = this;
212  
213                      while ( elem.firstChild )
214                          elem = elem.firstChild;
215  
216                      return elem;
217                  })
218                  .append(this);
219  
220          returnthis;
221      },
222  
223      wrapInner: function( html ) {
224          returnthis.each(function(){
225              jQuery( this ).contents().wrapAll( html );
226          });
227      },
228  
229      wrap: function( html ) {
230          returnthis.each(function(){
231              jQuery( this ).wrapAll( html );
232          });
233      },
234  
235      append: function() {
236          returnthis.domManip(arguments, true, false, function(elem){
237              if (this.nodeType == 1)
238                  this.appendChild( elem );
239          });
240      },
241  
242      prepend: function() {
243          returnthis.domManip(arguments, true, true, function(elem){
244              if (this.nodeType == 1)
245                  this.insertBefore( elem, this.firstChild );
246          });
247      },
248  
249      before: function() {
250          returnthis.domManip(arguments, false, false, function(elem){
251              this.parentNode.insertBefore( elem, this );
252          });
253      },
254  
255      after: function() {
256          returnthis.domManip(arguments, false, true, function(elem){
257              this.parentNode.insertBefore( elem, this.nextSibling );
258          });
259      },
260  
261      end: function() {
262          returnthis.prevObject || jQuery( [] );
263      },
264  
265      find: function( selector ) {
266          var elems = jQuery.map(this, function(elem){
267              return jQuery.find( selector, elem );
268          });
269  
270          returnthis.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
271              jQuery.unique( elems ) :
272              elems );
273      },
274  
275      clone: function( events ) {
276          // Do the clone 
277          var ret = this.map(function(){
278              if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
279                  // IE copies events bound via attachEvent when 
280                  // using cloneNode. Calling detachEvent on the 
281                  // clone will also remove the events from the orignal 
282                  // In order to get around this, we use innerHTML. 
283                  // Unfortunately, this means some modifications to 
284                  // attributes in IE that are actually only stored 
285                  // as properties will not be copied (such as the 
286                  // the name attribute on an input). 
287                  var clone = this.cloneNode(true),
288                      container = document.createElement("div");
289                  container.appendChild(clone);
290                  return jQuery.clean([container.innerHTML])[0];
291              } else
292                  returnthis.cloneNode(true);
293          });
294  
295          // Need to set the expando to null on the cloned set if it exists 
296          // removeData doesn't work here, IE removes it from the original as well 
297          // this is primarily for IE but the data expando shouldn't be copied over in any browser 
298          var clone = ret.find("*").andSelf().each(function(){
299              if ( this[ expando ] != undefined )
300                  this[ expando ] = null;
301          });
302  
303          // Copy the events from the original to the clone 
304          if ( events === true )
305              this.find("*").andSelf().each(function(i){
306                  if (this.nodeType == 3)
307                      return;
308                  var events = jQuery.data( this, "events" );
309  
310                  for ( var type in events )
311                      for ( var handler in events[ type ] )
312                          jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
313              });
314  
315          // Return the cloned set 
316          return ret;
317      },
318  
319      filter: function( selector ) {
320          returnthis.pushStack(
321              jQuery.isFunction( selector ) &&
322              jQuery.grep(this, function(elem, i){
323                  return selector.call( elem, i );
324              }) ||
325  
326              jQuery.multiFilter( selector, this ) );
327      },
328  
329      not: function( selector ) {
330          if ( selector.constructor == String )
331              // test special case where just one selector is passed in 
332              if ( isSimple.test( selector ) )
333                  returnthis.pushStack( jQuery.multiFilter( selector, this, true ) );
334              else
335                  selector = jQuery.multiFilter( selector, this );
336  
337          var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
338          returnthis.filter(function() {
339              return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
340          });
341      },
342  
343      add: function( selector ) {
344          returnthis.pushStack( jQuery.unique( jQuery.merge(
345              this.get(),
346              typeof selector == 'string' ?
347                  jQuery( selector ) :
348                  jQuery.makeArray( selector )
349          )));
350      },
351  
352      is: function( selector ) {
353          return !!selector && jQuery.multiFilter( selector, this ).length > 0;
354      },
355  
356      hasClass: function( selector ) {
357          returnthis.is( "." + selector );
358      },
359  
360      val: function( value ) {
361          if ( value == undefined ) {
362  
363              if ( this.length ) {
364                  var elem = this[0];
365  
366                  // We need to handle select boxes special 
367                  if ( jQuery.nodeName( elem, "select" ) ) {
368                      var index = elem.selectedIndex,
369                          values = [],
370                          options = elem.options,
371                          one = elem.type == "select-one";
372  
373                      // Nothing was selected 
374                      if ( index < 0 )
375                          returnnull;
376  
377                      // Loop through all the selected options 
378                      for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
379                          var option = options[ i ];
380  
381                          if ( option.selected ) {
382                              // Get the specifc value for the option 
383                              value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
384  
385                              // We don't need an array for one selects 
386                              if ( one )
387                                  returnvalue;
388  
389                              // Multi-Selects return an array 
390                              values.push( value );
391                          }
392                      }
393  
394                      return values;
395  
396                  // Everything else, we just grab the value 
397                  } else
398                      return (this[0].value || "").replace(/\r/g, "");
399  
400              }
401  
402              return undefined;
403          }
404  
405          if( value.constructor == Number )
406              value += '';
407  
408          returnthis.each(function(){
409              if ( this.nodeType != 1 )
410                  return;
411  
412              if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
413                  this.checked = (jQuery.inArray(this.value, value) >= 0 ||
414                      jQuery.inArray(this.name, value) >= 0);
415  
416              elseif ( jQuery.nodeName( this, "select" ) ) {
417                  var values = jQuery.makeArray(value);
418  
419                  jQuery( "option", this ).each(function(){
420                      this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
421                          jQuery.inArray( this.text, values ) >= 0);
422                  });
423  
424                  if ( !values.length )
425                      this.selectedIndex = -1;
426  
427              } else
428                  this.value = value;
429          });
430      },
431  
432      html: function( value ) {
433          returnvalue == undefined ?
434              (this[0] ?
435                  this[0].innerHTML :
436                  null) :
437              this.empty().append( value );
438      },
439  
440      replaceWith: function( value ) {
441          returnthis.after( value ).remove();
442      },
443  
444      eq: function( i ) {
445          returnthis.slice( i, i + 1 );
446      },
447  
448      slice: function() {
449          returnthis.pushStack( Array.prototype.slice.apply( this, arguments ) );
450      },
451  
452      map: function( callback ) {
453          returnthis.pushStack( jQuery.map(this, function(elem, i){
454              return callback.call( elem, i, elem );
455          }));
456      },
457  
458      andSelf: function() {
459          returnthis.add( this.prevObject );
460      },
461  
462      data: function( key, value ){
463          var parts = key.split(".");
464          parts[1] = parts[1] ? "." + parts[1] : "";
465  
466          if ( value === undefined ) {
467              var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
468  
469              if ( data === undefined && this.length )
470                  data = jQuery.data( this[0], key );
471  
472              return data === undefined && parts[1] ?
473                  this.data( parts[0] ) :
474                  data;
475          } else
476              returnthis.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
477                  jQuery.data( this, key, value );
478              });
479      },
480  
481      removeData: function( key ){
482          returnthis.each(function(){
483              jQuery.removeData( this, key );
484          });
485      },
486  
487      domManip: function( args, table, reverse, callback ) {
488          var clone = this.length > 1, elems;
489  
490          returnthis.each(function(){
491              if ( !elems ) {
492                  elems = jQuery.clean( args, this.ownerDocument );
493  
494                  if ( reverse )
495                      elems.reverse();
496              }
497  
498              var obj = this;
499  
500              if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
501                  obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
502  
503              var scripts = jQuery( [] );
504  
505              jQuery.each(elems, function(){
506                  var elem = clone ?
507                      jQuery( this ).clone( true )[0] :
508                      this;
509  
510                  // execute all scripts after the elements have been injected 
511                  if ( jQuery.nodeName( elem, "script" ) )
512                      scripts = scripts.add( elem );
513                  else {
514                      // Remove any inner scripts for later evaluation 
515                      if ( elem.nodeType == 1 )
516                          scripts = scripts.add( jQuery( "script", elem ).remove() );
517  
518                      // Inject the elements into the document 
519                      callback.call( obj, elem );
520                  }
521              });
522  
523              scripts.each( evalScript );
524          });
525      }
526  };
527  
528  // Give the init function the jQuery prototype for later instantiation 
529  jQuery.fn.init.prototype = jQuery.fn;
530  
531  function evalScript( i, elem ) {
532      if ( elem.src )
533          jQuery.ajax({
534              url: elem.src,
535              async: false,
536              dataType: "script"
537          });
538  
539      else
540          jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
541  
542      if ( elem.parentNode )
543          elem.parentNode.removeChild( elem );
544  }
545  
546  function now(){
547      return +newDate;
548  }
549  
550  jQuery.extend = jQuery.fn.extend = function() {
551      // copy reference to target object 
552      var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
553  
554      // Handle a deep copy situation 
555      if ( target.constructor == Boolean ) {
556          deep = target;
557          target = arguments[1] || {};
558          // skip the boolean and the target 
559          i = 2;
560      }
561  
562      // Handle case when target is a string or something (possible in deep copy) 
563      if ( typeof target != "object" && typeof target != "function" )
564          target = {};
565  
566      // extend jQuery itself if only one argument is passed 
567      if ( length == i ) {
568          target = this;
569          --i;
570      }
571  
572      for ( ; i < length; i++ )
573          // Only deal with non-null/undefined values 
574          if ( (options = arguments[ i ]) != null )
575              // Extend the base object 
576              for ( var name in options ) {
577                  var src = target[ name ], copy = options[ name ];
578  
579                  // Prevent never-ending loop 
580                  if ( target === copy )
581                      continue;
582  
583                  // Recurse if we're merging object values 
584                  if ( deep && copy && typeof copy == "object" && !copy.nodeType )
585                      target[ name ] = jQuery.extend( deep, 
586                          // Never move original objects, clone them 
587                          src || ( copy.length != null ? [ ] : { } )
588                      , copy );
589  
590                  // Don't bring in undefined values 
591                  elseif ( copy !== undefined )
592                      target[ name ] = copy;
593  
594              }
595  
596      // Return the modified object 
597      return target;
598  };
599  
600  var expando = "jQuery" + now(), uuid = 0, windowData = {},
601      // exclude the following css properties to add px 
602      exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
603      // cache defaultView 
604      defaultView = document.defaultView || {};
605  
606  jQuery.extend({
607      noConflict: function( deep ) {
608          window.$ = _$;
609  
610          if ( deep )
611              window.jQuery = _jQuery;
612  
613          return jQuery;
614      },
615  
616      // See test/unit/core.js for details concerning this function. 
617      isFunction: function( fn ) {
618          return !!fn && typeof fn != "string" && !fn.nodeName &&
619              fn.constructor != Array && /^[\s[]?function/.test( fn + "" );
620      },
621  
622      // check if an element is in a (or is an) XML document 
623      isXMLDoc: function( elem ) {
624          return elem.documentElement && !elem.body ||
625              elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
626      },
627  
628      // Evalulates a script in a global context 
629      globalEval: function( data ) {
630          data = jQuery.trim( data );
631  
632          if ( data ) {
633              // Inspired by code by Andrea Giammarchi 
634              // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html 
635              var head = document.getElementsByTagName("head")[0] || document.documentElement,
636                  script = document.createElement("script");
637  
638              script.type = "text/javascript";
639              if ( jQuery.browser.msie )
640                  script.text = data;
641              else
642                  script.appendChild( document.createTextNode( data ) );
643  
644              // Use insertBefore instead of appendChild  to circumvent an IE6 bug. 
645              // This arises when a base node is used (#2709). 
646              head.insertBefore( script, head.firstChild );
647              head.removeChild( script );
648          }
649      },
650  
651      nodeName: function( elem, name ) {
652          return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
653      },
654  
655      cache: {},
656  
657      data: function( elem, name, data ) {
658          elem = elem == window ?
659              windowData :
660              elem;
661  
662          var id = elem[ expando ];
663  
664          // Compute a unique ID for the element 
665          if ( !id )
666              id = elem[ expando ] = ++uuid;
667  
668          // Only generate the data cache if we're 
669          // trying to access or manipulate it 
670          if ( name && !jQuery.cache[ id ] )
671              jQuery.cache[ id ] = {};
672  
673          // Prevent overriding the named cache with undefined values 
674          if ( data !== undefined )
675              jQuery.cache[ id ][ name ] = data;
676  
677          // Return the named cache data, or the ID for the element 
678          return name ?
679              jQuery.cache[ id ][ name ] :
680              id;
681      },
682  
683      removeData: function( elem, name ) {
684          elem = elem == window ?
685              windowData :
686              elem;
687  
688          var id = elem[ expando ];
689  
690          // If we want to remove a specific section of the element's data 
691          if ( name ) {
692              if ( jQuery.cache[ id ] ) {
693                  // Remove the section of cache data 
694                  delete jQuery.cache[ id ][ name ];
695  
696                  // If we've removed all the data, remove the element's cache 
697                  name = "";
698  
699                  for ( name in jQuery.cache[ id ] )
700                      break;
701  
702                  if ( !name )
703                      jQuery.removeData( elem );
704              }
705  
706          // Otherwise, we want to remove all of the element's data 
707          } else {
708              // Clean up the element expando 
709              try {
710                  delete elem[ expando ];
711              } catch(e){
712                  // IE has trouble directly removing the expando 
713                  // but it's ok with using removeAttribute 
714                  if ( elem.removeAttribute )
715                      elem.removeAttribute( expando );
716              }
717  
718              // Completely remove the data cache 
719              delete jQuery.cache[ id ];
720          }
721      },
722  
723      // args is for internal usage only 
724      each: function( object, callback, args ) {
725          var name, i = 0, length = object.length;
726  
727          if ( args ) {
728              if ( length == undefined ) {
729                  for ( name in object )
730                      if ( callback.apply( object[ name ], args ) === false )
731                          break;
732              } else
733                  for ( ; i < length; )
734                      if ( callback.apply( object[ i++ ], args ) === false )
735                          break;
736  
737          // A special, fast, case for the most common use of each 
738          } else {
739              if ( length == undefined ) {
740                  for ( name in object )
741                      if ( callback.call( object[ name ], name, object[ name ] ) === false )
742                          break;
743              } else
744                  for ( varvalue = object[0];
745                      i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
746          }
747  
748          return object;
749      },
750  
751      prop: function( elem, value, type, i, name ) {
752          // Handle executable functions 
753          if ( jQuery.isFunction( value ) )
754              value = value.call( elem, i );
755  
756          // Handle passing in a number to a CSS property 
757          returnvalue && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
758              value + "px" :
759              value;
760      },
761  
762      className: {
763          // internal only, use addClass("class") 
764          add: function( elem, classNames ) {
765              jQuery.each((classNames || "").split(/\s+/), function(i, className){
766                  if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
767                      elem.className += (elem.className ? " " : "") + className;
768              });
769          },
770  
771          // internal only, use removeClass("class") 
772          remove: function( elem, classNames ) {
773              if (elem.nodeType == 1)
774                  elem.className = classNames != undefined ?
775                      jQuery.grep(elem.className.split(/\s+/), function(className){
776                          return !jQuery.className.has( classNames, className );
777                      }).join(" ") :
778                      "";
779          },
780  
781          // internal only, use hasClass("class") 
782          has: function( elem, className ) {
783              return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
784          }
785      },
786  
787      // A method for quickly swapping in/out CSS properties to get correct calculations 
788      swap: function( elem, options, callback ) {
789          var old = {};
790          // Remember the old values, and insert the new ones 
791          for ( var name in options ) {
792              old[ name ] = elem.style[ name ];
793              elem.style[ name ] = options[ name ];
794          }
795  
796          callback.call( elem );
797  
798          // Revert the old values 
799          for ( var name in options )
800              elem.style[ name ] = old[ name ];
801      },
802  
803      css: function( elem, name, force ) {
804          if ( name == "width" || name == "height" ) {
805              var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
806  
807              function getWH() {
808                  val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
809                  var padding = 0, border = 0;
810                  jQuery.each( which, function() {
811                      padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
812                      border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
813                  });
814                  val -= Math.round(padding + border);
815              }
816  
817              if ( jQuery(elem).is(":visible") )
818                  getWH();
819              else
820                  jQuery.swap( elem, props, getWH );
821  
822              returnMath.max(0, val);
823          }
824  
825          return jQuery.curCSS( elem, name, force );
826      },
827  
828      curCSS: function( elem, name, force ) {
829          var ret, style = elem.style;
830  
831          // A helper method for determining if an element's values are broken 
832          function color( elem ) {
833              if ( !jQuery.browser.safari )
834                  returnfalse;
835  
836              // defaultView is cached 
837              var ret = defaultView.getComputedStyle( elem, null );
838              return !ret || ret.getPropertyValue("color") == "";
839          }
840  
841          // We need to handle opacity special in IE 
842          if ( name == "opacity" && jQuery.browser.msie ) {
843              ret = jQuery.attr( style, "opacity" );
844  
845              return ret == "" ?
846                  "1" :
847                  ret;
848          }
849          // Opera sometimes will give the wrong display answer, this fixes it, see #2037 
850          if ( jQuery.browser.opera && name == "display" ) {
851              var save = style.outline;
852              style.outline = "0 solid black";
853              style.outline = save;
854          }
855  
856          // Make sure we're using the right name for getting the float value 
857          if ( name.match( /float/i ) )
858              name = styleFloat;
859  
860          if ( !force && style && style[ name ] )
861              ret = style[ name ];
862  
863          elseif ( defaultView.getComputedStyle ) {
864  
865              // Only "float" is needed here 
866              if ( name.match( /float/i ) )
867                  name = "float";
868  
869              name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
870  
871              var computedStyle = defaultView.getComputedStyle( elem, null );
872  
873              if ( computedStyle && !color( elem ) )
874                  ret = computedStyle.getPropertyValue( name );
875  
876              // If the element isn't reporting its values properly in Safari 
877              // then some display: none elements are involved 
878              else {
879                  var swap = [], stack = [], a = elem, i = 0;
880  
881                  // Locate all of the parent display: none elements 
882                  for ( ; a && color(a); a = a.parentNode )
883                      stack.unshift(a);
884  
885                  // Go through and make them visible, but in reverse 
886                  // (It would be better if we knew the exact display type that they had) 
887                  for ( ; i < stack.length; i++ )
888                      if ( color( stack[ i ] ) ) {
889                          swap[ i ] = stack[ i ].style.display;
890                          stack[ i ].style.display = "block";
891                      }
892  
893                  // Since we flip the display style, we have to handle that 
894                  // one special, otherwise get the value 
895                  ret = name == "display" && swap[ stack.length - 1 ] != null ?
896                      "none" :
897                      ( computedStyle && computedStyle.getPropertyValue( name ) ) || "";
898  
899                  // Finally, revert the display styles back 
900                  for ( i = 0; i < swap.length; i++ )
901                      if ( swap[ i ] != null )
902                          stack[ i ].style.display = swap[ i ];
903              }
904  
905              // We should always get a number back from opacity 
906              if ( name == "opacity" && ret == "" )
907                  ret = "1";
908  
909          } elseif ( elem.currentStyle ) {
910              var camelCase = name.replace(/\-(\w)/g, function(all, letter){
911                  return letter.toUpperCase();
912              });
913  
914              ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
915  
916              // From the awesome hack by Dean Edwards 
917              // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 
918  
919              // If we're not dealing with a regular pixel number 
920              // but a number that has a weird ending, we need to convert it to pixels 
921              if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
922                  // Remember the original values 
923                  var left = style.left, rsLeft = elem.runtimeStyle.left;
924  
925                  // Put in the new values to get a computed value out 
926                  elem.runtimeStyle.left = elem.currentStyle.left;
927                  style.left = ret || 0;
928                  ret = style.pixelLeft + "px";
929  
930                  // Revert the changed values 
931                  style.left = left;
932                  elem.runtimeStyle.left = rsLeft;
933              }
934          }
935  
936          return ret;
937      },
938  
939      clean: function( elems, context ) {
940          var ret = [];
941          context = context || document;
942          // !context.createElement fails in IE with an error but returns typeof 'object' 
943          if (typeof context.createElement == 'undefined')
944              context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
945  
946          jQuery.each(elems, function(i, elem){
947              if ( !elem )
948                  return;
949  
950              if ( elem.constructor == Number )
951                  elem += '';
952  
953              // Convert html string into DOM nodes 
954              if ( typeof elem == "string" ) {
955                  // Fix "XHTML"-style tags in all browsers 
956                  elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
957                      return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
958                          all :
959                          front + "></" + tag + ">";
960                  });
961  
962                  // Trim whitespace, otherwise indexOf won't work as expected 
963                  var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
964  
965                  var wrap =
966                      // option or optgroup 
967                      !tags.indexOf("<opt") &&
968                      [ 1, "<select multiple='multiple'>", "</select>" ] ||
969  
970                      !tags.indexOf("<leg") &&
971                      [ 1, "<fieldset>", "</fieldset>" ] ||
972  
973                      tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
974                      [ 1, "<table>", "</table>" ] ||
975  
976                      !tags.indexOf("<tr") &&
977                      [ 2, "<table><tbody>", "</tbody></table>" ] ||
978  
979                       // <thead> matched above 
980                      (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
981                      [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
982  
983                      !tags.indexOf("<col") &&
984                      [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
985  
986                      // IE can't serialize <link> and <script> tags normally 
987                      jQuery.browser.msie &&
988                      [ 1, "div<div>", "</div>" ] ||
989  
990                      [ 0, "", "" ];
991  
992                  // Go to html and back, then peel off extra wrappers 
993                  div.innerHTML = wrap[1] + elem + wrap[2];
994  
995                  // Move to the right depth 
996                  while ( wrap[0]-- )
997                      div = div.lastChild;
998  
999                  // Remove IE's autoinserted <tbody> from table fragments 
1000                 if ( jQuery.browser.msie ) {
1001
1002                     // String was a <table>, *may* have spurious <tbody> 
1003                     var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
1004                         div.firstChild && div.firstChild.childNodes :
1005
1006                         // String was a bare <thead> or <tfoot> 
1007                         wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
1008                             div.childNodes :
1009                             [];
1010
1011                     for ( var j = tbody.length - 1; j >= 0 ; --j )
1012                         if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
1013                             tbody[ j ].parentNode.removeChild( tbody[ j ] );
1014
1015                     // IE completely kills leading whitespace when innerHTML is used 
1016                     if ( /^\s/.test( elem ) )
1017                         div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
1018
1019                 }
1020
1021                 elem = jQuery.makeArray( div.childNodes );
1022             }
1023
1024             if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
1025                 return;
1026
1027             if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
1028                 ret.push( elem );
1029
1030             else
1031                 ret = jQuery.merge( ret, elem );
1032
1033         });
1034
1035         return ret;
1036     },
1037
1038     attr: function( elem, name, value ) {
1039         // don't set attributes on text and comment nodes 
1040         if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
1041             return undefined;
1042
1043         var notxml = !jQuery.isXMLDoc( elem ),
1044             // Whether we are setting (or getting) 
1045             set = value !== undefined,
1046             msie = jQuery.browser.msie;
1047
1048         // Try to normalize/fix the name 
1049         name = notxml && jQuery.props[ name ] || name;
1050
1051         // Only do all the following if this is a node (faster for style) 
1052         // IE elem.getAttribute passes even for style 
1053         if ( elem.tagName ) {
1054
1055             // These attributes require special treatment 
1056             var special = /href|src|style/.test( name );
1057
1058             // Safari mis-reports the default selected property of a hidden option 
1059             // Accessing the parent's selectedIndex property fixes it 
1060             if ( name == "selected" && jQuery.browser.safari )
1061                 elem.parentNode.selectedIndex;
1062
1063             // If applicable, access the attribute via the DOM 0 way 
1064             if ( name in elem && notxml && !special ) {
1065                 if ( set ){
1066                     // We can't allow the type property to be changed (since it causes problems in IE) 
1067                     if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
1068                         throw"type property can't be changed";
1069
1070                     elem[ name ] = value;
1071                 }
1072
1073                 // browsers index elements by id/name on forms, give priority to attributes. 
1074                 if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
1075                     return elem.getAttributeNode( name ).nodeValue;
1076
1077                 return elem[ name ];
1078             }
1079
1080             if ( msie && notxml &&  name == "style" )
1081                 return jQuery.attr( elem.style, "cssText", value );
1082
1083             if ( set )
1084                 // convert the value to a string (all browsers do this but IE) see #1070 
1085                 elem.setAttribute( name, "" + value );
1086
1087             var attr = msie && notxml && special
1088                     // Some attributes require a special call on IE 
1089                     ? elem.getAttribute( name, 2 )
1090                     : elem.getAttribute( name );
1091
1092             // Non-existent attributes return null, we normalize to undefined 
1093             return attr === null ? undefined : attr;
1094         }
1095
1096         // elem is actually elem.style ... set the style 
1097
1098         // IE uses filters for opacity 
1099         if ( msie && name == "opacity" ) {
1100             if ( set ) {
1101                 // IE has trouble with opacity if it does not have layout 
1102                 // Force it by setting the zoom level 
1103                 elem.zoom = 1;
1104
1105                 // Set the alpha filter to set the opacity 
1106                 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
1107                     (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
1108             }
1109
1110             return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
1111                 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
1112                 "";
1113         }
1114
1115         name = name.replace(/-([a-z])/ig, function(all, letter){
1116             return letter.toUpperCase();
1117         });
1118
1119         if ( set )
1120             elem[ name ] = value;
1121
1122         return elem[ name ];
1123     },
1124
1125     trim: function( text ) {
1126         return (text || "").replace( /^\s+|\s+$/g, "" );
1127     },
1128
1129     makeArray: function( array ) {
1130         var ret = [];
1131
1132         if( array != null ){
1133             var i = array.length;
1134             //the window, strings and functions also have 'length' 
1135             if( i == null || array.split || array.setInterval || array.call )
1136                 ret[0] = array;
1137             else
1138                 while( i )
1139                     ret[--i] = array[i];
1140         }
1141
1142         return ret;
1143     },
1144
1145     inArray: function( elem, array ) {
1146         for ( var i = 0, length = array.length; i < length; i++ )
1147         // Use === because on IE, window == document 
1148             if ( array[ i ] === elem )
1149                 return i;
1150
1151         return -1;
1152     },
1153
1154     merge: function( first, second ) {
1155         // We have to loop this way because IE & Opera overwrite the length 
1156         // expando of getElementsByTagName 
1157         var i = 0, elem, pos = first.length;
1158         // Also, we need to make sure that the correct elements are being returned 
1159         // (IE returns comment nodes in a '*' query) 
1160         if ( jQuery.browser.msie ) {
1161             while ( elem = second[ i++ ] )
1162                 if ( elem.nodeType != 8 )
1163                     first[ pos++ ] = elem;
1164
1165         } else
1166             while ( elem = second[ i++ ] )
1167                 first[ pos++ ] = elem;
1168
1169         return first;
1170     },
1171
1172     unique: function( array ) {
1173         var ret = [], done = {};
1174
1175         try {
1176
1177             for ( var i = 0, length = array.length; i < length; i++ ) {
1178                 var id = jQuery.data( array[ i ] );
1179
1180                 if ( !done[ id ] ) {
1181                     done[ id ] = true;
1182                     ret.push( array[ i ] );
1183                 }
1184             }
1185
1186         } catch( e ) {
1187             ret = array;
1188         }
1189
1190         return ret;
1191     },
1192
1193     grep: function( elems, callback, inv ) {
1194         var ret = [];
1195
1196         // Go through the array, only saving the items 
1197         // that pass the validator function 
1198         for ( var i = 0, length = elems.length; i < length; i++ )
1199             if ( !inv != !callback( elems[ i ], i ) )
1200                 ret.push( elems[ i ] );
1201
1202         return ret;
1203     },
1204
1205     map: function( elems, callback ) {
1206         var ret = [];
1207
1208         // Go through the array, translating each of the items to their 
1209         // new value (or values). 
1210         for ( var i = 0, length = elems.length; i < length; i++ ) {
1211             varvalue = callback( elems[ i ], i );
1212
1213             if ( value != null )
1214                 ret[ ret.length ] = value;
1215         }
1216
1217         return ret.concat.apply( [], ret );
1218     }
1219 });
1220
1221var userAgent = navigator.userAgent.toLowerCase();
1222
1223// Figure out what browser is being used 
1224 jQuery.browser = {
1225     version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
1226     safari: /webkit/.test( userAgent ),
1227     opera: /opera/.test( userAgent ),
1228     msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
1229     mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
1230 };
1231
1232var styleFloat = jQuery.browser.msie ?
1233     "styleFloat" :
1234     "cssFloat";
1235
1236 jQuery.extend({
1237     // Check to see if the W3C box model is being used 
1238     boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
1239
1240     props: {
1241         "for": "htmlFor",
1242         "class": "className",
1243         "float": styleFloat,
1244         cssFloat: styleFloat,
1245         styleFloat: styleFloat,
1246         readonly: "readOnly",
1247         maxlength: "maxLength",
1248         cellspacing: "cellSpacing"
1249     }
1250 });
1251
1252 jQuery.each({
1253     parent: function(elem){return elem.parentNode;},
1254     parents: function(elem){return jQuery.dir(elem,"parentNode");},
1255     next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
1256     prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
1257     nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
1258     prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
1259     siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
1260     children: function(elem){return jQuery.sibling(elem.firstChild);},
1261     contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
1262 }, function(name, fn){
1263     jQuery.fn[ name ] = function( selector ) {
1264         var ret = jQuery.map( this, fn );
1265
1266         if ( selector && typeof selector == "string" )
1267             ret = jQuery.multiFilter( selector, ret );
1268
1269         returnthis.pushStack( jQuery.unique( ret ) );
1270     };
1271 });
1272
1273 jQuery.each({
1274     appendTo: "append",
1275     prependTo: "prepend",
1276     insertBefore: "before",
1277     insertAfter: "after",
1278     replaceAll: "replaceWith"
1279 }, function(name, original){
1280     jQuery.fn[ name ] = function() {
1281         var args = arguments;
1282
1283         returnthis.each(function(){
1284             for ( var i = 0, length = args.length; i < length; i++ )
1285                 jQuery( args[ i ] )[ original ]( this );
1286         });
1287     };
1288 });
1289
1290 jQuery.each({
1291     removeAttr: function( name ) {
1292         jQuery.attr( this, name, "" );
1293         if (this.nodeType == 1)
1294             this.removeAttribute( name );
1295     },
1296
1297     addClass: function( classNames ) {
1298         jQuery.className.add( this, classNames );
1299     },
1300
1301     removeClass: function( classNames ) {
1302         jQuery.className.remove( this, classNames );
1303     },
1304
1305     toggleClass: function( classNames ) {
1306         jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
1307     },
1308
1309     remove: function( selector ) {
1310         if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
1311             // Prevent memory leaks 
1312             jQuery( "*", this ).add(this).each(function(){
1313                 jQuery.event.remove(this);
1314                 jQuery.removeData(this);
1315             });
1316             if (this.parentNode)
1317                 this.parentNode.removeChild( this );
1318         }
1319     },
1320
1321     empty: function() {
1322         // Remove element nodes and prevent memory leaks 
1323         jQuery( ">*", this ).remove();
1324
1325         // Remove any remaining nodes 
1326         while ( this.firstChild )
1327             this.removeChild( this.firstChild );
1328     }
1329 }, function(name, fn){
1330     jQuery.fn[ name ] = function(){
1331         returnthis.each( fn, arguments );
1332     };
1333 });
1334
1335 jQuery.each([ "Height", "Width" ], function(i, name){
1336     var type = name.toLowerCase();
1337
1338     jQuery.fn[ type ] = function( size ) {
1339         // Get window width or height 
1340         returnthis[0] == window ?
1341             // Opera reports document.body.client[Width/Height] properly in both quirks and standards 
1342             jQuery.browser.opera && document.body[ "client" + name ] ||
1343
1344             // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths) 
1345             jQuery.browser.safari && window[ "inner" + name ] ||
1346
1347             // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode 
1348             document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
1349
1350             // Get document width or height 
1351             this[0] == document ?
1352                 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater 
1353                 Math.max(
1354                     Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
1355                     Math.max(document.body["offset" + name], document.documentElement["offset" + name])
1356                 ) :
1357
1358                 // Get or set width or height on the element 
1359                 size == undefined ?
1360                     // Get width or height on the element 
1361                     (this.length ? jQuery.css( this[0], type ) : null) :
1362
1363                     // Set the width or height on the element (default to pixels if value is unitless) 
1364                     this.css( type, size.constructor == String ? size : size + "px" );
1365     };
1366 });
1367
1368// Helper function used by the dimensions and offset modules 
1369function num(elem, prop) {
1370     return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
1371 }var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
1372         "(?:[\\w*_-]|\\\\.)" :
1373         "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
1374     quickChild = new RegExp("^>\\s*(" + chars + "+)"),
1375     quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
1376     quickClass = new RegExp("^([#.]?)(" + chars + "*)");
1377
1378 jQuery.extend({
1379     expr: {
1380         "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
1381         "#": function(a,i,m){return a.getAttribute("id")==m[2];},
1382         ":": {
1383             // Position Checks 
1384             lt: function(a,i,m){return i<m[3]-0;},
1385             gt: function(a,i,m){return i>m[3]-0;},
1386             nth: function(a,i,m){return m[3]-0==i;},
1387             eq: function(a,i,m){return m[3]-0==i;},
1388             first: function(a,i){return i==0;},
1389             last: function(a,i,m,r){return i==r.length-1;},
1390             even: function(a,i){return i%2==0;},
1391             odd: function(a,i){return i%2;},
1392
1393             // Child Checks 
1394             "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
1395             "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
1396             "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},
1397
1398             // Parent Checks 
1399             parent: function(a){return a.firstChild;},
1400             empty: function(a){return !a.firstChild;},
1401
1402             // Text Check 
1403             contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
1404
1405             // Visibility 
1406             visible: function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
1407             hidden: function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},
1408
1409             // Form attributes 
1410             enabled: function(a){return !a.disabled;},
1411             disabled: function(a){return a.disabled;},
1412             checked: function(a){return a.checked;},
1413             selected: function(a){return a.selected||jQuery.attr(a,"selected");},
1414
1415             // Form elements 
1416             text: function(a){return"text"==a.type;},
1417             radio: function(a){return"radio"==a.type;},
1418             checkbox: function(a){return"checkbox"==a.type;},
1419             file: function(a){return"file"==a.type;},
1420             password: function(a){return"password"==a.type;},
1421             submit: function(a){return"submit"==a.type;},
1422             image: function(a){return"image"==a.type;},
1423             reset: function(a){return"reset"==a.type;},
1424             button: function(a){return"button"==a.type||jQuery.nodeName(a,"button");},
1425             input: function(a){return/input|select|textarea|button/i.test(a.nodeName);},
1426
1427             // :has() 
1428             has: function(a,i,m){return jQuery.find(m[3],a).length;},
1429
1430             // :header 
1431             header: function(a){return/h\d/i.test(a.nodeName);},
1432
1433             // :animated 
1434             animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
1435         }
1436     },
1437
1438     // The regular expressions that power the parsing engine 
1439     parse: [
1440         // Match: [@value='test'], [@foo] 
1441         /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
1442
1443         // Match: :contains('foo') 
1444         /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
1445
1446         // Match: :even, :last-child, #id, .class 
1447         new RegExp("^([:.#]*)(" + chars + "+)")
1448     ],
1449
1450     multiFilter: function( expr, elems, not ) {
1451         var old, cur = [];
1452
1453         while ( expr && expr != old ) {
1454             old = expr;
1455             var f = jQuery.filter( expr, elems, not );
1456             expr = f.t.replace(/^\s*,\s*/, "" );
1457             cur = not ? elems = f.r : jQuery.merge( cur, f.r );
1458         }
1459
1460         return cur;
1461     },
1462
1463     find: function( t, context ) {
1464         // Quickly handle non-string expressions 
1465         if ( typeof t != "string" )
1466             return [ t ];
1467
1468         // check to make sure context is a DOM element or a document 
1469         if ( context && context.nodeType != 1 && context.nodeType != 9)
1470             return [ ];
1471
1472         // Set the correct context (if none is provided) 
1473         context = context || document;
1474
1475         // Initialize the search 
1476         var ret = [context], done = [], last, nodeName;
1477
1478         // Continue while a selector expression exists, and while 
1479         // we're no longer looping upon ourselves 
1480         while ( t && last != t ) {
1481             var r = [];
1482             last = t;
1483
1484             t = jQuery.trim(t);
1485
1486             var foundToken = false,
1487
1488             // An attempt at speeding up child selectors that 
1489             // point to a specific element tag 
1490                 re = quickChild,
1491
1492                 m = re.exec(t);
1493
1494             if ( m ) {
1495                 nodeName = m[1].toUpperCase();
1496
1497                 // Perform our own iteration and filter 
1498                 for ( var i = 0; ret[i]; i++ )
1499                     for ( var c = ret[i].firstChild; c; c = c.nextSibling )
1500                         if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
1501                             r.push( c );
1502
1503                 ret = r;
1504                 t = t.replace( re, "" );
1505                 if ( t.indexOf(" ") == 0 ) continue;
1506                 foundToken = true;
1507             } else {
1508                 re = /^([>+~])\s*(\w*)/i;
1509
1510                 if ( (m = re.exec(t)) != null ) {
1511                     r = [];
1512
1513                     var merge = {};
1514                     nodeName = m[2].toUpperCase();
1515                     m = m[1];
1516
1517                     for ( var j = 0, rl = ret.length; j < rl; j++ ) {
1518                         var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
1519                         for ( ; n; n = n.nextSibling )
1520                             if ( n.nodeType == 1 ) {
1521                                 var id = jQuery.data(n);
1522
1523                                 if ( m == "~" && merge[id] ) break;
1524
1525                                 if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
1526                                     if ( m == "~" ) merge[id] = true;
1527                                     r.push( n );
1528                                 }
1529
1530                                 if ( m == "+" ) break;
1531                             }
1532                     }
1533
1534                     ret = r;
1535
1536                     // And remove the token 
1537                     t = jQuery.trim( t.replace( re, "" ) );
1538                     foundToken = true;
1539                 }
1540             }
1541
1542             // See if there's still an expression, and that we haven't already 
1543             // matched a token 
1544             if ( t && !foundToken ) {
1545                 // Handle multiple expressions 
1546                 if ( !t.indexOf(",") ) {
1547                     // Clean the result set 
1548                     if ( context == ret[0] ) ret.shift();
1549
1550                     // Merge the result sets 
1551                     done = jQuery.merge( done, ret );
1552
1553                     // Reset the context 
1554                     r = ret = [context];
1555
1556                     // Touch up the selector string 
1557                     t = " " + t.substr(1,t.length);
1558
1559                 } else {
1560                     // Optimize for the case nodeName#idName 
1561                     var re2 = quickID;
1562                     var m = re2.exec(t);
1563
1564                     // Re-organize the results, so that they're consistent 
1565                     if ( m ) {
1566                         m = [ 0, m[2], m[3], m[1] ];
1567
1568                     } else {
1569                         // Otherwise, do a traditional filter check for 
1570                         // ID, class, and element selectors 
1571                         re2 = quickClass;
1572                         m = re2.exec(t);
1573                     }
1574
1575                     m[2] = m[2].replace(/\\/g, "");
1576
1577                     var elem = ret[ret.length-1];
1578
1579                     // Try to do a global search by ID, where we can 
1580                     if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
1581                         // Optimization for HTML document case 
1582                         var oid = elem.getElementById(m[2]);
1583
1584                         // Do a quick check for the existence of the actual ID attribute 
1585                         // to avoid selecting by the name attribute in IE 
1586                         // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form 
1587                         if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
1588                             oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
1589
1590                         // Do a quick check for node name (where applicable) so 
1591                         // that div#foo searches will be really fast 
1592                         ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
1593                     } else {
1594                         // We need to find all descendant elements 
1595                         for ( var i = 0; ret[i]; i++ ) {
1596                             // Grab the tag name being searched for 
1597                             var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
1598
1599                             // Handle IE7 being really dumb about <object>s 
1600                             if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
1601                                 tag = "param";
1602
1603                             r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
1604                         }
1605
1606                         // It's faster to filter by class and be done with it 
1607                         if ( m[1] == "." )
1608                             r = jQuery.classFilter( r, m[2] );
1609
1610                         // Same with ID filtering 
1611                         if ( m[1] == "#" ) {
1612                             var tmp = [];
1613
1614                             // Try to find the element with the ID 
1615                             for ( var i = 0; r[i]; i++ )
1616                                 if ( r[i].getAttribute("id") == m[2] ) {
1617                                     tmp = [ r[i] ];
1618                                     break;
1619                                 }
1620
1621                             r = tmp;
1622                         }
1623
1624                         ret = r;
1625                     }
1626
1627                     t = t.replace( re2, "" );
1628                 }
1629
1630             }
1631
1632             // If a selector string still exists 
1633             if ( t ) {
1634                 // Attempt to filter it 
1635                 var val = jQuery.filter(t,r);
1636                 ret = r = val.r;
1637                 t = jQuery.trim(val.t);
1638             }
1639         }
1640
1641         // An error occurred with the selector; 
1642         // just return an empty set instead 
1643         if ( t )
1644             ret = [];
1645
1646         // Remove the root context 
1647         if ( ret && context == ret[0] )
1648             ret.shift();
1649
1650         // And combine the results 
1651         done = jQuery.merge( done, ret );
1652
1653         return done;
1654     },
1655
1656     classFilter: function(r,m,not){
1657         m = " " + m + " ";
1658         var tmp = [];
1659         for ( var i = 0; r[i]; i++ ) {
1660             var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
1661             if ( !not && pass || not && !pass )
1662                 tmp.push( r[i] );
1663         }
1664         return tmp;
1665     },
1666
1667     filter: function(t,r,not) {
1668         var last;
1669
1670         // Look for common filter expressions 
1671         while ( t && t != last ) {
1672             last = t;
1673
1674             var p = jQuery.parse, m;
1675
1676             for ( var i = 0; p[i]; i++ ) {
1677                 m = p[i].exec( t );
1678
1679                 if ( m ) {
1680                     // Remove what we just matched 
1681                     t = t.substring( m[0].length );
1682
1683                     m[2] = m[2].replace(/\\/g, "");
1684                     break;
1685                 }
1686             }
1687
1688             if ( !m )
1689                 break;
1690
1691             // :not() is a special case that can be optimized by 
1692             // keeping it out of the expression list 
1693             if ( m[1] == ":" && m[2] == "not" )
1694                 // optimize if only one selector found (most common case) 
1695                 r = isSimple.test( m[3] ) ?
1696                     jQuery.filter(m[3], r, true).r :
1697                     jQuery( r ).not( m[3] );
1698
1699             // We can get a big speed boost by filtering by class here 
1700             elseif ( m[1] == "." )
1701                 r = jQuery.classFilter(r, m[2], not);
1702
1703             elseif ( m[1] == "[" ) {
1704                 var tmp = [], type = m[3];
1705
1706                 for ( var i = 0, rl = r.length; i < rl; i++ ) {
1707                     var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
1708
1709                     if ( z == null || /href|src|selected/.test(m[2]) )
1710                         z = jQuery.attr(a,m[2]) || '';
1711
1712                     if ( (type == "" && !!z ||
1713                          type == "=" && z == m[5] ||
1714                          type == "!=" && z != m[5] ||
1715                          type == "^=" && z && !z.indexOf(m[5]) ||
1716                          type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
1717                          (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
1718                             tmp.push( a );
1719                 }
1720
1721                 r = tmp;
1722
1723             // We can get a speed boost by handling nth-child here 
1724             } elseif ( m[1] == ":" && m[2] == "nth-child" ) {
1725                 var merge = {}, tmp = [],
1726                     // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' 
1727                     test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
1728                         m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
1729                         !/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
1730                     // calculate the numbers (first)n+(last) including if they are negative 
1731                     first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
1732
1733                 // loop through all the elements left in the jQuery object 
1734                 for ( var i = 0, rl = r.length; i < rl; i++ ) {
1735                     var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
1736
1737                     if ( !merge[id] ) {
1738                         var c = 1;
1739
1740                         for ( var n = parentNode.firstChild; n; n = n.nextSibling )
1741                             if ( n.nodeType == 1 )
1742                                 n.nodeIndex = c++;
1743
1744                         merge[id] = true;
1745                     }
1746
1747                     var add = false;
1748
1749                     if ( first == 0 ) {
1750                         if ( node.nodeIndex == last )
1751                             add = true;
1752                     } elseif ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
1753                         add = true;
1754
1755                     if ( add ^ not )
1756                         tmp.push( node );
1757                 }
1758
1759                 r = tmp;
1760
1761             // Otherwise, find the expression to execute 
1762             } else {
1763                 var fn = jQuery.expr[ m[1] ];
1764                 if ( typeof fn == "object" )
1765                     fn = fn[ m[2] ];
1766
1767                 if ( typeof fn == "string" )
1768                     fn = eval("false||function(a,i){return " + fn + ";}");
1769
1770                 // Execute it against the current filter 
1771                 r = jQuery.grep( r, function(elem, i){
1772                     return fn(elem, i, m, r);
1773                 }, not );
1774             }
1775         }
1776
1777         // Return an array of filtered elements (r) 
1778         // and the modified expression string (t) 
1779         return { r: r, t: t };
1780     },
1781
1782     dir: function( elem, dir ){
1783         var matched = [],
1784             cur = elem[dir];
1785         while ( cur && cur != document ) {
1786             if ( cur.nodeType == 1 )
1787                 matched.push( cur );
1788             cur = cur[dir];
1789         }
1790         return matched;
1791     },
1792
1793     nth: function(cur,result,dir,elem){
1794         result = result || 1;
1795         var num = 0;
1796
1797         for ( ; cur; cur = cur[dir] )
1798             if ( cur.nodeType == 1 && ++num == result )
1799                 break;
1800
1801         return cur;
1802     },
1803
1804     sibling: function( n, elem ) {
1805         var r = [];
1806
1807         for ( ; n; n = n.nextSibling ) {
1808             if ( n.nodeType == 1 && n != elem )
1809                 r.push( n );
1810         }
1811
1812         return r;
1813     }
1814 });
1815/*
1816 * A number of helper functions used for managing events.
1817 * Many of the ideas behind this code orignated from
1818 * Dean Edwards' addEvent library.
1819 */
1820 jQuery.event = {
1821
1822     // Bind an event to an element 
1823     // Original by Dean Edwards 
1824     add: function(elem, types, handler, data) {
1825         if ( elem.nodeType == 3 || elem.nodeType == 8 )
1826             return;
1827
1828         // For whatever reason, IE has trouble passing the window object 
1829         // around, causing it to be cloned in the process 
1830         if ( jQuery.browser.msie && elem.setInterval )
1831             elem = window;
1832
1833         // Make sure that the function being executed has a unique ID 
1834         if ( !handler.guid )
1835             handler.guid = this.guid++;
1836
1837         // if data is passed, bind to handler 
1838         if( data != undefined ) {
1839             // Create temporary function pointer to original handler 
1840             var fn = handler;
1841
1842             // Create unique handler function, wrapped around original handler 
1843             handler = this.proxy( fn, function() {
1844                 // Pass arguments and context to original handler 
1845                 return fn.apply(this, arguments);
1846             });
1847
1848             // Store data in unique handler 
1849             handler.data = data;
1850         }
1851
1852         // Init the element's event structure 
1853         var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
1854             handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
1855                 // Handle the second event of a trigger and when 
1856                 // an event is called after a page has unloaded 
1857                 if ( typeof jQuery != "undefined" && !jQuery.event.triggered )
1858                     return jQuery.event.handle.apply(arguments.callee.elem, arguments);
1859             });
1860         // Add elem as a property of the handle function 
1861         // This is to prevent a memory leak with non-native 
1862         // event in IE. 
1863         handle.elem = elem;
1864
1865         // Handle multiple events separated by a space 
1866         // jQuery(...).bind("mouseover mouseout", fn); 
1867         jQuery.each(types.split(/\s+/), function(index, type) {
1868             // Namespaced event handlers 
1869             var parts = type.split(".");
1870             type = parts[0];
1871             handler.type = parts[1];
1872
1873             // Get the current list of functions bound to this event 
1874             var handlers = events[type];
1875
1876             // Init the event handler queue 
1877             if (!handlers) {
1878                 handlers = events[type] = {};
1879
1880                 // Check for a special event handler 
1881                 // Only use addEventListener/attachEvent if the special 
1882                 // events handler returns false 
1883                 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
1884                     // Bind the global event handler to the element 
1885                     if (elem.addEventListener)
1886                         elem.addEventListener(type, handle, false);
1887                     elseif (elem.attachEvent)
1888                         elem.attachEvent("on" + type, handle);
1889                 }
1890             }
1891
1892             // Add the function to the element's handler list 
1893             handlers[handler.guid] = handler;
1894
1895             // Keep track of which events have been used, for global triggering 
1896             jQuery.event.global[type] = true;
1897         });
1898
1899         // Nullify elem to prevent memory leaks in IE 
1900         elem = null;
1901     },
1902
1903     guid: 1,
1904     global: {},
1905
1906     // Detach an event or set of events from an element 
1907     remove: function(elem, types, handler) {
1908         // don't do events on text and comment nodes 
1909         if ( elem.nodeType == 3 || elem.nodeType == 8 )
1910             return;
1911
1912         var events = jQuery.data(elem, "events"), ret, index;
1913
1914         if ( events ) {
1915             // Unbind all events for the element 
1916             if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )
1917                 for ( var type in events )
1918                     this.remove( elem, type + (types || "") );
1919             else {
1920                 // types is actually an event object here 
1921                 if ( types.type ) {
1922                     handler = types.handler;
1923                     types = types.type;
1924                 }
1925
1926                 // Handle multiple events seperated by a space 
1927                 // jQuery(...).unbind("mouseover mouseout", fn); 
1928                 jQuery.each(types.split(/\s+/), function(index, type){
1929                     // Namespaced event handlers 
1930                     var parts = type.split(".");
1931                     type = parts[0];
1932
1933                     if ( events[type] ) {
1934                         // remove the given handler for the given type 
1935                         if ( handler )
1936                             delete events[type][handler.guid];
1937
1938                         // remove all handlers for the given type 
1939                         else
1940                             for ( handler in events[type] )
1941                                 // Handle the removal of namespaced events 
1942                                 if ( !parts[1] || events[type][handler].type == parts[1] )
1943                                     delete events[type][handler];
1944
1945                         // remove generic event handler if no more handlers exist 
1946                         for ( ret in events[type] ) break;
1947                         if ( !ret ) {
1948                             if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
1949                                 if (elem.removeEventListener)
1950                                     elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
1951                                 elseif (elem.detachEvent)
1952                                     elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
1953                             }
1954                             ret = null;
1955                             delete events[type];
1956                         }
1957                     }
1958                 });
1959             }
1960
1961             // Remove the expando if it's no longer used 
1962             for ( ret in events ) break;
1963             if ( !ret ) {
1964                 var handle = jQuery.data( elem, "handle" );
1965                 if ( handle ) handle.elem = null;
1966                 jQuery.removeData( elem, "events" );
1967                 jQuery.removeData( elem, "handle" );
1968             }
1969         }
1970     },
1971
1972     trigger: function(type, data, elem, donative, extra) {
1973         // Clone the incoming data, if any 
1974         data = jQuery.makeArray(data);
1975
1976         if ( type.indexOf("!") >= 0 ) {
1977             type = type.slice(0, -1);
1978             var exclusive = true;
1979         }
1980
1981         // Handle a global trigger 
1982         if ( !elem ) {
1983             // Only trigger if we've ever bound an event for it 
1984             if ( this.global[type] )
1985                 jQuery("*").add([window, document]).trigger(type, data);
1986
1987         // Handle triggering a single element 
1988         } else {
1989             // don't do events on text and comment nodes 
1990             if ( elem.nodeType == 3 || elem.nodeType == 8 )
1991                 return undefined;
1992
1993             var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
1994                 // Check to see if we need to provide a fake event, or not 
1995                 event = !data[0] || !data[0].preventDefault;
1996
1997             // Pass along a fake event 
1998             if ( event ) {
1999                 data.unshift({
2000                     type: type,
2001                     target: elem,
2002                     preventDefault: function(){},
2003                     stopPropagation: function(){},
2004                     timeStamp: now()
2005                 });
2006                 data[0][expando] = true; // no need to fix fake event 
2007             }
2008
2009             // Enforce the right trigger type 
2010             data[0].type = type;
2011             if ( exclusive )
2012                 data[0].exclusive = true;
2013
2014             // Trigger the event, it is assumed that "handle" is a function 
2015             var handle = jQuery.data(elem, "handle");
2016             if ( handle )
2017                 val = handle.apply( elem, data );
2018
2019             // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links) 
2020             if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
2021                 val = false;
2022
2023             // Extra functions don't get the custom event object 
2024             if ( event )
2025                 data.shift();
2026
2027             // Handle triggering of extra function 
2028             if ( extra && jQuery.isFunction( extra ) ) {
2029                 // call the extra function and tack the current return value on the end for possible inspection 
2030                 ret = extra.apply( elem, val == null ? data : data.concat( val ) );
2031                 // if anything is returned, give it precedence and have it overwrite the previous value 
2032                 if (ret !== undefined)
2033                     val = ret;
2034             }
2035
2036             // Trigger the native events (except for clicks on links) 
2037             if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
2038                 this.triggered = true;
2039                 try {
2040                     elem[ type ]();
2041                 // prevent IE from throwing an error for some hidden elements 
2042                 } catch (e) {}
2043             }
2044
2045             this.triggered = false;
2046         }
2047
2048         return val;
2049     },
2050
2051     handle: function(event) {
2052         // returned undefined or false 
2053         var val, ret, namespace, all, handlers;
2054
2055         event = arguments[0] = jQuery.event.fix( event || window.event );
2056
2057         // Namespaced event handlers 
2058         namespace = event.type.split(".");
2059         event.type = namespace[0];
2060         namespace = namespace[1];
2061         // Cache this now, all = true means, any handler 
2062         all = !namespace && !event.exclusive;
2063
2064         handlers = ( jQuery.data(this, "events") || {} )[event.type];
2065
2066         for ( var j in handlers ) {
2067             var handler = handlers[j];
2068
2069             // Filter the functions by class 
2070             if ( all || handler.type == namespace ) {
2071                 // Pass in a reference to the handler function itself 
2072                 // So that we can later remove it 
2073                 event.handler = handler;
2074                 event.data = handler.data;
2075
2076                 ret = handler.apply( this, arguments );
2077
2078                 if ( val !== false )
2079                     val = ret;
2080
2081                 if ( ret === false ) {
2082                     event.preventDefault();
2083                     event.stopPropagation();
2084                 }
2085             }
2086         }
2087
2088         return val;
2089     },
2090
2091     fix: function(event) {
2092         if ( event[expando] == true )
2093             return event;
2094
2095         // store a copy of the original event object 
2096         // and "clone" to set read-only properties 
2097         var originalEvent = event;
2098         event = { originalEvent: originalEvent };
2099         var props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");
2100         for ( var i=props.length; i; i-- )
2101             event[ props[i] ] = originalEvent[ props[i] ];
2102
2103         // Mark it as fixed 
2104         event[expando] = true;
2105
2106         // add preventDefault and stopPropagation since 
2107         // they will not work on the clone 
2108         event.preventDefault = function() {
2109             // if preventDefault exists run it on the original event 
2110             if (originalEvent.preventDefault)
2111                 originalEvent.preventDefault();
2112             // otherwise set the returnValue property of the original event to false (IE) 
2113             originalEvent.returnValue = false;
2114         };
2115         event.stopPropagation = function() {
2116             // if stopPropagation exists run it on the original event 
2117             if (originalEvent.stopPropagation)
2118                 originalEvent.stopPropagation();
2119             // otherwise set the cancelBubble property of the original event to true (IE) 
2120             originalEvent.cancelBubble = true;
2121         };
2122
2123         // Fix timeStamp 
2124         event.timeStamp = event.timeStamp || now();
2125
2126         // Fix target property, if necessary 
2127         if ( !event.target )
2128             event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either 
2129
2130         // check if target is a textnode (safari) 
2131         if ( event.target.nodeType == 3 )
2132             event.target = event.target.parentNode;
2133
2134         // Add relatedTarget, if necessary 
2135         if ( !event.relatedTarget && event.fromElement )
2136             event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
2137
2138         // Calculate pageX/Y if missing and clientX/Y available 
2139         if ( event.pageX == null && event.clientX != null ) {
2140             var doc = document.documentElement, body = document.body;
2141             event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
2142             event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
2143         }
2144
2145         // Add which for key events 
2146         if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
2147             event.which = event.charCode || event.keyCode;
2148
2149         // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) 
2150         if ( !event.metaKey && event.ctrlKey )
2151             event.metaKey = event.ctrlKey;
2152
2153         // Add which for click: 1 == left; 2 == middle; 3 == right 
2154         // Note: button is not normalized, so don't use it 
2155         if ( !event.which && event.button )
2156             event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2157
2158         return event;
2159     },
2160
2161     proxy: function( fn, proxy ){
2162         // Set the guid of unique handler to the same of original handler, so it can be removed 
2163         proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
2164         // So proxy can be declared as an argument 
2165         return proxy;
2166     },
2167
2168     special: {
2169         ready: {
2170             setup: function() {
2171                 // Make sure the ready event is setup 
2172                 bindReady();
2173                 return;
2174             },
2175
2176             teardown: function() { return; }
2177         },
2178
2179         mouseenter: {
2180             setup: function() {
2181                 if ( jQuery.browser.msie ) returnfalse;
2182                 jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
2183                 returntrue;
2184             },
2185
2186             teardown: function() {
2187                 if ( jQuery.browser.msie ) returnfalse;
2188                 jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
2189                 returntrue;
2190             },
2191
2192             handler: function(event) {
2193                 // If we actually just moused on to a sub-element, ignore it 
2194                 if ( withinElement(event, this) ) returntrue;
2195                 // Execute the right handlers by setting the event type to mouseenter 
2196                 event.type = "mouseenter";
2197                 return jQuery.event.handle.apply(this, arguments);
2198             }
2199         },
2200
2201         mouseleave: {
2202             setup: function() {
2203                 if ( jQuery.browser.msie ) returnfalse;
2204                 jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
2205                 returntrue;
2206             },
2207
2208             teardown: function() {
2209                 if ( jQuery.browser.msie ) returnfalse;
2210                 jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
2211                 returntrue;
2212             },
2213
2214             handler: function(event) {
2215                 // If we actually just moused on to a sub-element, ignore it 
2216                 if ( withinElement(event, this) ) returntrue;
2217                 // Execute the right handlers by setting the event type to mouseleave 
2218                 event.type = "mouseleave";
2219                 return jQuery.event.handle.apply(this, arguments);
2220             }
2221         }
2222     }
2223 };
2224
2225 jQuery.fn.extend({
2226     bind: function( type, data, fn ) {
2227         return type == "unload" ? this.one(type, data, fn) : this.each(function(){
2228             jQuery.event.add( this, type, fn || data, fn && data );
2229         });
2230     },
2231
2232     one: function( type, data, fn ) {
2233         var one = jQuery.event.proxy( fn || data, function(event) {
2234             jQuery(this).unbind(event, one);
2235             return (fn || data).apply( this, arguments );
2236         });
2237         returnthis.each(function(){
2238             jQuery.event.add( this, type, one, fn && data);
2239         });
2240     },
2241
2242     unbind: function( type, fn ) {
2243         returnthis.each(function(){
2244             jQuery.event.remove( this, type, fn );
2245         });
2246     },
2247
2248     trigger: function( type, data, fn ) {
2249         returnthis.each(function(){
2250             jQuery.event.trigger( type, data, this, true, fn );
2251         });
2252     },
2253
2254     triggerHandler: function( type, data, fn ) {
2255         returnthis[0] && jQuery.event.trigger( type, data, this[0], false, fn );
2256     },
2257
2258     toggle: function( fn ) {
2259         // Save reference to arguments for access in closure 
2260         var args = arguments, i = 1;
2261
2262         // link all the functions, so any of them can unbind this click handler 
2263         while( i < args.length )
2264             jQuery.event.proxy( fn, args[i++] );
2265
2266         returnthis.click( jQuery.event.proxy( fn, function(event) {
2267             // Figure out which function to execute 
2268             this.lastToggle = ( this.lastToggle || 0 ) % i;
2269
2270             // Make sure that clicks stop 
2271             event.preventDefault();
2272
2273             // and execute the function 
2274             return args[ this.lastToggle++ ].apply( this, arguments ) || false;
2275         }));
2276     },
2277
2278     hover: function(fnOver, fnOut) {
2279         returnthis.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
2280     },
2281
2282     ready: function(fn) {
2283         // Attach the listeners 
2284         bindReady();
2285
2286         // If the DOM is already ready 
2287         if ( jQuery.isReady )
2288             // Execute the function immediately 
2289             fn.call( document, jQuery );
2290
2291         // Otherwise, remember the function for later 
2292         else
2293             // Add the function to the wait list 
2294             jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
2295
2296         returnthis;
2297     }
2298 });
2299
2300 jQuery.extend({
2301     isReady: false,
2302     readyList: [],
2303     // Handle when the DOM is ready 
2304     ready: function() {
2305         // Make sure that the DOM is not already loaded 
2306         if ( !jQuery.isReady ) {
2307             // Remember that the DOM is ready 
2308             jQuery.isReady = true;
2309
2310             // If there are functions bound, to execute 
2311             if ( jQuery.readyList ) {
2312                 // Execute all of them 
2313                 jQuery.each( jQuery.readyList, function(){
2314                     this.call( document );
2315                 });
2316
2317                 // Reset the list of functions 
2318                 jQuery.readyList = null;
2319             }
2320
2321             // Trigger any bound ready events 
2322             jQuery(document).triggerHandler("ready");
2323         }
2324     }
2325 });
2326
2327var readyBound = false;
2328
2329function bindReady(){
2330     if ( readyBound ) return;
2331     readyBound = true;
2332
2333     // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event 
2334     if ( document.addEventListener && !jQuery.browser.opera)
2335         // Use the handy event callback 
2336         document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
2337
2338     // If IE is used and is not in a frame 
2339     // Continually check to see if the document is ready 
2340     if ( jQuery.browser.msie && window == top ) (function(){
2341         if (jQuery.isReady) return;
2342         try {
2343             // If IE is used, use the trick by Diego Perini 
2344             // http://javascript.nwbox.com/IEContentLoaded/ 
2345             document.documentElement.doScroll("left");
2346         } catch( error ) {
2347             setTimeout( arguments.callee, 0 );
2348             return;
2349         }
2350         // and execute any waiting functions 
2351         jQuery.ready();
2352     })();
2353
2354     if ( jQuery.browser.opera )
2355         document.addEventListener( "DOMContentLoaded", function () {
2356             if (jQuery.isReady) return;
2357             for (var i = 0; i < document.styleSheets.length; i++)
2358                 if (document.styleSheets[i].disabled) {
2359                     setTimeout( arguments.callee, 0 );
2360                     return;
2361                 }
2362             // and execute any waiting functions 
2363             jQuery.ready();
2364         }, false);
2365
2366     if ( jQuery.browser.safari ) {
2367         var numStyles;
2368         (function(){
2369             if (jQuery.isReady) return;
2370             if ( document.readyState != "loaded" && document.readyState != "complete" ) {
2371                 setTimeout( arguments.callee, 0 );
2372                 return;
2373             }
2374             if ( numStyles === undefined )
2375                 numStyles = jQuery("style, link[rel=stylesheet]").length;
2376             if ( document.styleSheets.length != numStyles ) {
2377                 setTimeout( arguments.callee, 0 );
2378                 return;
2379             }
2380             // and execute any waiting functions 
2381             jQuery.ready();
2382         })();
2383     }
2384
2385     // A fallback to window.onload, that will always work 
2386     jQuery.event.add( window, "load", jQuery.ready );
2387 }
2388
2389 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
2390     "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
2391     "submit,keydown,keypress,keyup,error").split(","), function(i, name){
2392
2393     // Handle event binding 
2394     jQuery.fn[name] = function(fn){
2395         return fn ? this.bind(name, fn) : this.trigger(name);
2396     };
2397 });
2398
2399// Checks if an event happened on an element within another element 
2400// Used in jQuery.event.special.mouseenter and mouseleave handlers 
2401var withinElement = function(event, elem) {
2402     // Check if mouse(over|out) are still within the same parent element 
2403     var parent = event.relatedTarget;
2404     // Traverse up the tree 
2405     while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
2406     // Return true if we actually just moused on to a sub-element 
2407     return parent == elem;
2408 };
2409
2410// Prevent memory leaks in IE 
2411// And prevent errors on refresh with events like mouseover in other browsers 
2412// Window isn't included so as not to unbind existing unload events 
2413 jQuery(window).bind("unload", function() {
2414     jQuery("*").add(document).unbind();
2415 });
2416 jQuery.fn.extend({
2417     // Keep a copy of the old load 
2418     _load: jQuery.fn.load,
2419
2420     load: function( url, params, callback ) {
2421         if ( typeof url != 'string' )
2422             returnthis._load( url );
2423
2424         var off = url.indexOf(" ");
2425         if ( off >= 0 ) {
2426             var selector = url.slice(off, url.length);
2427             url = url.slice(0, off);
2428         }
2429
2430         callback = callback || function(){};
2431
2432         // Default to a GET request 
2433         var type = "GET";
2434
2435         // If the second parameter was provided 
2436         if ( params )
2437             // If it's a function 
2438             if ( jQuery.isFunction( params ) ) {
2439                 // We assume that it's the callback 
2440                 callback = params;
2441                 params = null;
2442
2443             // Otherwise, build a param string 
2444             } else {
2445                 params = jQuery.param( params );
2446                 type = "POST";
2447             }
2448
2449         var self = this;
2450
2451         // Request the remote document 
2452         jQuery.ajax({
2453             url: url,
2454             type: type,
2455             dataType: "html",
2456             data: params,
2457             complete: function(res, status){
2458                 // If successful, inject the HTML into all the matched elements 
2459                 if ( status == "success" || status == "notmodified" )
2460                     // See if a selector was specified 
2461                     self.html( selector ?
2462                         // Create a dummy div to hold the results 
2463                         jQuery("<div/>")
2464                             // inject the contents of the document in, removing the scripts 
2465                             // to avoid any 'Permission Denied' errors in IE 
2466                             .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
2467
2468                             // Locate the specified elements 
2469                             .find(selector) :
2470
2471                         // If not, just inject the full result 
2472                         res.responseText );
2473
2474                 self.each( callback, [res.responseText, status, res] );
2475             }
2476         });
2477         returnthis;
2478     },
2479
2480     serialize: function() {
2481         return jQuery.param(this.serializeArray());
2482     },
2483     serializeArray: function() {
2484         returnthis.map(function(){
2485             return jQuery.nodeName(this, "form") ?
2486                 jQuery.makeArray(this.elements) : this;
2487         })
2488         .filter(function(){
2489             returnthis.name && !this.disabled &&
2490                 (this.checked || /select|textarea/i.test(this.nodeName) ||
2491                     /text|hidden|password/i.test(this.type));
2492         })
2493         .map(function(i, elem){
2494             var val = jQuery(this).val();
2495             return val == null ? null :
2496                 val.constructor == Array ?
2497                     jQuery.map( val, function(val, i){
2498                         return {name: elem.name, value: val};
2499                     }) :
2500                     {name: elem.name, value: val};
2501         }).get();
2502     }
2503 });
2504
2505// Attach a bunch of functions for handling common AJAX events 
2506 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
2507     jQuery.fn[o] = function(f){
2508         returnthis.bind(o, f);
2509     };
2510 });
2511
2512var jsc = now();
2513
2514 jQuery.extend({
2515     get: function( url, data, callback, type ) {
2516         // shift arguments if data argument was ommited 
2517         if ( jQuery.isFunction( data ) ) {
2518             callback = data;
2519             data = null;
2520         }
2521
2522         return jQuery.ajax({
2523             type: "GET",
2524             url: url,
2525             data: data,
2526             success: callback,
2527             dataType: type
2528         });
2529     },
2530
2531     getScript: function( url, callback ) {
2532         return jQuery.get(url, null, callback, "script");
2533     },
2534
2535     getJSON: function( url, data, callback ) {
2536         return jQuery.get(url, data, callback, "json");
2537     },
2538
2539     post: function( url, data, callback, type ) {
2540         if ( jQuery.isFunction( data ) ) {
2541             callback = data;
2542             data = {};
2543         }
2544
2545         return jQuery.ajax({
2546             type: "POST",
2547             url: url,
2548             data: data,
2549             success: callback,
2550             dataType: type
2551         });
2552     },
2553
2554     ajaxSetup: function( settings ) {
2555         jQuery.extend( jQuery.ajaxSettings, settings );
2556     },
2557
2558     ajaxSettings: {
2559         url: location.href,
2560         global: true,
2561         type: "GET",
2562         timeout: 0,
2563         contentType: "application/x-www-form-urlencoded",
2564         processData: true,
2565         async: true,
2566         data: null,
2567         username: null,
2568         password: null,
2569         accepts: {
2570             xml: "application/xml, text/xml",
2571             html: "text/html",
2572             script: "text/javascript, application/javascript",
2573             json: "application/json, text/javascript",
2574             text: "text/plain",
2575             _default: "*/*"
2576         }
2577     },
2578
2579     // Last-Modified header cache for next request 
2580     lastModified: {},
2581
2582     ajax: function( s ) {
2583         // Extend the settings, but re-extend 's' so that it can be 
2584         // checked again later (in the test suite, specifically) 
2585         s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
2586
2587         var jsonp, jsre = /=\?(&|$)/g, status, data,
2588             type = s.type.toUpperCase();
2589
2590         // convert data if not already a string 
2591         if ( s.data && s.processData && typeof s.data != "string" )
2592             s.data = jQuery.param(s.data);
2593
2594         // Handle JSONP Parameter Callbacks 
2595         if ( s.dataType == "jsonp" ) {
2596             if ( type == "GET" ) {
2597                 if ( !s.url.match(jsre) )
2598                     s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
2599             } elseif ( !s.data || !s.data.match(jsre) )
2600                 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
2601             s.dataType = "json";
2602         }
2603
2604         // Build temporary JSONP function 
2605         if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
2606             jsonp = "jsonp" + jsc++;
2607
2608             // Replace the =? sequence both in the query string and the data 
2609             if ( s.data )
2610                 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
2611             s.url = s.url.replace(jsre, "=" + jsonp + "$1");
2612
2613             // We need to make sure 
2614             // that a JSONP style response is executed properly 
2615             s.dataType = "script";
2616
2617             // Handle JSONP-style loading 
2618             window[ jsonp ] = function(tmp){
2619                 data = tmp;
2620                 success();
2621                 complete();
2622                 // Garbage collect 
2623                 window[ jsonp ] = undefined;
2624                 try{ delete window[ jsonp ]; } catch(e){}
2625                 if ( head )
2626                     head.removeChild( script );
2627             };
2628         }
2629
2630         if ( s.dataType == "script" && s.cache == null )
2631             s.cache = false;
2632
2633         if ( s.cache === false && type == "GET" ) {
2634             var ts = now();
2635             // try replacing _= if it is there 
2636             var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
2637             // if nothing was replaced, add timestamp to the end 
2638             s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
2639         }
2640
2641         // If data is available, append data to url for get requests 
2642         if ( s.data && type == "GET" ) {
2643             s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
2644
2645             // IE likes to send both get and post data, prevent this 
2646             s.data = null;
2647         }
2648
2649         // Watch for a new set of requests 
2650         if ( s.global && ! jQuery.active++ )
2651             jQuery.event.trigger( "ajaxStart" );
2652
2653         // Matches an absolute URL, and saves the domain 
2654         var remote = /^(?:\w+:)?\/\/([^\/?#]+)/;
2655
2656         // If we're requesting a remote document 
2657         // and trying to load JSON or Script with a GET 
2658         if ( s.dataType == "script" && type == "GET"
2659                 && remote.test(s.url) && remote.exec(s.url)[1] != location.host ){
2660             var head = document.getElementsByTagName("head")[0];
2661             var script = document.createElement("script");
2662             script.src = s.url;
2663             if (s.scriptCharset)
2664                 script.charset = s.scriptCharset;
2665
2666             // Handle Script loading 
2667             if ( !jsonp ) {
2668                 var done = false;
2669
2670                 // Attach handlers for all browsers 
2671                 script.onload = script.onreadystatechange = function(){
2672                     if ( !done && (!this.readyState ||
2673                             this.readyState == "loaded" || this.readyState == "complete") ) {
2674                         done = true;
2675                         success();
2676                         complete();
2677                         head.removeChild( script );
2678                     }
2679                 };
2680             }
2681
2682             head.appendChild(script);
2683
2684             // We handle everything using the script element injection 
2685             return undefined;
2686         }
2687
2688         var requestDone = false;
2689
2690         // Create the request object; Microsoft failed to properly 
2691         // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available 
2692         var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
2693
2694         // Open the socket 
2695         // Passing null username, generates a login popup on Opera (#2865) 
2696         if( s.username )
2697             xhr.open(type, s.url, s.async, s.username, s.password);
2698         else
2699             xhr.open(type, s.url, s.async);
2700
2701         // Need an extra try/catch for cross domain requests in Firefox 3 
2702         try {
2703             // Set the correct header, if data is being sent 
2704             if ( s.data )
2705                 xhr.setRequestHeader("Content-Type", s.contentType);
2706
2707             // Set the If-Modified-Since header, if ifModified mode. 
2708             if ( s.ifModified )
2709                 xhr.setRequestHeader("If-Modified-Since",
2710                     jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
2711
2712             // Set header so the called script knows that it's an XMLHttpRequest 
2713             xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
2714
2715             // Set the Accepts header for the server, depending on the dataType 
2716             xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
2717                 s.accepts[ s.dataType ] + ", */*" :
2718                 s.accepts._default );
2719         } catch(e){}
2720
2721         // Allow custom headers/mimetypes 
2722         if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
2723             // cleanup active request counter 
2724             s.global && jQuery.active--;
2725             // close opended socket 
2726             xhr.abort();
2727             returnfalse;
2728         }
2729
2730         if ( s.global )
2731             jQuery.event.trigger("ajaxSend", [xhr, s]);
2732
2733         // Wait for a response to come back 
2734         var onreadystatechange = function(isTimeout){
2735             // The transfer is complete and the data is available, or the request timed out