Inital Import.
authorJohn Resig <jeresig@gmail.com>
Wed, 22 Mar 2006 03:33:07 +0000 (03:33 +0000)
committerJohn Resig <jeresig@gmail.com>
Wed, 22 Mar 2006 03:33:07 +0000 (03:33 +0000)
12 files changed:
ajax/ajax.js [new file with mode: 0644]
browse/.htaccess [new file with mode: 0644]
browse/Pack.pm [new file with mode: 0644]
browse/ParseMaster.pm [new file with mode: 0644]
browse/browse-new.cgi [new file with mode: 0755]
browse/browse.cgi [new file with mode: 0755]
browse/copyright.txt [new file with mode: 0644]
core/core.js [new file with mode: 0644]
event/event.js [new file with mode: 0644]
fx/fx.js [new file with mode: 0644]
sort/sort.js [new file with mode: 0644]
tmpl/tmpl.js [new file with mode: 0644]

diff --git a/ajax/ajax.js b/ajax/ajax.js
new file mode 100644 (file)
index 0000000..87eadbf
--- /dev/null
@@ -0,0 +1,88 @@
+// AJAX Plugin
+// Docs Here:
+// http://jquery.com/docs/ajax/
+
+if ( typeof XMLHttpRequest == 'undefined' && typeof window.ActiveXObject == 'function') {
+  var XMLHttpRequest = function() {
+    return new ActiveXObject((navigator.userAgent.toLowerCase().indexOf('msie 5') >= 0) ? 
+      "Microsoft.XMLHTTP" : "Msxml2.XMLHTTP");
+  };
+}
+
+$.xml = function( type, url, data, ret ) {
+  var xml = new XMLHttpRequest();
+
+  if ( xml ) {
+    xml.open(type || "GET", url, true);
+
+    if ( data )
+      xml.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+
+    if ( ret )
+      xml.onreadystatechange = function() {
+        if ( xml.readyState == 4 ) ret(xml);
+      };
+
+    xml.send(data)
+  }
+};
+
+$.httpData = function(r,type) {
+  return r.getResponseHeader("content-type").indexOf("xml") > 0 || type == "xml" ?
+    r.responseXML : r.responseText;
+};
+
+$.get = function( url, ret, type ) {
+  $.xml( "GET", url, null, function(r) {
+    if ( ret ) ret( $.httpData(r,type) );
+  });
+};
+
+$.getXML = function( url, ret ) {
+  $.get( url, ret, "xml" );
+};
+
+$.post = function( url, data, ret, type ) {
+  $.xml( "POST", url, $.param(data), function(r) {
+    if ( ret ) ret( $.httpData(r,type) );
+  });
+};
+
+$.postXML = function( url, data, ret ) {
+  $.post( url, data, ret, "xml" );
+};
+
+$.param = function(a) {
+  var s = [];
+  for ( var i in a )
+    s[s.length] = i + "=" + encodeURIComponent( a[i] );
+  return s.join("&");
+};
+
+$.fn.load = function(a,o,f) {
+  // Arrrrghhhhhhhh!!
+  // I overwrote the event plugin's .load
+  // this won't happen again, I hope -John
+  if ( a && a.constructor == Function )
+    return this.bind("load", a);
+
+  var t = "GET";
+  if ( o && o.constructor == Function ) {
+    f = o; o = null;
+  }
+  if (o != null) {
+    o = $.param(o);
+    t = "POST";
+  }
+  var self = this;
+  $.xml(t,a,o,function(h){
+  var h = h.responseText;
+    self.html(h).find("script").each(function(){
+      try {
+        eval( this.text || this.textContent || this.innerHTML );
+      } catch(e){}
+    });
+    if(f)f(h);
+  });
+  return this;
+};
diff --git a/browse/.htaccess b/browse/.htaccess
new file mode 100644 (file)
index 0000000..bd61da6
--- /dev/null
@@ -0,0 +1,5 @@
+RewriteEngine On
+RewriteRule ^$ /docs/SourceCode/ [L,QSA]
+RewriteRule ^([^/]+).js$ browse-new.cgi?v=$1 [L,QSA]
+RewriteRule ^([^/]+)/$ browse-new.cgi?v=$1 [L,QSA]
+RewriteRule ^([^/]+)/([a-z0-9-]+)/?$ browse-new.cgi?v=$1&custom=$2 [L,QSA]
diff --git a/browse/Pack.pm b/browse/Pack.pm
new file mode 100644 (file)
index 0000000..fbd2292
--- /dev/null
@@ -0,0 +1,467 @@
+#Pack (July 2005)\r
+#  Based on "Pack.js" by Dean Edwards <http://dean.edwards.name/>\r
+#  Ported to Perl by Rob Seiler, ELR Software Pty Ltd <http://www.elr.com.au>\r
+#  Copyright 2005. License <http://creativecommons.org/licenses/LGPL/2.1/>\r
+\r
+package Pack;\r
+use strict;\r
+use Data::Dumper;\r
+\r
+use ParseMaster;\r
+\r
+# Package wide variable declarations\r
+use vars qw/$VERSION $PM_VERSION\r
+            $_X_encodePrivate $_JSunpack $_JSdecode %baseLookup\r
+            $_X_encode10 $_X_encode36 $_X_encode62 $_X_encode95\r
+            $_JSencode10 $_JSencode36 $_JSencode62 $_JSencode95\r
+            @_X_parsers\r
+            $_X_script $_X_encoding $_X_fastDecode $_X_specialChars\r
+           /;\r
+$VERSION    = '024';\r
+$PM_VERSION = $ParseMaster::VERSION;\r
+\r
+# Package wide constants\r
+my $X_IGNORE  = q{$1};\r
+my $X_ENCODE  = q/\x24encode\(\x24count\)/;  # NB: requires g modifier\r
+my $PERL      = 'perl';     # Flag to indicate whether we need to use one of our "internal" Perl encoding functions\r
+my $JSCRIPT   = 'jscript';  # or embed a pre-build JScript encoding function\r
+########################################\r
+\r
+##################\r
+sub pack($$$$) { # require 4 arguments\r
+##################\r
+#print Dumper(@_);\r
+  ($_X_script, $_X_encoding, $_X_fastDecode, $_X_specialChars) = @_;\r
+  # validate parameters (sort of!)\r
+  $_X_script  .= "\n";\r
+  $_X_encoding = ($_X_encoding > 95) ? 95 : $_X_encoding;\r
+\r
+  @_X_parsers = (); # Reset parsers\r
+\r
+####################\r
+  sub _X_pack($) { # require 1 argument\r
+####################\r
+  # apply all parsing routines\r
+    my $X_script = shift;\r
+    for (my $i = 0; $i<scalar(@_X_parsers); $i++) {\r
+      my $X_parse = $_X_parsers[$i];\r
+       $X_script = &$X_parse($X_script);\r
+    }\r
+    return $X_script;\r
+  };\r
+\r
+######################\r
+  sub _X_addParser { #\r
+######################\r
+  # keep a list of parsing functions, they'll be executed all at once\r
+    my $X_parser = shift;\r
+    push (@_X_parsers,$X_parser);\r
+  }\r
+\r
+#############################\r
+  sub _X_basicCompression { #\r
+#############################\r
+    # zero encoding - just removal of white space and comments\r
+    my $X_script = shift;\r
+    my $parser = ParseMaster->new();\r
+    # make safe\r
+    $parser->escapeChar("\\");\r
+    # protect strings\r
+    $parser->add(q/'[^'\n\r]*'/, $X_IGNORE);\r
+    $parser->add(q/"[^"\n\r]*"/, $X_IGNORE);\r
+    # remove comments\r
+    $parser->add(q/\/\/[^\n\r]*[\n\r]/);\r
+    $parser->add(q/\/\*[^*]*\*+([^\/][^*]*\*+)*\//);\r
+    # protect regular expressions\r
+    $parser->add(q/\s+(\/[^\/\n\r\*][^\/\n\r]*\/g?i?)/, q{$2}); # IGNORE\r
+    $parser->add(q/[^\w\x24\/'"*)\?:]\/[^\/\n\r\*][^\/\n\r]*\/g?i?/, $X_IGNORE);\r
+    # remove: ;;; doSomething();\r
+    $parser->add(q/;;[^\n\r]+[\n\r]/) if ($_X_specialChars);\r
+    # remove redundant semi-colons\r
+    $parser->add(q/;+\s*([};])/, q{$2});\r
+    # remove white-space\r
+    $parser->add(q/(\b|\x24)\s+(\b|\x24)/, q{$2 $3});\r
+    $parser->add(q/([+\-])\s+([+\-])/, q{$2 $3});\r
+    $parser->add(q/\s+/, '');\r
+    # done\r
+    return $parser->exec($X_script);\r
+  }\r
+\r
+###############################\r
+  sub _X_encodeSpecialChars { #\r
+###############################\r
+    my $X_script = shift;\r
+    my $parser = ParseMaster->new();\r
+    # replace: $name -> n, $$name -> $$na\r
+    $parser->add(q/((\x24+)([a-zA-Z\x24_]+))(\d*)/,\r
+      sub {\r
+        my $X_offset   = pop;\r
+        my @X_match    = @_;\r
+        my $X_length   = length($X_match[$X_offset+2]);\r
+        my $lengthnext = length($X_match[$X_offset+3]);\r
+        my $X_start = $X_length - ((($X_length - $lengthnext) > 0) ? ($X_length - $lengthnext) : 0);\r
+        my $str = $X_match[$X_offset+1];\r
+        $str = substr($str,$X_start,$X_length) . $X_match[$X_offset+4];\r
+        return "$str";\r
+      });\r
+     # replace: _name -> _0, double-underscore (__name) is ignored\r
+     my $X_regexp = q/\b_[A-Za-z\d]\w*/;\r
+     # build the word list\r
+     my %X_keywords = &_X_analyze($X_script, $X_regexp, $_X_encodePrivate);\r
+#print Dumper(%X_keywords);\r
+     # quick ref\r
+     my $X_encoded = \$X_keywords{X_encoded}; # eg _private1 => '_0',_private2 => '_1';\r
+#print Dumper($X_encoded);\r
+     $parser->add($X_regexp, sub {my $X_offset = pop; my @X_match = @_; return ${$X_encoded}->{$X_match[$X_offset]};});\r
+\r
+     return $parser->exec($X_script);\r
+  };\r
+\r
+###########################\r
+  sub _X_encodeKeywords { #\r
+###########################\r
+    my $X_script = shift;\r
+    # escape high-ascii values already in the script (i.e. in strings)\r
+    if ($_X_encoding > 62) {$X_script = &_X_escape95($X_script)};\r
+    # create the parser\r
+    my $parser = ParseMaster->new();\r
+    my $X_encode = &_X_getEncoder($_X_encoding,$PERL);\r
+    # for high-ascii, don't encode single character low-ascii\r
+    my $X_regexp = ($_X_encoding > 62) ? q/\w\w+/ : q/\w+/;\r
+    # build the word list\r
+    my %X_keywords = &_X_analyze($X_script, $X_regexp, $X_encode);\r
+#print Dumper(%X_keywords);\r
+    my $X_encoded = \$X_keywords{X_encoded}; # eg alert => 2, function => 10 etc\r
+    # encode\r
+    $parser->add($X_regexp, sub {my $X_offset = pop; my @X_match = @_; return ${$X_encoded}->{$X_match[$X_offset]};});\r
+    # if encoded, wrap the script in a decoding function\r
+\r
+    return $X_script && _X_bootStrap(\$parser->exec($X_script), \%X_keywords);\r
+  }\r
+\r
+####################\r
+  sub _X_analyze { #\r
+####################\r
+#print Dumper(@_);\r
+    my ($X_script, $X_regexp, $X_encode) = @_;\r
+    # analyse\r
+    # retreive all words in the script\r
+    my @X_all = $X_script =~ m/$X_regexp/g; # Save all captures in a list context\r
+    my %XX_sorted    = ();  # list of words sorted by frequency\r
+    my %XX_encoded   = ();  # dictionary of word->encoding\r
+    my %XX_protected = ();  # instances of "protected" words\r
+    if (@X_all) {\r
+      my @X_unsorted  = (); # same list, not sorted\r
+      my %X_protected = (); # "protected" words (dictionary of word->"word")\r
+      my %X_values    = (); # dictionary of charCode->encoding (eg. 256->ff)\r
+      my %X_count     = (); # word->count\r
+      my $i = scalar(@X_all); my $j = 0; my $X_word = '';\r
+      # count the occurrences - used for sorting later\r
+      do {\r
+        $X_word = '$' . $X_all[--$i];\r
+        if (!exists($X_count{$X_word})) {\r
+          $X_count{$X_word}   = [0,$i]; # Store both the usage count and original array position (ie a secondary sort key)\r
+          $X_unsorted[$j]   = $X_word;\r
+          # make a dictionary of all of the protected words in this script\r
+          #   these are words that might be mistaken for encoding\r
+          $X_values{$j}     = &$X_encode($j);\r
+          my $v           = '$'.$X_values{$j};\r
+          $X_protected{$v}  = $j++;\r
+        }\r
+        # increment the word counter\r
+        $X_count{$X_word}[0]++;\r
+      } while ($i);\r
+#print Dumper (%X_values);\r
+#print Dumper (@X_unsorted);\r
+#print Dumper (%X_protected);\r
+      # prepare to sort the word list, first we must protect\r
+      #  words that are also used as codes. we assign them a code\r
+      #  equivalent to the word itself.\r
+      # e.g. if "do" falls within our encoding range\r
+      #       then we store keywords["do"] = "do";\r
+      # this avoids problems when decoding\r
+       $i = scalar(@X_unsorted);\r
+      do {\r
+        $X_word = $X_unsorted[--$i];\r
+        if (exists($X_protected{$X_word})) {\r
+          $XX_sorted{$X_protected{$X_word}} = substr($X_word,1);\r
+          $XX_protected{$X_protected{$X_word}} = 1; # true\r
+          $X_count{$X_word}[0] = 0;\r
+        }\r
+      } while ($i);\r
+#print Dumper (%XX_protected);\r
+#print Dumper (%XX_sorted);\r
+#print Dumper (%X_count);\r
+      # sort the words by frequency\r
+      # Sort with count a primary key and original array order as secondary key - which is apparently the default in javascript!\r
+      @X_unsorted = sort ({($X_count{$b}[0] - $X_count{$a}[0]) or ($X_count{$b}[1] <=> $X_count{$a}[1])} @X_unsorted);\r
+#print Dumper (@X_unsorted) . "\n";\r
+\r
+      $j = 0;\r
+      # because there are "protected" words in the list\r
+      # we must add the sorted words around them\r
+      do {\r
+        if (!exists($XX_sorted{$i})) {$XX_sorted{$i} = substr($X_unsorted[$j++],1)}\r
+        $XX_encoded{$XX_sorted{$i}} = $X_values{$i};\r
+      } while (++$i < scalar(@X_unsorted));\r
+    }\r
+#print Dumper(X_sorted => \%XX_sorted, X_encoded => \%XX_encoded, X_protected => \%XX_protected);\r
+    return (X_sorted => \%XX_sorted, X_encoded => \%XX_encoded, X_protected => \%XX_protected);\r
+  }\r
+\r
+######################\r
+  sub _X_bootStrap { #\r
+######################\r
+    # build the boot function used for loading and decoding\r
+    my ($X_packed, $X_keywords) = @_; # Reference arguments!\r
+#print Dumper ($X_keywords) . "\n";\r
+\r
+    # $packed: the packed script - dereference and escape\r
+    $X_packed = "'" . &_X_escape($$X_packed) ."'";\r
+\r
+    my %sorted    = %{$$X_keywords{X_sorted}};    # Dereference to local variables\r
+    my %protected = %{$$X_keywords{X_protected}}; # for simplicity\r
+\r
+    my @sorted    = ();\r
+    foreach my $key (keys %sorted) {$sorted[$key] = $sorted{$key}}; # Convert hash to a standard list\r
+\r
+    # ascii: base for encoding\r
+    my $X_ascii = ((scalar(@sorted) > $_X_encoding) ? $_X_encoding : scalar(@sorted)) || 1;\r
+\r
+    # count: number of (unique {RS}) words contained in the script\r
+    my $X_count = scalar(@sorted); # Use $X_count for assigning $X_ascii\r
+\r
+    # keywords: list of words contained in the script\r
+    foreach my $i (keys %protected) {$sorted[$i] = ''}; # Blank out protected words\r
+#print Dumper(@sorted) . "\n";\r
+\r
+    # convert from a string to an array - prepare keywords as a JScript string->array {RS}\r
+    $X_keywords = "'" . join('|',@sorted) . "'.split('|')";\r
+\r
+    # encode: encoding function (used for decoding the script)\r
+    my $X_encode = $_X_encoding > 62 ? $_JSencode95 : &_X_getEncoder($X_ascii,$JSCRIPT); # This is a JScript function (as a string)\r
+       $X_encode =~ s/_encoding/\x24ascii/g; $X_encode =~ s/arguments\.callee/\x24encode/g;\r
+    my $X_inline = '$count' . ($X_ascii > 10 ? '.toString($ascii)' : '');\r
+\r
+    # decode: code snippet to speed up decoding\r
+    my $X_decode = '';\r
+    if ($_X_fastDecode) {\r
+      # create the decoder\r
+      $X_decode = &_X_getFunctionBody($_JSdecode); # ie from the Javascript literal function\r
+      if ($_X_encoding > 62) {$X_decode =~ s/\\\\w/[\\xa1-\\xff]/g}\r
+      # perform the encoding inline for lower ascii values\r
+      elsif ($X_ascii < 36) {$X_decode =~ s/$X_ENCODE/$X_inline/g}\r
+      # special case: when $X_count==0 there ar no keywords. i want to keep\r
+      # the basic shape of the unpacking funcion so i'll frig the code...\r
+      if (!$X_count) {$X_decode =~ s/(\x24count)\s*=\s*1/$1=0/}\r
+    }\r
+\r
+    # boot function\r
+    my $X_unpack = $_JSunpack;\r
+    if ($_X_fastDecode) {\r
+      # insert the decoder\r
+      $X_unpack =~ s/\{/\{$X_decode;/;\r
+    }\r
+    $X_unpack =~ s/"/'/g;\r
+    if ($_X_encoding > 62) { # high-ascii\r
+      # get rid of the word-boundaries for regexp matches\r
+      $X_unpack =~ s/'\\\\b'\s*\+|\+\s*'\\\\b'//g; # Not checked! {RS}\r
+    }\r
+    if ($X_ascii > 36 || $_X_encoding > 62 || $_X_fastDecode) {\r
+    # insert the encode function\r
+    $X_unpack =~ s/\{/\{\$encode=$X_encode;/;\r
+    } else {\r
+      # perform the encoding inline\r
+      $X_unpack =~ s/$X_ENCODE/$X_inline/;\r
+    }\r
+\r
+    # arguments   {RS} Do this before using &pack because &pack changes the pack parameters (eg $fastDecode) in Perl!!\r
+    my $X_params = "$X_packed,$X_ascii,$X_count,$X_keywords"; # Interpolate to comma separated string\r
+    if ($_X_fastDecode) {\r
+      # insert placeholders for the decoder\r
+      $X_params .= ',0,{}';\r
+    }\r
+\r
+    # pack the boot function too\r
+    $X_unpack = &pack($X_unpack,0,0,1);\r
+\r
+    # the whole thing\r
+    return "eval(" . $X_unpack . "(" . $X_params . "))\n";\r
+  };\r
+\r
+#######################\r
+  sub _X_getEncoder { #\r
+#######################\r
+  # mmm.. ..which one do i need ?? ({RS} Perl or JScript ??)\r
+    my ($X_ascii,$language) = @_;\r
+    my $perl_encoder    = ($X_ascii > 10) ? ($X_ascii > 36) ? ($X_ascii > 62) ? $_X_encode95 : $_X_encode62 : $_X_encode36 : $_X_encode10;\r
+    my $jscript_encoder = ($X_ascii > 10) ? ($X_ascii > 36) ? ($X_ascii > 62) ? $_JSencode95 : $_JSencode62 : $_JSencode36 : $_JSencode10;\r
+    return ($language eq $JSCRIPT) ? $jscript_encoder : $perl_encoder;\r
+  };\r
+\r
+#############################\r
+# Perl versions of encoders #\r
+#############################\r
+  # base10 zero encoding - characters: 0123456789\r
+  $_X_encode10 = sub {return &_encodeBase(shift,10)};\r
+  # base36               - characters: 0123456789abcdefghijklmnopqrstuvwxyz\r
+  $_X_encode36 = sub {return &_encodeBase(shift,36)};\r
+  # base62               - characters: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\r
+  $_X_encode62 = sub {return &_encodeBase(shift,62)};\r
+  # high-ascii values    - characters: ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ\r
+  $_X_encode95 = sub {return &_encodeBase(shift,95)};\r
+  # Lookup character sets for baseN encoding\r
+     $baseLookup{10} = [(0..9)[0..9]];                    # base 10\r
+     $baseLookup{36} = [(0..9,'a'..'z')[0..35]];          # base 36\r
+     $baseLookup{62} = [(0..9,'a'..'z','A'..'Z')[0..61]]; # base 62\r
+     $baseLookup{95} = (); for (my $i=0; $i<95; $i++) {$baseLookup{95}[$i] = chr($i+161)}; # base95 (high ascii)\r
+#print Dumper(%baseLookup);\r
+#####################\r
+  sub _encodeBase { #\r
+#####################\r
+  # Generic base conversion function using defined lookup arrays (perl version only)\r
+    my ($X_charCode, $base) = @_;\r
+    my $X_encoded = '';\r
+    # Do we know this encoding?\r
+    if (exists ($baseLookup{$base})) {\r
+      if ($X_charCode == 0) {$X_encoded = $baseLookup{$base}[0]}\r
+      while($X_charCode > 0) {\r
+        $X_encoded  = $baseLookup{$base}[$X_charCode % $base] . $X_encoded;\r
+        $X_charCode = int($X_charCode / $base);\r
+      }\r
+    }\r
+    else {$X_encoded = "$X_charCode"} # default is to return unchanged (ie as for base 10) if no baselookup is available\r
+    return $X_encoded;\r
+  };\r
+\r
+#############################\r
+  $_X_encodePrivate = sub { #\r
+#############################\r
+  # special _chars\r
+    my $X_charCode = shift;\r
+    return '_' . $X_charCode;\r
+  };\r
+\r
+############################\r
+  sub _X_escape($script) { #\r
+############################\r
+  # protect characters used by the parser\r
+    my $X_script = shift;\r
+    $X_script =~ s/([\\'])/\\$1/g;\r
+    return $X_script;\r
+  };\r
+\r
+#####################\r
+  sub _X_escape95 { #\r
+#####################\r
+  # protect high-ascii characters already in the script\r
+    my $X_script = shift;\r
+    $X_script =~ s/([\xa1-\xff])/sprintf("\\x%1x",ord($1))/eg;\r
+    return $X_script;\r
+  };\r
+\r
+############################\r
+  sub _X_getFunctionBody { #\r
+############################\r
+  # extract the body of a function (ie between opening/closing {}) - consistent with Dean Edwards approach\r
+    my $X_function = shift;\r
+    $X_function =~ m/^.*\{(.*)\}*$/sg; # Multiline, global (greedy)\r
+    my $start = index($X_function,'{');\r
+    my $end   = rindex($X_function,'}');\r
+    $X_function = substr($X_function,($start+1),($end-1-$start));\r
+    return $X_function;\r
+  };\r
+\r
+######################\r
+  sub _X_globalize { #\r
+######################\r
+  # set the global flag on a RegExp (you have to create a new one) !!! Unused in perl version\r
+    # my $X_regexp = shift;\r
+  };\r
+\r
+  # build the parsing routine\r
+  &_X_addParser(\&_X_basicCompression);\r
+  &_X_addParser(\&_X_encodeSpecialChars) if ($_X_specialChars);\r
+  &_X_addParser(\&_X_encodeKeywords)     if ($_X_encoding);\r
+\r
+  # go!\r
+  return &_X_pack($_X_script);\r
+}\r
+\r
+########################\r
+# Javascript Literals  #\r
+########################\r
+\r
+# JScript function "_unpack" - from DeanEdwards pack.js (NB: No ";" after final "}")\r
+($_JSunpack) = <<'END_JSCRIPT_UNPACK';\r
+/* unpacking function - this is the boot strap function   */\r
+/* data extracted from this packing routine is passed to  */\r
+/* this function when decoded in the target               */\r
+function($packed, $ascii, $count, $keywords, $encode, $decode) {\r
+  while ($count--)\r
+    if ($keywords[$count])\r
+     $packed = $packed.replace(new RegExp('\\b' + $encode($count) + '\\b', 'g'), $keywords[$count]);\r
+  /* RS_Debug = $packed; */  /* {RS} !!!!!!!!! */\r
+  return $packed;\r
+}\r
+END_JSCRIPT_UNPACK\r
+\r
+# JScript function "_decode" - from DeanEdwards pack.js\r
+($_JSdecode) = <<'END_JSCRIPT_DECODE';\r
+  /* code-snippet inserted into the unpacker to speed up decoding */\r
+  function() {\r
+    /* does the browser support String.replace where the */\r
+    /*  replacement value is a function? */\r
+    if (!''.replace(/^/, String)) {\r
+      /* decode all the values we need */\r
+          while ($count--) $decode[$encode($count)] = $keywords[$count] || $encode($count);\r
+          /* global replacement function */\r
+          $keywords = [function($encoded){return $decode[$encoded]}];\r
+          /* generic match */\r
+          $encode = function(){return'\\w+'};\r
+          /* reset the loop counter -  we are now doing a global replace */\r
+          $count = 1;\r
+      }\r
+  };\r
+END_JSCRIPT_DECODE\r
+\r
+# JScript versions of encoders\r
+($_JSencode10) = <<'END_JSCRIPT_ENCODE10';\r
+  /* zero encoding */\r
+  /* characters: 0123456789 */\r
+  function($charCode) {\r
+    return $charCode;\r
+  };\r
+END_JSCRIPT_ENCODE10\r
+\r
+($_JSencode36) = <<'END_JSCRIPT_ENCODE36';\r
+  /* inherent base36 support */\r
+  /* characters: 0123456789abcdefghijklmnopqrstuvwxyz */\r
+  function($charCode) {\r
+    return $charCode.toString(36);\r
+  };\r
+END_JSCRIPT_ENCODE36\r
+\r
+($_JSencode62) = <<'END_JSCRIPT_ENCODE62';\r
+  /* hitch a ride on base36 and add the upper case alpha characters */\r
+  /* characters: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ */\r
+  function($charCode) {\r
+    return ($charCode < _encoding ? '' : arguments.callee(parseInt($charCode / _encoding))) +\r
+    (($charCode = $charCode % _encoding) > 35 ? String.fromCharCode($charCode + 29) : $charCode.toString(36));\r
+   };\r
+END_JSCRIPT_ENCODE62\r
+\r
+($_JSencode95) = <<'END_JSCRIPT_ENCODE95';\r
+ /* use high-ascii values */\r
+ /* characters: ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ */\r
+ function($charCode) {\r
+   return ($charCode < _encoding ? '' : arguments.callee($charCode / _encoding)) +\r
+     String.fromCharCode($charCode % _encoding + 161);\r
+ };\r
+END_JSCRIPT_ENCODE95\r
+\r
+###########\r
+# END     #\r
+###########\r
+1; # Pack #\r
+###########\r
diff --git a/browse/ParseMaster.pm b/browse/ParseMaster.pm
new file mode 100644 (file)
index 0000000..f07ba68
--- /dev/null
@@ -0,0 +1,207 @@
+#ParseMaster (July 25 2005)\r
+#  Based on "ParseMaster.js" by Dean Edwards <http://dean.edwards.name/>\r
+#  Ported to Perl by Rob Seiler, ELR Software Pty Ltd <http://www.elr.com.au>\r
+#  Copyright 2005. License <http://creativecommons.org/licenses/LGPL/2.1/>\r
+\r
+package ParseMaster;\r
+use strict;\r
+use Data::Dumper;\r
+\r
+# Package wide variable declarations\r
+use vars qw/$VERSION\r
+            @_X_escaped @_X_patterns\r
+           /;\r
+\r
+$VERSION    = '017';\r
+\r
+# constants\r
+my $X_EXPRESSION  = 0;\r
+my $X_REPLACEMENT = 1;\r
+my $X_LENGTH      = 2;\r
+\r
+# re's used to determine nesting levels\r
+my $X_GROUPS      = qr/\(/o;                # NB: Requires g modifier!\r
+my $X_SUB_REPLACE = qr/\$\d/o;\r
+my $X_INDEXED     = qr/^\$\d+$/o;\r
+my $XX_ESCAPE     = qr/\\./o;               # NB: Requires g modifier!\r
+my $XX_DELETED    = qr/\001[^\001]*\001/o;  # NB: Requires g modifier!\r
+my $DIGIT         = qr/[^\D]/o;             # Yep - this is a digit - contains no non-digits\r
+\r
+# Constructor\r
+sub new {\r
+  my $class = shift;\r
+  my $self  = {};\r
+  @_X_escaped  = ();  # Re-initialize global for each instance\r
+  @_X_patterns = ();  # Re-initialize global for each instance\r
+  # Instance variables - access by similarly named set/get functions\r
+  $self->{_ignoreCase_} = 0;\r
+  $self->{_escapeChar_} = '';\r
+  bless ($self, $class);\r
+  return $self;\r
+}\r
+\r
+sub ignoreCase {\r
+  my ($self, $value) = @_;\r
+  if (defined($value)) {\r
+    $self->{_ignoreCase_} = $value;\r
+  }\r
+  return $self->{_ignoreCase_};\r
+}\r
+\r
+sub escapeChar{\r
+  my ($self, $value) = @_;\r
+  if (defined($value)) {\r
+    $self->{_escapeChar_} = $value;\r
+  }\r
+  return $self->{_escapeChar_};\r
+}\r
+\r
+#######################\r
+# Public Parsemaster functions\r
+\r
+my $X_DELETE = sub(@$) {\r
+  my $X_offset = pop;\r
+  my @X_match = @_;\r
+  return (chr(001) . $X_match[$X_offset] . chr(001));\r
+}; # NB semicolon required for closure!\r
+\r
+# create and add a new pattern to the patterns collection\r
+sub add {\r
+  my ($self, $expression, $X_replacement) = @_;\r
+  if (!$X_replacement) {$X_replacement = $X_DELETE};\r
+\r
+  # count the number of sub-expressions\r
+  my $temp = &_X_internalEscape($expression);\r
+  my $length  = 1; # Always at least one because each pattern is itself a sub-expression\r
+     $length += $temp =~ s/$X_GROUPS//g; # One way to count the left capturing parentheses in the regexp string\r
+\r
+  # does the pattern deal with sub-expressions?\r
+  if ((ref($X_replacement) ne "CODE") && ($X_replacement =~ m/$X_SUB_REPLACE/)) {\r
+    if ($X_replacement =~ m/$X_INDEXED/) { # a simple lookup? (eg "$2")\r
+      # store the index (used for fast retrieval of matched strings)\r
+      $X_replacement = substr($X_replacement,1) - 1;\r
+    }\r
+    else { # a complicated lookup (eg "Hello $2 $1")\r
+      my $i = $length;\r
+      while ($i) { # Had difficulty getting Perl to do Dean's splitting and joining of strings containing $'s\r
+        my $str = '$a[$o+' . ($i-1) . ']'; # eg $a[$o+1]\r
+        $X_replacement =~ s/\$$i/$str/;      # eg $2 $3 -> $a[$o+1] $a[$o+2]\r
+        $i--;\r
+      }\r
+      # build a function to do the lookup - returns interpolated string of array lookups\r
+      $X_replacement = eval('sub {my $o=pop; my @a=@_; return "' . $X_replacement . '"};');\r
+    }\r
+  }\r
+  else {}\r
+  # pass the modified arguments\r
+  &_X_add($expression || q/^$/, $X_replacement, $length);\r
+}\r
+\r
+# execute the global replacement\r
+sub exec {\r
+#print Dumper(@_X_patterns);\r
+  my ($self, $X_string) = @_;\r
+  my $escChar    = $self->escapeChar();\r
+  my $ignoreCase = $self->ignoreCase();\r
+  my ($regexp,$captures) = &_getPatterns();  # Concatenated and parenthesized regexp eg '(regex1)|(regex2)|(regex3)' etc\r
+  $X_string = &_X_escape($X_string, $escChar);\r
+  if ($ignoreCase) {$X_string =~ s/$regexp/{&_X_replacement(&_matchVars($captures,\$X_string))}/gie} # Pass $X_String as a\r
+    else           {$X_string =~ s/$regexp/{&_X_replacement(&_matchVars($captures,\$X_string))}/ge}  # reference for speed\r
+\r
+  $X_string = &_X_unescape($X_string, $escChar);\r
+  $X_string =~ s/$XX_DELETED//g;\r
+  return $X_string;\r
+}\r
+\r
+sub _X_add {\r
+  push (@_X_patterns, [@_]); # Save each argument set as is into an array of arrays\r
+}\r
+\r
+# this is the global replace function (it's quite complicated)\r
+sub _X_replacement {\r
+  my (@arguments) = @_;\r
+#print Dumper (@arguments);\r
+  if ($arguments[0] le '') {return ''}\r
+  # Dereference last index (source String) here - faster than in _matchVars (maybe not needed at all?)\r
+  $arguments[$#arguments] = ${$arguments[$#arguments]};\r
+  my $i = 1;\r
+  # loop through the patterns\r
+  for (my $j=0; $j<scalar(@_X_patterns); $j++) { # Loop through global all @_X_patterns\r
+    my @X_pattern = @{$_X_patterns[$j]};\r
+    # do we have a result? NB: "if ($arguments[$i])" as in Dean's Javascript is false for the value 0!!!\r
+    if ((defined $arguments[$i]) && ($arguments[$i] gt '')) {\r
+      my $X_replacement = $X_pattern[$X_REPLACEMENT];\r
+      # switch on type of $replacement\r
+      if (ref($X_replacement) eq "CODE") {     # function\r
+        return &$X_replacement(@arguments,$i);\r
+      }\r
+      elsif ($X_replacement =~ m/$DIGIT/) {    # number (contains no non-digits)\r
+        return $arguments[$X_replacement + $i];\r
+      }\r
+      else { # default\r
+        return $X_replacement;                 # default\r
+      }\r
+    } # skip over references to sub-expressions\r
+    else {$i += $X_pattern[$X_LENGTH]}\r
+  }\r
+}\r
+\r
+#######################\r
+# Private functions\r
+#######################\r
+\r
+# encode escaped characters\r
+sub _X_escape {\r
+  my ($X_string, $X_escapeChar) = @_;\r
+  if ($X_escapeChar) {\r
+    my $re = '\\'.$X_escapeChar.'(.)';\r
+    $X_string =~ s/$re/{push(@_X_escaped,$1); $X_escapeChar}/ge;\r
+  }\r
+  return $X_string;\r
+}\r
+\r
+# decode escaped characters\r
+sub _X_unescape {\r
+  my ($X_string, $X_escapeChar) = @_;\r
+  if ($X_escapeChar) { # We'll only do this if there is an $X_escapeChar!\r
+    my $re = '\\'.$X_escapeChar;\r
+    $X_string =~ s/$re/{$X_escapeChar . (shift(@_X_escaped))}/ge; # Don't use Dean Edwards as below 'or' here - because zero will return ''!\r
+  # $X_string =~ s/$re/{$X_escapeChar . (shift(@_X_escaped) || '')}/ge;\r
+  }\r
+  return $X_string;\r
+}\r
+\r
+sub _X_internalEscape {\r
+  my ($string) = shift;\r
+  $string =~ s/$XX_ESCAPE//g;\r
+  return $string;\r
+}\r
+\r
+# Builds an array of match variables to (approximately) emulate that available in Javascript String.replace()\r
+sub _matchVars {\r
+  my ($m,$sref) = @_;\r
+  my @args = (1..$m);                # establish the number potential memory variables\r
+  my @mv = map {eval("\$$_")} @args; # matchvarv[1..m] = the memory variables $1 .. $m\r
+  unshift (@mv, $&);                 # matchvar[0]     = the substring that matched\r
+  push    (@mv, length($`));         # matchvar[m+1]   =  offset within the source string where the match occurred (= length of prematch string)\r
+  push    (@mv, $sref);              # matchvar[m+2]   = reference to full source string (dereference in caller if/when needed)\r
+#print Dumper (@mv);\r
+  return @mv;\r
+}\r
+\r
+sub _getPatterns {\r
+  my @Patterns = ();\r
+  my $lcp = 0;\r
+  for (my $i=0; $i<scalar(@_X_patterns); $i++) {       # Loop through global all @_patterns\r
+    push (@Patterns, $_X_patterns[$i][$X_EXPRESSION]); # accumulate the expressions\r
+    $lcp += $_X_patterns[$i][$X_LENGTH];               # sum the left capturing parenthesis counts\r
+  }\r
+  my $str = "(" . join(')|(',@Patterns). ")";          # enclose each pattern in () separated by "|"\r
+  return ($str, $lcp);\r
+}\r
+\r
+##################\r
+# END            #\r
+##################\r
+1; # ParseMaster #\r
+##################\r
diff --git a/browse/browse-new.cgi b/browse/browse-new.cgi
new file mode 100755 (executable)
index 0000000..54f7fbe
--- /dev/null
@@ -0,0 +1,85 @@
+#!/usr/bin/perl
+
+use Pack;
+use CGI;
+use LWP::Simple;
+use Digest::MD5 qw(md5_hex);
+
+chdir("/home/jquery/www/src/");
+
+my $cgi = new CGI();
+print $cgi->header('text/javascript');
+my $c = $cgi->param('c') || 'compressed';
+my $v = $cgi->param('v') || 'latest';
+my $live = 0;
+#$v = "0.10" if ( $v eq 'latest' );
+if ( $v eq 'dev' ) {
+  $live = 1;
+  $c = 'sane';
+  $v = 'latest';
+} elsif ( $v eq 'debug' ) {
+  $c = 'sane';
+  $v = 'latest';
+}
+
+my @files = $cgi->param('files') ?
+       split(',', join(',', $cgi->param('files')) ):
+       ("jquery","fx","event","ajax");
+
+if ($cgi->param('custom') && $cgi->param('custom') !~ /-/) {
+  $c = $cgi->param('custom');
+}
+
+my $md5 = $cgi->param('custom') || join('-',dupe(@files),$v,$c);
+my $j = "build/$md5\.js";
+my $stamp = "/* Built " . localtime() . " */\n";
+
+if ( !-e $j && !$live ) {
+       my $f = getf();
+       open( F, ">$j" );
+       print F $stamp;
+       print F $c eq 'compressed' ? &Pack::pack($f, 62, 1, 0) : $f;
+       close( F );
+
+       if ( $c eq 'compressed' ) {
+         my $tj = $j;
+         $tj =~ s/$c\.js$/sane\.js/;
+         open( F, ">$tj" );
+         print F $stamp;
+         print F $f;
+         close( F );
+       }
+}
+
+if ( $cgi->param('files') ) {
+       print $cgi->redirect("/src/$v/$md5/");
+} else {
+       #print $cgi->header('text/javascript');
+       if ( $live ) {
+               print getf();
+       } else {
+               my $t = `cat copyright.txt $j`;
+               $v = $v eq 'latest' ? 'Current' : "Version $v";
+               $t =~ s/\$VERSION/$v/ig;
+               $t =~ s/\$MD5/$md5/ig;
+               my $url = $cgi->param('v') . "/";
+               $url .= $cgi->param('custom') . "/" if ( $cgi->param('custom') );
+               $t =~ s/\$URL/$url/ig;
+               print $t;
+       }
+}
+
+sub getf {
+       my $f = '';
+       foreach ( @files ) {
+               $f .= `cat $_/$_\-$v\.js`;
+       }
+       $f =~ s/\r//g;
+       $f;
+}
+
+sub dupe {
+  my %check;
+  $check{$_} = 1 foreach (@_);
+  return sort keys %check;
+}
diff --git a/browse/browse.cgi b/browse/browse.cgi
new file mode 100755 (executable)
index 0000000..751af3b
--- /dev/null
@@ -0,0 +1,51 @@
+#!/usr/bin/perl
+
+use Pack;
+use CGI;
+use LWP::Simple;
+use Digest::MD5 qw(md5_hex);
+
+chdir("/home/jquery/www/src/");
+
+my $cgi = new CGI();
+my $c = $cgi->param('c') || 'compressed';
+my $v = $cgi->param('v');
+#$v = "0.10" if ( $v eq 'latest' );
+my @files = $cgi->param('files') ?
+       split(',', join(',', $cgi->param('files')) ):
+       ("jquery","minifx","fx","event");
+
+my $md5 = $cgi->param('custom') || join('-',dupe(@files),$v,$c);
+my $j = "build/$md5\.js";
+
+if ( !-e $j ) {
+       my $f = '';
+       foreach ( @files ) {
+               $f .= `cat $_/$_\-$v\.js`;
+       }
+       $f =~ s/\r//g;
+       my $o = $c eq 'compressed' ? &Pack::pack($f, 62, 1, 0) : $f;
+       open( F, ">$j" );
+       print F $o;
+       close( F );
+}
+
+if ( $cgi->param('files') ) {
+       print $cgi->redirect("/src/$v/$md5/");
+} else {
+       print $cgi->header('text/javascript');
+       my $t = `cat copyright.txt $j`;
+       $v = $v eq 'latest' ? 'Current' : "Version $v";
+       $t =~ s/\$VERSION/$v/ig;
+       $t =~ s/\$MD5/$md5/ig;
+       my $url = $cgi->param('v') . "/";
+       $url .= $cgi->param('custom') . "/" if ( $cgi->param('custom') );
+       $t =~ s/\$URL/$url/ig;
+       print $t;
+}
+
+sub dupe {
+  my %check;
+  $check{$_} = 1 foreach (@_);
+  return sort keys %check;
+}
diff --git a/browse/copyright.txt b/browse/copyright.txt
new file mode 100644 (file)
index 0000000..9fd2a07
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * jQuery - $VERSION
+ * New Wave Javascript
+ * http://jquery.com/
+ *
+ * To use, place this HTML into the <head>...</head> of your web page:
+ * <script type="text/javascript" src="http://jquery.com/src/$URL"></script>
+ *
+ * This licensed under the Creative Commons Attribution-ShareAlike License.
+ * License Info: http://creativecommons.org/licenses/by-sa/2.5/ 
+ *
+ *** NOTE:
+ * This code is compressed, for the original code please visit jquery.com.
+ * If you don't see anything below this comment, it's a bug with Firefox
+ * the code is there, it's just one long, compressed, line - trust me.
+ ***
+ */
diff --git a/core/core.js b/core/core.js
new file mode 100644 (file)
index 0000000..6b1d2f1
--- /dev/null
@@ -0,0 +1,748 @@
+/*
+ * JQuery (http://jquery.com/)
+ * By John Resig (http://ejohn.org/)
+ * Under an Attribution, Share Alike License
+ */
+
+function $(a,c) {
+       var $a = a || $.context || document;
+       var $c = c && c.$jquery && c.get(0) || c;
+       
+       // Since we're using Prototype's $ function,
+       // be nice and have backwards compatability
+       if ( typeof Prototype != "undefined" ) {
+               if ( $a.constructor == String ) {
+                       var re = new RegExp( "[^a-zA-Z0-9_-]" );
+                       if ( !re.test($a) ) {
+                               $c = $c && $c.documentElement || document;
+                               if ( $c.getElementsByTagName($a).length == 0 ) {
+                                       var obj = $c.getElementById($a);
+                                       if ( obj != null ) return obj;
+                               }
+                       }
+               } else if ( $a.constructor == Array ) {
+                       return $.map( $a, function(b){
+                               if ( b.constructor == String )
+                                       return document.getElementById(b);
+                               return b;
+                       });
+               }
+       }
+
+       // Load Dynamic Function List
+       var self = {
+               cur: $.Select($a,$c),
+               $jquery: "0.30",
+               
+               // The only two getters
+               size: function() {return this.get().length},
+               get: function(i) {
+                       return i == null ? this.cur : this.cur[i];
+               },
+               
+               each: function(f) {
+                       for ( var i = 0; i < this.size(); i++ )
+                               $.apply( this.get(i), f, [i] );
+                       return this;
+               },
+               set: function(a,b) {
+                       return this.each(function(){
+                               if ( b == null )
+                                       for ( var j in a )
+                                               $.attr(this,j,a[j]);
+                               else
+                                       $.attr(this,a,b);
+                       });
+               },
+               html: function(h) {
+                       return h == null && this.size() ?
+        this.get(0).innerHTML : this.set( "innerHTML", h );
+               },
+               val: function(h) {
+                       return h == null && this.size() ?
+        this.get(0).value : this.set( "value", h );
+               },
+               
+               css: function(a,b) {
+                       return this.each(function(){
+                               if ( !b )
+                                       for ( var j in a )
+                                               $.attr(this.style,j,a[j]);
+                               else
+                                       $.attr(this.style,a,b);
+                       });
+               },
+               toggle: function() {
+                       return this.each(function(){
+                               var d = $.getCSS(this,"display");
+                               if ( d == "none" || d == '' )
+                                       $(this).show();
+                               else
+                                       $(this).hide();
+                       });
+               },
+               show: function(a) {
+                       return this.each(function(){
+                               this.style.display = this.$$oldblock ? this.$$oldblock : '';
+                               if ( $.getCSS(this,"display") == "none" ) this.style.display = 'block';
+                       });
+               },
+               hide: function(a) {
+                       return this.each(function(){
+                               this.$$oldblock = $.getCSS(this,"display");
+                               if ( this.$$oldblock == "none" ) this.$$oldblock = 'block';
+                               this.style.display = 'none';
+                       });
+               },
+               addClass: function(c) {
+                       return this.each(function(){
+                               if ($.hasWord(this,c)) return;
+                               this.className += ( this.className.length > 0 ? " " : "" ) + c;
+                       });
+               },
+               removeClass: function(c) {
+                       return this.each(function(){
+                               this.className = c == null ? '' :
+                                       this.className.replace(
+                                               new RegExp('(^|\\s*\\b[^-])'+c+'($|\\b(?=[^-]))', 'g'), '');
+                       });
+               },
+               // TODO: Optomize
+               toggleClass: function(c) {
+                       return this.each(function(){
+                               if ($.hasWord(this,c))
+                                       this.className = 
+                                               this.className.replace(
+                                                       new RegExp('(\\s*\\b[^-])'+c+'($|\\b(?=[^-]))', 'g'), '');
+                               else
+                                       this.className += ( this.className.length > 0 ? " " : "" ) + c;
+                       });
+               },
+               remove: function() {
+                       this.each(function(){this.parentNode.removeChild( this );});
+                       this.cur = [];
+                       return this;
+               },
+               
+               wrap: function() {
+                       var a = $.clean(arguments);
+                       return this.each(function(){
+                               var b = a[0].cloneNode(true);
+                               this.parentNode.insertBefore( b, this );
+                               while ( b.firstChild ) b = b.firstChild;
+                               b.appendChild( this );
+                       });
+               },
+               
+               append: function() {
+      var clone = this.size() > 1;
+                       var a = $.clean(arguments);
+                       return this.each(function(){
+                               for ( var i in a )
+                                 this.appendChild( clone ? a[i].cloneNode(true) : a[i] );
+                       });
+               },
+
+               appendTo: function() {
+                       var a = arguments;
+                       return this.each(function(){
+                               for ( var i = 0; i < a.length; i++ )
+                                       $(a[i]).append( this );
+                       });
+               },
+               
+               prepend: function() {
+      var clone = this.size() > 1;
+                       var a = $.clean(arguments);
+                       return this.each(function(){
+                               for ( var i = a.length - 1; i >= 0; i-- )
+                                       this.insertBefore( clone ? a[i].cloneNode(true) : a[i], this.firstChild );
+                       });
+               },
+               
+               before: function() {
+      var clone = this.size() > 1;
+                       var a = $.clean(arguments);
+                       return this.each(function(){
+                               for ( var i in a )
+                                       this.parentNode.insertBefore( clone ? a[i].cloneNode(true) : a[i], this );
+                       });
+               },
+               
+               after: function() {
+      var clone = this.size() > 1;
+                       var a = $.clean(arguments);
+                       return this.each(function(){
+                               for ( var i = a.length - 1; i >= 0; i-- )
+                                       this.parentNode.insertBefore( clone ? a[i].cloneNode(true) : a[i], this.nextSibling );
+                       });
+               },
+
+               empty: function() {
+                       return this.each(function(){
+                               while ( this.firstChild )
+                                       this.removeChild( this.firstChild );
+                       });
+               },
+               
+               bind: function(t,f) {
+                       return this.each(function(){addEvent(this,t,f);});
+               },
+               unbind: function(t,f) {
+                       return this.each(function(){removeEvent(this,t,f);});
+               },
+               trigger: function(t) {
+                       return this.each(function(){triggerEvent(this,t);});
+               },
+               
+               find: function(t) {
+                       var old = [], ret = [];
+                       this.each(function(){
+                               old[old.length] = this;
+                               ret = $.merge( ret, $.Select(t,this) );
+                       });
+                       this.old = old;
+                       this.cur = ret;
+                       return this;
+               },
+               end: function() {
+                       this.cur = this.old;
+                       return this;
+               },
+               
+               parent: function(a) {
+                       if ( a == null ) a = 1;
+                       this.cur = $.map(this.cur,function(d){
+                               var b = $.parents(d);
+                               if ( a == 0 )
+                                       return b;
+                               else if ( a.constructor == String ) {
+                                       var c = $.filter(a,b);
+                                       return c.length > 0 ? c[0] : null;
+                               } else
+                                       return b.length >= a ? b[a-1] : null;
+                       });
+                       return this;
+               },
+               
+               parents: function(a) {
+                       return this;
+               },
+               
+               filter: function(t) {
+                       this.cur = $.filter(t,this.cur).r;
+                       return this;
+               },
+               not: function(t) {
+                       this.cur = t.constructor == String ?
+                               $.filter(t,this.cur,false).r :
+                               $.grep(this.cur,function(a){return a != t;});
+                       return this;
+               },
+               add: function(t) {
+                       this.cur = $.merge( this.cur, t.constructor == String ?
+                               $.Select(t) : t.constructor == Array ? t : [t] );
+                       return this;
+               },
+               is: function(t) {
+                       return $.filter(t,this.cur).r.length > 0;
+               },
+               isNot: function(t) {
+                       return !this.s(t);
+               }
+       };
+       
+       // TODO: Remove need to return this
+       for ( var i in $.fn ) {
+               if ( self[i] != null )
+                       self["_"+i] = self[i];
+               self[i] = $.fn[i];
+       }
+       
+       if ( typeof Prototype != "undefined" && $a.constructor != String ) {
+               if ( $c ) $a = self.get();
+               for ( var i in self ) {(function(j){
+                       try {
+                               if ( $a[j] == null ) {
+                                       $a[j] = function() {
+                                               return $.apply(self,self[j],arguments);
+                                       };
+                               }
+                       } catch(e) {}
+               })(i);}
+               return $a;
+       }
+       
+       return self;
+}
+
+$.apply = function(o,f,a) {
+       a = a || [];
+       if ( f.apply )
+               return f.apply( o, a );
+  else {
+               var p = [];
+               for (var i = 0; i < a.length; i++)
+                       p[i] = 'a['+i+']';
+               o.$$exec = this;
+               var r = eval('o.$$exec(' + p.join(',') + ')');
+               o.$$exec = null;
+               return r;
+       }
+};
+
+$.getCSS = function(e,p) {
+       // Adapted from Prototype 1.4.0
+       if ( p == 'height' || p == 'width' ) {
+    if ($.getCSS(e,"display") != 'none')
+                       return p == 'height' ?
+                               e.offsetHeight || parseInt(e.style.height) : 
+                               e.offsetWidth || parseInt(e.style.width);
+    var els = e.style;
+    var ov = els.visibility;
+    var op = els.position;
+               var od = els.display;
+    els.visibility = 'hidden';
+    els.position = 'absolute';
+    els.display = '';
+               var oHeight = e.clientHeight || parseInt(e.style.height);
+    var oWidth = e.clientWidth || parseInt(e.style.width);
+    els.display = od;
+    els.position = op;
+    els.visibility = ov;
+               return p == 'height' ? oHeight : oWidth;
+  }
+       
+  if (e.style[p])
+    return e.style[p];
+  else if (e.currentStyle)
+    return e.currentStyle[p];
+  else if (document.defaultView && document.defaultView.getComputedStyle) {
+    p = p.replace(/([A-Z])/g,"-$1");
+    p = p.toLowerCase();
+    var s = document.defaultView.getComputedStyle(e,"");
+    var r = s ? s.getPropertyValue(p) : p;
+               return r;
+  } else
+    return null;
+};
+$.css = $.getCSS;
+
+$.clean = function(a) {
+       var r = [];
+       for ( var i = 0; i < a.length; i++ )
+               if ( a[i].constructor == String ) {
+                       var div = document.createElement("div");
+                       div.innerHTML = a[i];
+                       for ( var j = 0; j < div.childNodes.length; j++ )
+                               r[r.length] = div.childNodes[j];
+               } else if ( a[i].length )
+                       for ( var j = 0; j < a[i].length; j++ )
+                               r[r.length] = a[i][j];
+               else if ( a[i] != null )
+                       r[r.length] = 
+                               a[i].nodeType ? a[i] : document.createTextNode(a[i].toString());
+       return r;
+};
+
+$.g = {
+       '': "m[2] == '*' || a.nodeName.toUpperCase() == m[2].toUpperCase()",
+       '#': "a.id == m[2]",
+       ':': {
+               lt: "i < m[3]-0",
+               gt: "i > m[3]-0",
+               nth: "m[3] - 0 == i",
+               eq: "m[3] - 0 == i",
+               first: "i == 0",
+               last: "i == r.length - 1",
+               even: "i % 2 == 0",
+               odd: "i % 2 == 1",
+               "first-child": "$.sibling(a,0).cur",
+               "nth-child": "(m[3] == 'even'?$.sibling(a,m[3]).n % 2 == 0 :(m[3] == 'odd'?$.sibling(a,m[3]).n % 2 == 1:$.sibling(a,m[3]).cur))",
+               "last-child": "$.sibling(a,0,true).cur",
+               "nth-last-child": "$.sibling(a,m[3],true).cur",
+               "first-of-type": "$.ofType(a,0)",
+               "nth-of-type": "$.ofType(a,m[3])",
+               "last-of-type": "$.ofType(a,0,true)",
+               "nth-last-of-type": "$.ofType(a,m[3],true)",
+               "only-of-type": "$.ofType(a) == 1",
+               "only-child": "$.sibling(a).length == 1",
+               parent: "a.childNodes.length > 0",
+               empty: "a.childNodes.length == 0",
+               root: "a == ( a.ownerDocument ? a.ownerDocument : document ).documentElement",
+               contains: "(a.innerText || a.innerHTML).indexOf(m[3]) != -1",
+               visible: "(!a.type || a.type != 'hidden') && ($.getCSS(a,'display') != 'none' && $.getCSS(a,'visibility') != 'hidden')",
+               hidden: "(a.type && a.type == 'hidden') || $.getCSS(a,'display') == 'none' || $.getCSS(a,'visibility') == 'hidden'",
+               enabled: "a.disabled == false",
+               disabled: "a.disabled",
+               checked: "a.checked"
+       },
+       // TODO: Write getAttribute helper
+       ".": "$.hasWord(a.className||a.getAttribute('class'),m[2])",
+       "@": {
+               "=": "$.attr(a,m[3]) == m[4]",
+               "!=": "$.attr(a,m[3]) != m[4]",
+               "~=": "$.hasWord($.attr(a,m[3]),m[4])",
+               "|=": "$.attr(a,m[3]).indexOf(m[4]) == 0",
+               "^=": "$.attr(a,m[3]).indexOf(m[4]) == 0",
+               "$=": "$.attr(a,m[3]).substr( $.attr(a,m[3]).length - m[4].length, m[4].length ) == m[4]",
+               "*=": "$.attr(a,m[3]).indexOf(m[4]) >= 0",
+               "": "m[3] == '*' ? a.attributes.length > 0 : $.attr(a,m[3])"
+       },
+       "[": "$.Select(m[2],a).length > 0"
+};
+
+$.fn = {};
+
+$.Select = function( t, context ) {
+       context = context || $.context || document;
+       if ( t.constructor != String ) return [t];
+       
+       if ( t.indexOf("//") == 0 ) {
+               context = context.documentElement;
+               t = t.substr(2,t.length);
+       } else if ( t.indexOf("/") == 0 ) {
+               context = context.documentElement;
+               t = t.substr(1,t.length);
+               // FIX Assume the root element is right :(
+               if ( t.indexOf('/') )
+                       t = t.substr(t.indexOf('/'),t.length);
+       }
+       
+       var ret = [context];
+  var done = [];
+       var last = null;
+  
+  while ( t.length > 0 && last != t ) {
+    var r = [];
+               last = t;
+    
+    t = $.cleanSpaces(t);
+    
+    var re = new RegExp( "^//", "i" );
+    t = t.replace( re, "" );
+
+    if ( t.indexOf('..') == 0 || t.indexOf('/..') == 0 ) {
+                       if ( t.indexOf('/') == 0 )
+                               t = t.substr(1,t.length);
+      r = $.map( ret, function(a){ return a.parentNode; } );
+                       t = t.substr(2,t.length);
+                       t = $.cleanSpaces(t);
+    } else if ( t.indexOf('>') == 0 || t.indexOf('/') == 0 ) {
+      r = $.map( ret, function(a){ return ( a.childNodes.length > 0 ? $.sibling( a.firstChild ) : null ); } );
+                       t = t.substr(1,t.length);
+                       t = $.cleanSpaces(t);
+    } else if ( t.indexOf('+') == 0 ) {
+      r = $.map( ret, function(a){ return $.sibling(a).next; } );
+                       t = t.substr(1,t.length);
+                       t = $.cleanSpaces(t);
+    } else if ( t.indexOf('~') == 0 ) {
+      r = $.map( ret, function(a){
+        var r = [];
+        var s = $.sibling(a);
+        if ( s.n > 0 )
+          for ( var i = s.n; i < s.length; i++ )
+            r[r.length] = s[i];
+        return r;
+      } );
+                       t = t.substr(1,t.length);
+                       t = $.cleanSpaces(t);
+    } else if ( t.indexOf(',') == 0 || t.indexOf('|') == 0 ) {
+      if ( ret[0] == context ) ret.shift();
+      done = $.merge( done, ret );
+      r = ret = [context];
+                       t = " " + t.substr(1,t.length);
+    } else {
+      var re = new RegExp( "^([#.]?)([a-z0-9\\*_-]*)", "i" );
+      var m = re.exec(t);
+                       
+                       if ( m[1] == "#" ) { // Ummm, should make this work in all XML docs
+                               var oid = document.getElementById(m[2]);
+                               r = oid ? [oid] : [];
+        t = t.replace( re, "" );
+                       } else {
+                         if ( m[2] == "" || m[1] == "." ) m[2] = "*";
+
+                         for ( var i = 0; i < ret.length; i++ ) {
+                                 var o = ret[i];
+                                 if ( o ) {
+                                         switch( m[2] ) {
+                                                 case '*':
+                                                         r = $.merge( $.getAll(o), r );
+                                                 break;
+                                                 case 'text': case 'radio': case 'checkbox': case 'hidden':
+                                                 case 'button': case 'submit': case 'image': case 'password':
+                                                 case 'reset': case 'file':
+                                                         r = $.merge( $.grep( $.tag(o,"input"), 
+                                                                                 function(a){ return a.type == m[2] }), r );
+                                                 break;
+                                                 case 'input':
+                                                         r = $.merge( $.tag(o,"input"), r );
+                                                         r = $.merge( $.tag(o,"select"), r );
+                                                         r = $.merge( $.tag(o,"textarea"), r );
+                                                 break;
+                                                 default:
+                                                         r = $.merge( r, $.tag(o,m[2]) );
+                                                 break;
+                                         }
+                                 }
+                         }
+                       }
+    }
+
+               var val = $.filter(t,r);
+               ret = r = val.r;
+               t = $.cleanSpaces(val.t);
+  }
+
+  if ( ret && ret[0] == context ) ret.shift();
+  done = $.merge( done, ret );
+  return done;
+};
+
+$.tag = function(a,b){
+  return a && typeof a.getElementsByTagName != "undefined" ?
+    a.getElementsByTagName( b ) : [];
+};
+
+$.attr = function(o,a,v){
+  if ( a && a.constructor == String ) {
+    var fix = {
+      'for': 'htmlFor',
+      'text': 'cssText',
+      'class': 'className',
+      'float': 'cssFloat'
+    };
+    a = (fix[a] && fix[a].replace && fix[a]) || a;
+    var r = new RegExp("-([a-z])","ig");
+    a = a.replace(r,function(z,b){return b.toUpperCase();});
+    if ( v != null ) {
+      o[a] = v;
+      if ( o.setAttribute ) o.setAttribute(a,v);
+    } 
+    return o[a] || o.getAttribute(a) || '';
+  } else return '';
+};
+
+$.filter = function(t,r,not) {
+       var g = $.grep;
+       if ( not == false ) var g = function(a,f) {return $.grep(a,f,true);};
+       
+       while ( t.length > 0 && t.match(/^[:\\.#\\[a-zA-Z\\*]/) ) {
+               var re = new RegExp( "^\\[ *@([a-z0-9\\(\\)_-]+) *([~!\\|\\*$^=]*) *'?\"?([^'\"]*)'?\"? *\\]", "i" );
+               var m = re.exec(t);
+               
+               if ( m != null ) {
+                       m = ['', '@', m[2], m[1], m[3]];
+               } else {
+                       var re = new RegExp( "^(\\[) *([^\\]]*) *\\]", "i" );
+                       var m = re.exec(t);
+                       
+                       if ( m == null ) {
+                               var re = new RegExp( "^(:)([a-z0-9\\*_-]*)\\( *[\"']?([^ \\)'\"]*)['\"]? *\\)", "i" );
+                               var m = re.exec(t);
+                               
+                               if ( m == null ) {
+                                       var re = new RegExp( "^([:\\.#]*)([a-z0-9\\*_-]*)", "i" );
+                                       var m = re.exec(t);
+                               }
+                       }
+               }
+               t = t.replace( re, "" );
+               
+               if ( m[1] == ":" && m[2] == "not" )
+                       r = $.filter(m[3],r,false).r;
+               else {
+                       if ( $.g[m[1]].constructor == String )
+                               var f = $.g[m[1]];
+                       else if ( $.g[m[1]][m[2]] )
+                               var f = $.g[m[1]][m[2]];
+                                               
+                       if ( f != null ) {
+                               eval("f = function(a,i){return " + f + "}");
+                               r = g( r, f );
+                       }
+               }
+       }
+       return { r: r, t: t };
+};
+
+$.parents = function(a){
+       var b = [];
+       var c = a.parentNode;
+       while ( c != null && c != c.documentElement ) {
+               b[b.length] = c;
+               c = c.parentNode;
+       }
+       return b;
+};
+
+$.cleanSpaces = function(t){return t.replace(/^\s+|\s+$/g, '')};
+
+$.ofType = function(a,n,e) {
+  var t = $.grep($.sibling(a),function(b){return b.nodeName == a.nodeName});
+  if ( e ) n = t.length - n - 1;
+  return n != null ? t[n] == a : t.length;
+};
+
+$.sibling = function(a,n,e) {
+  var type = [];
+  var tmp = a.parentNode.childNodes;
+  for ( var i = 0; i < tmp.length; i++ ) {
+    if ( tmp[i].nodeType == 1 )
+      type[type.length] = tmp[i];
+    if ( tmp[i] == a )
+      type.n = type.length - 1;
+  }
+  if ( e ) n = type.length - n - 1;
+  type.cur = ( type[n] == a );
+  type.prev = ( type.n > 0 ? type[type.n - 1] : null );
+  type.next = ( type.n < type.length - 1 ? type[type.n + 1] : null );
+  return type;
+};
+
+$.hasWord = function(e,a) {
+  if ( e == null ) return false;
+  if ( e.className != null ) e = e.className;
+  return new RegExp("(^|\\s)" + a + "(\\s|$)").test(e)
+};
+
+$.getAll = function(o,r) {
+       r = r || [];
+       var s = o.childNodes;
+       for ( var i = 0; i < s.length; i++ ) {
+               if ( s[i].nodeType == 1 ) {
+                       r[r.length] = s[i];
+                       $.getAll( s[i], r );
+               }
+       }
+       return r;
+};
+
+$.merge = function(a,b) {
+       var d = [];
+       for ( var j = 0; j < b.length; j++ )
+               d[j] = b[j];
+       
+  for ( var i = 0; i < a.length; i++ ) {
+    var c = true;
+    for ( var j = 0; j < b.length; j++ )
+      if ( a[i] == b[j] )
+        c = false;
+               if ( c )
+                       d[d.length] = a[i];
+  }
+       return d;
+};
+
+$.grep = function(a,f,s) {
+  var r = [];
+       if ( a != null )
+               for ( var i = 0; i < a.length; i++ )
+                       if ( (!s && f(a[i],i)) || (s && !f(a[i],i)) )
+                               r[r.length] = a[i];
+  return r;
+};
+
+$.map = function(a,f) {
+  var r = [];
+  for ( var i = 0; i < a.length; i++ ) {
+    var t = f(a[i],i);
+    if ( t != null ) {
+      if ( t.constructor != Array ) t = [t];
+                       r = $.merge( t, r );
+               }
+  }
+  return r;
+};
+
+// Bind an event to an element
+// Original by Dean Edwards
+function addEvent(element, type, handler) {
+       if ( element.location ) element = window; // Ughhhhh....
+       if (!handler.$$guid) handler.$$guid = addEvent.guid++;
+       if (!element.events) element.events = {};
+       var handlers = element.events[type];
+       if (!handlers) {
+               handlers = element.events[type] = {};
+               if (element["on" + type])
+                       handlers[0] = element["on" + type];
+       }
+       handlers[handler.$$guid] = handler;
+       element["on" + type] = handleEvent;
+};
+addEvent.guid = 1;
+
+// Detach an event or set of events from an element
+function removeEvent(element, type, handler) {
+       if (element.events) {
+               if (type && element.events[type]) {
+                       if ( handler ) {
+                               delete element.events[type][handler.$$guid];
+                       } else {
+                               for ( var i in element.events[type] )
+                                       delete element.events[type][i];
+                       }
+               } else {
+                       for ( var i in element.events )
+                               removeEvent( element, i );
+               }
+       }
+};
+
+function triggerEvent(element,type) {
+  if ( element["on" + type] )
+    element["on" + type]({ type: type });
+}
+
+function handleEvent(event) {
+       var returnValue = true;
+       event = event || fixEvent(window.event);
+       var handlers = [];
+       for ( var i in this.events[event.type] )
+               handlers[handlers.length] = this.events[event.type][i];
+  for ( var i = 0; i < handlers.length; i++ ) {
+               try {
+                       if ( handlers[i].constructor == Function ) {
+                               this.$$handleEvent = handlers[i];
+                               if (this.$$handleEvent(event) === false) {
+                                       event.preventDefault();
+                                       event.stopPropagation();
+                                       returnValue = false;
+                               }
+                       }
+               } catch(e){}
+       }
+       return returnValue;
+};
+
+function fixEvent(event) {
+       event.preventDefault = fixEvent.preventDefault;
+       event.stopPropagation = fixEvent.stopPropagation;
+       return event;
+};
+fixEvent.preventDefault = function() {
+       this.returnValue = false;
+};
+fixEvent.stopPropagation = function() {
+       this.cancelBubble = true;
+};
+
+// Move to module
+
+$.fn.text = function(e) {
+       e = e || this.cur;
+       var t = "";
+       for ( var j = 0; j < e.length; j++ ) {
+               for ( var i = 0; i < e[j].childNodes.length; i++ )
+                       t += e[j].childNodes[i].nodeType != 1 ?
+                               e[j].childNodes[i].nodeValue :
+                               $.fn.text(e[j].childNodes[i].childNodes);
+       }
+       return t;
+};
+
+setTimeout(function(){
+  if ( typeof Prototype != "undefined" && $.g == null && $.clean == null )
+    throw "Error: You are overwriting jQuery, please include jQuery last.";
+}, 1000);
diff --git a/event/event.js b/event/event.js
new file mode 100644 (file)
index 0000000..e11a2c0
--- /dev/null
@@ -0,0 +1,73 @@
+var e = ["blur","focus","contextmenu","load","resize","scroll","unload",
+       "click","dblclick","mousedown","mouseup","mouseenter","mouseleave",
+       "mousemove","mouseover","mouseout","change","reset","select","submit",
+       "keydown","keypress","keyup","abort","error","ready"];
+for ( var i = 0; i < e.length; i++ ) {
+       (function(){
+               var o = e[i];
+               $.fn[o] = function(f){ return this.bind(o, f); };
+               $.fn["un"+o] = function(f){ return this.unbind(o, f); };
+               $.fn["do"+o] = function(){ return this.trigger(o); };
+               $.fn["one"+o] = function(f){ return this.bind(o, function(e){
+                       if ( this[o+f] != null ) return true;
+                       this[o+f]++;
+                       return $.apply(this,f,[e]);
+               }); };
+               
+               // Deprecated
+               //$.fn["on"+o] = function(f){ return this.bind(o, f); };
+       })();
+}
+
+$.fn.hover = function(f,g) {
+       // Check if mouse(over|out) are still within the same parent element
+       return this.each(function(){
+               var obj = this;
+               addEvent(this, "mouseover", function(e) {
+                       var p = ( e.fromElement != null ? e.fromElement : e.relatedTarget );
+                       while ( p && p != obj ) p = p.parentNode;
+                       if ( p == obj ) return false;
+                       return $.apply(obj,f,[e]);
+               });
+               addEvent(this, "mouseout", function(e) {
+                       var p = ( e.toElement != null ? e.toElement : e.relatedTarget );
+                       while ( p && p != obj ) p = p.parentNode;
+                       if ( p == obj ) return false;
+                       return $.apply(obj,g,[e]);
+               });
+       });
+};
+
+// Deprecated
+$.fn.onhover = $.fn.hover;
+
+$.fn.ready = function(f) {
+       return this.each(function(){
+               if ( this.$$timer ) {
+                       this.$$ready.push( f );
+               } else {
+                       var obj = this;
+                       this.$$ready = [ f ];
+                       this.$$timer = setInterval( function(){
+                               if ( obj && obj.getElementsByTagName && obj.getElementById && obj.body ) {
+                                       clearInterval( obj.$$timer );
+                                       obj.$$timer = null;
+                                       for ( var i = 0; i < obj.$$ready.length; i++ )
+                                               $.apply( obj, obj.$$ready[i] );
+                                       obj.$$ready = null;
+                               }
+                       }, 13 );
+               }
+       });
+};
+
+// Deprecated
+$.fn.onready = $.fn.ready;
+
+$.fn.toggle = function(a,b) {
+       return a && b ? this.click(function(e){
+               this.$$last = this.$$last == a ? b : a;
+               e.preventDefault();
+               return $.apply( this, this.$$last, [e] ) || false;
+       }) : this._toggle();
+};
diff --git a/fx/fx.js b/fx/fx.js
new file mode 100644 (file)
index 0000000..6e48920
--- /dev/null
+++ b/fx/fx.js
@@ -0,0 +1,170 @@
+function fx(el,op,ty,tz){
+       var z = this;
+       z.a = function(){z.el.style[ty]=z.now+z.o.unit};
+       z.max = function(){return z.el["io"+ty]||z.el["natural"+tz]||z.el["scroll"+tz]||z.cur()};
+       z.cur = function(){return parseInt($.getCSS(z.el,ty))};
+       z.show = function(){z.ss("block");z.custom(0,z.max())};
+       z.hide = function(){z.el.$o=$.getCSS(z.el,"overflow");z.el["io"+ty]=this.cur();z.custom(z.cur(),0)};
+       z.ss = function(a){if(y.display!=a)y.display=a};
+       z.toggle = function(){if(z.cur()>0)z.hide();else z.show()};
+       z.modify = function(a){z.custom(z.cur(),z.cur()+a)};
+       z.clear = function(){clearInterval(z.timer);z.timer=null};
+       z.el = el.constructor==String?document.getElementById(el):el;
+       var y = z.el.style;
+        z.oo = y.overflow;
+       y.overflow = "hidden";
+       z.o = {
+          unit: "px",
+          duration: (op && op.duration) || 400,
+          onComplete: (op && op.onComplete) || op
+        };
+       z.step = function(f,tt){
+               var t = (new Date).getTime();
+               var p = (t - z.s) / z.o.duration;
+               if (t >= z.o.duration+z.s) {
+                       z.now = tt;
+                       z.clear();
+                       setTimeout(function(){
+                               y.overflow = z.oo;
+                               if(y.height=="0px"||y.width=="0px")z.ss("none");
+                               $.setAuto( z.el, "height" );
+                               $.setAuto( z.el, "width" );
+                               if(z.o.onComplete.constructor == Function){z.el.$_ = z.o.onComplete;z.el.$_();}
+                       },13);
+               } else
+                       z.now = ((-Math.cos(p*Math.PI)/2) + 0.5) * (tt-f) + f;
+               z.a();
+       };
+       z.custom = function(f,t){
+               if(z.timer)return;this.now=f;z.a();z.io=z.cur();z.s=(new Date).getTime();
+               z.timer=setInterval(function(){z.step(f,t);}, 13);
+       };
+}
+fx.fn = ["show","hide","toggle"];
+fx.ty = ["Height","Width","Left","Top"];
+for(var i in fx.ty){(function(){
+       var c = fx.ty[i];
+       fx[c] = function(a,b){
+               return new fx(a,b,c.toLowerCase(),c);};
+})()}
+fx.Opacity = function(a,b){
+       var o = new fx(a,b,"opacity");
+       o.cur = function(){return parseFloat(o.el.style.opacity);};
+       o.a = function() {
+               var e = o.el.style;
+               if (o.now == 1) o.now = 0.9999;
+               if (window.ActiveXObject)
+                       e.filter = "alpha(opacity=" + o.now*100 + ")";
+               e.opacity = o.now;
+       };
+       o.io = o.now = 1;
+       o.a();
+       return o;
+};
+fx.Resize = function(e,o){
+       var z = this;
+       var h = new fx.Height(e,o);
+       if(o) o.onComplete = null;
+       var w = new fx.Width(e,o);
+       function c(a,b,c){return (!a||a==c||b==c);}
+       for(var i in fx.fn){(function(){
+               var j = fx.fn[i];
+               z[j] = function(a,b){
+                       if(c(a,b,"height")) h[j]();
+                       if(c(a,b,"width")) w[j]();
+               };
+       })()}
+       z.modify = function(c,d){
+               h.modify(c);
+               w.modify(d);
+       };
+};
+fx.FadeSize = function(e,o){
+       var z = this;
+       var p = new fx.Opacity(e,o);
+       if(o) o.onComplete = null;
+       var r = new fx.Resize(e,o);
+       for(var i in fx.fn){(function(){
+               var j = fx.fn[i];
+               z[j] = function(a,b){p[j]();r[j](a,b);};
+       })()}
+};
+
+$.speed = function(s,o) {
+  if ( o && o.constructor == Function ) o = { onComplete: o };
+  o = o || {};
+  var ss = {"crawl":1200,"xslow":850,"slow":600,"medium":400,"fast":200,"xfast":75,"normal":400};
+  o.duration = typeof s == "number" ? s : ss[s] || 400;
+  return o;
+};
+
+$.fn.hide = function(a,o) {
+  o = $.speed(a,o);
+  return a ? this.each(function(){
+    new fx.FadeSize(this,o).hide();
+  }) : this._hide();
+};
+
+$.fn.show = function(a,o) {
+  o = $.speed(a,o);
+  return a ? this.each(function(){
+    new fx.FadeSize(this,o).show();
+  }) : this._show();
+};
+
+$.fn.slideDown = function(a,o) {
+  o = $.speed(a,o);
+  return this.each(function(){
+    new fx.Resize(this,o).show("height");
+  });
+};
+
+$.fn.slideUp = function(a,o) {
+  o = $.speed(a,o);
+  return this.each(function(){
+    new fx.Resize(this,o).hide("height");
+  });
+};
+
+$.fn.fadeOut = function(a,o) {
+  o = $.speed(a,o);
+  return a ? this.each(function(){
+    new fx.Opacity(this,o).hide();
+  }) : this._hide();
+};
+
+$.fn.fadeIn = function(a,o) {
+  o = $.speed(a,o);
+  return a ? this.each(function(){
+    new fx.Opacity(this,o).show();
+  }) : this._show();
+};
+
+$.fn.center = function(f) {
+  return this.each(function(){
+               if ( !f && this.nodeName == 'IMG' &&
+                                !this.offsetWidth && !this.offsetHeight ) {
+                       var self = this;
+                       setTimeout(function(){
+                               $(self).center(true);
+                       }, 13);
+               } else {
+                       var s = this.style;
+                       var p = this.parentNode;
+                       if ( $.css(p,"position") == 'static' )
+                               p.style.position = 'relative';
+                       s.position = 'absolute';
+                       s.left = parseInt(($.css(p,"width") - $.css(this,"width"))/2) + "px";
+                       s.top = parseInt(($.css(p,"height") - $.css(this,"height"))/2) + "px";
+               }
+  });
+};
+
+$.setAuto = function(e,p) {
+  var a = e.style[p];
+  var o = $.css(e,p);
+  e.style[p] = 'auto';
+  var n = $.css(e,p);
+  if ( o != n )
+    e.style[p] = a;
+};
diff --git a/sort/sort.js b/sort/sort.js
new file mode 100644 (file)
index 0000000..5a08b77
--- /dev/null
@@ -0,0 +1,57 @@
+$.fn.sort = function(f) {
+       cur = cur.sort(function(a,b){
+               if ( typeof f == 'object' )
+                       var ret = f(a,b);
+               else
+                       var ret = $.fn.genericSort(a,b,f);
+
+               if ( a < b )
+                       b.parentNode.insertBefore( a, b );
+               else if ( a > b )
+                       a.parentNode.insertBefore( b, a );
+               return ret;
+       });
+       return this;
+}
+
+$.fn.reverse = function() {
+       cur[0].parentNode.appendChild( cur[0] );
+       for ( var i = 1; cur && i < cur.length; i++ )
+               cur[i-1].parentNode.insertBefore( cur[i], cur[i-1] );
+       cur = cur.reverse();
+       return this;
+}
+
+$.fn.genericSort = function(a,b,c) {
+       if ( typeof a == "string" || typeof b == "string" ) {
+       } else if ( c != null ) {
+               a = sibling(a.firstChild)[c].innerText;
+               b = sibling(b.firstChild)[c].innerText;
+       } else {
+               a = a.innerText;
+               b = b.innerText;
+       }
+       
+       // Case insensitive
+       a = a.toLowerCase();
+       b = b.toLowerCase();
+       
+       // Figure out if it's an American-style date
+       var re = new RegExp( "^(\d{2}).(\d{2}).(\d{2,4})$" );
+       var ma = re.exec(a);
+       var mb = re.exec(b);
+       
+       if ( ma.length && mb.length ) {
+               a = ma.reverse().join('');
+               b = mb.reverse().join('');
+       }
+       
+       // If it contains a number, sort on that only
+       if ( a.match(/\d/) ) {
+               var re = new RegExp("[^0-9.-]","ig");
+               a = parseFloat( a.replace( re, "" ) );
+               b = parseFloat( b.replace( re, "" ) );
+       }
+       
+       return ( a < b ? -1 : ( a > b ? 1 : 0 ) );
+}
diff --git a/tmpl/tmpl.js b/tmpl/tmpl.js
new file mode 100644 (file)
index 0000000..2ada8fa
--- /dev/null
@@ -0,0 +1,106 @@
+$.fn.get = function(i) {
+       return i == null ?
+               this.$$unclean ? $.sibling(this.$$unclean[0]) : this.cur :
+                       (this.get())[i];
+};
+
+$.fn._get = function(i) {
+       return i == null ? this.cur : this.cur[i];
+};
+
+$.fn.set = function(a,b) {
+       return this.each(function(){
+               if ( b == null )
+                       for ( var j in a )
+                               this[$.attr(j)] = a[j];
+               else {
+                       if ( b.constructor != String ) { // TODO: Fix this
+                               for ( var i in b ) {    
+                                       var c = $.Select(i,this);
+                                       for ( var j in c )
+                                               c[j][$.attr(a)] = b[i];
+                               }
+                       } else
+                               this[$.attr(a)] = b;
+               }
+       });
+};
+
+function $C(a) {
+  if ( a.indexOf('<') >= 0 ) {
+    if ( a.indexOf('<tr') >= 0 ) {
+      var r = $C("table").html("<tbody>"+a+"</tbody>");
+      r.$$unclean = r.get(0).childNodes[0].childNodes;
+    } else {
+      var r = $C("div").html(a);
+      r.$$unclean = r.get(0).childNodes;
+    }
+    return r;
+  } else {
+    return $(document.createElement(a),document);
+  }
+};
+
+$.fn.appendTo = function() {
+       var self = this;
+       var a = arguments;
+       return this.each(function(){
+               for ( var i = 0; i < a.length; i++ ) {
+                       if ( self.$$unclean )
+                               $(a[i]).append( self.get() );
+                       else
+                               $(a[i]).append( this );
+               }
+       });
+};
+
+$.clean = function(a) {
+       var r = [];
+       for ( var i = 0; i < a.length; i++ ) {
+               if ( a[i].constructor == String ) {
+                       // Cool, but has scary side-effects
+                       //a[i] = a[i].replace( /#([a-zA-Z0-9_-]+)/g, " id='$1' " );
+                       //a[i] = a[i].replace( /\.([a-zA-Z0-9_-]+)/g, " class='$1' " );
+                       var div = document.createElement("div");
+                       div.innerHTML = a[i];
+                       for ( var j = 0; j < div.childNodes.length; j++ )
+                               r[r.length] = div.childNodes[j];
+               } else if ( a[i].length ) {
+                       for ( var j = 0; j < a[i].length; j++ )
+                               r[r.length] = a[i][j];
+               } else {
+                       r[r.length] = a[i];
+               }
+       }
+       return r;
+};
+
+// Frequently-used Accessors
+window.cssQuery = $.Select;
+document.getElementsByClass = function(a){return $.Select("."+a)};
+document.getElementsBySelector = $.Select;
+
+       
+       // Make Xpath Axes Sane
+       //var re = new RegExp( "/?descendant::", "i" );
+       //t = t.replace( re, " " );
+       //var re = new RegExp( "/?child::", "i" );
+       //t = t.replace( re, "/" );
+       // If only...
+       //var re = new RegExp( "/?following-sibling::", "i" );
+       //t = t.replace( re, " + " );
+       //var re = new RegExp( "/?preceding-sibling::", "i" );
+       //t = t.replace( re, " ~ " );
+       //var re = new RegExp( "/?self::", "i" );
+       //t = t.replace( re, "" );
+       //var re = new RegExp( "/?parent::", "i" );
+       //t = t.replace( re, " .. " );
+       
+       // following
+       // preceding
+       // ancestor
+       // ancestor-or-self
+       // descendant-or-self
+
+// Deprecated
+//style: function(a,b){ return this.css(a,b); },