diff --git a/browserid/static/dialog/dialog/controllers/addemail_controller.js b/browserid/static/dialog/dialog/controllers/addemail_controller.js
new file mode 100644
index 0000000000000000000000000000000000000000..f056257b3f5514805636a35f3bcf19f51ff3721e
--- /dev/null
+++ b/browserid/static/dialog/dialog/controllers/addemail_controller.js
@@ -0,0 +1,10 @@
+//
+// a JMVC controller for signing in
+//
+
+$.Controller("AddEmail", {}, {
+    init: function(el) {
+      this.element.html("<h2>Add Email!</h2>");
+    },
+
+  });
\ No newline at end of file
diff --git a/browserid/static/dialog/dialog/controllers/authenticate_controller.js b/browserid/static/dialog/dialog/controllers/authenticate_controller.js
new file mode 100644
index 0000000000000000000000000000000000000000..0b5c10e640c69d9ddde936140ee0239c55ab9e1e
--- /dev/null
+++ b/browserid/static/dialog/dialog/controllers/authenticate_controller.js
@@ -0,0 +1,13 @@
+//
+// a JMVC controller for signing in
+//
+
+$.Controller("Authenticate", {}, {
+    init: function(el) {
+      this.element.html("<h2>Authenticate!</h2>");
+    },
+
+    "click" : function(div, ev) {
+      alert('div is ' + div);
+    }
+  });
\ No newline at end of file
diff --git a/browserid/static/dialog/dialog/controllers/errormessage_controller.js b/browserid/static/dialog/dialog/controllers/errormessage_controller.js
new file mode 100644
index 0000000000000000000000000000000000000000..30acf301e011f1ac6e874144646ef9b912fe4601
--- /dev/null
+++ b/browserid/static/dialog/dialog/controllers/errormessage_controller.js
@@ -0,0 +1,10 @@
+//
+// a JMVC controller for signing in
+//
+
+$.Controller("ErrorMessage", {}, {
+    init: function(el) {
+      this.element.html("<h2>Error!</h2>");
+    },
+
+  });
\ No newline at end of file
diff --git a/browserid/static/dialog/dialog/controllers/signin_controller.js b/browserid/static/dialog/dialog/controllers/signin_controller.js
new file mode 100644
index 0000000000000000000000000000000000000000..9b1192a5232596200489595b98c988dc8dbb0dc5
--- /dev/null
+++ b/browserid/static/dialog/dialog/controllers/signin_controller.js
@@ -0,0 +1,13 @@
+//
+// a JMVC controller for signing in
+//
+
+$.Controller("Signin", {}, {
+    init: function(el) {
+      this.element.html("<h2>Sign In!</h2>");
+    },
+
+    "click" : function(div, ev) {
+      alert('div is ' + div);
+    }
+  });
\ No newline at end of file
diff --git a/browserid/static/dialog/dialog/controllers/waiting_controller.js b/browserid/static/dialog/dialog/controllers/waiting_controller.js
new file mode 100644
index 0000000000000000000000000000000000000000..e544d6504ea7ce730720cc91d65b59bd2b72ec6e
--- /dev/null
+++ b/browserid/static/dialog/dialog/controllers/waiting_controller.js
@@ -0,0 +1,10 @@
+//
+// a JMVC controller for signing in
+//
+
+$.Controller("Waiting", {}, {
+    init: function(el) {
+      this.element.html("<h2>Waiting!</h2>");
+    },
+
+  });
\ No newline at end of file
diff --git a/browserid/static/dialog/dialog/dialog.css b/browserid/static/dialog/dialog/dialog.css
new file mode 100644
index 0000000000000000000000000000000000000000..62aab7ebd574bdd24850cfc4aa2b768e01726b2a
--- /dev/null
+++ b/browserid/static/dialog/dialog/dialog.css
@@ -0,0 +1,2 @@
+body {font-family: verdana}
+td {padding: 3px;}
\ No newline at end of file
diff --git a/browserid/static/dialog/dialog/dialog.html b/browserid/static/dialog/dialog/dialog.html
new file mode 100644
index 0000000000000000000000000000000000000000..4a3aac558a724e465b43e68b2f0ae1ed48ab31cb
--- /dev/null
+++ b/browserid/static/dialog/dialog/dialog.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>Browser ID</title>
+		<script type='text/javascript' src='../steal/steal.js?dialog,development'></script>
+    <script>
+      $(document).ready(function() {
+         $('#signin').signin().hide();
+         $('#authenticate').authenticate().hide();
+         $('#waiting').waiting().hide();
+         $('#addemail').add_email().hide();
+         $('#error').error_message().hide();
+      });
+    </script>
+	</head>
+	<body>
+<div id="header">
+  <div class="title"><img src="/i/browserid_logo_lil.png"></div><div class="subtitle">A better way to log in.</div>
+</div>
+
+<div id="signin" class="dialog">
+</div>
+
+<div id="authenticate" class="dialog">
+</div>
+
+<div id="addemail" class="dialog">
+</div>
+
+<div id="error" class="dialog">
+</div>
+
+<div id="waiting" class="dialog">
+</div>
+	</body>
+</html>
diff --git a/browserid/static/dialog/dialog/dialog.js b/browserid/static/dialog/dialog/dialog.js
new file mode 100644
index 0000000000000000000000000000000000000000..733730c5de005b513fbfddb0e75a5129167b5f8a
--- /dev/null
+++ b/browserid/static/dialog/dialog/dialog.js
@@ -0,0 +1,23 @@
+steal.plugins(	
+	'jquery/controller',			// a widget factory
+	'jquery/controller/subscribe',	// subscribe to OpenAjax.hub
+	'jquery/view/ejs',				// client side templates
+	'jquery/controller/view')		// lookup views with the controller's name
+	
+	.css('style')	// loads styles
+
+	.resources('jschannel',
+             'underscore-min',
+             'crypto',
+             'crypto-stubs',
+             'main')					// 3rd party script's (like jQueryUI), in resources folder
+
+	.models()						// loads files in models folder 
+
+	.controllers('signin',
+               'authenticate',
+               'addemail',
+               'errormessage',
+               'waiting')					// loads files in controllers folder
+
+	.views();						// adds views to be added to build
\ No newline at end of file
diff --git a/browserid/static/dialog/dialog/funcunit.html b/browserid/static/dialog/dialog/funcunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..0d401b335084b7c47d9114e80fc5a0dabaa0c414
--- /dev/null
+++ b/browserid/static/dialog/dialog/funcunit.html
@@ -0,0 +1,14 @@
+<html>
+	<head>
+		<link rel="stylesheet" type="text/css" href="../../../../../../../funcunit/qunit/qunit.css" />
+		<title>dialog FuncUnit Test</title>
+		<script type='text/javascript' src='../../../../../../../steal/steal.js?/web/browserid/browserid/static/dialog/dialog/test/funcunit'></script>
+	</head>
+	<body>
+		<h1 id="qunit-header">dialog Test Suite</h1>
+		<h2 id="qunit-banner"></h2>
+		<div id="qunit-testrunner-toolbar"></div>
+		<h2 id="qunit-userAgent"></h2>
+		<ol id="qunit-tests"></ol>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/dialog/qunit.html b/browserid/static/dialog/dialog/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..55b77ece98e9e048bae8c82dd6dfef70f046d570
--- /dev/null
+++ b/browserid/static/dialog/dialog/qunit.html
@@ -0,0 +1,20 @@
+<html>
+	<head>
+		<link rel="stylesheet" type="text/css" href="../../../../../../../funcunit/qunit/qunit.css" />
+		<title>dialog QUnit Test</title>
+		<script type='text/javascript'>
+			steal = {ignoreControllers: true}
+		</script>
+		<script type='text/javascript' src='../../../../../../../steal/steal.js?/web/browserid/browserid/static/dialog/dialog/test/qunit'></script>
+	</head>
+	<body>
+
+		<h1 id="qunit-header">dialog Test Suite</h1>
+		<h2 id="qunit-banner"></h2>
+		<div id="qunit-testrunner-toolbar"></div>
+		<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+		<ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/dialog/resources/crypto-stubs.js b/browserid/static/dialog/dialog/resources/crypto-stubs.js
new file mode 100644
index 0000000000000000000000000000000000000000..3f70d686fbe1ffa1fdddd34e06f4c461fcb27cd2
--- /dev/null
+++ b/browserid/static/dialog/dialog/resources/crypto-stubs.js
@@ -0,0 +1,40 @@
+// This file is the cryptographic routines that are required for
+// BrowserID's HTML5 implementation
+
+CryptoStubs = (function() {
+
+"use strict";var sjcl={cipher:{},hash:{},mode:{},misc:{},codec:{},exception:{corrupt:function(b){this.toString=function(){return"CORRUPT: "+this.message};this.message=b},invalid:function(b){this.toString=function(){return"INVALID: "+this.message};this.message=b},bug:function(b){this.toString=function(){return"BUG: "+this.message};this.message=b}}};sjcl.cipher.aes=function(j){this.h[0][0][0]||this.w();var i,p,o,n,m=this.h[0][4],l=this.h[1];i=j.length;var k=1;if(i!==4&&i!==6&&i!==8){throw new sjcl.exception.invalid("invalid aes key size")}this.a=[o=j.slice(0),n=[]];for(j=i;j<4*i+28;j++){p=o[j-1];if(j%i===0||i===8&&j%i===4){p=m[p>>>24]<<24^m[p>>16&255]<<16^m[p>>8&255]<<8^m[p&255];if(j%i===0){p=p<<8^p>>>24^k<<24;k=k<<1^(k>>7)*283}}o[j]=o[j-i]^p}for(i=0;j;i++,j--){p=o[i&3?j:j-4];n[i]=j<=4||i<4?p:l[0][m[p>>>24]]^l[1][m[p>>16&255]]^l[2][m[p>>8&255]]^l[3][m[p&255]]}};sjcl.cipher.aes.prototype={encrypt:function(b){return this.H(b,0)},decrypt:function(b){return this.H(b,1)},h:[[[],[],[],[],[]],[[],[],[],[],[]]],w:function(){var B=this.h[0],A=this.h[1],y=B[4],x=A[4],w,v,u,s=[],r=[],p,q,o,n;for(w=0;w<256;w++){r[(s[w]=w<<1^(w>>7)*283)^w]=w}for(v=u=0;!y[v];v^=p||1,u=r[u]||1){o=u^u<<1^u<<2^u<<3^u<<4;o=o>>8^o&255^99;y[v]=o;x[o]=v;q=s[w=s[p=s[v]]];n=q*16843009^w*65537^p*257^v*16843008;q=s[o]*257^o*16843008;for(w=0;w<4;w++){B[w][v]=q=q<<24^q>>>8;A[w][o]=n=n<<24^n>>>8}}for(w=0;w<5;w++){B[w]=B[w].slice(0);A[w]=A[w].slice(0)}},H:function(L,K){if(L.length!==4){throw new sjcl.exception.invalid("invalid aes block size")}var J=this.a[K],I=L[0]^J[0],H=L[K?3:1]^J[1],G=L[2]^J[2];L=L[K?1:3]^J[3];var F,E,D,B=J.length/4-2,C,A=4,y=[0,0,0,0];F=this.h[K];var x=F[0],w=F[1],v=F[2],u=F[3],s=F[4];for(C=0;C<B;C++){F=x[I>>>24]^w[H>>16&255]^v[G>>8&255]^u[L&255]^J[A];E=x[H>>>24]^w[G>>16&255]^v[L>>8&255]^u[I&255]^J[A+1];D=x[G>>>24]^w[L>>16&255]^v[I>>8&255]^u[H&255]^J[A+2];L=x[L>>>24]^w[I>>16&255]^v[H>>8&255]^u[G&255]^J[A+3];A+=4;I=F;H=E;G=D}for(C=0;C<4;C++){y[K?3&-C:C]=s[I>>>24]<<24^s[H>>16&255]<<16^s[G>>8&255]<<8^s[L&255]^J[A++];F=I;I=H;H=G;G=L;L=F}return y}};sjcl.bitArray={bitSlice:function(f,d,g){f=sjcl.bitArray.P(f.slice(d/32),32-(d&31)).slice(1);return g===undefined?f:sjcl.bitArray.clamp(f,g-d)},concat:function(g,f){if(g.length===0||f.length===0){return g.concat(f)}var i=g[g.length-1],h=sjcl.bitArray.getPartial(i);return h===32?g.concat(f):sjcl.bitArray.P(f,h,i|0,g.slice(0,g.length-1))},bitLength:function(d){var c=d.length;if(c===0){return 0}return(c-1)*32+sjcl.bitArray.getPartial(d[c-1])},clamp:function(f,d){if(f.length*32<d){return f}f=f.slice(0,Math.ceil(d/32));var g=f.length;d&=31;if(g>0&&d){f[g-1]=sjcl.bitArray.partial(d,f[g-1]&2147483648>>d-1,1)}return f},partial:function(f,d,g){if(f===32){return d}return(g?d|0:d<<32-f)+f*1099511627776},getPartial:function(b){return Math.round(b/1099511627776)||32},equal:function(g,f){if(sjcl.bitArray.bitLength(g)!==sjcl.bitArray.bitLength(f)){return false}var i=0,h;for(h=0;h<g.length;h++){i|=g[h]^f[h]}return i===0},P:function(g,f,j,i){var h;h=0;if(i===undefined){i=[]}for(;f>=32;f-=32){i.push(j);j=0}if(f===0){return i.concat(g)}for(h=0;h<g.length;h++){i.push(j|g[h]>>>f);j=g[h]<<32-f}h=g.length?g[g.length-1]:0;g=sjcl.bitArray.getPartial(h);i.push(sjcl.bitArray.partial(f+g&31,f+g>32?j:i.pop(),1));return i},k:function(d,c){return[d[0]^c[0],d[1]^c[1],d[2]^c[2],d[3]^c[3]]}};sjcl.codec.utf8String={fromBits:function(g){var f="",j=sjcl.bitArray.bitLength(g),i,h;for(i=0;i<j/8;i++){if((i&3)===0){h=g[i/4]}f+=String.fromCharCode(h>>>24);h<<=8}return decodeURIComponent(escape(f))},toBits:function(g){g=unescape(encodeURIComponent(g));var f=[],i,h=0;for(i=0;i<g.length;i++){h=h<<8|g.charCodeAt(i);if((i&3)===3){f.push(h);h=0}}i&3&&f.push(sjcl.bitArray.partial(8*(i&3),h));return f}};sjcl.codec.hex={fromBits:function(f){var d="",g;for(g=0;g<f.length;g++){d+=((f[g]|0)+263882790666240).toString(16).substr(4)}return d.substr(0,sjcl.bitArray.bitLength(f)/4)},toBits:function(g){var f,i=[],h;g=g.replace(/\s|0x/g,"");h=g.length;g+="00000000";for(f=0;f<g.length;f+=8){i.push(parseInt(g.substr(f,8),16)^0)}return sjcl.bitArray.clamp(i,h*4)}};sjcl.codec.base64={D:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",fromBits:function(j,i){var p="",o,n=0,m=sjcl.codec.base64.D,l=0,k=sjcl.bitArray.bitLength(j);for(o=0;p.length*6<k;){p+=m.charAt((l^j[o]>>>n)>>>26);if(n<6){l=j[o]<<6-n;n+=26;o++}else{l<<=6;n-=6}}for(;p.length&3&&!i;){p+="="}return p},toBits:function(i){i=i.replace(/\s|=/g,"");var h=[],n,m=0,l=sjcl.codec.base64.D,k=0,j;for(n=0;n<i.length;n++){j=l.indexOf(i.charAt(n));if(j<0){throw new sjcl.exception.invalid("this isn't base64!")}if(m>26){m-=26;h.push(k^j>>>m);k=j<<32-m}else{m+=6;k^=j<<32-m}}m&56&&h.push(sjcl.bitArray.partial(m&56,k,1));return h}};sjcl.hash.sha256=function(b){this.a[0]||this.w();if(b){this.n=b.n.slice(0);this.i=b.i.slice(0);this.e=b.e}else{this.reset()}};sjcl.hash.sha256.hash=function(b){return(new sjcl.hash.sha256).update(b).finalize()};sjcl.hash.sha256.prototype={blockSize:512,reset:function(){this.n=this.N.slice(0);this.i=[];this.e=0;return this},update:function(f){if(typeof f==="string"){f=sjcl.codec.utf8String.toBits(f)}var d,g=this.i=sjcl.bitArray.concat(this.i,f);d=this.e;f=this.e=d+sjcl.bitArray.bitLength(f);for(d=512+d&-512;d<=f;d+=512){this.C(g.splice(0,16))}return this},finalize:function(){var f,d=this.i,g=this.n;d=sjcl.bitArray.concat(d,[sjcl.bitArray.partial(1,1)]);for(f=d.length+2;f&15;f++){d.push(0)}d.push(Math.floor(this.e/4294967296));for(d.push(this.e|0);d.length;){this.C(d.splice(0,16))}this.reset();return g},N:[],a:[],w:function(){function g(a){return(a-Math.floor(a))*4294967296|0}var f=0,i=2,h;g:for(;f<64;i++){for(h=2;h*h<=i;h++){if(i%h===0){continue g}}if(f<8){this.N[f]=g(Math.pow(i,0.5))}this.a[f]=g(Math.pow(i,1/3));f++}},C:function(D){var C,B,A=D.slice(0),y=this.n,x=this.a,w=y[0],v=y[1],u=y[2],r=y[3],s=y[4],q=y[5],p=y[6],o=y[7];for(D=0;D<64;D++){if(D<16){C=A[D]}else{C=A[D+1&15];B=A[D+14&15];C=A[D&15]=(C>>>7^C>>>18^C>>>3^C<<25^C<<14)+(B>>>17^B>>>19^B>>>10^B<<15^B<<13)+A[D&15]+A[D+9&15]|0}C=C+o+(s>>>6^s>>>11^s>>>25^s<<26^s<<21^s<<7)+(p^s&(q^p))+x[D];o=p;p=q;q=s;s=r+C|0;r=u;u=v;v=w;w=C+(v&u^r&(v^u))+(v>>>2^v>>>13^v>>>22^v<<30^v<<19^v<<10)|0}y[0]=y[0]+w|0;y[1]=y[1]+v|0;y[2]=y[2]+u|0;y[3]=y[3]+r|0;y[4]=y[4]+s|0;y[5]=y[5]+q|0;y[6]=y[6]+p|0;y[7]=y[7]+o|0}};sjcl.mode.ccm={name:"ccm",encrypt:function(u,s,r,q,p){var o,n=s.slice(0),m=sjcl.bitArray,l=m.bitLength(r)/8,j=m.bitLength(n)/8;p=p||64;q=q||[];if(l<7){throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes")}for(o=2;o<4&&j>>>8*o;o++){}if(o<15-l){o=15-l}r=m.clamp(r,8*(15-o));s=sjcl.mode.ccm.G(u,s,r,q,p,o);n=sjcl.mode.ccm.I(u,n,r,s,p,o);return m.concat(n.data,n.tag)},decrypt:function(u,s,r,q,p){p=p||64;q=q||[];var o=sjcl.bitArray,n=o.bitLength(r)/8,m=o.bitLength(s),l=o.clamp(s,m-p),j=o.bitSlice(s,m-p);m=(m-p)/8;if(n<7){throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes")}for(s=2;s<4&&m>>>8*s;s++){}if(s<15-n){s=15-n}r=o.clamp(r,8*(15-s));l=sjcl.mode.ccm.I(u,l,r,j,p,s);u=sjcl.mode.ccm.G(u,l.data,r,q,p,s);if(!o.equal(l.tag,u)){throw new sjcl.exception.corrupt("ccm: tag doesn't match")}return l.data},G:function(r,q,p,o,n,m){var l=[],k=sjcl.bitArray,j=k.k;n/=8;if(n%2||n<4||n>16){throw new sjcl.exception.invalid("ccm: invalid tag length")}if(o.length>4294967295||q.length>4294967295){throw new sjcl.exception.bug("ccm: can't deal with 4GiB or more data")}m=[k.partial(8,(o.length?64:0)|n-2<<2|m-1)];m=k.concat(m,p);m[3]|=k.bitLength(q)/8;m=r.encrypt(m);if(o.length){p=k.bitLength(o)/8;if(p<=65279){l=[k.partial(16,p)]}else{if(p<=4294967295){l=k.concat([k.partial(16,65534)],[p])}}l=k.concat(l,o);for(o=0;o<l.length;o+=4){m=r.encrypt(j(m,l.slice(o,o+4)))}}for(o=0;o<q.length;o+=4){m=r.encrypt(j(m,q.slice(o,o+4)))}return k.clamp(m,n*8)},I:function(u,s,r,q,p,o){var n,m=sjcl.bitArray;n=m.k;var l=s.length,j=m.bitLength(s);r=m.concat([m.partial(8,o-1)],r).concat([0,0,0]).slice(0,4);q=m.bitSlice(n(q,u.encrypt(r)),0,p);if(!l){return{tag:q,data:[]}}for(n=0;n<l;n+=4){r[3]++;p=u.encrypt(r);s[n]^=p[0];s[n+1]^=p[1];s[n+2]^=p[2];s[n+3]^=p[3]}return{tag:q,data:m.clamp(s,j)}}};sjcl.mode.ocb2={name:"ocb2",encrypt:function(B,A,y,x,w,v){if(sjcl.bitArray.bitLength(y)!==128){throw new sjcl.exception.invalid("ocb iv must be 128 bits")}var u,s=sjcl.mode.ocb2.A,r=sjcl.bitArray,p=r.k,q=[0,0,0,0];y=s(B.encrypt(y));var o,n=[];x=x||[];w=w||64;for(u=0;u+4<A.length;u+=4){o=A.slice(u,u+4);q=p(q,o);n=n.concat(p(y,B.encrypt(p(y,o))));y=s(y)}o=A.slice(u);A=r.bitLength(o);u=B.encrypt(p(y,[0,0,0,A]));o=r.clamp(p(o,u),A);q=p(q,p(o,u));q=B.encrypt(p(q,p(y,s(y))));if(x.length){q=p(q,v?x:sjcl.mode.ocb2.pmac(B,x))}return n.concat(r.concat(o,r.clamp(q,w)))},decrypt:function(F,E,D,C,B,A){if(sjcl.bitArray.bitLength(D)!==128){throw new sjcl.exception.invalid("ocb iv must be 128 bits")}B=B||64;var y=sjcl.mode.ocb2.A,x=sjcl.bitArray,w=x.k,u=[0,0,0,0],v=y(F.encrypt(D)),s,r,q=sjcl.bitArray.bitLength(E)-B,p=[];C=C||[];for(D=0;D+4<q/32;D+=4){s=w(v,F.decrypt(w(v,E.slice(D,D+4))));u=w(u,s);p=p.concat(s);v=y(v)}r=q-D*32;s=F.encrypt(w(v,[0,0,0,r]));s=w(s,x.clamp(E.slice(D),r));u=w(u,s);u=F.encrypt(w(u,w(v,y(v))));if(C.length){u=w(u,A?C:sjcl.mode.ocb2.pmac(F,C))}if(!x.equal(x.clamp(u,B),x.bitSlice(E,q))){throw new sjcl.exception.corrupt("ocb: tag doesn't match")}return p.concat(x.clamp(s,r))},pmac:function(j,i){var p,o=sjcl.mode.ocb2.A,n=sjcl.bitArray,m=n.k,l=[0,0,0,0],k=j.encrypt([0,0,0,0]);k=m(k,o(o(k)));for(p=0;p+4<i.length;p+=4){k=o(k);l=m(l,j.encrypt(m(k,i.slice(p,p+4))))}i=i.slice(p);if(n.bitLength(i)<128){k=m(k,o(k));i=n.concat(i,[2147483648|0])}l=m(l,i);return j.encrypt(m(o(m(k,o(k))),l))},A:function(b){return[b[0]<<1^b[1]>>>31,b[1]<<1^b[2]>>>31,b[2]<<1^b[3]>>>31,b[3]<<1^(b[0]>>>31)*135]}};sjcl.misc.hmac=function(g,f){this.M=f=f||sjcl.hash.sha256;var i=[[],[]],h=f.prototype.blockSize/32;this.l=[new f,new f];if(g.length>h){g=f.hash(g)}for(f=0;f<h;f++){i[0][f]=g[f]^909522486;i[1][f]=g[f]^1549556828}this.l[0].update(i[0]);this.l[1].update(i[1])};sjcl.misc.hmac.prototype.encrypt=sjcl.misc.hmac.prototype.mac=function(d,c){d=(new this.M(this.l[0])).update(d,c).finalize();return(new this.M(this.l[1])).update(d).finalize()};sjcl.misc.pbkdf2=function(w,v,u,s,r){u=u||1000;if(s<0||u<0){throw sjcl.exception.invalid("invalid params to pbkdf2")}if(typeof w==="string"){w=sjcl.codec.utf8String.toBits(w)}r=r||sjcl.misc.hmac;w=new r(w);var q,p,o,n,l=[],m=sjcl.bitArray;for(n=1;32*l.length<(s||1);n++){r=q=w.encrypt(m.concat(v,[n]));for(p=1;p<u;p++){q=w.encrypt(q);for(o=0;o<q.length;o++){r[o]^=q[o]}}l=l.concat(r)}if(s){l=m.clamp(l,s)}return l};sjcl.random={randomWords:function(g,f){var i=[];f=this.isReady(f);var h;if(f===0){throw new sjcl.exception.notready("generator isn't seeded")}else{f&2&&this.U(!(f&1))}for(f=0;f<g;f+=4){(f+1)%65536===0&&this.L();h=this.u();i.push(h[0],h[1],h[2],h[3])}this.L();return i.slice(0,g)},setDefaultParanoia:function(b){this.t=b},addEntropy:function(j,i,p){p=p||"user";var o,n,m=(new Date).valueOf(),l=this.q[p],k=this.isReady();o=this.F[p];if(o===undefined){o=this.F[p]=this.R++}if(l===undefined){l=this.q[p]=0}this.q[p]=(this.q[p]+1)%this.b.length;switch(typeof j){case"number":break;case"object":if(i===undefined){for(p=i=0;p<j.length;p++){for(n=j[p];n>0;){i++;n>>>=1}}}this.b[l].update([o,this.J++,2,i,m,j.length].concat(j));break;case"string":if(i===undefined){i=j.length}this.b[l].update([o,this.J++,3,i,m,j.length]);this.b[l].update(j);break;default:throw new sjcl.exception.bug("random: addEntropy only supports number, array or string")}this.j[l]+=i;this.f+=i;if(k===0){this.isReady()!==0&&this.K("seeded",Math.max(this.g,this.f));this.K("progress",this.getProgress())}},isReady:function(b){b=this.B[b!==undefined?b:this.t];return this.g&&this.g>=b?this.j[0]>80&&(new Date).valueOf()>this.O?3:1:this.f>=b?2:0},getProgress:function(b){b=this.B[b?b:this.t];return this.g>=b?1["0"]:this.f>b?1["0"]:this.f/b},startCollectors:function(){if(!this.m){if(window.addEventListener){window.addEventListener("load",this.o,false);window.addEventListener("mousemove",this.p,false)}else{if(document.attachEvent){document.attachEvent("onload",this.o);document.attachEvent("onmousemove",this.p)}else{throw new sjcl.exception.bug("can't attach event")}}this.m=true}},stopCollectors:function(){if(this.m){if(window.removeEventListener){window.removeEventListener("load",this.o);window.removeEventListener("mousemove",this.p)}else{if(window.detachEvent){window.detachEvent("onload",this.o);window.detachEvent("onmousemove",this.p)}}this.m=false}},addEventListener:function(d,c){this.r[d][this.Q++]=c},removeEventListener:function(g,f){var i;g=this.r[g];var h=[];for(i in g){g.hasOwnProperty[i]&&g[i]===f&&h.push(i)}for(f=0;f<h.length;f++){i=h[f];delete g[i]}},b:[new sjcl.hash.sha256],j:[0],z:0,q:{},J:0,F:{},R:0,g:0,f:0,O:0,a:[0,0,0,0,0,0,0,0],d:[0,0,0,0],s:undefined,t:6,m:false,r:{progress:{},seeded:{}},Q:0,B:[0,48,64,96,128,192,256,384,512,768,1024],u:function(){for(var b=0;b<4;b++){this.d[b]=this.d[b]+1|0;if(this.d[b]){break}}return this.s.encrypt(this.d)},L:function(){this.a=this.u().concat(this.u());this.s=new sjcl.cipher.aes(this.a)},T:function(b){this.a=sjcl.hash.sha256.hash(this.a.concat(b));this.s=new sjcl.cipher.aes(this.a);for(b=0;b<4;b++){this.d[b]=this.d[b]+1|0;if(this.d[b]){break}}},U:function(g){var f=[],i=0,h;this.O=f[0]=(new Date).valueOf()+30000;for(h=0;h<16;h++){f.push(Math.random()*4294967296|0)}for(h=0;h<this.b.length;h++){f=f.concat(this.b[h].finalize());i+=this.j[h];this.j[h]=0;if(!g&&this.z&1<<h){break}}if(this.z>=1<<this.b.length){this.b.push(new sjcl.hash.sha256);this.j.push(0)}this.f-=i;if(i>this.g){this.g=i}this.z++;this.T(f)},p:function(b){sjcl.random.addEntropy([b.x||b.clientX||b.offsetX,b.y||b.clientY||b.offsetY],2,"mouse")},o:function(){sjcl.random.addEntropy(new Date,2,"loadtime")},K:function(g,f){var i;g=sjcl.random.r[g];var h=[];for(i in g){g.hasOwnProperty(i)&&h.push(g[i])}for(i=0;i<h.length;i++){h[i](f)}}};sjcl.json={defaults:{v:1,iter:1000,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},encrypt:function(h,g,l,k){l=l||{};k=k||{};var j=sjcl.json,i=j.c({iv:sjcl.random.randomWords(4,0)},j.defaults);j.c(i,l);if(typeof i.salt==="string"){i.salt=sjcl.codec.base64.toBits(i.salt)}if(typeof i.iv==="string"){i.iv=sjcl.codec.base64.toBits(i.iv)}if(!sjcl.mode[i.mode]||!sjcl.cipher[i.cipher]||typeof h==="string"&&i.iter<=100||i.ts!==64&&i.ts!==96&&i.ts!==128||i.ks!==128&&i.ks!==192&&i.ks!==256||i.iv.length<2||i.iv.length>4){throw new sjcl.exception.invalid("json encrypt: invalid parameters")}if(typeof h==="string"){l=sjcl.misc.cachedPbkdf2(h,i);h=l.key.slice(0,i.ks/32);i.salt=l.salt}if(typeof g==="string"){g=sjcl.codec.utf8String.toBits(g)}l=new sjcl.cipher[i.cipher](h);j.c(k,i);k.key=h;i.ct=sjcl.mode[i.mode].encrypt(l,g,i.iv,i.adata,i.tag);return j.encode(j.V(i,j.defaults))},decrypt:function(g,f,j,i){j=j||{};i=i||{};var h=sjcl.json;f=h.c(h.c(h.c({},h.defaults),h.decode(f)),j,true);if(typeof f.salt==="string"){f.salt=sjcl.codec.base64.toBits(f.salt)}if(typeof f.iv==="string"){f.iv=sjcl.codec.base64.toBits(f.iv)}if(!sjcl.mode[f.mode]||!sjcl.cipher[f.cipher]||typeof g==="string"&&f.iter<=100||f.ts!==64&&f.ts!==96&&f.ts!==128||f.ks!==128&&f.ks!==192&&f.ks!==256||!f.iv||f.iv.length<2||f.iv.length>4){throw new sjcl.exception.invalid("json decrypt: invalid parameters")}if(typeof g==="string"){j=sjcl.misc.cachedPbkdf2(g,f);g=j.key.slice(0,f.ks/32);f.salt=j.salt}j=new sjcl.cipher[f.cipher](g);j=sjcl.mode[f.mode].decrypt(j,f.ct,f.iv,f.adata,f.tag);h.c(i,f);i.key=g;return sjcl.codec.utf8String.fromBits(j)},encode:function(g){var f,i="{",h="";for(f in g){if(g.hasOwnProperty(f)){if(!f.match(/^[a-z0-9]+$/i)){throw new sjcl.exception.invalid("json encode: invalid property name")}i+=h+f+":";h=",";switch(typeof g[f]){case"number":case"boolean":i+=g[f];break;case"string":i+='"'+escape(g[f])+'"';break;case"object":i+='"'+sjcl.codec.base64.fromBits(g[f],1)+'"';break;default:throw new sjcl.exception.bug("json encode: unsupported type")}}}return i+"}"},decode:function(g){g=g.replace(/\s/g,"");if(!g.match(/^\{.*\}$/)){throw new sjcl.exception.invalid("json decode: this isn't json!")}g=g.replace(/^\{|\}$/g,"").split(/,/);var f={},i,h;for(i=0;i<g.length;i++){if(!(h=g[i].match(/^([a-z][a-z0-9]*):(?:(\d+)|"([a-z0-9+\/%*_.@=\-]*)")$/i))){throw new sjcl.exception.invalid("json decode: this isn't json!")}f[h[1]]=h[2]?parseInt(h[2],10):h[1].match(/^(ct|salt|iv)$/)?sjcl.codec.base64.toBits(h[3]):unescape(h[3])}return f},c:function(g,f,i){if(g===undefined){g={}}if(f===undefined){return g}var h;for(h in f){if(f.hasOwnProperty(h)){if(i&&g[h]!==undefined&&g[h]!==f[h]){throw new sjcl.exception.invalid("required parameter overridden")}g[h]=f[h]}}return g},V:function(g,f){var i={},h;for(h in g){if(g.hasOwnProperty(h)&&g[h]!==f[h]){i[h]=g[h]}}return i},W:function(g,f){var i={},h;for(h=0;h<f.length;h++){if(g[f[h]]!==undefined){i[f[h]]=g[f[h]]}}return i}};sjcl.encrypt=sjcl.json.encrypt;sjcl.decrypt=sjcl.json.decrypt;sjcl.misc.S={};sjcl.misc.cachedPbkdf2=function(g,f){var i=sjcl.misc.S,h;f=f||{};h=f.iter||1000;i=i[g]=i[g]||{};h=i[h]=i[h]||{firstSalt:f.salt&&f.salt.length?f.salt.slice(0):sjcl.random.randomWords(2,0)};i=f.salt===undefined?h.firstSalt:f.salt;h[i]=h[i]||sjcl.misc.pbkdf2(g,i,f.iter);return{key:h[i].slice(0),salt:i.slice(0)}};var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var b64pad="=";function hex2b64(d){var b;var f;var a="";for(b=0;b+3<=d.length;b+=3){f=parseInt(d.substring(b,b+3),16);a+=b64map.charAt(f>>6)+b64map.charAt(f&63)}if(b+1==d.length){f=parseInt(d.substring(b,b+1),16);a+=b64map.charAt(f<<2)}else{if(b+2==d.length){f=parseInt(d.substring(b,b+2),16);a+=b64map.charAt(f>>2)+b64map.charAt((f&3)<<4)}}while((a.length&3)>0){a+=b64pad}return a}function b64tohex(g){var d="";var f;var b=0;var c;for(f=0;f<g.length;++f){if(g.charAt(f)==b64pad){break}var a=b64map.indexOf(g.charAt(f));if(a<0){continue}if(b==0){d+=int2char(a>>2);c=a&3;b=1}else{if(b==1){d+=int2char((c<<2)|(a>>4));c=a&15;b=2}else{if(b==2){d+=int2char(c);d+=int2char(a>>2);c=a&3;b=3}else{d+=int2char((c<<2)|(a>>4));d+=int2char(a&15);b=0}}}}if(b==1){d+=int2char(c<<2)}return d}function b64toBA(f){var d=b64tohex(f);var c;var b=new Array();for(c=0;2*c<d.length;++c){b[c]=parseInt(d.substring(2*c,2*c+2),16)}return b}var dbits;var canary=244837814094590;var j_lm=((canary&16777215)==15715070);function BigInteger(f,d,g){if(f!=null){if("number"==typeof f){this.fromNumber(f,d,g)}else{if(d==null&&"string"!=typeof f){this.fromString(f,256)}else{this.fromString(f,d)}}}}function nbi(){return new BigInteger(null)}function am1(g,a,b,f,k,h){while(--h>=0){var d=a*this[g++]+b[f]+k;k=Math.floor(d/67108864);b[f++]=d&67108863}return k}function am2(g,r,s,f,p,a){var o=r&32767,q=r>>15;while(--a>=0){var d=this[g]&32767;var k=this[g++]>>15;var b=q*d+k*o;d=o*d+((b&32767)<<15)+s[f]+(p&1073741823);p=(d>>>30)+(b>>>15)+q*k+(p>>>30);s[f++]=d&1073741823}return p}function am3(g,r,s,f,p,a){var o=r&16383,q=r>>14;while(--a>=0){var d=this[g]&16383;var k=this[g++]>>14;var b=q*d+k*o;d=o*d+((b&16383)<<14)+s[f]+p;p=(d>>28)+(b>>14)+q*k;s[f++]=d&268435455}return p}try{if(j_lm&&(navigator&&navigator.appName=="Microsoft Internet Explorer")){BigInteger.prototype.am=am2;dbits=30}else{if(j_lm&&(navigator&&navigator.appName!="Netscape")){BigInteger.prototype.am=am1;dbits=26}else{BigInteger.prototype.am=am3;dbits=28}}}catch(e){BigInteger.prototype.am=am3;dbits=28}BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=((1<<dbits)-1);BigInteger.prototype.DV=(1<<dbits);var BI_FP=52;BigInteger.prototype.FV=Math.pow(2,BI_FP);BigInteger.prototype.F1=BI_FP-dbits;BigInteger.prototype.F2=2*dbits-BI_FP;var BI_RM="0123456789abcdefghijklmnopqrstuvwxyz";var BI_RC=new Array();var rr,vv;rr="0".charCodeAt(0);for(vv=0;vv<=9;++vv){BI_RC[rr++]=vv}rr="a".charCodeAt(0);for(vv=10;vv<36;++vv){BI_RC[rr++]=vv}rr="A".charCodeAt(0);for(vv=10;vv<36;++vv){BI_RC[rr++]=vv}function int2char(a){return BI_RM.charAt(a)}function intAt(b,a){var d=BI_RC[b.charCodeAt(a)];return(d==null)?-1:d}function bnpCopyTo(b){for(var a=this.t-1;a>=0;--a){b[a]=this[a]}b.t=this.t;b.s=this.s}function bnpFromInt(a){this.t=1;this.s=(a<0)?-1:0;if(a>0){this[0]=a}else{if(a<-1){this[0]=a+DV}else{this.t=0}}}function nbv(a){var b=nbi();b.fromInt(a);return b}function bnpFromString(j,c){var f;if(c==16){f=4}else{if(c==8){f=3}else{if(c==256){f=8}else{if(c==2){f=1}else{if(c==32){f=5}else{if(c==4){f=2}else{this.fromRadix(j,c);return}}}}}}this.t=0;this.s=0;var h=j.length,d=false,g=0;while(--h>=0){var a=(f==8)?j[h]&255:intAt(j,h);if(a<0){if(j.charAt(h)=="-"){d=true}continue}d=false;if(g==0){this[this.t++]=a}else{if(g+f>this.DB){this[this.t-1]|=(a&((1<<(this.DB-g))-1))<<g;this[this.t++]=(a>>(this.DB-g))}else{this[this.t-1]|=a<<g}}g+=f;if(g>=this.DB){g-=this.DB}}if(f==8&&(j[0]&128)!=0){this.s=-1;if(g>0){this[this.t-1]|=((1<<(this.DB-g))-1)<<g}}this.clamp();if(d){BigInteger.ZERO.subTo(this,this)}}function bnpClamp(){var a=this.s&this.DM;while(this.t>0&&this[this.t-1]==a){--this.t}}function bnToString(c){if(this.s<0){return"-"+this.negate().toString(c)}var f;if(c==16){f=4}else{if(c==8){f=3}else{if(c==2){f=1}else{if(c==32){f=5}else{if(c==4){f=2}else{return this.toRadix(c)}}}}}var h=(1<<f)-1,n,a=false,j="",g=this.t;var l=this.DB-(g*this.DB)%f;if(g-->0){if(l<this.DB&&(n=this[g]>>l)>0){a=true;j=int2char(n)}while(g>=0){if(l<f){n=(this[g]&((1<<l)-1))<<(f-l);n|=this[--g]>>(l+=this.DB-f)}else{n=(this[g]>>(l-=f))&h;if(l<=0){l+=this.DB;--g}}if(n>0){a=true}if(a){j+=int2char(n)}}}return a?j:"0"}function bnNegate(){var a=nbi();BigInteger.ZERO.subTo(this,a);return a}function bnAbs(){return(this.s<0)?this.negate():this}function bnCompareTo(b){var d=this.s-b.s;if(d!=0){return d}var c=this.t;d=c-b.t;if(d!=0){return d}while(--c>=0){if((d=this[c]-b[c])!=0){return d}}return 0}function nbits(a){var c=1,b;if((b=a>>>16)!=0){a=b;c+=16}if((b=a>>8)!=0){a=b;c+=8}if((b=a>>4)!=0){a=b;c+=4}if((b=a>>2)!=0){a=b;c+=2}if((b=a>>1)!=0){a=b;c+=1}return c}function bnBitLength(){if(this.t<=0){return 0}return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM))}function bnpDLShiftTo(c,b){var a;for(a=this.t-1;a>=0;--a){b[a+c]=this[a]}for(a=c-1;a>=0;--a){b[a]=0}b.t=this.t+c;b.s=this.s}function bnpDRShiftTo(c,b){for(var a=c;a<this.t;++a){b[a-c]=this[a]}b.t=Math.max(this.t-c,0);b.s=this.s}function bnpLShiftTo(k,f){var b=k%this.DB;var a=this.DB-b;var h=(1<<a)-1;var g=Math.floor(k/this.DB),j=(this.s<<b)&this.DM,d;for(d=this.t-1;d>=0;--d){f[d+g+1]=(this[d]>>a)|j;j=(this[d]&h)<<b}for(d=g-1;d>=0;--d){f[d]=0}f[g]=j;f.t=this.t+g+1;f.s=this.s;f.clamp()}function bnpRShiftTo(h,d){d.s=this.s;var f=Math.floor(h/this.DB);if(f>=this.t){d.t=0;return}var b=h%this.DB;var a=this.DB-b;var g=(1<<b)-1;d[0]=this[f]>>b;for(var c=f+1;c<this.t;++c){d[c-f-1]|=(this[c]&g)<<a;d[c-f]=this[c]>>b}if(b>0){d[this.t-f-1]|=(this.s&g)<<a}d.t=this.t-f;d.clamp()}function bnpSubTo(d,g){var f=0,h=0,b=Math.min(d.t,this.t);while(f<b){h+=this[f]-d[f];g[f++]=h&this.DM;h>>=this.DB}if(d.t<this.t){h-=d.s;while(f<this.t){h+=this[f];g[f++]=h&this.DM;h>>=this.DB}h+=this.s}else{h+=this.s;while(f<d.t){h-=d[f];g[f++]=h&this.DM;h>>=this.DB}h-=d.s}g.s=(h<0)?-1:0;if(h<-1){g[f++]=this.DV+h}else{if(h>0){g[f++]=h}}g.t=f;g.clamp()}function bnpMultiplyTo(c,f){var b=this.abs(),g=c.abs();var d=b.t;f.t=d+g.t;while(--d>=0){f[d]=0}for(d=0;d<g.t;++d){f[d+b.t]=b.am(0,g[d],f,d,0,b.t)}f.s=0;f.clamp();if(this.s!=c.s){BigInteger.ZERO.subTo(f,f)}}function bnpSquareTo(d){var a=this.abs();var b=d.t=2*a.t;while(--b>=0){d[b]=0}for(b=0;b<a.t-1;++b){var f=a.am(b,a[b],d,2*b,0,1);if((d[b+a.t]+=a.am(b+1,2*a[b],d,2*b+1,f,a.t-b-1))>=a.DV){d[b+a.t]-=a.DV;d[b+a.t+1]=1}}if(d.t>0){d[d.t-1]+=a.am(b,a[b],d,2*b,0,1)}d.s=0;d.clamp()}function bnpDivRemTo(n,h,g){var w=n.abs();if(w.t<=0){return}var k=this.abs();if(k.t<w.t){if(h!=null){h.fromInt(0)}if(g!=null){this.copyTo(g)}return}if(g==null){g=nbi()}var d=nbi(),a=this.s,l=n.s;var v=this.DB-nbits(w[w.t-1]);if(v>0){w.lShiftTo(v,d);k.lShiftTo(v,g)}else{w.copyTo(d);k.copyTo(g)}var p=d.t;var b=d[p-1];if(b==0){return}var o=b*(1<<this.F1)+((p>1)?d[p-2]>>this.F2:0);var B=this.FV/o,A=(1<<this.F1)/o,x=1<<this.F2;var u=g.t,s=u-p,f=(h==null)?nbi():h;d.dlShiftTo(s,f);if(g.compareTo(f)>=0){g[g.t++]=1;g.subTo(f,g)}BigInteger.ONE.dlShiftTo(p,f);f.subTo(d,d);while(d.t<p){d[d.t++]=0}while(--s>=0){var c=(g[--u]==b)?this.DM:Math.floor(g[u]*B+(g[u-1]+x)*A);if((g[u]+=d.am(0,c,g,s,0,p))<c){d.dlShiftTo(s,f);g.subTo(f,g);while(g[u]<--c){g.subTo(f,g)}}}if(h!=null){g.drShiftTo(p,h);if(a!=l){BigInteger.ZERO.subTo(h,h)}}g.t=p;g.clamp();if(v>0){g.rShiftTo(v,g)}if(a<0){BigInteger.ZERO.subTo(g,g)}}function bnMod(b){var c=nbi();this.abs().divRemTo(b,null,c);if(this.s<0&&c.compareTo(BigInteger.ZERO)>0){b.subTo(c,c)}return c}function Classic(a){this.m=a}function cConvert(a){if(a.s<0||a.compareTo(this.m)>=0){return a.mod(this.m)}else{return a}}function cRevert(a){return a}function cReduce(a){a.divRemTo(this.m,null,a)}function cMulTo(a,c,b){a.multiplyTo(c,b);this.reduce(b)}function cSqrTo(a,b){a.squareTo(b);this.reduce(b)}Classic.prototype.convert=cConvert;Classic.prototype.revert=cRevert;Classic.prototype.reduce=cReduce;Classic.prototype.mulTo=cMulTo;Classic.prototype.sqrTo=cSqrTo;function bnpInvDigit(){if(this.t<1){return 0}var a=this[0];if((a&1)==0){return 0}var b=a&3;b=(b*(2-(a&15)*b))&15;b=(b*(2-(a&255)*b))&255;b=(b*(2-(((a&65535)*b)&65535)))&65535;b=(b*(2-a*b%this.DV))%this.DV;return(b>0)?this.DV-b:-b}function Montgomery(a){this.m=a;this.mp=a.invDigit();this.mpl=this.mp&32767;this.mph=this.mp>>15;this.um=(1<<(a.DB-15))-1;this.mt2=2*a.t}function montConvert(a){var b=nbi();a.abs().dlShiftTo(this.m.t,b);b.divRemTo(this.m,null,b);if(a.s<0&&b.compareTo(BigInteger.ZERO)>0){this.m.subTo(b,b)}return b}function montRevert(a){var b=nbi();a.copyTo(b);this.reduce(b);return b}function montReduce(a){while(a.t<=this.mt2){a[a.t++]=0}for(var c=0;c<this.m.t;++c){var b=a[c]&32767;var d=(b*this.mpl+(((b*this.mph+(a[c]>>15)*this.mpl)&this.um)<<15))&a.DM;b=c+this.m.t;a[b]+=this.m.am(0,d,a,c,0,this.m.t);while(a[b]>=a.DV){a[b]-=a.DV;a[++b]++}}a.clamp();a.drShiftTo(this.m.t,a);if(a.compareTo(this.m)>=0){a.subTo(this.m,a)}}function montSqrTo(a,b){a.squareTo(b);this.reduce(b)}function montMulTo(a,c,b){a.multiplyTo(c,b);this.reduce(b)}Montgomery.prototype.convert=montConvert;Montgomery.prototype.revert=montRevert;Montgomery.prototype.reduce=montReduce;Montgomery.prototype.mulTo=montMulTo;Montgomery.prototype.sqrTo=montSqrTo;function bnpIsEven(){return((this.t>0)?(this[0]&1):this.s)==0}function bnpExp(h,j){if(h>4294967295||h<1){return BigInteger.ONE}var f=nbi(),a=nbi(),d=j.convert(this),c=nbits(h)-1;d.copyTo(f);while(--c>=0){j.sqrTo(f,a);if((h&(1<<c))>0){j.mulTo(a,d,f)}else{var b=f;f=a;a=b}}return j.revert(f)}function bnModPowInt(b,a){var c;if(b<256||a.isEven()){c=new Classic(a)}else{c=new Montgomery(a)}return this.exp(b,c)}BigInteger.prototype.copyTo=bnpCopyTo;BigInteger.prototype.fromInt=bnpFromInt;BigInteger.prototype.fromString=bnpFromString;BigInteger.prototype.clamp=bnpClamp;BigInteger.prototype.dlShiftTo=bnpDLShiftTo;BigInteger.prototype.drShiftTo=bnpDRShiftTo;BigInteger.prototype.lShiftTo=bnpLShiftTo;BigInteger.prototype.rShiftTo=bnpRShiftTo;BigInteger.prototype.subTo=bnpSubTo;BigInteger.prototype.multiplyTo=bnpMultiplyTo;BigInteger.prototype.squareTo=bnpSquareTo;BigInteger.prototype.divRemTo=bnpDivRemTo;BigInteger.prototype.invDigit=bnpInvDigit;BigInteger.prototype.isEven=bnpIsEven;BigInteger.prototype.exp=bnpExp;BigInteger.prototype.toString=bnToString;BigInteger.prototype.negate=bnNegate;BigInteger.prototype.abs=bnAbs;BigInteger.prototype.compareTo=bnCompareTo;BigInteger.prototype.bitLength=bnBitLength;BigInteger.prototype.mod=bnMod;BigInteger.prototype.modPowInt=bnModPowInt;BigInteger.ZERO=nbv(0);BigInteger.ONE=nbv(1);function bnClone(){var a=nbi();this.copyTo(a);return a}function bnIntValue(){if(this.s<0){if(this.t==1){return this[0]-this.DV}else{if(this.t==0){return -1}}}else{if(this.t==1){return this[0]}else{if(this.t==0){return 0}}}return((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0]}function bnByteValue(){return(this.t==0)?this.s:(this[0]<<24)>>24}function bnShortValue(){return(this.t==0)?this.s:(this[0]<<16)>>16}function bnpChunkSize(a){return Math.floor(Math.LN2*this.DB/Math.log(a))}function bnSigNum(){if(this.s<0){return -1}else{if(this.t<=0||(this.t==1&&this[0]<=0)){return 0}else{return 1}}}function bnpToRadix(c){if(c==null){c=10}if(this.signum()==0||c<2||c>36){return"0"}var g=this.chunkSize(c);var f=Math.pow(c,g);var j=nbv(f),k=nbi(),i=nbi(),h="";this.divRemTo(j,k,i);while(k.signum()>0){h=(f+i.intValue()).toString(c).substr(1)+h;k.divRemTo(j,k,i)}return i.intValue().toString(c)+h}function bnpFromRadix(n,k){this.fromInt(0);if(k==null){k=10}var g=this.chunkSize(k);var h=Math.pow(k,g),f=false,a=0,m=0;for(var c=0;c<n.length;++c){var l=intAt(n,c);if(l<0){if(n.charAt(c)=="-"&&this.signum()==0){f=true}continue}m=k*m+l;if(++a>=g){this.dMultiply(h);this.dAddOffset(m,0);a=0;m=0}}if(a>0){this.dMultiply(Math.pow(k,a));this.dAddOffset(m,0)}if(f){BigInteger.ZERO.subTo(this,this)}}function bnpFromNumber(g,f,i){if("number"==typeof f){if(g<2){this.fromInt(1)}else{this.fromNumber(g,i);if(!this.testBit(g-1)){this.bitwiseTo(BigInteger.ONE.shiftLeft(g-1),op_or,this)}if(this.isEven()){this.dAddOffset(1,0)}while(!this.isProbablePrime(f)){this.dAddOffset(2,0);if(this.bitLength()>g){this.subTo(BigInteger.ONE.shiftLeft(g-1),this)}}}}else{var d=new Array(),h=g&7;d.length=(g>>3)+1;f.nextBytes(d);if(h>0){d[0]&=((1<<h)-1)}else{d[0]=0}this.fromString(d,256)}}function bnToByteArray(){var b=this.t,c=new Array();c[0]=this.s;var f=this.DB-(b*this.DB)%8,g,a=0;if(b-->0){if(f<this.DB&&(g=this[b]>>f)!=(this.s&this.DM)>>f){c[a++]=g|(this.s<<(this.DB-f))}while(b>=0){if(f<8){g=(this[b]&((1<<f)-1))<<(8-f);g|=this[--b]>>(f+=this.DB-8)}else{g=(this[b]>>(f-=8))&255;if(f<=0){f+=this.DB;--b}}if((g&128)!=0){g|=-256}if(a==0&&(this.s&128)!=(g&128)){++a}if(a>0||g!=this.s){c[a++]=g}}}return c}function bnEquals(b){return(this.compareTo(b)==0)}function bnMin(b){return(this.compareTo(b)<0)?this:b}function bnMax(b){return(this.compareTo(b)>0)?this:b}function bnpBitwiseTo(c,j,g){var d,h,b=Math.min(c.t,this.t);for(d=0;d<b;++d){g[d]=j(this[d],c[d])}if(c.t<this.t){h=c.s&this.DM;for(d=b;d<this.t;++d){g[d]=j(this[d],h)}g.t=this.t}else{h=this.s&this.DM;for(d=b;d<c.t;++d){g[d]=j(h,c[d])}g.t=c.t}g.s=j(this.s,c.s);g.clamp()}function op_and(a,b){return a&b}function bnAnd(b){var c=nbi();this.bitwiseTo(b,op_and,c);return c}function op_or(a,b){return a|b}function bnOr(b){var c=nbi();this.bitwiseTo(b,op_or,c);return c}function op_xor(a,b){return a^b}function bnXor(b){var c=nbi();this.bitwiseTo(b,op_xor,c);return c}function op_andnot(a,b){return a&~b}function bnAndNot(b){var c=nbi();this.bitwiseTo(b,op_andnot,c);return c}function bnNot(){var b=nbi();for(var a=0;a<this.t;++a){b[a]=this.DM&~this[a]}b.t=this.t;b.s=~this.s;return b}function bnShiftLeft(b){var a=nbi();if(b<0){this.rShiftTo(-b,a)}else{this.lShiftTo(b,a)}return a}function bnShiftRight(b){var a=nbi();if(b<0){this.lShiftTo(-b,a)}else{this.rShiftTo(b,a)}return a}function lbit(a){if(a==0){return -1}var b=0;if((a&65535)==0){a>>=16;b+=16}if((a&255)==0){a>>=8;b+=8}if((a&15)==0){a>>=4;b+=4}if((a&3)==0){a>>=2;b+=2}if((a&1)==0){++b}return b}function bnGetLowestSetBit(){for(var a=0;a<this.t;++a){if(this[a]!=0){return a*this.DB+lbit(this[a])}}if(this.s<0){return this.t*this.DB}return -1}function cbit(a){var b=0;while(a!=0){a&=a-1;++b}return b}function bnBitCount(){var c=0,a=this.s&this.DM;for(var b=0;b<this.t;++b){c+=cbit(this[b]^a)}return c}function bnTestBit(b){var a=Math.floor(b/this.DB);if(a>=this.t){return(this.s!=0)}return((this[a]&(1<<(b%this.DB)))!=0)}function bnpChangeBit(c,b){var a=BigInteger.ONE.shiftLeft(c);this.bitwiseTo(a,b,a);return a}function bnSetBit(a){return this.changeBit(a,op_or)}function bnClearBit(a){return this.changeBit(a,op_andnot)}function bnFlipBit(a){return this.changeBit(a,op_xor)}function bnpAddTo(d,g){var f=0,h=0,b=Math.min(d.t,this.t);while(f<b){h+=this[f]+d[f];g[f++]=h&this.DM;h>>=this.DB}if(d.t<this.t){h+=d.s;while(f<this.t){h+=this[f];g[f++]=h&this.DM;h>>=this.DB}h+=this.s}else{h+=this.s;while(f<d.t){h+=d[f];g[f++]=h&this.DM;h>>=this.DB}h+=d.s}g.s=(h<0)?-1:0;if(h>0){g[f++]=h}else{if(h<-1){g[f++]=this.DV+h}}g.t=f;g.clamp()}function bnAdd(b){var c=nbi();this.addTo(b,c);return c}function bnSubtract(b){var c=nbi();this.subTo(b,c);return c}function bnMultiply(b){var c=nbi();this.multiplyTo(b,c);return c}function bnDivide(b){var c=nbi();this.divRemTo(b,c,null);return c}function bnRemainder(b){var c=nbi();this.divRemTo(b,null,c);return c}function bnDivideAndRemainder(b){var d=nbi(),c=nbi();this.divRemTo(b,d,c);return new Array(d,c)}function bnpDMultiply(a){this[this.t]=this.am(0,a-1,this,0,0,this.t);++this.t;this.clamp()}function bnpDAddOffset(b,a){if(b==0){return}while(this.t<=a){this[this.t++]=0}this[a]+=b;while(this[a]>=this.DV){this[a]-=this.DV;if(++a>=this.t){this[this.t++]=0}++this[a]}}function NullExp(){}function nNop(a){return a}function nMulTo(a,c,b){a.multiplyTo(c,b)}function nSqrTo(a,b){a.squareTo(b)}NullExp.prototype.convert=nNop;NullExp.prototype.revert=nNop;NullExp.prototype.mulTo=nMulTo;NullExp.prototype.sqrTo=nSqrTo;function bnPow(a){return this.exp(a,new NullExp())}function bnpMultiplyLowerTo(b,g,f){var d=Math.min(this.t+b.t,g);f.s=0;f.t=d;while(d>0){f[--d]=0}var c;for(c=f.t-this.t;d<c;++d){f[d+this.t]=this.am(0,b[d],f,d,0,this.t)}for(c=Math.min(b.t,g);d<c;++d){this.am(0,b[d],f,d,0,g-d)}f.clamp()}function bnpMultiplyUpperTo(b,f,d){--f;var c=d.t=this.t+b.t-f;d.s=0;while(--c>=0){d[c]=0}for(c=Math.max(f-this.t,0);c<b.t;++c){d[this.t+c-f]=this.am(f-c,b[c],d,0,0,this.t+c-f)}d.clamp();d.drShiftTo(1,d)}function Barrett(a){this.r2=nbi();this.q3=nbi();BigInteger.ONE.dlShiftTo(2*a.t,this.r2);this.mu=this.r2.divide(a);this.m=a}function barrettConvert(a){if(a.s<0||a.t>2*this.m.t){return a.mod(this.m)}else{if(a.compareTo(this.m)<0){return a}else{var b=nbi();a.copyTo(b);this.reduce(b);return b}}}function barrettRevert(a){return a}function barrettReduce(a){a.drShiftTo(this.m.t-1,this.r2);if(a.t>this.m.t+1){a.t=this.m.t+1;a.clamp()}this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);while(a.compareTo(this.r2)<0){a.dAddOffset(1,this.m.t+1)}a.subTo(this.r2,a);while(a.compareTo(this.m)>=0){a.subTo(this.m,a)}}function barrettSqrTo(a,b){a.squareTo(b);this.reduce(b)}function barrettMulTo(a,c,b){a.multiplyTo(c,b);this.reduce(b)}Barrett.prototype.convert=barrettConvert;Barrett.prototype.revert=barrettRevert;Barrett.prototype.reduce=barrettReduce;Barrett.prototype.mulTo=barrettMulTo;Barrett.prototype.sqrTo=barrettSqrTo;function bnModPow(q,f){var o=q.bitLength(),h,b=nbv(1),v;if(o<=0){return b}else{if(o<18){h=1}else{if(o<48){h=3}else{if(o<144){h=4}else{if(o<768){h=5}else{h=6}}}}}if(o<8){v=new Classic(f)}else{if(f.isEven()){v=new Barrett(f)}else{v=new Montgomery(f)}}var p=new Array(),d=3,s=h-1,a=(1<<h)-1;p[1]=v.convert(this);if(h>1){var A=nbi();v.sqrTo(p[1],A);while(d<=a){p[d]=nbi();v.mulTo(A,p[d-2],p[d]);d+=2}}var l=q.t-1,x,u=true,c=nbi(),y;o=nbits(q[l])-1;while(l>=0){if(o>=s){x=(q[l]>>(o-s))&a}else{x=(q[l]&((1<<(o+1))-1))<<(s-o);if(l>0){x|=q[l-1]>>(this.DB+o-s)}}d=h;while((x&1)==0){x>>=1;--d}if((o-=d)<0){o+=this.DB;--l}if(u){p[x].copyTo(b);u=false}else{while(d>1){v.sqrTo(b,c);v.sqrTo(c,b);d-=2}if(d>0){v.sqrTo(b,c)}else{y=b;b=c;c=y}v.mulTo(c,p[x],b)}while(l>=0&&(q[l]&(1<<o))==0){v.sqrTo(b,c);y=b;b=c;c=y;if(--o<0){o=this.DB-1;--l}}}return v.revert(b)}function bnGCD(c){var b=(this.s<0)?this.negate():this.clone();var j=(c.s<0)?c.negate():c.clone();if(b.compareTo(j)<0){var f=b;b=j;j=f}var d=b.getLowestSetBit(),h=j.getLowestSetBit();if(h<0){return b}if(d<h){h=d}if(h>0){b.rShiftTo(h,b);j.rShiftTo(h,j)}while(b.signum()>0){if((d=b.getLowestSetBit())>0){b.rShiftTo(d,b)}if((d=j.getLowestSetBit())>0){j.rShiftTo(d,j)}if(b.compareTo(j)>=0){b.subTo(j,b);b.rShiftTo(1,b)}else{j.subTo(b,j);j.rShiftTo(1,j)}}if(h>0){j.lShiftTo(h,j)}return j}function bnpModInt(f){if(f<=0){return 0}var c=this.DV%f,b=(this.s<0)?f-1:0;if(this.t>0){if(c==0){b=this[0]%f}else{for(var a=this.t-1;a>=0;--a){b=(c*b+this[a])%f}}}return b}function bnModInverse(g){var k=g.isEven();if((this.isEven()&&k)||g.signum()==0){return BigInteger.ZERO}var j=g.clone(),i=this.clone();var h=nbv(1),f=nbv(0),n=nbv(0),l=nbv(1);while(j.signum()!=0){while(j.isEven()){j.rShiftTo(1,j);if(k){if(!h.isEven()||!f.isEven()){h.addTo(this,h);f.subTo(g,f)}h.rShiftTo(1,h)}else{if(!f.isEven()){f.subTo(g,f)}}f.rShiftTo(1,f)}while(i.isEven()){i.rShiftTo(1,i);if(k){if(!n.isEven()||!l.isEven()){n.addTo(this,n);l.subTo(g,l)}n.rShiftTo(1,n)}else{if(!l.isEven()){l.subTo(g,l)}}l.rShiftTo(1,l)}if(j.compareTo(i)>=0){j.subTo(i,j);if(k){h.subTo(n,h)}f.subTo(l,f)}else{i.subTo(j,i);if(k){n.subTo(h,n)}l.subTo(f,l)}}if(i.compareTo(BigInteger.ONE)!=0){return BigInteger.ZERO}if(l.compareTo(g)>=0){return l.subtract(g)}if(l.signum()<0){l.addTo(g,l)}else{return l}if(l.signum()<0){return l.add(g)}else{return l}}var lowprimes=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509];var lplim=(1<<26)/lowprimes[lowprimes.length-1];function bnIsProbablePrime(f){var d,b=this.abs();if(b.t==1&&b[0]<=lowprimes[lowprimes.length-1]){for(d=0;d<lowprimes.length;++d){if(b[0]==lowprimes[d]){return true}}return false}if(b.isEven()){return false}d=1;while(d<lowprimes.length){var a=lowprimes[d],c=d+1;while(c<lowprimes.length&&a<lplim){a*=lowprimes[c++]}a=b.modInt(a);while(d<c){if(a%lowprimes[d++]==0){return false}}}return b.millerRabin(f)}function bnpMillerRabin(g){var h=this.subtract(BigInteger.ONE);var c=h.getLowestSetBit();if(c<=0){return false}var l=h.shiftRight(c);g=(g+1)>>1;if(g>lowprimes.length){g=lowprimes.length}var b=nbi();for(var f=0;f<g;++f){b.fromInt(lowprimes[f]);var m=b.modPow(l,this);if(m.compareTo(BigInteger.ONE)!=0&&m.compareTo(h)!=0){var d=1;while(d++<c&&m.compareTo(h)!=0){m=m.modPowInt(2,this);if(m.compareTo(BigInteger.ONE)==0){return false}}if(m.compareTo(h)!=0){return false}}}return true}BigInteger.prototype.chunkSize=bnpChunkSize;BigInteger.prototype.toRadix=bnpToRadix;BigInteger.prototype.fromRadix=bnpFromRadix;BigInteger.prototype.fromNumber=bnpFromNumber;BigInteger.prototype.bitwiseTo=bnpBitwiseTo;BigInteger.prototype.changeBit=bnpChangeBit;BigInteger.prototype.addTo=bnpAddTo;BigInteger.prototype.dMultiply=bnpDMultiply;BigInteger.prototype.dAddOffset=bnpDAddOffset;BigInteger.prototype.multiplyLowerTo=bnpMultiplyLowerTo;BigInteger.prototype.multiplyUpperTo=bnpMultiplyUpperTo;BigInteger.prototype.modInt=bnpModInt;BigInteger.prototype.millerRabin=bnpMillerRabin;BigInteger.prototype.clone=bnClone;BigInteger.prototype.intValue=bnIntValue;BigInteger.prototype.byteValue=bnByteValue;BigInteger.prototype.shortValue=bnShortValue;BigInteger.prototype.signum=bnSigNum;BigInteger.prototype.toByteArray=bnToByteArray;BigInteger.prototype.equals=bnEquals;BigInteger.prototype.min=bnMin;BigInteger.prototype.max=bnMax;BigInteger.prototype.and=bnAnd;BigInteger.prototype.or=bnOr;BigInteger.prototype.xor=bnXor;BigInteger.prototype.andNot=bnAndNot;BigInteger.prototype.not=bnNot;BigInteger.prototype.shiftLeft=bnShiftLeft;BigInteger.prototype.shiftRight=bnShiftRight;BigInteger.prototype.getLowestSetBit=bnGetLowestSetBit;BigInteger.prototype.bitCount=bnBitCount;BigInteger.prototype.testBit=bnTestBit;BigInteger.prototype.setBit=bnSetBit;BigInteger.prototype.clearBit=bnClearBit;BigInteger.prototype.flipBit=bnFlipBit;BigInteger.prototype.add=bnAdd;BigInteger.prototype.subtract=bnSubtract;BigInteger.prototype.multiply=bnMultiply;BigInteger.prototype.divide=bnDivide;BigInteger.prototype.remainder=bnRemainder;BigInteger.prototype.divideAndRemainder=bnDivideAndRemainder;BigInteger.prototype.modPow=bnModPow;BigInteger.prototype.modInverse=bnModInverse;BigInteger.prototype.pow=bnPow;BigInteger.prototype.gcd=bnGCD;BigInteger.prototype.isProbablePrime=bnIsProbablePrime;function parseBigInt(b,a){return new BigInteger(b,a)}function linebrk(c,d){var a="";var b=0;while(b+d<c.length){a+=c.substring(b,b+d)+"\n";b+=d}return a+c.substring(b,c.length)}function byte2Hex(a){if(a<16){return"0"+a.toString(16)}else{return a.toString(16)}}function pkcs1pad2(f,j){if(j<f.length+11){alert("Message too long for RSA");return null}var h=new Array();var d=f.length-1;while(d>=0&&j>0){var g=f.charCodeAt(d--);if(g<128){h[--j]=g}else{if((g>127)&&(g<2048)){h[--j]=(g&63)|128;h[--j]=(g>>6)|192}else{h[--j]=(g&63)|128;h[--j]=((g>>6)&63)|128;h[--j]=(g>>12)|224}}}h[--j]=0;var b=new SecureRandom();var a=new Array();while(j>2){a[0]=0;while(a[0]==0){b.nextBytes(a)}h[--j]=a[0]}h[--j]=2;h[--j]=0;return new BigInteger(h)}function RSAKey(){this.n=null;this.e=0;this.d=null;this.p=null;this.q=null;this.dmp1=null;this.dmq1=null;this.coeff=null}function RSASetPublic(b,a){if(b!=null&&a!=null&&b.length>0&&a.length>0){this.n=parseBigInt(b,16);this.e=parseInt(a,16)}else{alert("Invalid RSA public key")}}function RSADoPublic(a){return a.modPowInt(this.e,this.n)}function RSAEncrypt(d){var a=pkcs1pad2(d,(this.n.bitLength()+7)>>3);if(a==null){return null}var f=this.doPublic(a);if(f==null){return null}var b=f.toString(16);if((b.length&1)==0){return b}else{return"0"+b}}RSAKey.prototype.doPublic=RSADoPublic;RSAKey.prototype.setPublic=RSASetPublic;RSAKey.prototype.encrypt=RSAEncrypt;function pkcs1unpad2(h,k){var a=h.toByteArray();var g=0;while(g<a.length&&a[g]==0){++g}if(a.length-g!=k-1||a[g]!=2){return null}++g;while(a[g]!=0){if(++g>=a.length){return null}}var f="";while(++g<a.length){var j=a[g]&255;if(j<128){f+=String.fromCharCode(j)}else{if((j>191)&&(j<224)){f+=String.fromCharCode(((j&31)<<6)|(a[g+1]&63));++g}else{f+=String.fromCharCode(((j&15)<<12)|((a[g+1]&63)<<6)|(a[g+2]&63));g+=2}}}return f}function RSASetPrivate(c,a,b){if(c!=null&&a!=null&&c.length>0&&a.length>0){this.n=parseBigInt(c,16);this.e=parseInt(a,16);this.d=parseBigInt(b,16)}else{alert("Invalid RSA private key")}}function RSASetPrivateEx(h,d,f,c,b,a,i,g){if(h!=null&&d!=null&&h.length>0&&d.length>0){this.n=parseBigInt(h,16);this.e=parseInt(d,16);this.d=parseBigInt(f,16);this.p=parseBigInt(c,16);this.q=parseBigInt(b,16);this.dmp1=parseBigInt(a,16);this.dmq1=parseBigInt(i,16);this.coeff=parseBigInt(g,16)}else{alert("Invalid RSA private key")}}function RSAGenerate(b,j){var a=new SecureRandom();var g=b>>1;this.e=parseInt(j,16);var c=new BigInteger(j,16);for(;;){for(;;){this.p=new BigInteger(b-g,1,a);if(this.p.subtract(BigInteger.ONE).gcd(c).compareTo(BigInteger.ONE)==0&&this.p.isProbablePrime(10)){break}}for(;;){this.q=new BigInteger(g,1,a);if(this.q.subtract(BigInteger.ONE).gcd(c).compareTo(BigInteger.ONE)==0&&this.q.isProbablePrime(10)){break}}if(this.p.compareTo(this.q)<=0){var i=this.p;this.p=this.q;this.q=i}var h=this.p.subtract(BigInteger.ONE);var d=this.q.subtract(BigInteger.ONE);var f=h.multiply(d);if(f.gcd(c).compareTo(BigInteger.ONE)==0){this.n=this.p.multiply(this.q);this.d=c.modInverse(f);this.dmp1=this.d.mod(h);this.dmq1=this.d.mod(d);this.coeff=this.q.modInverse(this.p);break}}}function RSAPrivateKeySerializeASN1(){function g(j,k){var i=k.toByteArray();j.push(2);j.push(i.length);return j.concat(i)}var c=[];c.push(48);c.push(130);c.push(1);c.push(0);c.push(2);c.push(1);c.push(0);c=g(c,this.n);c=g(c,new BigInteger(""+this.e,10));c=g(c,this.d);c=g(c,this.p);c=g(c,this.q);c=g(c,this.dmp1);c=g(c,this.dmq1);c=g(c,this.coeff);var f=c.length-4;var a=new BigInteger(""+f,10).toByteArray();c[2]=a[0];c[3]=a[1];var b="";for(var d=0;d<c.length;d++){b+=int2char((c[d]&240)>>4);b+=int2char(c[d]&15)}b=hex2b64(b);var h="";for(var d=0;d<b.length;d++){if(d>0&&(d%64)==0){h+="\n"}h+=b[d]}return"-----BEGIN RSA PRIVATE KEY-----\n"+h+"\n-----END RSA PRIVATE KEY-----\n"}function RSAPublicKeySerializeASN1(){function g(o){var n=0;for(var q=0;q<o.length;q++){n+=o[q].length}var p=[];p.push(48);if(n<128){p.push(n)}else{var m=new BigInteger(""+n,10).toByteArray();p.push(128|m.length);for(var q=0;q<m.length;q++){p.push(m[q])}}for(var q=0;q<o.length;q++){p=p.concat(o[q])}return p}function b(n){var i=n.toByteArray();var m=[];m.push(2);m.push(i.length);return m.concat(i)}function k(m){var i=[];i.push(3);i.push(m.length+1);i.push(0);return i.concat(m)}var h=g([b(this.n),b(new BigInteger(""+this.e,10))]);var a=k(h);var j=g([[6,9,42,134,72,134,247,13,1,1,1],[5,0],]);var l=g([j,a]);var d="";for(var f=0;f<l.length;f++){d+=int2char((l[f]&240)>>4);d+=int2char(l[f]&15)}d=hex2b64(d);var c="";for(var f=0;f<d.length;f++){if(f>0&&(f%64)==0){c+="\n"}c+=d[f]}return"-----BEGIN PUBLIC KEY-----\n"+c+"\n-----END PUBLIC KEY-----\n"}function RSADoPrivate(a){if(this.p==null||this.q==null){return a.modPow(this.d,this.n)}var c=a.mod(this.p).modPow(this.dmp1,this.p);var b=a.mod(this.q).modPow(this.dmq1,this.q);while(c.compareTo(b)<0){c=c.add(this.p)}return c.subtract(b).multiply(this.coeff).mod(this.p).multiply(this.q).add(b)}function RSADecrypt(b){var d=parseBigInt(b,16);var a=this.doPrivate(d);if(a==null){return null}return pkcs1unpad2(a,(this.n.bitLength()+7)>>3)}RSAKey.prototype.doPrivate=RSADoPrivate;RSAKey.prototype.setPrivate=RSASetPrivate;RSAKey.prototype.setPrivateEx=RSASetPrivateEx;RSAKey.prototype.generate=RSAGenerate;RSAKey.prototype.decrypt=RSADecrypt;RSAKey.prototype.serializePrivateASN1=RSAPrivateKeySerializeASN1;RSAKey.prototype.serializePublicASN1=RSAPublicKeySerializeASN1;function _asnhex_getByteLengthOfL_AtObj(b,c){if(b.substring(c+2,c+3)!="8"){return 1}var a=parseInt(b.substring(c+3,c+4));if(a==0){return -1}if(0<a&&a<10){return a+1}return -2}function _asnhex_getHexOfL_AtObj(b,c){var a=_asnhex_getByteLengthOfL_AtObj(b,c);if(a<1){return""}return b.substring(c+2,c+2+a*2)}function _asnhex_getIntOfL_AtObj(c,d){var b=_asnhex_getHexOfL_AtObj(c,d);if(b==""){return -1}var a;if(parseInt(b.substring(0,1))<8){a=parseBigInt(b,16)}else{a=parseBigInt(b.substring(2),16)}return a.intValue()}function _asnhex_getStartPosOfV_AtObj(b,c){var a=_asnhex_getByteLengthOfL_AtObj(b,c);if(a<0){return a}return c+(a+1)*2}function _asnhex_getHexOfV_AtObj(c,d){var b=_asnhex_getStartPosOfV_AtObj(c,d);var a=_asnhex_getIntOfL_AtObj(c,d);return c.substring(b,b+a*2)}function _asnhex_getPosOfNextSibling_AtObj(c,d){var b=_asnhex_getStartPosOfV_AtObj(c,d);var a=_asnhex_getIntOfL_AtObj(c,d);return b+a*2}function _asnhex_getPosArrayOfChildren_AtObj(g,l){var c=new Array();var j=_asnhex_getStartPosOfV_AtObj(g,l);c.push(j);var b=_asnhex_getIntOfL_AtObj(g,l);var i=j;var d=0;while(1){var f=_asnhex_getPosOfNextSibling_AtObj(g,i);if(f==null||(f-j>=(b*2))){break}if(d>=200){break}c.push(f);i=f;d++}return c}function _rsapem_pemToBase64(b){var a=b;a=a.replace("-----BEGIN RSA PRIVATE KEY-----","");a=a.replace("-----END RSA PRIVATE KEY-----","");a=a.replace(/[ \n]+/g,"");return a}function _rsapubpem_pemToBase64(b){if(b.indexOf("-----BEGIN PUBLIC KEY-----")!=0){throw"Malformed input to readPublicKeyFromPEMString: input does not start with '-----BEGIN PUBLIC KEY-----'"}var a=b;a=a.replace("-----BEGIN PUBLIC KEY-----","");a=a.replace("-----END PUBLIC KEY-----","");a=a.replace(/[ \n]+/g,"");return a}function _rsapem_getPosArrayOfChildrenFromHex(d){var k=new Array();var l=_asnhex_getStartPosOfV_AtObj(d,0);var g=_asnhex_getPosOfNextSibling_AtObj(d,l);var i=_asnhex_getPosOfNextSibling_AtObj(d,g);var b=_asnhex_getPosOfNextSibling_AtObj(d,i);var m=_asnhex_getPosOfNextSibling_AtObj(d,b);var f=_asnhex_getPosOfNextSibling_AtObj(d,m);var h=_asnhex_getPosOfNextSibling_AtObj(d,f);var c=_asnhex_getPosOfNextSibling_AtObj(d,h);var j=_asnhex_getPosOfNextSibling_AtObj(d,c);k.push(l,g,i,b,m,f,h,c,j);return k}function _rsapem_getHexValueArrayOfChildrenFromHex(i){var o=_rsapem_getPosArrayOfChildrenFromHex(i);var r=_asnhex_getHexOfV_AtObj(i,o[0]);var f=_asnhex_getHexOfV_AtObj(i,o[1]);var j=_asnhex_getHexOfV_AtObj(i,o[2]);var k=_asnhex_getHexOfV_AtObj(i,o[3]);var c=_asnhex_getHexOfV_AtObj(i,o[4]);var b=_asnhex_getHexOfV_AtObj(i,o[5]);var h=_asnhex_getHexOfV_AtObj(i,o[6]);var g=_asnhex_getHexOfV_AtObj(i,o[7]);var l=_asnhex_getHexOfV_AtObj(i,o[8]);var m=new Array();m.push(r,f,j,k,c,b,h,g,l);return m}function _rsapem_readPrivateKeyFromPEMString(f){var c=_rsapem_pemToBase64(f);var d=b64tohex(c);var b=_rsapem_getHexValueArrayOfChildrenFromHex(d);this.setPrivateEx(b[1],b[2],b[3],b[4],b[5],b[6],b[7],b[8])}function _rsapem_readPublicKeyFromPEMString(c){var h=_rsapubpem_pemToBase64(c);var g=b64tohex(h);var b=_asnhex_getPosArrayOfChildren_AtObj(g,0);var f=_asnhex_getHexOfV_AtObj(g,b[0]);var j=_asnhex_getHexOfV_AtObj(g,b[1]);j=j.substring(2,j.length);var i=_asnhex_getPosArrayOfChildren_AtObj(j,0);var a=_asnhex_getHexOfV_AtObj(j,i[0]);var d=_asnhex_getHexOfV_AtObj(j,i[1]);this.setPublic(a,d)}RSAKey.prototype.readPrivateKeyFromPEMString=_rsapem_readPrivateKeyFromPEMString;RSAKey.prototype.readPublicKeyFromPEMString=_rsapem_readPublicKeyFromPEMString;var _RSASIGN_DIHEAD=[];_RSASIGN_DIHEAD.sha1="3021300906052b0e03021a05000414";_RSASIGN_DIHEAD.sha256="3031300d060960864801650304020105000420";var _RSASIGN_HASHHEXFUNC=[];_RSASIGN_HASHHEXFUNC.sha256=function(a){return sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash(a))};function _rsasign_getHexPaddedDigestInfoForString(n,h,b){var d=h/4;var k=_RSASIGN_HASHHEXFUNC[b];var f=k(n);var a="0001";var l="00"+_RSASIGN_DIHEAD[b]+f;var j="";var m=d-a.length-l.length;for(var g=0;g<m;g+=2){j+="ff"}var c=a+j+l;return c}function _rsasign_signString(g,c){var h=_rsasign_getHexPaddedDigestInfoForString(g,this.n.bitLength(),c);var f=h.length;var b=parseBigInt(h,16);var d=this.doPrivate(b);var a=d.toString(16);while(a.length<f){a="0"+a}return a}function _rsasign_signStringWithSHA1(d){var f=_rsasign_getHexPaddedDigestInfoForString(d,this.n.bitLength(),"sha1");var b=parseBigInt(f,16);var c=this.doPrivate(b);var a=c.toString(16);return a}function _rsasign_signStringWithSHA256(d){var f=_rsasign_getHexPaddedDigestInfoForString(d,this.n.bitLength(),"sha256");var b=parseBigInt(f,16);var c=this.doPrivate(b);var a=c.toString(16);return a}function _rsasign_getDecryptSignatureBI(a,d,c){var b=new RSAKey();b.setPublic(d,c);var f=b.doPublic(a);return f}function _rsasign_getHexDigestInfoFromSig(a,c,b){var f=_rsasign_getDecryptSignatureBI(a,c,b);var d=f.toString(16).replace(/^1f+00/,"");return d}function _rsasign_getAlgNameAndHashFromHexDisgestInfo(g){for(var f in _RSASIGN_DIHEAD){var d=_RSASIGN_DIHEAD[f];var b=d.length;if(g.substring(0,b)==d){var c=[f,g.substring(b)];return c}}return[]}function _rsasign_verifySignatureWithArgs(g,b,h,k){var f=_rsasign_getHexDigestInfoFromSig(b,h,k);var i=_rsasign_getAlgNameAndHashFromHexDisgestInfo(f);if(i.length==0){return false}var d=i[0];var j=i[1];var a=_RSASIGN_HASHHEXFUNC[d];var c=a(g);return(j==c)}function _rsasign_verifyHexSignatureForMessage(c,b){var d=parseBigInt(c,16);var a=_rsasign_verifySignatureWithArgs(b,d,this.n.toString(16),this.e.toString(16));return a}function _rsasign_verifyString(g,k){k=k.replace(/[ \n]+/g,"");var b=parseBigInt(k,16);var j=this.doPublic(b);var f=j.toString(16).replace(/^1f+00/,"");var h=_rsasign_getAlgNameAndHashFromHexDisgestInfo(f);if(h.length==0){return false}var d=h[0];var i=h[1];var a=_RSASIGN_HASHHEXFUNC[d];var c=a(g);return(i==c)}RSAKey.prototype.signString=_rsasign_signString;RSAKey.prototype.signStringWithSHA1=_rsasign_signStringWithSHA1;RSAKey.prototype.signStringWithSHA256=_rsasign_signStringWithSHA256;RSAKey.prototype.verifyString=_rsasign_verifyString;RSAKey.prototype.verifyHexSignatureForMessage=_rsasign_verifyHexSignatureForMessage;function _x509_pemToBase64(a){var b=a;b=b.replace("-----BEGIN CERTIFICATE-----","");b=b.replace("-----END CERTIFICATE-----","");b=b.replace(/[ \n]+/g,"");return b}function _x509_pemToHex(a){var c=_x509_pemToBase64(a);var b=b64tohex(c);return b}function _x509_getHexTbsCertificateFromCert(b){var a=_asnhex_getStartPosOfV_AtObj(b,0);return a}function _x509_getSubjectPublicKeyInfoPosFromCertHex(d){var c=_asnhex_getStartPosOfV_AtObj(d,0);var b=_asnhex_getPosArrayOfChildren_AtObj(d,c);if(b.length<1){return -1}if(d.substring(b[0],b[0]+10)=="a003020102"){if(b.length<6){return -1}return b[6]}else{if(b.length<5){return -1}return b[5]}}function _x509_getSubjectPublicKeyPosFromCertHex(g){var f=_x509_getSubjectPublicKeyInfoPosFromCertHex(g);if(f==-1){return -1}var b=_asnhex_getPosArrayOfChildren_AtObj(g,f);if(b.length!=2){return -1}var d=b[1];if(g.substring(d,d+2)!="03"){return -1}var c=_asnhex_getStartPosOfV_AtObj(g,d);if(g.substring(c,c+2)!="00"){return -1}return c+2}function _x509_getPublicKeyHexArrayFromCertHex(g){var f=_x509_getSubjectPublicKeyPosFromCertHex(g);var b=_asnhex_getPosArrayOfChildren_AtObj(g,f);if(b.length!=2){return[]}var d=_asnhex_getHexOfV_AtObj(g,b[0]);var c=_asnhex_getHexOfV_AtObj(g,b[1]);if(d!=null&&c!=null){return[d,c]}else{return[]}}function _x509_getPublicKeyHexArrayFromCertPEM(c){var d=_x509_pemToHex(c);var b=_x509_getPublicKeyHexArrayFromCertHex(d);return b}function _x509_readCertPEM(c){var f=_x509_pemToHex(c);var b=_x509_getPublicKeyHexArrayFromCertHex(f);var d=new RSAKey();d.setPublic(b[0],b[1]);this.subjectPublicKeyRSA=d;this.subjectPublicKeyRSA_hN=b[0];this.subjectPublicKeyRSA_hE=b[1]}function _x509_readCertPEMWithoutRSAInit(c){var d=_x509_pemToHex(c);var b=_x509_getPublicKeyHexArrayFromCertHex(d);this.subjectPublicKeyRSA.setPublic(b[0],b[1]);this.subjectPublicKeyRSA_hN=b[0];this.subjectPublicKeyRSA_hE=b[1]}function X509(){this.subjectPublicKeyRSA=null;this.subjectPublicKeyRSA_hN=null;this.subjectPublicKeyRSA_hE=null}X509.prototype.readCertPEM=_x509_readCertPEM;X509.prototype.readCertPEMWithoutRSAInit=_x509_readCertPEMWithoutRSAInit;function Arcfour(){this.i=0;this.j=0;this.S=new Array()}function ARC4init(d){var c,a,b;for(c=0;c<256;++c){this.S[c]=c}a=0;for(c=0;c<256;++c){a=(a+this.S[c]+d[c%d.length])&255;b=this.S[c];this.S[c]=this.S[a];this.S[a]=b}this.i=0;this.j=0}function ARC4next(){var a;this.i=(this.i+1)&255;this.j=(this.j+this.S[this.i])&255;a=this.S[this.i];this.S[this.i]=this.S[this.j];this.S[this.j]=a;return this.S[(a+this.S[this.i])&255]}Arcfour.prototype.init=ARC4init;Arcfour.prototype.next=ARC4next;function prng_newstate(){return new Arcfour()}var rng_psize=256;var rng_state;var rng_pool;var rng_pptr;function rng_seed_int(a){rng_pool[rng_pptr++]^=a&255;rng_pool[rng_pptr++]^=(a>>8)&255;rng_pool[rng_pptr++]^=(a>>16)&255;rng_pool[rng_pptr++]^=(a>>24)&255;if(rng_pptr>=rng_psize){rng_pptr-=rng_psize}}function rng_seed_time(){rng_seed_int(new Date().getTime())}if(rng_pool==null){rng_pool=new Array();rng_pptr=0;var t;if(navigator.appName=="Netscape"&&navigator.appVersion<"5"&&window.crypto){var z=window.crypto.random(32);for(t=0;t<z.length;++t){rng_pool[rng_pptr++]=z.charCodeAt(t)&255}}while(rng_pptr<rng_psize){t=Math.floor(65536*Math.random());rng_pool[rng_pptr++]=t>>>8;rng_pool[rng_pptr++]=t&255}rng_pptr=0;rng_seed_time()}function rng_get_byte(){if(rng_state==null){rng_seed_time();rng_state=prng_newstate();rng_state.init(rng_pool);for(rng_pptr=0;rng_pptr<rng_pool.length;++rng_pptr){rng_pool[rng_pptr]=0}rng_pptr=0}return rng_state.next()}function rng_get_bytes(b){var a;for(a=0;a<b.length;++a){b[a]=rng_get_byte()}}function SecureRandom(){}SecureRandom.prototype.nextBytes=rng_get_bytes;var jwt={};var JWTInternals=(function(){var v="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";function r(D){var B="";var C;var y=0;var A;for(C=0;C<D.length;++C){var x=v.indexOf(D.charAt(C));if(x<0){continue}if(y==0){B+=int2char(x>>2);A=x&3;y=1}else{if(y==1){B+=int2char((A<<2)|(x>>4));A=x&15;y=2}else{if(y==2){B+=int2char(A);B+=int2char(x>>2);A=x&3;y=3}else{B+=int2char((A<<2)|(x>>4));B+=int2char(x&15);y=0}}}}if(y==1){B+=int2char(A<<2)}return B}function f(x){return hex2b64(x).split("=")[0].replace(/\+/g,"-").replace(/\//g,"_")}function g(x){var y=window.btoa(x);y=y.split("=")[0];y=y.replace(/\+/g,"-");y=y.replace(/\//g,"_");return y}function m(x){var y=x;y=y.replace(/-/g,"+");y=y.replace(/_/g,"/");switch(y.length%4){case 0:break;case 2:y+="==";break;case 3:y+="=";break;default:throw new p("Illegal base64url string!")}return window.atob(y)}function o(x){this.message=x;this.toString=function(){return"No such algorithm: "+this.message}}function c(x){this.message=x;this.toString=function(){return"Not implemented: "+this.message}}function s(x){this.message=x;this.toString=function(){return"Malformed JSON web token: "+this.message}}function p(x){this.message=x;this.toString=function(){return"Malformed input: "+this.message}}function h(y,x){if(y=="sha256"){this.hash=sjcl.hash.sha256}else{throw new o("HMAC does not support hash "+y)}this.key=sjcl.codec.utf8String.toBits(x)}h.prototype={update:function q(x){this.data=x},finalize:function d(){},sign:function k(){var y=new sjcl.misc.hmac(this.key,this.hash);var x=y.encrypt(this.data);return g(window.atob(sjcl.codec.base64.fromBits(x)))},verify:function i(A){var y=new sjcl.misc.hmac(this.key,this.hash);var x=y.encrypt(this.data);return g(window.atob(sjcl.codec.base64.fromBits(x)))==A}};function a(x,y){if(x=="sha1"){this.hash="sha1"}else{if(x=="sha256"){this.hash="sha256"}else{throw new o("JWT algorithm: "+x)}}this.keyPEM=y}a.prototype={update:function q(x){this.data=x},finalize:function d(){},sign:function k(){var y=new RSAKey();y.readPrivateKeyFromPEMString(this.keyPEM);var x=y.signString(this.data,this.hash);return f(x)},verify:function i(y){var x=this.keyPEM.verifyString(this.data,r(y));return x}};function w(y,x){this.objectStr=y;this.pkAlgorithm=x}var l={parse:function b(x){var A=x.split(".");if(A.length!=3){throw new s("Must have three parts")}var y=new w();y.headerSegment=A[0];y.payloadSegment=A[1];y.cryptoSegment=A[2];y.pkAlgorithm=m(A[0]);return y}};function u(x){if(typeof x=="string"){return JSON.parse(x)}return x}function n(y,x){if("ES256"===y){throw new c("ECDSA-SHA256 not yet implemented")}else{if("ES384"===y){throw new c("ECDSA-SHA384 not yet implemented")}else{if("ES512"===y){throw new c("ECDSA-SHA512 not yet implemented")}else{if("HS256"===y){return new h("sha256",x)}else{if("HS384"===y){throw new c("HMAC-SHA384 not yet implemented")}else{if("HS512"===y){throw new c("HMAC-SHA512 not yet implemented")}else{if("RS256"===y){return new a("sha256",x)}else{if("RS384"===y){throw new c("RSA-SHA384 not yet implemented")}else{if("RS512"===y){throw new c("RSA-SHA512 not yet implemented")}else{throw new o("Unknown algorithm: "+y)}}}}}}}}}}w.prototype={serialize:function j(F){var A=u(this.pkAlgorithm);var E=A.alg;var D=n(E,F);var B=g(this.pkAlgorithm);var G=g(this.objectStr);var C=B+"."+G;D.update(C);var x=D.finalize();var y=D.sign();return B+"."+G+"."+y},verify:function i(y){var B=u(this.pkAlgorithm);var A=B.alg;var x=n(A,y);x.update(this.headerSegment+"."+this.payloadSegment);x.finalize();return x.verify(this.cryptoSegment)}};jwt.WebToken=w;jwt.WebTokenParser=l;jwt.base64urlencode=g;jwt.base64urldecode=m})();
+
+  function genKeyPair() {
+    // fake keypairs.  they're a random string with pub or priv prepended.
+    var key = new RSAKey();
+    key.generate(512, "10001");
+
+    // hm.  PEM encoding, anyone?
+    return {
+      pub: key.serializePublicASN1(),
+      priv: key.serializePrivateASN1()
+    };
+  }
+
+  function createAssertion(audience, email, privkey, issuer) {
+    var assertion = {
+      audience: audience,
+      email: email,
+      "valid-until": (new Date()).getTime() + (1000 * 120), // 2 mins from now.
+    };
+    if (issuer) {
+      assertion.issuer = issuer;
+    }
+
+    var token = new jwt.WebToken(JSON.stringify(assertion), JSON.stringify({alg:"RS256"}));
+    var signed = token.serialize(privkey);
+    return signed;
+  }
+
+  return {
+    genKeyPair: genKeyPair,
+    createAssertion: createAssertion
+  };
+})();
+
diff --git a/browserid/static/dialog/dialog/resources/crypto.js b/browserid/static/dialog/dialog/resources/crypto.js
new file mode 100644
index 0000000000000000000000000000000000000000..2281a9fd9faa55cfce18990dab8c5dcf3cdfebc5
--- /dev/null
+++ b/browserid/static/dialog/dialog/resources/crypto.js
@@ -0,0 +1,2580 @@
+"use strict";var sjcl={cipher:{},hash:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toString=function(){return"CORRUPT: "+this.message};this.message=a},invalid:function(a){this.toString=function(){return"INVALID: "+this.message};this.message=a},bug:function(a){this.toString=function(){return"BUG: "+this.message};this.message=a}}};
+sjcl.cipher.aes=function(a){this.h[0][0][0]||this.w();var b,c,d,e,f=this.h[0][4],g=this.h[1];b=a.length;var h=1;if(b!==4&&b!==6&&b!==8)throw new sjcl.exception.invalid("invalid aes key size");this.a=[d=a.slice(0),e=[]];for(a=b;a<4*b+28;a++){c=d[a-1];if(a%b===0||b===8&&a%b===4){c=f[c>>>24]<<24^f[c>>16&255]<<16^f[c>>8&255]<<8^f[c&255];if(a%b===0){c=c<<8^c>>>24^h<<24;h=h<<1^(h>>7)*283}}d[a]=d[a-b]^c}for(b=0;a;b++,a--){c=d[b&3?a:a-4];e[b]=a<=4||b<4?c:g[0][f[c>>>24]]^g[1][f[c>>16&255]]^g[2][f[c>>8&255]]^
+g[3][f[c&255]]}};
+sjcl.cipher.aes.prototype={encrypt:function(a){return this.H(a,0)},decrypt:function(a){return this.H(a,1)},h:[[[],[],[],[],[]],[[],[],[],[],[]]],w:function(){var a=this.h[0],b=this.h[1],c=a[4],d=b[4],e,f,g,h=[],i=[],k,j,l,m;for(e=0;e<0x100;e++)i[(h[e]=e<<1^(e>>7)*283)^e]=e;for(f=g=0;!c[f];f^=k||1,g=i[g]||1){l=g^g<<1^g<<2^g<<3^g<<4;l=l>>8^l&255^99;c[f]=l;d[l]=f;j=h[e=h[k=h[f]]];m=j*0x1010101^e*0x10001^k*0x101^f*0x1010100;j=h[l]*0x101^l*0x1010100;for(e=0;e<4;e++){a[e][f]=j=j<<24^j>>>8;b[e][l]=m=m<<24^m>>>8}}for(e=
+0;e<5;e++){a[e]=a[e].slice(0);b[e]=b[e].slice(0)}},H:function(a,b){if(a.length!==4)throw new sjcl.exception.invalid("invalid aes block size");var c=this.a[b],d=a[0]^c[0],e=a[b?3:1]^c[1],f=a[2]^c[2];a=a[b?1:3]^c[3];var g,h,i,k=c.length/4-2,j,l=4,m=[0,0,0,0];g=this.h[b];var n=g[0],o=g[1],p=g[2],q=g[3],r=g[4];for(j=0;j<k;j++){g=n[d>>>24]^o[e>>16&255]^p[f>>8&255]^q[a&255]^c[l];h=n[e>>>24]^o[f>>16&255]^p[a>>8&255]^q[d&255]^c[l+1];i=n[f>>>24]^o[a>>16&255]^p[d>>8&255]^q[e&255]^c[l+2];a=n[a>>>24]^o[d>>16&
+255]^p[e>>8&255]^q[f&255]^c[l+3];l+=4;d=g;e=h;f=i}for(j=0;j<4;j++){m[b?3&-j:j]=r[d>>>24]<<24^r[e>>16&255]<<16^r[f>>8&255]<<8^r[a&255]^c[l++];g=d;d=e;e=f;f=a;a=g}return m}};
+sjcl.bitArray={bitSlice:function(a,b,c){a=sjcl.bitArray.P(a.slice(b/32),32-(b&31)).slice(1);return c===undefined?a:sjcl.bitArray.clamp(a,c-b)},concat:function(a,b){if(a.length===0||b.length===0)return a.concat(b);var c=a[a.length-1],d=sjcl.bitArray.getPartial(c);return d===32?a.concat(b):sjcl.bitArray.P(b,d,c|0,a.slice(0,a.length-1))},bitLength:function(a){var b=a.length;if(b===0)return 0;return(b-1)*32+sjcl.bitArray.getPartial(a[b-1])},clamp:function(a,b){if(a.length*32<b)return a;a=a.slice(0,Math.ceil(b/
+32));var c=a.length;b&=31;if(c>0&&b)a[c-1]=sjcl.bitArray.partial(b,a[c-1]&2147483648>>b-1,1);return a},partial:function(a,b,c){if(a===32)return b;return(c?b|0:b<<32-a)+a*0x10000000000},getPartial:function(a){return Math.round(a/0x10000000000)||32},equal:function(a,b){if(sjcl.bitArray.bitLength(a)!==sjcl.bitArray.bitLength(b))return false;var c=0,d;for(d=0;d<a.length;d++)c|=a[d]^b[d];return c===0},P:function(a,b,c,d){var e;e=0;if(d===undefined)d=[];for(;b>=32;b-=32){d.push(c);c=0}if(b===0)return d.concat(a);
+for(e=0;e<a.length;e++){d.push(c|a[e]>>>b);c=a[e]<<32-b}e=a.length?a[a.length-1]:0;a=sjcl.bitArray.getPartial(e);d.push(sjcl.bitArray.partial(b+a&31,b+a>32?c:d.pop(),1));return d},k:function(a,b){return[a[0]^b[0],a[1]^b[1],a[2]^b[2],a[3]^b[3]]}};
+sjcl.codec.utf8String={fromBits:function(a){var b="",c=sjcl.bitArray.bitLength(a),d,e;for(d=0;d<c/8;d++){if((d&3)===0)e=a[d/4];b+=String.fromCharCode(e>>>24);e<<=8}return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c<a.length;c++){d=d<<8|a.charCodeAt(c);if((c&3)===3){b.push(d);d=0}}c&3&&b.push(sjcl.bitArray.partial(8*(c&3),d));return b}};
+sjcl.codec.hex={fromBits:function(a){var b="",c;for(c=0;c<a.length;c++)b+=((a[c]|0)+0xf00000000000).toString(16).substr(4);return b.substr(0,sjcl.bitArray.bitLength(a)/4)},toBits:function(a){var b,c=[],d;a=a.replace(/\s|0x/g,"");d=a.length;a+="00000000";for(b=0;b<a.length;b+=8)c.push(parseInt(a.substr(b,8),16)^0);return sjcl.bitArray.clamp(c,d*4)}};
+sjcl.codec.base64={D:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",fromBits:function(a,b){var c="",d,e=0,f=sjcl.codec.base64.D,g=0,h=sjcl.bitArray.bitLength(a);for(d=0;c.length*6<h;){c+=f.charAt((g^a[d]>>>e)>>>26);if(e<6){g=a[d]<<6-e;e+=26;d++}else{g<<=6;e-=6}}for(;c.length&3&&!b;)c+="=";return c},toBits:function(a){a=a.replace(/\s|=/g,"");var b=[],c,d=0,e=sjcl.codec.base64.D,f=0,g;for(c=0;c<a.length;c++){g=e.indexOf(a.charAt(c));if(g<0)throw new sjcl.exception.invalid("this isn't base64!");
+if(d>26){d-=26;b.push(f^g>>>d);f=g<<32-d}else{d+=6;f^=g<<32-d}}d&56&&b.push(sjcl.bitArray.partial(d&56,f,1));return b}};sjcl.hash.sha256=function(a){this.a[0]||this.w();if(a){this.n=a.n.slice(0);this.i=a.i.slice(0);this.e=a.e}else this.reset()};sjcl.hash.sha256.hash=function(a){return(new sjcl.hash.sha256).update(a).finalize()};
+sjcl.hash.sha256.prototype={blockSize:512,reset:function(){this.n=this.N.slice(0);this.i=[];this.e=0;return this},update:function(a){if(typeof a==="string")a=sjcl.codec.utf8String.toBits(a);var b,c=this.i=sjcl.bitArray.concat(this.i,a);b=this.e;a=this.e=b+sjcl.bitArray.bitLength(a);for(b=512+b&-512;b<=a;b+=512)this.C(c.splice(0,16));return this},finalize:function(){var a,b=this.i,c=this.n;b=sjcl.bitArray.concat(b,[sjcl.bitArray.partial(1,1)]);for(a=b.length+2;a&15;a++)b.push(0);b.push(Math.floor(this.e/
+4294967296));for(b.push(this.e|0);b.length;)this.C(b.splice(0,16));this.reset();return c},N:[],a:[],w:function(){function a(e){return(e-Math.floor(e))*0x100000000|0}var b=0,c=2,d;a:for(;b<64;c++){for(d=2;d*d<=c;d++)if(c%d===0)continue a;if(b<8)this.N[b]=a(Math.pow(c,0.5));this.a[b]=a(Math.pow(c,1/3));b++}},C:function(a){var b,c,d=a.slice(0),e=this.n,f=this.a,g=e[0],h=e[1],i=e[2],k=e[3],j=e[4],l=e[5],m=e[6],n=e[7];for(a=0;a<64;a++){if(a<16)b=d[a];else{b=d[a+1&15];c=d[a+14&15];b=d[a&15]=(b>>>7^b>>>18^
+b>>>3^b<<25^b<<14)+(c>>>17^c>>>19^c>>>10^c<<15^c<<13)+d[a&15]+d[a+9&15]|0}b=b+n+(j>>>6^j>>>11^j>>>25^j<<26^j<<21^j<<7)+(m^j&(l^m))+f[a];n=m;m=l;l=j;j=k+b|0;k=i;i=h;h=g;g=b+(h&i^k&(h^i))+(h>>>2^h>>>13^h>>>22^h<<30^h<<19^h<<10)|0}e[0]=e[0]+g|0;e[1]=e[1]+h|0;e[2]=e[2]+i|0;e[3]=e[3]+k|0;e[4]=e[4]+j|0;e[5]=e[5]+l|0;e[6]=e[6]+m|0;e[7]=e[7]+n|0}};
+sjcl.mode.ccm={name:"ccm",encrypt:function(a,b,c,d,e){var f,g=b.slice(0),h=sjcl.bitArray,i=h.bitLength(c)/8,k=h.bitLength(g)/8;e=e||64;d=d||[];if(i<7)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(f=2;f<4&&k>>>8*f;f++);if(f<15-i)f=15-i;c=h.clamp(c,8*(15-f));b=sjcl.mode.ccm.G(a,b,c,d,e,f);g=sjcl.mode.ccm.I(a,g,c,b,e,f);return h.concat(g.data,g.tag)},decrypt:function(a,b,c,d,e){e=e||64;d=d||[];var f=sjcl.bitArray,g=f.bitLength(c)/8,h=f.bitLength(b),i=f.clamp(b,h-e),k=f.bitSlice(b,
+h-e);h=(h-e)/8;if(g<7)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(b=2;b<4&&h>>>8*b;b++);if(b<15-g)b=15-g;c=f.clamp(c,8*(15-b));i=sjcl.mode.ccm.I(a,i,c,k,e,b);a=sjcl.mode.ccm.G(a,i.data,c,d,e,b);if(!f.equal(i.tag,a))throw new sjcl.exception.corrupt("ccm: tag doesn't match");return i.data},G:function(a,b,c,d,e,f){var g=[],h=sjcl.bitArray,i=h.k;e/=8;if(e%2||e<4||e>16)throw new sjcl.exception.invalid("ccm: invalid tag length");if(d.length>0xffffffff||b.length>0xffffffff)throw new sjcl.exception.bug("ccm: can't deal with 4GiB or more data");
+f=[h.partial(8,(d.length?64:0)|e-2<<2|f-1)];f=h.concat(f,c);f[3]|=h.bitLength(b)/8;f=a.encrypt(f);if(d.length){c=h.bitLength(d)/8;if(c<=65279)g=[h.partial(16,c)];else if(c<=0xffffffff)g=h.concat([h.partial(16,65534)],[c]);g=h.concat(g,d);for(d=0;d<g.length;d+=4)f=a.encrypt(i(f,g.slice(d,d+4)))}for(d=0;d<b.length;d+=4)f=a.encrypt(i(f,b.slice(d,d+4)));return h.clamp(f,e*8)},I:function(a,b,c,d,e,f){var g,h=sjcl.bitArray;g=h.k;var i=b.length,k=h.bitLength(b);c=h.concat([h.partial(8,f-1)],c).concat([0,
+0,0]).slice(0,4);d=h.bitSlice(g(d,a.encrypt(c)),0,e);if(!i)return{tag:d,data:[]};for(g=0;g<i;g+=4){c[3]++;e=a.encrypt(c);b[g]^=e[0];b[g+1]^=e[1];b[g+2]^=e[2];b[g+3]^=e[3]}return{tag:d,data:h.clamp(b,k)}}};
+sjcl.mode.ocb2={name:"ocb2",encrypt:function(a,b,c,d,e,f){if(sjcl.bitArray.bitLength(c)!==128)throw new sjcl.exception.invalid("ocb iv must be 128 bits");var g,h=sjcl.mode.ocb2.A,i=sjcl.bitArray,k=i.k,j=[0,0,0,0];c=h(a.encrypt(c));var l,m=[];d=d||[];e=e||64;for(g=0;g+4<b.length;g+=4){l=b.slice(g,g+4);j=k(j,l);m=m.concat(k(c,a.encrypt(k(c,l))));c=h(c)}l=b.slice(g);b=i.bitLength(l);g=a.encrypt(k(c,[0,0,0,b]));l=i.clamp(k(l,g),b);j=k(j,k(l,g));j=a.encrypt(k(j,k(c,h(c))));if(d.length)j=k(j,f?d:sjcl.mode.ocb2.pmac(a,
+d));return m.concat(i.concat(l,i.clamp(j,e)))},decrypt:function(a,b,c,d,e,f){if(sjcl.bitArray.bitLength(c)!==128)throw new sjcl.exception.invalid("ocb iv must be 128 bits");e=e||64;var g=sjcl.mode.ocb2.A,h=sjcl.bitArray,i=h.k,k=[0,0,0,0],j=g(a.encrypt(c)),l,m,n=sjcl.bitArray.bitLength(b)-e,o=[];d=d||[];for(c=0;c+4<n/32;c+=4){l=i(j,a.decrypt(i(j,b.slice(c,c+4))));k=i(k,l);o=o.concat(l);j=g(j)}m=n-c*32;l=a.encrypt(i(j,[0,0,0,m]));l=i(l,h.clamp(b.slice(c),m));k=i(k,l);k=a.encrypt(i(k,i(j,g(j))));if(d.length)k=
+i(k,f?d:sjcl.mode.ocb2.pmac(a,d));if(!h.equal(h.clamp(k,e),h.bitSlice(b,n)))throw new sjcl.exception.corrupt("ocb: tag doesn't match");return o.concat(h.clamp(l,m))},pmac:function(a,b){var c,d=sjcl.mode.ocb2.A,e=sjcl.bitArray,f=e.k,g=[0,0,0,0],h=a.encrypt([0,0,0,0]);h=f(h,d(d(h)));for(c=0;c+4<b.length;c+=4){h=d(h);g=f(g,a.encrypt(f(h,b.slice(c,c+4))))}b=b.slice(c);if(e.bitLength(b)<128){h=f(h,d(h));b=e.concat(b,[2147483648|0])}g=f(g,b);return a.encrypt(f(d(f(h,d(h))),g))},A:function(a){return[a[0]<<
+1^a[1]>>>31,a[1]<<1^a[2]>>>31,a[2]<<1^a[3]>>>31,a[3]<<1^(a[0]>>>31)*135]}};sjcl.misc.hmac=function(a,b){this.M=b=b||sjcl.hash.sha256;var c=[[],[]],d=b.prototype.blockSize/32;this.l=[new b,new b];if(a.length>d)a=b.hash(a);for(b=0;b<d;b++){c[0][b]=a[b]^909522486;c[1][b]=a[b]^1549556828}this.l[0].update(c[0]);this.l[1].update(c[1])};sjcl.misc.hmac.prototype.encrypt=sjcl.misc.hmac.prototype.mac=function(a,b){a=(new this.M(this.l[0])).update(a,b).finalize();return(new this.M(this.l[1])).update(a).finalize()};
+sjcl.misc.pbkdf2=function(a,b,c,d,e){c=c||1E3;if(d<0||c<0)throw sjcl.exception.invalid("invalid params to pbkdf2");if(typeof a==="string")a=sjcl.codec.utf8String.toBits(a);e=e||sjcl.misc.hmac;a=new e(a);var f,g,h,i,k=[],j=sjcl.bitArray;for(i=1;32*k.length<(d||1);i++){e=f=a.encrypt(j.concat(b,[i]));for(g=1;g<c;g++){f=a.encrypt(f);for(h=0;h<f.length;h++)e[h]^=f[h]}k=k.concat(e)}if(d)k=j.clamp(k,d);return k};
+sjcl.random={randomWords:function(a,b){var c=[];b=this.isReady(b);var d;if(b===0)throw new sjcl.exception.notready("generator isn't seeded");else b&2&&this.U(!(b&1));for(b=0;b<a;b+=4){(b+1)%0x10000===0&&this.L();d=this.u();c.push(d[0],d[1],d[2],d[3])}this.L();return c.slice(0,a)},setDefaultParanoia:function(a){this.t=a},addEntropy:function(a,b,c){c=c||"user";var d,e,f=(new Date).valueOf(),g=this.q[c],h=this.isReady();d=this.F[c];if(d===undefined)d=this.F[c]=this.R++;if(g===undefined)g=this.q[c]=0;this.q[c]=
+(this.q[c]+1)%this.b.length;switch(typeof a){case "number":break;case "object":if(b===undefined)for(c=b=0;c<a.length;c++)for(e=a[c];e>0;){b++;e>>>=1}this.b[g].update([d,this.J++,2,b,f,a.length].concat(a));break;case "string":if(b===undefined)b=a.length;this.b[g].update([d,this.J++,3,b,f,a.length]);this.b[g].update(a);break;default:throw new sjcl.exception.bug("random: addEntropy only supports number, array or string");}this.j[g]+=b;this.f+=b;if(h===0){this.isReady()!==0&&this.K("seeded",Math.max(this.g,
+this.f));this.K("progress",this.getProgress())}},isReady:function(a){a=this.B[a!==undefined?a:this.t];return this.g&&this.g>=a?this.j[0]>80&&(new Date).valueOf()>this.O?3:1:this.f>=a?2:0},getProgress:function(a){a=this.B[a?a:this.t];return this.g>=a?1["0"]:this.f>a?1["0"]:this.f/a},startCollectors:function(){if(!this.m){if(window.addEventListener){window.addEventListener("load",this.o,false);window.addEventListener("mousemove",this.p,false)}else if(document.attachEvent){document.attachEvent("onload",
+this.o);document.attachEvent("onmousemove",this.p)}else throw new sjcl.exception.bug("can't attach event");this.m=true}},stopCollectors:function(){if(this.m){if(window.removeEventListener){window.removeEventListener("load",this.o);window.removeEventListener("mousemove",this.p)}else if(window.detachEvent){window.detachEvent("onload",this.o);window.detachEvent("onmousemove",this.p)}this.m=false}},addEventListener:function(a,b){this.r[a][this.Q++]=b},removeEventListener:function(a,b){var c;a=this.r[a];
+var d=[];for(c in a)a.hasOwnProperty[c]&&a[c]===b&&d.push(c);for(b=0;b<d.length;b++){c=d[b];delete a[c]}},b:[new sjcl.hash.sha256],j:[0],z:0,q:{},J:0,F:{},R:0,g:0,f:0,O:0,a:[0,0,0,0,0,0,0,0],d:[0,0,0,0],s:undefined,t:6,m:false,r:{progress:{},seeded:{}},Q:0,B:[0,48,64,96,128,192,0x100,384,512,768,1024],u:function(){for(var a=0;a<4;a++){this.d[a]=this.d[a]+1|0;if(this.d[a])break}return this.s.encrypt(this.d)},L:function(){this.a=this.u().concat(this.u());this.s=new sjcl.cipher.aes(this.a)},T:function(a){this.a=
+sjcl.hash.sha256.hash(this.a.concat(a));this.s=new sjcl.cipher.aes(this.a);for(a=0;a<4;a++){this.d[a]=this.d[a]+1|0;if(this.d[a])break}},U:function(a){var b=[],c=0,d;this.O=b[0]=(new Date).valueOf()+3E4;for(d=0;d<16;d++)b.push(Math.random()*0x100000000|0);for(d=0;d<this.b.length;d++){b=b.concat(this.b[d].finalize());c+=this.j[d];this.j[d]=0;if(!a&&this.z&1<<d)break}if(this.z>=1<<this.b.length){this.b.push(new sjcl.hash.sha256);this.j.push(0)}this.f-=c;if(c>this.g)this.g=c;this.z++;this.T(b)},p:function(a){sjcl.random.addEntropy([a.x||
+a.clientX||a.offsetX,a.y||a.clientY||a.offsetY],2,"mouse")},o:function(){sjcl.random.addEntropy(new Date,2,"loadtime")},K:function(a,b){var c;a=sjcl.random.r[a];var d=[];for(c in a)a.hasOwnProperty(c)&&d.push(a[c]);for(c=0;c<d.length;c++)d[c](b)}};
+sjcl.json={defaults:{v:1,iter:1E3,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},encrypt:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json,f=e.c({iv:sjcl.random.randomWords(4,0)},e.defaults);e.c(f,c);if(typeof f.salt==="string")f.salt=sjcl.codec.base64.toBits(f.salt);if(typeof f.iv==="string")f.iv=sjcl.codec.base64.toBits(f.iv);if(!sjcl.mode[f.mode]||!sjcl.cipher[f.cipher]||typeof a==="string"&&f.iter<=100||f.ts!==64&&f.ts!==96&&f.ts!==128||f.ks!==128&&f.ks!==192&&f.ks!==0x100||f.iv.length<2||f.iv.length>
+4)throw new sjcl.exception.invalid("json encrypt: invalid parameters");if(typeof a==="string"){c=sjcl.misc.cachedPbkdf2(a,f);a=c.key.slice(0,f.ks/32);f.salt=c.salt}if(typeof b==="string")b=sjcl.codec.utf8String.toBits(b);c=new sjcl.cipher[f.cipher](a);e.c(d,f);d.key=a;f.ct=sjcl.mode[f.mode].encrypt(c,b,f.iv,f.adata,f.tag);return e.encode(e.V(f,e.defaults))},decrypt:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json;b=e.c(e.c(e.c({},e.defaults),e.decode(b)),c,true);if(typeof b.salt==="string")b.salt=
+sjcl.codec.base64.toBits(b.salt);if(typeof b.iv==="string")b.iv=sjcl.codec.base64.toBits(b.iv);if(!sjcl.mode[b.mode]||!sjcl.cipher[b.cipher]||typeof a==="string"&&b.iter<=100||b.ts!==64&&b.ts!==96&&b.ts!==128||b.ks!==128&&b.ks!==192&&b.ks!==0x100||!b.iv||b.iv.length<2||b.iv.length>4)throw new sjcl.exception.invalid("json decrypt: invalid parameters");if(typeof a==="string"){c=sjcl.misc.cachedPbkdf2(a,b);a=c.key.slice(0,b.ks/32);b.salt=c.salt}c=new sjcl.cipher[b.cipher](a);c=sjcl.mode[b.mode].decrypt(c,
+b.ct,b.iv,b.adata,b.tag);e.c(d,b);d.key=a;return sjcl.codec.utf8String.fromBits(c)},encode:function(a){var b,c="{",d="";for(b in a)if(a.hasOwnProperty(b)){if(!b.match(/^[a-z0-9]+$/i))throw new sjcl.exception.invalid("json encode: invalid property name");c+=d+b+":";d=",";switch(typeof a[b]){case "number":case "boolean":c+=a[b];break;case "string":c+='"'+escape(a[b])+'"';break;case "object":c+='"'+sjcl.codec.base64.fromBits(a[b],1)+'"';break;default:throw new sjcl.exception.bug("json encode: unsupported type");
+}}return c+"}"},decode:function(a){a=a.replace(/\s/g,"");if(!a.match(/^\{.*\}$/))throw new sjcl.exception.invalid("json decode: this isn't json!");a=a.replace(/^\{|\}$/g,"").split(/,/);var b={},c,d;for(c=0;c<a.length;c++){if(!(d=a[c].match(/^([a-z][a-z0-9]*):(?:(\d+)|"([a-z0-9+\/%*_.@=\-]*)")$/i)))throw new sjcl.exception.invalid("json decode: this isn't json!");b[d[1]]=d[2]?parseInt(d[2],10):d[1].match(/^(ct|salt|iv)$/)?sjcl.codec.base64.toBits(d[3]):unescape(d[3])}return b},c:function(a,b,c){if(a===
+undefined)a={};if(b===undefined)return a;var d;for(d in b)if(b.hasOwnProperty(d)){if(c&&a[d]!==undefined&&a[d]!==b[d])throw new sjcl.exception.invalid("required parameter overridden");a[d]=b[d]}return a},V:function(a,b){var c={},d;for(d in a)if(a.hasOwnProperty(d)&&a[d]!==b[d])c[d]=a[d];return c},W:function(a,b){var c={},d;for(d=0;d<b.length;d++)if(a[b[d]]!==undefined)c[b[d]]=a[b[d]];return c}};sjcl.encrypt=sjcl.json.encrypt;sjcl.decrypt=sjcl.json.decrypt;sjcl.misc.S={};
+sjcl.misc.cachedPbkdf2=function(a,b){var c=sjcl.misc.S,d;b=b||{};d=b.iter||1E3;c=c[a]=c[a]||{};d=c[d]=c[d]||{firstSalt:b.salt&&b.salt.length?b.salt.slice(0):sjcl.random.randomWords(2,0)};c=b.salt===undefined?d.firstSalt:b.salt;d[c]=d[c]||sjcl.misc.pbkdf2(a,c,b.iter);return{key:d[c].slice(0),salt:c.slice(0)}};
+var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+var b64pad="=";
+
+function hex2b64(h) {
+  var i;
+  var c;
+  var ret = "";
+  for(i = 0; i+3 <= h.length; i+=3) {
+    c = parseInt(h.substring(i,i+3),16);
+    ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
+  }
+  if(i+1 == h.length) {
+    c = parseInt(h.substring(i,i+1),16);
+    ret += b64map.charAt(c << 2);
+  }
+  else if(i+2 == h.length) {
+    c = parseInt(h.substring(i,i+2),16);
+    ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
+  }
+  while((ret.length & 3) > 0) ret += b64pad;
+  return ret;
+}
+
+// convert a base64 string to hex
+function b64tohex(s) {
+  var ret = ""
+  var i;
+  var k = 0; // b64 state, 0-3
+  var slop;
+  for(i = 0; i < s.length; ++i) {
+    if(s.charAt(i) == b64pad) break;
+    var v = b64map.indexOf(s.charAt(i));
+    if(v < 0) continue;
+    if(k == 0) {
+      ret += int2char(v >> 2);
+      slop = v & 3;
+      k = 1;
+    }
+    else if(k == 1) {
+      ret += int2char((slop << 2) | (v >> 4));
+      slop = v & 0xf;
+      k = 2;
+    }
+    else if(k == 2) {
+      ret += int2char(slop);
+      ret += int2char(v >> 2);
+      slop = v & 3;
+      k = 3;
+    }
+    else {
+      ret += int2char((slop << 2) | (v >> 4));
+      ret += int2char(v & 0xf);
+      k = 0;
+    }
+  }
+  if(k == 1)
+    ret += int2char(slop << 2);
+  return ret;
+}
+
+// convert a base64 string to a byte/number array
+function b64toBA(s) {
+  //piggyback on b64tohex for now, optimize later
+  var h = b64tohex(s);
+  var i;
+  var a = new Array();
+  for(i = 0; 2*i < h.length; ++i) {
+    a[i] = parseInt(h.substring(2*i,2*i+2),16);
+  }
+  return a;
+}
+// Copyright (c) 2005  Tom Wu
+// All Rights Reserved.
+// See "LICENSE" for details.
+
+// Basic JavaScript BN library - subset useful for RSA encryption.
+
+// Bits per digit
+var dbits;
+
+// JavaScript engine analysis
+var canary = 0xdeadbeefcafe;
+var j_lm = ((canary&0xffffff)==0xefcafe);
+
+// (public) Constructor
+function BigInteger(a,b,c) {
+  if(a != null)
+    if("number" == typeof a) this.fromNumber(a,b,c);
+    else if(b == null && "string" != typeof a) this.fromString(a,256);
+    else this.fromString(a,b);
+}
+
+// return new, unset BigInteger
+function nbi() { return new BigInteger(null); }
+
+// am: Compute w_j += (x*this_i), propagate carries,
+// c is initial carry, returns final carry.
+// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
+// We need to select the fastest one that works in this environment.
+
+// am1: use a single mult and divide to get the high bits,
+// max digit bits should be 26 because
+// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
+function am1(i,x,w,j,c,n) {
+  while(--n >= 0) {
+    var v = x*this[i++]+w[j]+c;
+    c = Math.floor(v/0x4000000);
+    w[j++] = v&0x3ffffff;
+  }
+  return c;
+}
+// am2 avoids a big mult-and-extract completely.
+// Max digit bits should be <= 30 because we do bitwise ops
+// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
+function am2(i,x,w,j,c,n) {
+  var xl = x&0x7fff, xh = x>>15;
+  while(--n >= 0) {
+    var l = this[i]&0x7fff;
+    var h = this[i++]>>15;
+    var m = xh*l+h*xl;
+    l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);
+    c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
+    w[j++] = l&0x3fffffff;
+  }
+  return c;
+}
+// Alternately, set max digit bits to 28 since some
+// browsers slow down when dealing with 32-bit numbers.
+function am3(i,x,w,j,c,n) {
+  var xl = x&0x3fff, xh = x>>14;
+  while(--n >= 0) {
+    var l = this[i]&0x3fff;
+    var h = this[i++]>>14;
+    var m = xh*l+h*xl;
+    l = xl*l+((m&0x3fff)<<14)+w[j]+c;
+    c = (l>>28)+(m>>14)+xh*h;
+    w[j++] = l&0xfffffff;
+  }
+  return c;
+}
+try {
+  if(j_lm && (navigator && navigator.appName == "Microsoft Internet Explorer")) {
+    BigInteger.prototype.am = am2;
+    dbits = 30;
+  }
+  else if(j_lm && (navigator && navigator.appName != "Netscape")) {
+    BigInteger.prototype.am = am1;
+    dbits = 26;
+  }
+  else { // Mozilla/Netscape seems to prefer am3
+    BigInteger.prototype.am = am3;
+    dbits = 28;
+  }
+} catch (e) {
+  BigInteger.prototype.am = am3;
+  dbits = 28;
+}
+
+BigInteger.prototype.DB = dbits;
+BigInteger.prototype.DM = ((1<<dbits)-1);
+BigInteger.prototype.DV = (1<<dbits);
+
+var BI_FP = 52;
+BigInteger.prototype.FV = Math.pow(2,BI_FP);
+BigInteger.prototype.F1 = BI_FP-dbits;
+BigInteger.prototype.F2 = 2*dbits-BI_FP;
+
+// Digit conversions
+var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
+var BI_RC = new Array();
+var rr,vv;
+rr = "0".charCodeAt(0);
+for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
+rr = "a".charCodeAt(0);
+for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+rr = "A".charCodeAt(0);
+for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+
+function int2char(n) { return BI_RM.charAt(n); }
+function intAt(s,i) {
+  var c = BI_RC[s.charCodeAt(i)];
+  return (c==null)?-1:c;
+}
+
+// (protected) copy this to r
+function bnpCopyTo(r) {
+  for(var i = this.t-1; i >= 0; --i) r[i] = this[i];
+  r.t = this.t;
+  r.s = this.s;
+}
+
+// (protected) set from integer value x, -DV <= x < DV
+function bnpFromInt(x) {
+  this.t = 1;
+  this.s = (x<0)?-1:0;
+  if(x > 0) this[0] = x;
+  else if(x < -1) this[0] = x+DV;
+  else this.t = 0;
+}
+
+// return bigint initialized to value
+function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
+
+// (protected) set from string and radix
+function bnpFromString(s,b) {
+  var k;
+  if(b == 16) k = 4;
+  else if(b == 8) k = 3;
+  else if(b == 256) k = 8; // byte array
+  else if(b == 2) k = 1;
+  else if(b == 32) k = 5;
+  else if(b == 4) k = 2;
+  else { this.fromRadix(s,b); return; }
+  this.t = 0;
+  this.s = 0;
+  var i = s.length, mi = false, sh = 0;
+  while(--i >= 0) {
+    var x = (k==8)?s[i]&0xff:intAt(s,i);
+    if(x < 0) {
+      if(s.charAt(i) == "-") mi = true;
+      continue;
+    }
+    mi = false;
+    if(sh == 0)
+      this[this.t++] = x;
+    else if(sh+k > this.DB) {
+      this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
+      this[this.t++] = (x>>(this.DB-sh));
+    }
+    else
+      this[this.t-1] |= x<<sh;
+    sh += k;
+    if(sh >= this.DB) sh -= this.DB;
+  }
+  if(k == 8 && (s[0]&0x80) != 0) {
+    this.s = -1;
+    if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
+  }
+  this.clamp();
+  if(mi) BigInteger.ZERO.subTo(this,this);
+}
+
+// (protected) clamp off excess high words
+function bnpClamp() {
+  var c = this.s&this.DM;
+  while(this.t > 0 && this[this.t-1] == c) --this.t;
+}
+
+// (public) return string representation in given radix
+function bnToString(b) {
+  if(this.s < 0) return "-"+this.negate().toString(b);
+  var k;
+  if(b == 16) k = 4;
+  else if(b == 8) k = 3;
+  else if(b == 2) k = 1;
+  else if(b == 32) k = 5;
+  else if(b == 4) k = 2;
+  else return this.toRadix(b);
+  var km = (1<<k)-1, d, m = false, r = "", i = this.t;
+  var p = this.DB-(i*this.DB)%k;
+  if(i-- > 0) {
+    if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }
+    while(i >= 0) {
+      if(p < k) {
+        d = (this[i]&((1<<p)-1))<<(k-p);
+        d |= this[--i]>>(p+=this.DB-k);
+      }
+      else {
+        d = (this[i]>>(p-=k))&km;
+        if(p <= 0) { p += this.DB; --i; }
+      }
+      if(d > 0) m = true;
+      if(m) r += int2char(d);
+    }
+  }
+  return m?r:"0";
+}
+
+// (public) -this
+function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
+
+// (public) |this|
+function bnAbs() { return (this.s<0)?this.negate():this; }
+
+// (public) return + if this > a, - if this < a, 0 if equal
+function bnCompareTo(a) {
+  var r = this.s-a.s;
+  if(r != 0) return r;
+  var i = this.t;
+  r = i-a.t;
+  if(r != 0) return r;
+  while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
+  return 0;
+}
+
+// returns bit length of the integer x
+function nbits(x) {
+  var r = 1, t;
+  if((t=x>>>16) != 0) { x = t; r += 16; }
+  if((t=x>>8) != 0) { x = t; r += 8; }
+  if((t=x>>4) != 0) { x = t; r += 4; }
+  if((t=x>>2) != 0) { x = t; r += 2; }
+  if((t=x>>1) != 0) { x = t; r += 1; }
+  return r;
+}
+
+// (public) return the number of bits in "this"
+function bnBitLength() {
+  if(this.t <= 0) return 0;
+  return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
+}
+
+// (protected) r = this << n*DB
+function bnpDLShiftTo(n,r) {
+  var i;
+  for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
+  for(i = n-1; i >= 0; --i) r[i] = 0;
+  r.t = this.t+n;
+  r.s = this.s;
+}
+
+// (protected) r = this >> n*DB
+function bnpDRShiftTo(n,r) {
+  for(var i = n; i < this.t; ++i) r[i-n] = this[i];
+  r.t = Math.max(this.t-n,0);
+  r.s = this.s;
+}
+
+// (protected) r = this << n
+function bnpLShiftTo(n,r) {
+  var bs = n%this.DB;
+  var cbs = this.DB-bs;
+  var bm = (1<<cbs)-1;
+  var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;
+  for(i = this.t-1; i >= 0; --i) {
+    r[i+ds+1] = (this[i]>>cbs)|c;
+    c = (this[i]&bm)<<bs;
+  }
+  for(i = ds-1; i >= 0; --i) r[i] = 0;
+  r[ds] = c;
+  r.t = this.t+ds+1;
+  r.s = this.s;
+  r.clamp();
+}
+
+// (protected) r = this >> n
+function bnpRShiftTo(n,r) {
+  r.s = this.s;
+  var ds = Math.floor(n/this.DB);
+  if(ds >= this.t) { r.t = 0; return; }
+  var bs = n%this.DB;
+  var cbs = this.DB-bs;
+  var bm = (1<<bs)-1;
+  r[0] = this[ds]>>bs;
+  for(var i = ds+1; i < this.t; ++i) {
+    r[i-ds-1] |= (this[i]&bm)<<cbs;
+    r[i-ds] = this[i]>>bs;
+  }
+  if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;
+  r.t = this.t-ds;
+  r.clamp();
+}
+
+// (protected) r = this - a
+function bnpSubTo(a,r) {
+  var i = 0, c = 0, m = Math.min(a.t,this.t);
+  while(i < m) {
+    c += this[i]-a[i];
+    r[i++] = c&this.DM;
+    c >>= this.DB;
+  }
+  if(a.t < this.t) {
+    c -= a.s;
+    while(i < this.t) {
+      c += this[i];
+      r[i++] = c&this.DM;
+      c >>= this.DB;
+    }
+    c += this.s;
+  }
+  else {
+    c += this.s;
+    while(i < a.t) {
+      c -= a[i];
+      r[i++] = c&this.DM;
+      c >>= this.DB;
+    }
+    c -= a.s;
+  }
+  r.s = (c<0)?-1:0;
+  if(c < -1) r[i++] = this.DV+c;
+  else if(c > 0) r[i++] = c;
+  r.t = i;
+  r.clamp();
+}
+
+// (protected) r = this * a, r != this,a (HAC 14.12)
+// "this" should be the larger one if appropriate.
+function bnpMultiplyTo(a,r) {
+  var x = this.abs(), y = a.abs();
+  var i = x.t;
+  r.t = i+y.t;
+  while(--i >= 0) r[i] = 0;
+  for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);
+  r.s = 0;
+  r.clamp();
+  if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
+}
+
+// (protected) r = this^2, r != this (HAC 14.16)
+function bnpSquareTo(r) {
+  var x = this.abs();
+  var i = r.t = 2*x.t;
+  while(--i >= 0) r[i] = 0;
+  for(i = 0; i < x.t-1; ++i) {
+    var c = x.am(i,x[i],r,2*i,0,1);
+    if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
+      r[i+x.t] -= x.DV;
+      r[i+x.t+1] = 1;
+    }
+  }
+  if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);
+  r.s = 0;
+  r.clamp();
+}
+
+// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
+// r != q, this != m.  q or r may be null.
+function bnpDivRemTo(m,q,r) {
+  var pm = m.abs();
+  if(pm.t <= 0) return;
+  var pt = this.abs();
+  if(pt.t < pm.t) {
+    if(q != null) q.fromInt(0);
+    if(r != null) this.copyTo(r);
+    return;
+  }
+  if(r == null) r = nbi();
+  var y = nbi(), ts = this.s, ms = m.s;
+  var nsh = this.DB-nbits(pm[pm.t-1]);	// normalize modulus
+  if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
+  else { pm.copyTo(y); pt.copyTo(r); }
+  var ys = y.t;
+  var y0 = y[ys-1];
+  if(y0 == 0) return;
+  var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);
+  var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;
+  var i = r.t, j = i-ys, t = (q==null)?nbi():q;
+  y.dlShiftTo(j,t);
+  if(r.compareTo(t) >= 0) {
+    r[r.t++] = 1;
+    r.subTo(t,r);
+  }
+  BigInteger.ONE.dlShiftTo(ys,t);
+  t.subTo(y,y);	// "negative" y so we can replace sub with am later
+  while(y.t < ys) y[y.t++] = 0;
+  while(--j >= 0) {
+    // Estimate quotient digit
+    var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);
+    if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) {	// Try it out
+      y.dlShiftTo(j,t);
+      r.subTo(t,r);
+      while(r[i] < --qd) r.subTo(t,r);
+    }
+  }
+  if(q != null) {
+    r.drShiftTo(ys,q);
+    if(ts != ms) BigInteger.ZERO.subTo(q,q);
+  }
+  r.t = ys;
+  r.clamp();
+  if(nsh > 0) r.rShiftTo(nsh,r);	// Denormalize remainder
+  if(ts < 0) BigInteger.ZERO.subTo(r,r);
+}
+
+// (public) this mod a
+function bnMod(a) {
+  var r = nbi();
+  this.abs().divRemTo(a,null,r);
+  if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
+  return r;
+}
+
+// Modular reduction using "classic" algorithm
+function Classic(m) { this.m = m; }
+function cConvert(x) {
+  if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
+  else return x;
+}
+function cRevert(x) { return x; }
+function cReduce(x) { x.divRemTo(this.m,null,x); }
+function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
+function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
+
+Classic.prototype.convert = cConvert;
+Classic.prototype.revert = cRevert;
+Classic.prototype.reduce = cReduce;
+Classic.prototype.mulTo = cMulTo;
+Classic.prototype.sqrTo = cSqrTo;
+
+// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
+// justification:
+//         xy == 1 (mod m)
+//         xy =  1+km
+//   xy(2-xy) = (1+km)(1-km)
+// x[y(2-xy)] = 1-k^2m^2
+// x[y(2-xy)] == 1 (mod m^2)
+// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
+// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
+// JS multiply "overflows" differently from C/C++, so care is needed here.
+function bnpInvDigit() {
+  if(this.t < 1) return 0;
+  var x = this[0];
+  if((x&1) == 0) return 0;
+  var y = x&3;		// y == 1/x mod 2^2
+  y = (y*(2-(x&0xf)*y))&0xf;	// y == 1/x mod 2^4
+  y = (y*(2-(x&0xff)*y))&0xff;	// y == 1/x mod 2^8
+  y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff;	// y == 1/x mod 2^16
+  // last step - calculate inverse mod DV directly;
+  // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
+  y = (y*(2-x*y%this.DV))%this.DV;		// y == 1/x mod 2^dbits
+  // we really want the negative inverse, and -DV < y < DV
+  return (y>0)?this.DV-y:-y;
+}
+
+// Montgomery reduction
+function Montgomery(m) {
+  this.m = m;
+  this.mp = m.invDigit();
+  this.mpl = this.mp&0x7fff;
+  this.mph = this.mp>>15;
+  this.um = (1<<(m.DB-15))-1;
+  this.mt2 = 2*m.t;
+}
+
+// xR mod m
+function montConvert(x) {
+  var r = nbi();
+  x.abs().dlShiftTo(this.m.t,r);
+  r.divRemTo(this.m,null,r);
+  if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
+  return r;
+}
+
+// x/R mod m
+function montRevert(x) {
+  var r = nbi();
+  x.copyTo(r);
+  this.reduce(r);
+  return r;
+}
+
+// x = x/R mod m (HAC 14.32)
+function montReduce(x) {
+  while(x.t <= this.mt2)	// pad x so am has enough room later
+    x[x.t++] = 0;
+  for(var i = 0; i < this.m.t; ++i) {
+    // faster way of calculating u0 = x[i]*mp mod DV
+    var j = x[i]&0x7fff;
+    var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
+    // use am to combine the multiply-shift-add into one call
+    j = i+this.m.t;
+    x[j] += this.m.am(0,u0,x,i,0,this.m.t);
+    // propagate carry
+    while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
+  }
+  x.clamp();
+  x.drShiftTo(this.m.t,x);
+  if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
+}
+
+// r = "x^2/R mod m"; x != r
+function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
+
+// r = "xy/R mod m"; x,y != r
+function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
+
+Montgomery.prototype.convert = montConvert;
+Montgomery.prototype.revert = montRevert;
+Montgomery.prototype.reduce = montReduce;
+Montgomery.prototype.mulTo = montMulTo;
+Montgomery.prototype.sqrTo = montSqrTo;
+
+// (protected) true iff this is even
+function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }
+
+// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
+function bnpExp(e,z) {
+  if(e > 0xffffffff || e < 1) return BigInteger.ONE;
+  var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
+  g.copyTo(r);
+  while(--i >= 0) {
+    z.sqrTo(r,r2);
+    if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
+    else { var t = r; r = r2; r2 = t; }
+  }
+  return z.revert(r);
+}
+
+// (public) this^e % m, 0 <= e < 2^32
+function bnModPowInt(e,m) {
+  var z;
+  if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
+  return this.exp(e,z);
+}
+
+// protected
+BigInteger.prototype.copyTo = bnpCopyTo;
+BigInteger.prototype.fromInt = bnpFromInt;
+BigInteger.prototype.fromString = bnpFromString;
+BigInteger.prototype.clamp = bnpClamp;
+BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
+BigInteger.prototype.drShiftTo = bnpDRShiftTo;
+BigInteger.prototype.lShiftTo = bnpLShiftTo;
+BigInteger.prototype.rShiftTo = bnpRShiftTo;
+BigInteger.prototype.subTo = bnpSubTo;
+BigInteger.prototype.multiplyTo = bnpMultiplyTo;
+BigInteger.prototype.squareTo = bnpSquareTo;
+BigInteger.prototype.divRemTo = bnpDivRemTo;
+BigInteger.prototype.invDigit = bnpInvDigit;
+BigInteger.prototype.isEven = bnpIsEven;
+BigInteger.prototype.exp = bnpExp;
+
+// public
+BigInteger.prototype.toString = bnToString;
+BigInteger.prototype.negate = bnNegate;
+BigInteger.prototype.abs = bnAbs;
+BigInteger.prototype.compareTo = bnCompareTo;
+BigInteger.prototype.bitLength = bnBitLength;
+BigInteger.prototype.mod = bnMod;
+BigInteger.prototype.modPowInt = bnModPowInt;
+
+// "constants"
+BigInteger.ZERO = nbv(0);
+BigInteger.ONE = nbv(1);
+// Copyright (c) 2005-2009  Tom Wu
+// All Rights Reserved.
+// See "LICENSE" for details.
+
+// Extended JavaScript BN functions, required for RSA private ops.
+
+// Version 1.1: new BigInteger("0", 10) returns "proper" zero
+
+// (public)
+function bnClone() { var r = nbi(); this.copyTo(r); return r; }
+
+// (public) return value as integer
+function bnIntValue() {
+  if(this.s < 0) {
+    if(this.t == 1) return this[0]-this.DV;
+    else if(this.t == 0) return -1;
+  }
+  else if(this.t == 1) return this[0];
+  else if(this.t == 0) return 0;
+  // assumes 16 < DB < 32
+  return ((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0];
+}
+
+// (public) return value as byte
+function bnByteValue() { return (this.t==0)?this.s:(this[0]<<24)>>24; }
+
+// (public) return value as short (assumes DB>=16)
+function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; }
+
+// (protected) return x s.t. r^x < DV
+function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); }
+
+// (public) 0 if this == 0, 1 if this > 0
+function bnSigNum() {
+  if(this.s < 0) return -1;
+  else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;
+  else return 1;
+}
+
+// (protected) convert to radix string
+function bnpToRadix(b) {
+  if(b == null) b = 10;
+  if(this.signum() == 0 || b < 2 || b > 36) return "0";
+  var cs = this.chunkSize(b);
+  var a = Math.pow(b,cs);
+  var d = nbv(a), y = nbi(), z = nbi(), r = "";
+  this.divRemTo(d,y,z);
+  while(y.signum() > 0) {
+    r = (a+z.intValue()).toString(b).substr(1) + r;
+    y.divRemTo(d,y,z);
+  }
+  return z.intValue().toString(b) + r;
+}
+
+// (protected) convert from radix string
+function bnpFromRadix(s,b) {
+  this.fromInt(0);
+  if(b == null) b = 10;
+  var cs = this.chunkSize(b);
+  var d = Math.pow(b,cs), mi = false, j = 0, w = 0;
+  for(var i = 0; i < s.length; ++i) {
+    var x = intAt(s,i);
+    if(x < 0) {
+      if(s.charAt(i) == "-" && this.signum() == 0) mi = true;
+      continue;
+    }
+    w = b*w+x;
+    if(++j >= cs) {
+      this.dMultiply(d);
+      this.dAddOffset(w,0);
+      j = 0;
+      w = 0;
+    }
+  }
+  if(j > 0) {
+    this.dMultiply(Math.pow(b,j));
+    this.dAddOffset(w,0);
+  }
+  if(mi) BigInteger.ZERO.subTo(this,this);
+}
+
+// (protected) alternate constructor
+function bnpFromNumber(a,b,c) {
+  if("number" == typeof b) {
+    // new BigInteger(int,int,RNG)
+    if(a < 2) this.fromInt(1);
+    else {
+      this.fromNumber(a,c);
+      if(!this.testBit(a-1))	// force MSB set
+        this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);
+      if(this.isEven()) this.dAddOffset(1,0); // force odd
+      while(!this.isProbablePrime(b)) {
+        this.dAddOffset(2,0);
+        if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this);
+      }
+    }
+  }
+  else {
+    // new BigInteger(int,RNG)
+    var x = new Array(), t = a&7;
+    x.length = (a>>3)+1;
+    b.nextBytes(x);
+    if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0;
+    this.fromString(x,256);
+  }
+}
+
+// (public) convert to bigendian byte array
+function bnToByteArray() {
+  var i = this.t, r = new Array();
+  r[0] = this.s;
+  var p = this.DB-(i*this.DB)%8, d, k = 0;
+  if(i-- > 0) {
+    if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p)
+      r[k++] = d|(this.s<<(this.DB-p));
+    while(i >= 0) {
+      if(p < 8) {
+        d = (this[i]&((1<<p)-1))<<(8-p);
+        d |= this[--i]>>(p+=this.DB-8);
+      }
+      else {
+        d = (this[i]>>(p-=8))&0xff;
+        if(p <= 0) { p += this.DB; --i; }
+      }
+      if((d&0x80) != 0) d |= -256;
+      if(k == 0 && (this.s&0x80) != (d&0x80)) ++k;
+      if(k > 0 || d != this.s) r[k++] = d;
+    }
+  }
+  return r;
+}
+
+function bnEquals(a) { return(this.compareTo(a)==0); }
+function bnMin(a) { return(this.compareTo(a)<0)?this:a; }
+function bnMax(a) { return(this.compareTo(a)>0)?this:a; }
+
+// (protected) r = this op a (bitwise)
+function bnpBitwiseTo(a,op,r) {
+  var i, f, m = Math.min(a.t,this.t);
+  for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]);
+  if(a.t < this.t) {
+    f = a.s&this.DM;
+    for(i = m; i < this.t; ++i) r[i] = op(this[i],f);
+    r.t = this.t;
+  }
+  else {
+    f = this.s&this.DM;
+    for(i = m; i < a.t; ++i) r[i] = op(f,a[i]);
+    r.t = a.t;
+  }
+  r.s = op(this.s,a.s);
+  r.clamp();
+}
+
+// (public) this & a
+function op_and(x,y) { return x&y; }
+function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; }
+
+// (public) this | a
+function op_or(x,y) { return x|y; }
+function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; }
+
+// (public) this ^ a
+function op_xor(x,y) { return x^y; }
+function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; }
+
+// (public) this & ~a
+function op_andnot(x,y) { return x&~y; }
+function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; }
+
+// (public) ~this
+function bnNot() {
+  var r = nbi();
+  for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i];
+  r.t = this.t;
+  r.s = ~this.s;
+  return r;
+}
+
+// (public) this << n
+function bnShiftLeft(n) {
+  var r = nbi();
+  if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r);
+  return r;
+}
+
+// (public) this >> n
+function bnShiftRight(n) {
+  var r = nbi();
+  if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r);
+  return r;
+}
+
+// return index of lowest 1-bit in x, x < 2^31
+function lbit(x) {
+  if(x == 0) return -1;
+  var r = 0;
+  if((x&0xffff) == 0) { x >>= 16; r += 16; }
+  if((x&0xff) == 0) { x >>= 8; r += 8; }
+  if((x&0xf) == 0) { x >>= 4; r += 4; }
+  if((x&3) == 0) { x >>= 2; r += 2; }
+  if((x&1) == 0) ++r;
+  return r;
+}
+
+// (public) returns index of lowest 1-bit (or -1 if none)
+function bnGetLowestSetBit() {
+  for(var i = 0; i < this.t; ++i)
+    if(this[i] != 0) return i*this.DB+lbit(this[i]);
+  if(this.s < 0) return this.t*this.DB;
+  return -1;
+}
+
+// return number of 1 bits in x
+function cbit(x) {
+  var r = 0;
+  while(x != 0) { x &= x-1; ++r; }
+  return r;
+}
+
+// (public) return number of set bits
+function bnBitCount() {
+  var r = 0, x = this.s&this.DM;
+  for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x);
+  return r;
+}
+
+// (public) true iff nth bit is set
+function bnTestBit(n) {
+  var j = Math.floor(n/this.DB);
+  if(j >= this.t) return(this.s!=0);
+  return((this[j]&(1<<(n%this.DB)))!=0);
+}
+
+// (protected) this op (1<<n)
+function bnpChangeBit(n,op) {
+  var r = BigInteger.ONE.shiftLeft(n);
+  this.bitwiseTo(r,op,r);
+  return r;
+}
+
+// (public) this | (1<<n)
+function bnSetBit(n) { return this.changeBit(n,op_or); }
+
+// (public) this & ~(1<<n)
+function bnClearBit(n) { return this.changeBit(n,op_andnot); }
+
+// (public) this ^ (1<<n)
+function bnFlipBit(n) { return this.changeBit(n,op_xor); }
+
+// (protected) r = this + a
+function bnpAddTo(a,r) {
+  var i = 0, c = 0, m = Math.min(a.t,this.t);
+  while(i < m) {
+    c += this[i]+a[i];
+    r[i++] = c&this.DM;
+    c >>= this.DB;
+  }
+  if(a.t < this.t) {
+    c += a.s;
+    while(i < this.t) {
+      c += this[i];
+      r[i++] = c&this.DM;
+      c >>= this.DB;
+    }
+    c += this.s;
+  }
+  else {
+    c += this.s;
+    while(i < a.t) {
+      c += a[i];
+      r[i++] = c&this.DM;
+      c >>= this.DB;
+    }
+    c += a.s;
+  }
+  r.s = (c<0)?-1:0;
+  if(c > 0) r[i++] = c;
+  else if(c < -1) r[i++] = this.DV+c;
+  r.t = i;
+  r.clamp();
+}
+
+// (public) this + a
+function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; }
+
+// (public) this - a
+function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; }
+
+// (public) this * a
+function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; }
+
+// (public) this / a
+function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; }
+
+// (public) this % a
+function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; }
+
+// (public) [this/a,this%a]
+function bnDivideAndRemainder(a) {
+  var q = nbi(), r = nbi();
+  this.divRemTo(a,q,r);
+  return new Array(q,r);
+}
+
+// (protected) this *= n, this >= 0, 1 < n < DV
+function bnpDMultiply(n) {
+  this[this.t] = this.am(0,n-1,this,0,0,this.t);
+  ++this.t;
+  this.clamp();
+}
+
+// (protected) this += n << w words, this >= 0
+function bnpDAddOffset(n,w) {
+  if(n == 0) return;
+  while(this.t <= w) this[this.t++] = 0;
+  this[w] += n;
+  while(this[w] >= this.DV) {
+    this[w] -= this.DV;
+    if(++w >= this.t) this[this.t++] = 0;
+    ++this[w];
+  }
+}
+
+// A "null" reducer
+function NullExp() {}
+function nNop(x) { return x; }
+function nMulTo(x,y,r) { x.multiplyTo(y,r); }
+function nSqrTo(x,r) { x.squareTo(r); }
+
+NullExp.prototype.convert = nNop;
+NullExp.prototype.revert = nNop;
+NullExp.prototype.mulTo = nMulTo;
+NullExp.prototype.sqrTo = nSqrTo;
+
+// (public) this^e
+function bnPow(e) { return this.exp(e,new NullExp()); }
+
+// (protected) r = lower n words of "this * a", a.t <= n
+// "this" should be the larger one if appropriate.
+function bnpMultiplyLowerTo(a,n,r) {
+  var i = Math.min(this.t+a.t,n);
+  r.s = 0; // assumes a,this >= 0
+  r.t = i;
+  while(i > 0) r[--i] = 0;
+  var j;
+  for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t);
+  for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i);
+  r.clamp();
+}
+
+// (protected) r = "this * a" without lower n words, n > 0
+// "this" should be the larger one if appropriate.
+function bnpMultiplyUpperTo(a,n,r) {
+  --n;
+  var i = r.t = this.t+a.t-n;
+  r.s = 0; // assumes a,this >= 0
+  while(--i >= 0) r[i] = 0;
+  for(i = Math.max(n-this.t,0); i < a.t; ++i)
+    r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n);
+  r.clamp();
+  r.drShiftTo(1,r);
+}
+
+// Barrett modular reduction
+function Barrett(m) {
+  // setup Barrett
+  this.r2 = nbi();
+  this.q3 = nbi();
+  BigInteger.ONE.dlShiftTo(2*m.t,this.r2);
+  this.mu = this.r2.divide(m);
+  this.m = m;
+}
+
+function barrettConvert(x) {
+  if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m);
+  else if(x.compareTo(this.m) < 0) return x;
+  else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }
+}
+
+function barrettRevert(x) { return x; }
+
+// x = x mod m (HAC 14.42)
+function barrettReduce(x) {
+  x.drShiftTo(this.m.t-1,this.r2);
+  if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); }
+  this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);
+  this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);
+  while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1);
+  x.subTo(this.r2,x);
+  while(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
+}
+
+// r = x^2 mod m; x != r
+function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
+
+// r = x*y mod m; x,y != r
+function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
+
+Barrett.prototype.convert = barrettConvert;
+Barrett.prototype.revert = barrettRevert;
+Barrett.prototype.reduce = barrettReduce;
+Barrett.prototype.mulTo = barrettMulTo;
+Barrett.prototype.sqrTo = barrettSqrTo;
+
+// (public) this^e % m (HAC 14.85)
+function bnModPow(e,m) {
+  var i = e.bitLength(), k, r = nbv(1), z;
+  if(i <= 0) return r;
+  else if(i < 18) k = 1;
+  else if(i < 48) k = 3;
+  else if(i < 144) k = 4;
+  else if(i < 768) k = 5;
+  else k = 6;
+  if(i < 8)
+    z = new Classic(m);
+  else if(m.isEven())
+    z = new Barrett(m);
+  else
+    z = new Montgomery(m);
+
+  // precomputation
+  var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1;
+  g[1] = z.convert(this);
+  if(k > 1) {
+    var g2 = nbi();
+    z.sqrTo(g[1],g2);
+    while(n <= km) {
+      g[n] = nbi();
+      z.mulTo(g2,g[n-2],g[n]);
+      n += 2;
+    }
+  }
+
+  var j = e.t-1, w, is1 = true, r2 = nbi(), t;
+  i = nbits(e[j])-1;
+  while(j >= 0) {
+    if(i >= k1) w = (e[j]>>(i-k1))&km;
+    else {
+      w = (e[j]&((1<<(i+1))-1))<<(k1-i);
+      if(j > 0) w |= e[j-1]>>(this.DB+i-k1);
+    }
+
+    n = k;
+    while((w&1) == 0) { w >>= 1; --n; }
+    if((i -= n) < 0) { i += this.DB; --j; }
+    if(is1) {	// ret == 1, don't bother squaring or multiplying it
+      g[w].copyTo(r);
+      is1 = false;
+    }
+    else {
+      while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; }
+      if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; }
+      z.mulTo(r2,g[w],r);
+    }
+
+    while(j >= 0 && (e[j]&(1<<i)) == 0) {
+      z.sqrTo(r,r2); t = r; r = r2; r2 = t;
+      if(--i < 0) { i = this.DB-1; --j; }
+    }
+  }
+  return z.revert(r);
+}
+
+// (public) gcd(this,a) (HAC 14.54)
+function bnGCD(a) {
+  var x = (this.s<0)?this.negate():this.clone();
+  var y = (a.s<0)?a.negate():a.clone();
+  if(x.compareTo(y) < 0) { var t = x; x = y; y = t; }
+  var i = x.getLowestSetBit(), g = y.getLowestSetBit();
+  if(g < 0) return x;
+  if(i < g) g = i;
+  if(g > 0) {
+    x.rShiftTo(g,x);
+    y.rShiftTo(g,y);
+  }
+  while(x.signum() > 0) {
+    if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x);
+    if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y);
+    if(x.compareTo(y) >= 0) {
+      x.subTo(y,x);
+      x.rShiftTo(1,x);
+    }
+    else {
+      y.subTo(x,y);
+      y.rShiftTo(1,y);
+    }
+  }
+  if(g > 0) y.lShiftTo(g,y);
+  return y;
+}
+
+// (protected) this % n, n < 2^26
+function bnpModInt(n) {
+  if(n <= 0) return 0;
+  var d = this.DV%n, r = (this.s<0)?n-1:0;
+  if(this.t > 0)
+    if(d == 0) r = this[0]%n;
+    else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n;
+  return r;
+}
+
+// (public) 1/this % m (HAC 14.61)
+function bnModInverse(m) {
+  var ac = m.isEven();
+  if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
+  var u = m.clone(), v = this.clone();
+  var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
+  while(u.signum() != 0) {
+    while(u.isEven()) {
+      u.rShiftTo(1,u);
+      if(ac) {
+        if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); }
+        a.rShiftTo(1,a);
+      }
+      else if(!b.isEven()) b.subTo(m,b);
+      b.rShiftTo(1,b);
+    }
+    while(v.isEven()) {
+      v.rShiftTo(1,v);
+      if(ac) {
+        if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); }
+        c.rShiftTo(1,c);
+      }
+      else if(!d.isEven()) d.subTo(m,d);
+      d.rShiftTo(1,d);
+    }
+    if(u.compareTo(v) >= 0) {
+      u.subTo(v,u);
+      if(ac) a.subTo(c,a);
+      b.subTo(d,b);
+    }
+    else {
+      v.subTo(u,v);
+      if(ac) c.subTo(a,c);
+      d.subTo(b,d);
+    }
+  }
+  if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
+  if(d.compareTo(m) >= 0) return d.subtract(m);
+  if(d.signum() < 0) d.addTo(m,d); else return d;
+  if(d.signum() < 0) return d.add(m); else return d;
+}
+
+var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509];
+var lplim = (1<<26)/lowprimes[lowprimes.length-1];
+
+// (public) test primality with certainty >= 1-.5^t
+function bnIsProbablePrime(t) {
+  var i, x = this.abs();
+  if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) {
+    for(i = 0; i < lowprimes.length; ++i)
+      if(x[0] == lowprimes[i]) return true;
+    return false;
+  }
+  if(x.isEven()) return false;
+  i = 1;
+  while(i < lowprimes.length) {
+    var m = lowprimes[i], j = i+1;
+    while(j < lowprimes.length && m < lplim) m *= lowprimes[j++];
+    m = x.modInt(m);
+    while(i < j) if(m%lowprimes[i++] == 0) return false;
+  }
+  return x.millerRabin(t);
+}
+
+// (protected) true if probably prime (HAC 4.24, Miller-Rabin)
+function bnpMillerRabin(t) {
+  var n1 = this.subtract(BigInteger.ONE);
+  var k = n1.getLowestSetBit();
+  if(k <= 0) return false;
+  var r = n1.shiftRight(k);
+  t = (t+1)>>1;
+  if(t > lowprimes.length) t = lowprimes.length;
+  var a = nbi();
+  for(var i = 0; i < t; ++i) {
+    a.fromInt(lowprimes[i]);
+    var y = a.modPow(r,this);
+    if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
+      var j = 1;
+      while(j++ < k && y.compareTo(n1) != 0) {
+        y = y.modPowInt(2,this);
+        if(y.compareTo(BigInteger.ONE) == 0) return false;
+      }
+      if(y.compareTo(n1) != 0) return false;
+    }
+  }
+  return true;
+}
+
+// protected
+BigInteger.prototype.chunkSize = bnpChunkSize;
+BigInteger.prototype.toRadix = bnpToRadix;
+BigInteger.prototype.fromRadix = bnpFromRadix;
+BigInteger.prototype.fromNumber = bnpFromNumber;
+BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
+BigInteger.prototype.changeBit = bnpChangeBit;
+BigInteger.prototype.addTo = bnpAddTo;
+BigInteger.prototype.dMultiply = bnpDMultiply;
+BigInteger.prototype.dAddOffset = bnpDAddOffset;
+BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
+BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
+BigInteger.prototype.modInt = bnpModInt;
+BigInteger.prototype.millerRabin = bnpMillerRabin;
+
+// public
+BigInteger.prototype.clone = bnClone;
+BigInteger.prototype.intValue = bnIntValue;
+BigInteger.prototype.byteValue = bnByteValue;
+BigInteger.prototype.shortValue = bnShortValue;
+BigInteger.prototype.signum = bnSigNum;
+BigInteger.prototype.toByteArray = bnToByteArray;
+BigInteger.prototype.equals = bnEquals;
+BigInteger.prototype.min = bnMin;
+BigInteger.prototype.max = bnMax;
+BigInteger.prototype.and = bnAnd;
+BigInteger.prototype.or = bnOr;
+BigInteger.prototype.xor = bnXor;
+BigInteger.prototype.andNot = bnAndNot;
+BigInteger.prototype.not = bnNot;
+BigInteger.prototype.shiftLeft = bnShiftLeft;
+BigInteger.prototype.shiftRight = bnShiftRight;
+BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
+BigInteger.prototype.bitCount = bnBitCount;
+BigInteger.prototype.testBit = bnTestBit;
+BigInteger.prototype.setBit = bnSetBit;
+BigInteger.prototype.clearBit = bnClearBit;
+BigInteger.prototype.flipBit = bnFlipBit;
+BigInteger.prototype.add = bnAdd;
+BigInteger.prototype.subtract = bnSubtract;
+BigInteger.prototype.multiply = bnMultiply;
+BigInteger.prototype.divide = bnDivide;
+BigInteger.prototype.remainder = bnRemainder;
+BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
+BigInteger.prototype.modPow = bnModPow;
+BigInteger.prototype.modInverse = bnModInverse;
+BigInteger.prototype.pow = bnPow;
+BigInteger.prototype.gcd = bnGCD;
+BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
+
+// BigInteger interfaces not implemented in jsbn:
+
+// BigInteger(int signum, byte[] magnitude)
+// double doubleValue()
+// float floatValue()
+// int hashCode()
+// long longValue()
+// static BigInteger valueOf(long val)
+// Depends on jsbn.js and rng.js
+
+// Version 1.1: support utf-8 encoding in pkcs1pad2
+
+// convert a (hex) string to a bignum object
+function parseBigInt(str,r) {
+  return new BigInteger(str,r);
+}
+
+function linebrk(s,n) {
+  var ret = "";
+  var i = 0;
+  while(i + n < s.length) {
+    ret += s.substring(i,i+n) + "\n";
+    i += n;
+  }
+  return ret + s.substring(i,s.length);
+}
+
+function byte2Hex(b) {
+  if(b < 0x10)
+    return "0" + b.toString(16);
+  else
+    return b.toString(16);
+}
+
+// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
+function pkcs1pad2(s,n) {
+  if(n < s.length + 11) { // TODO: fix for utf-8
+    alert("Message too long for RSA");
+    return null;
+  }
+  var ba = new Array();
+  var i = s.length - 1;
+  while(i >= 0 && n > 0) {
+    var c = s.charCodeAt(i--);
+    if(c < 128) { // encode using utf-8
+      ba[--n] = c;
+    }
+    else if((c > 127) && (c < 2048)) {
+      ba[--n] = (c & 63) | 128;
+      ba[--n] = (c >> 6) | 192;
+    }
+    else {
+      ba[--n] = (c & 63) | 128;
+      ba[--n] = ((c >> 6) & 63) | 128;
+      ba[--n] = (c >> 12) | 224;
+    }
+  }
+  ba[--n] = 0;
+  var rng = new SecureRandom();
+  var x = new Array();
+  while(n > 2) { // random non-zero pad
+    x[0] = 0;
+    while(x[0] == 0) rng.nextBytes(x);
+    ba[--n] = x[0];
+  }
+  ba[--n] = 2;
+  ba[--n] = 0;
+  return new BigInteger(ba);
+}
+
+// "empty" RSA key constructor
+function RSAKey() {
+  this.n = null;
+  this.e = 0;
+  this.d = null;
+  this.p = null;
+  this.q = null;
+  this.dmp1 = null;
+  this.dmq1 = null;
+  this.coeff = null;
+}
+
+// Set the public key fields N and e from hex strings
+function RSASetPublic(N,E) {
+  if(N != null && E != null && N.length > 0 && E.length > 0) {
+    this.n = parseBigInt(N,16);
+    this.e = parseInt(E,16);
+  }
+  else
+    alert("Invalid RSA public key");
+}
+
+// Perform raw public operation on "x": return x^e (mod n)
+function RSADoPublic(x) {
+  return x.modPowInt(this.e, this.n);
+}
+
+// Return the PKCS#1 RSA encryption of "text" as an even-length hex string
+function RSAEncrypt(text) {
+  var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);
+  if(m == null) return null;
+  var c = this.doPublic(m);
+  if(c == null) return null;
+  var h = c.toString(16);
+  if((h.length & 1) == 0) return h; else return "0" + h;
+}
+
+// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
+//function RSAEncryptB64(text) {
+//  var h = this.encrypt(text);
+//  if(h) return hex2b64(h); else return null;
+//}
+
+// protected
+RSAKey.prototype.doPublic = RSADoPublic;
+
+// public
+RSAKey.prototype.setPublic = RSASetPublic;
+RSAKey.prototype.encrypt = RSAEncrypt;
+//RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
+// Depends on rsa.js and jsbn2.js
+
+// Version 1.1: support utf-8 decoding in pkcs1unpad2
+
+// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
+function pkcs1unpad2(d,n) {
+  var b = d.toByteArray();
+  var i = 0;
+  while(i < b.length && b[i] == 0) ++i;
+  if(b.length-i != n-1 || b[i] != 2)
+    return null;
+  ++i;
+  while(b[i] != 0)
+    if(++i >= b.length) return null;
+  var ret = "";
+  while(++i < b.length) {
+    var c = b[i] & 255;
+    if(c < 128) { // utf-8 decode
+      ret += String.fromCharCode(c);
+    }
+    else if((c > 191) && (c < 224)) {
+      ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63));
+      ++i;
+    }
+    else {
+      ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63));
+      i += 2;
+    }
+  }
+  return ret;
+}
+
+// Set the private key fields N, e, and d from hex strings
+function RSASetPrivate(N,E,D) {
+  if(N != null && E != null && N.length > 0 && E.length > 0) {
+    this.n = parseBigInt(N,16);
+    this.e = parseInt(E,16);
+    this.d = parseBigInt(D,16);
+  }
+  else
+    alert("Invalid RSA private key");
+}
+
+// Set the private key fields N, e, d and CRT params from hex strings
+function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) {
+  if(N != null && E != null && N.length > 0 && E.length > 0) {
+    this.n = parseBigInt(N,16);
+    this.e = parseInt(E,16);
+    this.d = parseBigInt(D,16);
+    this.p = parseBigInt(P,16);
+    this.q = parseBigInt(Q,16);
+    this.dmp1 = parseBigInt(DP,16);
+    this.dmq1 = parseBigInt(DQ,16);
+    this.coeff = parseBigInt(C,16);
+  }
+  else
+    alert("Invalid RSA private key");
+}
+
+// Generate a new random private key B bits long, using public expt E
+function RSAGenerate(B,E) {
+  var rng = new SecureRandom();
+  var qs = B>>1;
+  this.e = parseInt(E,16);
+  var ee = new BigInteger(E,16);
+  for(;;) {
+    for(;;) {
+      this.p = new BigInteger(B-qs,1,rng);
+      if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break;
+    }
+    for(;;) {
+      this.q = new BigInteger(qs,1,rng);
+      if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break;
+    }
+    if(this.p.compareTo(this.q) <= 0) {
+      var t = this.p;
+      this.p = this.q;
+      this.q = t;
+    }
+    var p1 = this.p.subtract(BigInteger.ONE);
+    var q1 = this.q.subtract(BigInteger.ONE);
+    var phi = p1.multiply(q1);
+    if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
+      this.n = this.p.multiply(this.q);
+      this.d = ee.modInverse(phi);
+      this.dmp1 = this.d.mod(p1);
+      this.dmq1 = this.d.mod(q1);
+      this.coeff = this.q.modInverse(this.p);
+      break;
+    }
+  }
+}
+
+// Returns an ASN1-encoded RSAPrivateKey (PKCS1) data structure
+function RSAPrivateKeySerializeASN1() {
+  function concatBigInteger(bytes, bigInt) {
+    var bigIntBytes = bigInt.toByteArray();
+    bytes.push(0x02); // INTEGER
+    bytes.push(bigIntBytes.length); // #BYTES
+    //  bytes.push(00); // this appears in some encodings, and I don't understand why.  leading zeros?
+    return bytes.concat(bigIntBytes);
+  }
+  var bytes=[];
+  // sequence
+  bytes.push(0x30);
+  bytes.push(0x82);//XX breaks on 1024 bit keys?
+  bytes.push(0x01);
+  bytes.push(0x00);// replace with actual length (-256)...
+  // version (integer 0)
+  bytes.push(0x02); // INTEGER
+  bytes.push(0x01); // #BYTES
+  bytes.push(0x00); // value
+  // modulus (n)
+  bytes = concatBigInteger(bytes, this.n);
+  
+  // publicExponent (e)
+  bytes = concatBigInteger(bytes, new BigInteger(""+this.e, 10));
+  
+  // privateExponent (d)
+  bytes = concatBigInteger(bytes, this.d);
+
+  // prime1 (p)
+  bytes = concatBigInteger(bytes, this.p);
+
+  // prime2 (q)
+  bytes = concatBigInteger(bytes, this.q);
+
+  // exponent1 (d mod p-1 -> dmp1)
+  bytes = concatBigInteger(bytes, this.dmp1);
+
+  // exponent2 (q mod p-1 -> dmq1)
+  bytes = concatBigInteger(bytes, this.dmq1);
+
+  // coefficient ((inverse of q) mod p -> coeff)
+  bytes = concatBigInteger(bytes, this.coeff);
+
+  var actualLength = bytes.length - 4;
+  var lenBytes = new BigInteger("" + actualLength, 10).toByteArray();
+  bytes[2] = lenBytes[0];
+  bytes[3] = lenBytes[1];
+    
+  var buffer = "";
+  for (var i=0;i<bytes.length;i++) { 
+    buffer += int2char((bytes[i] & 0xf0) >> 4);
+    buffer += int2char(bytes[i] & 0x0f);
+  }
+  buffer = hex2b64(buffer);
+  var newlineBuffer = "";
+  for (var i=0;i<buffer.length;i++) { 
+    if (i>0 && (i % 64) == 0) newlineBuffer += "\n";
+    newlineBuffer += buffer[i];
+  }
+  return "-----BEGIN RSA PRIVATE KEY-----\n" + newlineBuffer + "\n-----END RSA PRIVATE KEY-----\n";
+}
+
+
+// Returns an ASN1-encoded X509 Public Key data structure
+function RSAPublicKeySerializeASN1() {
+  
+  function encodeSequence(contentObjects) {
+    var len = 0;
+    for (var i=0;i<contentObjects.length;i++) {
+      len += contentObjects[i].length;
+    }
+    var out = [];
+    out.push(0x30); // SEQUENCE, constructed
+    if (len < 128) {
+      out.push(len);
+    } else {
+      var lenBytes = new BigInteger("" + len, 10).toByteArray();
+      out.push(0x80 | lenBytes.length);
+      for (var i=0;i<lenBytes.length;i++) out.push(lenBytes[i]);
+    }
+    for (var i=0;i<contentObjects.length;i++) {
+      out = out.concat(contentObjects[i]);
+    }
+    return out;
+  }
+
+  function encodeBigInteger(bigInt) {
+    var bigIntBytes = bigInt.toByteArray();
+    var bytes= [];
+    bytes.push(0x02); // INTEGER
+    bytes.push(bigIntBytes.length); // #BYTES
+    return bytes.concat(bigIntBytes);
+  }
+
+  function encodeBitString(bits) {
+    var bytes=[];
+    bytes.push(0x03); // BIT STRING
+    bytes.push(bits.length+1);  // #Bytes
+    bytes.push(0);// remainder
+    return bytes.concat(bits);
+  }
+
+  // construct exponent-modulus sequence:
+  var neSequence = encodeSequence(
+    [
+      encodeBigInteger(this.n),
+      encodeBigInteger(new BigInteger("" + this.e, 10))
+    ]
+  );
+  var neBitString = encodeBitString(neSequence);
+
+  // construct :rsaEncryption sequence:
+  var rsaEncSequence = encodeSequence(
+    [
+      [0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01],
+      [0x05, 0x00],// NULL
+    ]
+  );
+
+  // construct outer sequence
+  var bytes = encodeSequence([rsaEncSequence, neBitString]);
+  
+  var buffer = "";
+  for (var i=0;i<bytes.length;i++) { 
+    buffer += int2char((bytes[i] & 0xf0) >> 4);
+    buffer += int2char(bytes[i] & 0x0f);
+  }
+  buffer = hex2b64(buffer);
+  var newlineBuffer = "";
+  for (var i=0;i<buffer.length;i++) { 
+    if (i>0 && (i % 64) == 0) newlineBuffer += "\n";
+    newlineBuffer += buffer[i];
+  }
+  return "-----BEGIN PUBLIC KEY-----\n" + newlineBuffer + "\n-----END PUBLIC KEY-----\n";
+}
+
+
+
+
+// Perform raw private operation on "x": return x^d (mod n)
+function RSADoPrivate(x) {
+  if(this.p == null || this.q == null)
+    return x.modPow(this.d, this.n);
+
+  // TODO: re-calculate any missing CRT params
+  var xp = x.mod(this.p).modPow(this.dmp1, this.p);
+  var xq = x.mod(this.q).modPow(this.dmq1, this.q);
+
+  while(xp.compareTo(xq) < 0)
+    xp = xp.add(this.p);
+  return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);
+}
+
+// Return the PKCS#1 RSA decryption of "ctext".
+// "ctext" is an even-length hex string and the output is a plain string.
+function RSADecrypt(ctext) {
+  var c = parseBigInt(ctext, 16);
+  var m = this.doPrivate(c);
+  if(m == null) return null;
+  return pkcs1unpad2(m, (this.n.bitLength()+7)>>3);
+}
+
+// Return the PKCS#1 RSA decryption of "ctext".
+// "ctext" is a Base64-encoded string and the output is a plain string.
+//function RSAB64Decrypt(ctext) {
+//  var h = b64tohex(ctext);
+//  if(h) return this.decrypt(h); else return null;
+//}
+
+// protected
+RSAKey.prototype.doPrivate = RSADoPrivate;
+
+// public
+RSAKey.prototype.setPrivate = RSASetPrivate;
+RSAKey.prototype.setPrivateEx = RSASetPrivateEx;
+RSAKey.prototype.generate = RSAGenerate;
+RSAKey.prototype.decrypt = RSADecrypt;
+RSAKey.prototype.serializePrivateASN1 = RSAPrivateKeySerializeASN1;
+RSAKey.prototype.serializePublicASN1 = RSAPublicKeySerializeASN1;
+
+//RSAKey.prototype.b64_decrypt = RSAB64Decrypt;
+//
+// asn1hex.js - Hexadecimal represented ASN.1 string library
+//
+//
+// version: 1.0 (2010-Jun-03)
+//
+// Copyright (c) 2010 Kenji Urushima (kenji.urushima@gmail.com)
+//
+// This software is licensed under the terms of the MIT License.
+// http://www.opensource.org/licenses/mit-license.php
+//
+// The above copyright and license notice shall be 
+// included in all copies or substantial portions of the Software.
+// 
+//
+// Depends on:
+//
+
+// MEMO:
+//   f('3082025b02...', 2) ... 82025b ... 3bytes
+//   f('020100', 2) ... 01 ... 1byte
+//   f('0203001...', 2) ... 03 ... 1byte
+//   f('02818003...', 2) ... 8180 ... 2bytes
+//   f('3080....0000', 2) ... 80 ... -1
+//
+//   Requirements:
+//   - ASN.1 type octet length MUST be 1. 
+//     (i.e. ASN.1 primitives like SET, SEQUENCE, INTEGER, OCTETSTRING ...)
+//   - 
+function _asnhex_getByteLengthOfL_AtObj(s, pos) {
+
+  // read 3nd nybble of entry (offset 2-3) if it's not 8, return 1
+  if (s.substring(pos + 2, pos + 3) != '8') return 1;
+  
+  // if it is 8, pull nybble 4 (offset 3-4) for length
+  var i = parseInt(s.substring(pos + 3, pos + 4));
+
+  // if length 0, return indefinite
+  if (i == 0) return -1; 		// length octet '80' indefinite length
+
+  // if between 0 and 10, return 1 more than that
+  if (0 < i && i < 10) return i + 1;	// including '8?' octet;
+
+  // incorrect
+  return -2;				// malformed format
+}
+
+function _asnhex_getHexOfL_AtObj(s, pos) {
+  var len = _asnhex_getByteLengthOfL_AtObj(s, pos);
+  if (len < 1) return '';
+  return s.substring(pos + 2, pos + 2 + len * 2);
+}
+
+//
+//   getting ASN.1 length value at the position 'idx' of
+//   hexa decimal string 's'.
+//
+//   f('3082025b02...', 0) ... 82025b ... ???
+//   f('020100', 0) ... 01 ... 1
+//   f('0203001...', 0) ... 03 ... 3
+//   f('02818003...', 0) ... 8180 ... 128
+function _asnhex_getIntOfL_AtObj(s, pos) {
+
+  var hLength = _asnhex_getHexOfL_AtObj(s, pos);
+  if (hLength == '') return -1;
+  var bi;
+  if (parseInt(hLength.substring(0, 1)) < 8) {
+     bi = parseBigInt(hLength, 16);
+  } else {
+     bi = parseBigInt(hLength.substring(2), 16);
+  }
+  return bi.intValue();
+}
+
+//
+// get ASN.1 value starting string position 
+// for ASN.1 object refered by index 'idx'.
+//
+function _asnhex_getStartPosOfV_AtObj(s, pos) {
+
+  // Get the byte length of this object header
+  var l_len = _asnhex_getByteLengthOfL_AtObj(s, pos);
+
+  if (l_len < 0) return l_len;
+  
+  // Skip over the object header
+  return pos + (l_len + 1) * 2;
+}
+
+function _asnhex_getHexOfV_AtObj(s, pos) {
+  var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos);
+  var len = _asnhex_getIntOfL_AtObj(s, pos);
+
+  return s.substring(pos1, pos1 + len * 2);
+}
+
+function _asnhex_getPosOfNextSibling_AtObj(s, pos) {
+  var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos);
+  var len = _asnhex_getIntOfL_AtObj(s, pos);
+  return pos1 + len * 2;
+}
+
+function _asnhex_getPosArrayOfChildren_AtObj(h, pos) {
+  var a = new Array();
+  var p0 = _asnhex_getStartPosOfV_AtObj(h, pos);
+  a.push(p0);
+
+  var len = _asnhex_getIntOfL_AtObj(h, pos);
+  var p = p0;
+  var k = 0;
+  while (1) {
+    var pNext = _asnhex_getPosOfNextSibling_AtObj(h, p);
+    if (pNext == null || (pNext - p0  >= (len * 2))) break;
+    if (k >= 200) break;
+
+    a.push(pNext);
+    p = pNext;
+
+    k++;
+  }
+
+  return a;
+}
+//
+// rsa-pem.js - adding function for reading/writing PKCS#1 PEM private key
+//              to RSAKey class.
+//
+// version: 1.0 (2010-Jun-03)
+//
+// Copyright (c) 2010 Kenji Urushima (kenji.urushima@gmail.com)
+//
+// This software is licensed under the terms of the MIT License.
+// http://www.opensource.org/licenses/mit-license.php
+//
+// The above copyright and license notice shall be 
+// included in all copies or substantial portions of the Software.
+// 
+//
+// Depends on:
+//
+//
+//
+// _RSApem_pemToBase64(sPEM)
+//
+//   removing PEM header, PEM footer and space characters including
+//   new lines from PEM formatted RSA private key string.
+//
+function _rsapem_pemToBase64(sPEMPrivateKey) {
+  var s = sPEMPrivateKey;
+  s = s.replace("-----BEGIN RSA PRIVATE KEY-----", "");
+  s = s.replace("-----END RSA PRIVATE KEY-----", "");
+  s = s.replace(/[ \n]+/g, "");
+  return s;
+}
+
+function _rsapubpem_pemToBase64(sPEMPublicKey) {
+  if (sPEMPublicKey.indexOf("-----BEGIN PUBLIC KEY-----") != 0) {
+    throw "Malformed input to readPublicKeyFromPEMString: input does not start with '-----BEGIN PUBLIC KEY-----'";
+  }
+  var s = sPEMPublicKey;
+  s = s.replace("-----BEGIN PUBLIC KEY-----", "");
+  s = s.replace("-----END PUBLIC KEY-----", "");
+  s = s.replace(/[ \n]+/g, "");
+  return s;
+}
+
+function _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey) {
+  var a = new Array();
+  var v1 = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0);
+  var n1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, v1);
+  var e1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, n1);
+  var d1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, e1);
+  var p1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, d1);
+  var q1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, p1);
+  var dp1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, q1);
+  var dq1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, dp1);
+  var co1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, dq1);
+  a.push(v1, n1, e1, d1, p1, q1, dp1, dq1, co1);
+  return a;
+}
+
+function _rsapem_getHexValueArrayOfChildrenFromHex(hPrivateKey) {
+  var posArray = _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey);
+  var v =  _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]);
+  var n =  _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]);
+  var e =  _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[2]);
+  var d =  _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[3]);
+  var p =  _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[4]);
+  var q =  _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[5]);
+  var dp = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[6]);
+  var dq = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[7]);
+  var co = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[8]);
+  var a = new Array();
+  a.push(v, n, e, d, p, q, dp, dq, co);
+  return a;
+}
+
+function _rsapem_readPrivateKeyFromPEMString(keyPEM) {
+  var keyB64 = _rsapem_pemToBase64(keyPEM);
+  var keyHex = b64tohex(keyB64) // depends base64.js
+  var a = _rsapem_getHexValueArrayOfChildrenFromHex(keyHex);
+  this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]);
+}
+
+
+
+function _rsapem_readPublicKeyFromPEMString(keyPEM) {
+  var keyB64 = _rsapubpem_pemToBase64(keyPEM);
+  var keyHex = b64tohex(keyB64) // depends base64.js
+
+  /* expected structure is:
+      0:d=0  hl=4 l= 290 cons: SEQUENCE          
+    4:d=1  hl=2 l=  13 cons: SEQUENCE          
+    6:d=2  hl=2 l=   9 prim: OBJECT            :rsaEncryption
+   17:d=2  hl=2 l=   0 prim: NULL              
+   19:d=1  hl=4 l= 271 prim: BIT STRING        
+  */
+  var offsets = _asnhex_getPosArrayOfChildren_AtObj(keyHex, 0);
+  var type = _asnhex_getHexOfV_AtObj(keyHex, offsets[0]);
+  var key = _asnhex_getHexOfV_AtObj(keyHex, offsets[1]);
+
+  // key is a BITSTRING; first octet is number of bits by which
+  // the length of the bitstring is less than the next multiple of eight.
+  // for now we assume it is zero and ignore it.
+  key = key.substring(2, key.length);
+  var keyOffsets = _asnhex_getPosArrayOfChildren_AtObj(key, 0);
+  var n = _asnhex_getHexOfV_AtObj(key, keyOffsets[0]);
+  var e = _asnhex_getHexOfV_AtObj(key, keyOffsets[1]);
+  this.setPublic(n, e);
+}
+
+RSAKey.prototype.readPrivateKeyFromPEMString = _rsapem_readPrivateKeyFromPEMString;
+RSAKey.prototype.readPublicKeyFromPEMString = _rsapem_readPublicKeyFromPEMString;
+//
+// rsa-sign.js - adding signing functions to RSAKey class.
+//
+//
+// version: 1.0 (2010-Jun-03)
+//
+// Copyright (c) 2010 Kenji Urushima (kenji.urushima@gmail.com)
+//
+// This software is licensed under the terms of the MIT License.
+// http://www.opensource.org/licenses/mit-license.php
+//
+// The above copyright and license notice shall be 
+// included in all copies or substantial portions of the Software.
+
+//
+// Depends on:
+//   function sha1.hex(s) of sha1.js
+//   jsbn.js
+//   jsbn2.js
+//   rsa.js
+//   rsa2.js
+//
+
+// keysize / pmstrlen
+//  512 /  128
+// 1024 /  256
+// 2048 /  512
+// 4096 / 1024
+
+// As for _RSASGIN_DIHEAD values for each hash algorithm, see PKCS#1 v2.1 spec (p38).
+var _RSASIGN_DIHEAD = [];
+_RSASIGN_DIHEAD['sha1'] = "3021300906052b0e03021a05000414";
+_RSASIGN_DIHEAD['sha256'] = "3031300d060960864801650304020105000420";
+//_RSASIGN_DIHEAD['md2'] = "3020300c06082a864886f70d020205000410";
+//_RSASIGN_DIHEAD['md5'] = "3020300c06082a864886f70d020505000410";
+//_RSASIGN_DIHEAD['sha384'] = "3041300d060960864801650304020205000430";
+//_RSASIGN_DIHEAD['sha512'] = "3051300d060960864801650304020305000440";
+var _RSASIGN_HASHHEXFUNC = [];
+//_RSASIGN_HASHHEXFUNC['sha1'] = sha1.hex;
+_RSASIGN_HASHHEXFUNC['sha256'] = function(i) { return sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash(i)); }
+
+// ========================================================================
+// Signature Generation
+// ========================================================================
+
+function _rsasign_getHexPaddedDigestInfoForString(s, keySize, hashAlg) {
+  var pmStrLen = keySize / 4;
+  var hashFunc = _RSASIGN_HASHHEXFUNC[hashAlg];
+  var sHashHex = hashFunc(s);
+
+  var sHead = "0001";
+  var sTail = "00" + _RSASIGN_DIHEAD[hashAlg] + sHashHex;
+  var sMid = "";
+  var fLen = pmStrLen - sHead.length - sTail.length;
+  for (var i = 0; i < fLen; i += 2) {
+    sMid += "ff";
+  }
+  var sPaddedMessageHex = sHead + sMid + sTail;
+  
+  return sPaddedMessageHex;
+}
+
+function _rsasign_signString(s, hashAlg) {
+  var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), hashAlg);
+  var hexLength = hPM.length;
+  var biPaddedMessage = parseBigInt(hPM, 16);
+  var biSign = this.doPrivate(biPaddedMessage);
+  var hexSign = biSign.toString(16);
+  while (hexSign.length < hexLength) hexSign = '0' + hexSign;
+  return hexSign;
+}
+
+function _rsasign_signStringWithSHA1(s) {
+  var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), 'sha1');  
+  var biPaddedMessage = parseBigInt(hPM, 16);
+  var biSign = this.doPrivate(biPaddedMessage);
+  var hexSign = biSign.toString(16);
+  return hexSign;
+}
+
+function _rsasign_signStringWithSHA256(s) {
+  var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), 'sha256');
+  var biPaddedMessage = parseBigInt(hPM, 16);
+  var biSign = this.doPrivate(biPaddedMessage);
+  var hexSign = biSign.toString(16);
+  return hexSign;
+}
+
+// ========================================================================
+// Signature Verification
+// ========================================================================
+
+function _rsasign_getDecryptSignatureBI(biSig, hN, hE) {
+  var rsa = new RSAKey();
+  rsa.setPublic(hN, hE);
+  var biDecryptedSig = rsa.doPublic(biSig);
+  return biDecryptedSig;
+}
+
+function _rsasign_getHexDigestInfoFromSig(biSig, hN, hE) {
+  var biDecryptedSig = _rsasign_getDecryptSignatureBI(biSig, hN, hE);
+  var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
+  return hDigestInfo;
+}
+
+function _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo) {
+  for (var algName in _RSASIGN_DIHEAD) {
+    var head = _RSASIGN_DIHEAD[algName];
+    var len = head.length;
+    if (hDigestInfo.substring(0, len) == head) {
+      var a = [algName, hDigestInfo.substring(len)];
+      return a;
+    }
+  }
+  return [];
+}
+
+function _rsasign_verifySignatureWithArgs(sMsg, biSig, hN, hE) {
+  var hDigestInfo = _rsasign_getHexDigestInfoFromSig(biSig, hN, hE);
+  var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
+  if (digestInfoAry.length == 0) return false;
+  var algName = digestInfoAry[0];
+  var diHashValue = digestInfoAry[1];
+  var ff = _RSASIGN_HASHHEXFUNC[algName];
+  var msgHashValue = ff(sMsg);
+  return (diHashValue == msgHashValue);
+}
+
+function _rsasign_verifyHexSignatureForMessage(hSig, sMsg) {
+  var biSig = parseBigInt(hSig, 16);
+  var result = _rsasign_verifySignatureWithArgs(sMsg, biSig,
+						this.n.toString(16),
+						this.e.toString(16));
+  return result;
+}
+
+function _rsasign_verifyString(sMsg, hSig) {
+  hSig = hSig.replace(/[ \n]+/g, "");
+  var biSig = parseBigInt(hSig, 16);
+  var biDecryptedSig = this.doPublic(biSig);
+  var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
+  var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
+  
+  if (digestInfoAry.length == 0) return false;
+  var algName = digestInfoAry[0];
+  var diHashValue = digestInfoAry[1];
+  var ff = _RSASIGN_HASHHEXFUNC[algName];
+  var msgHashValue = ff(sMsg);
+  return (diHashValue == msgHashValue);
+}
+
+RSAKey.prototype.signString = _rsasign_signString;
+RSAKey.prototype.signStringWithSHA1 = _rsasign_signStringWithSHA1;
+RSAKey.prototype.signStringWithSHA256 = _rsasign_signStringWithSHA256;
+
+RSAKey.prototype.verifyString = _rsasign_verifyString;
+RSAKey.prototype.verifyHexSignatureForMessage = _rsasign_verifyHexSignatureForMessage;
+
+// 
+// x509.js - X509 class to read subject public key from certificate.
+//
+// version: 1.0 (2010-Jun-03)
+//
+// Copyright (c) 2010 Kenji Urushima (kenji.urushima@gmail.com)
+//
+// This software is licensed under the terms of the MIT License.
+// http://www.opensource.org/licenses/mit-license.php
+//
+// The above copyright and license notice shall be 
+// included in all copies or substantial portions of the Software.
+// 
+
+// Depends:
+//   base64.js
+//   rsa.js
+
+function _x509_pemToBase64(sCertPEM) {
+  var s = sCertPEM;
+  s = s.replace("-----BEGIN CERTIFICATE-----", "");
+  s = s.replace("-----END CERTIFICATE-----", "");
+  s = s.replace(/[ \n]+/g, "");
+  return s;
+}
+
+function _x509_pemToHex(sCertPEM) {
+  var b64Cert = _x509_pemToBase64(sCertPEM);
+  var hCert = b64tohex(b64Cert);
+  return hCert;
+}
+
+function _x509_getHexTbsCertificateFromCert(hCert) {
+  var pTbsCert = _asnhex_getStartPosOfV_AtObj(hCert, 0);
+  return pTbsCert;
+}
+
+// NOTE: privateKeyUsagePeriod field of X509v2 not supported.
+// NOTE: v1 and v3 supported
+function _x509_getSubjectPublicKeyInfoPosFromCertHex(hCert) {
+  var pTbsCert = _asnhex_getStartPosOfV_AtObj(hCert, 0);
+  var a = _asnhex_getPosArrayOfChildren_AtObj(hCert, pTbsCert); 
+  if (a.length < 1) return -1;
+  if (hCert.substring(a[0], a[0] + 10) == "a003020102") { // v3
+    if (a.length < 6) return -1;
+    return a[6];
+  } else {
+    if (a.length < 5) return -1;
+    return a[5];
+  }
+}
+
+// NOTE: Without BITSTRING encapsulation.
+function _x509_getSubjectPublicKeyPosFromCertHex(hCert) {
+  var pInfo = _x509_getSubjectPublicKeyInfoPosFromCertHex(hCert);
+  if (pInfo == -1) return -1;    
+  var a = _asnhex_getPosArrayOfChildren_AtObj(hCert, pInfo); 
+  if (a.length != 2) return -1;
+  var pBitString = a[1];
+  if (hCert.substring(pBitString, pBitString + 2) != '03') return -1;
+  var pBitStringV = _asnhex_getStartPosOfV_AtObj(hCert, pBitString);
+
+  if (hCert.substring(pBitStringV, pBitStringV + 2) != '00') return -1;
+  return pBitStringV + 2;
+}
+
+function _x509_getPublicKeyHexArrayFromCertHex(hCert) {
+  var p = _x509_getSubjectPublicKeyPosFromCertHex(hCert);
+  var a = _asnhex_getPosArrayOfChildren_AtObj(hCert, p); 
+  if (a.length != 2) return [];
+  var hN = _asnhex_getHexOfV_AtObj(hCert, a[0]);
+  var hE = _asnhex_getHexOfV_AtObj(hCert, a[1]);
+  if (hN != null && hE != null) {
+    return [hN, hE];
+  } else {
+    return [];
+  }
+}
+
+function _x509_getPublicKeyHexArrayFromCertPEM(sCertPEM) {
+  var hCert = _x509_pemToHex(sCertPEM);
+  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
+  return a;
+}
+
+function _x509_readCertPEM(sCertPEM) {
+  var hCert = _x509_pemToHex(sCertPEM);
+  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
+  var rsa = new RSAKey();
+  rsa.setPublic(a[0], a[1]);
+  this.subjectPublicKeyRSA = rsa;
+  this.subjectPublicKeyRSA_hN = a[0];
+  this.subjectPublicKeyRSA_hE = a[1];
+}
+
+function _x509_readCertPEMWithoutRSAInit(sCertPEM) {
+  var hCert = _x509_pemToHex(sCertPEM);
+  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
+  this.subjectPublicKeyRSA.setPublic(a[0], a[1]);
+  this.subjectPublicKeyRSA_hN = a[0];
+  this.subjectPublicKeyRSA_hE = a[1];
+}
+
+function X509() {
+  this.subjectPublicKeyRSA = null;
+  this.subjectPublicKeyRSA_hN = null;
+  this.subjectPublicKeyRSA_hE = null;
+}
+
+X509.prototype.readCertPEM = _x509_readCertPEM;
+X509.prototype.readCertPEMWithoutRSAInit = _x509_readCertPEMWithoutRSAInit;
+
+// prng4.js - uses Arcfour as a PRNG
+
+function Arcfour() {
+  this.i = 0;
+  this.j = 0;
+  this.S = new Array();
+}
+
+// Initialize arcfour context from key, an array of ints, each from [0..255]
+function ARC4init(key) {
+  var i, j, t;
+  for(i = 0; i < 256; ++i)
+    this.S[i] = i;
+  j = 0;
+  for(i = 0; i < 256; ++i) {
+    j = (j + this.S[i] + key[i % key.length]) & 255;
+    t = this.S[i];
+    this.S[i] = this.S[j];
+    this.S[j] = t;
+  }
+  this.i = 0;
+  this.j = 0;
+}
+
+function ARC4next() {
+  var t;
+  this.i = (this.i + 1) & 255;
+  this.j = (this.j + this.S[this.i]) & 255;
+  t = this.S[this.i];
+  this.S[this.i] = this.S[this.j];
+  this.S[this.j] = t;
+  return this.S[(t + this.S[this.i]) & 255];
+}
+
+Arcfour.prototype.init = ARC4init;
+Arcfour.prototype.next = ARC4next;
+
+// Plug in your RNG constructor here
+function prng_newstate() {
+  return new Arcfour();
+}
+
+// Pool size must be a multiple of 4 and greater than 32.
+// An array of bytes the size of the pool will be passed to init()
+var rng_psize = 256;
+
+
+// Random number generator - requires a PRNG backend, e.g. prng4.js
+
+// For best results, put code like
+// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
+// in your main HTML document.
+
+var rng_state;
+var rng_pool;
+var rng_pptr;
+
+// Mix in a 32-bit integer into the pool
+function rng_seed_int(x) {
+  rng_pool[rng_pptr++] ^= x & 255;
+  rng_pool[rng_pptr++] ^= (x >> 8) & 255;
+  rng_pool[rng_pptr++] ^= (x >> 16) & 255;
+  rng_pool[rng_pptr++] ^= (x >> 24) & 255;
+  if(rng_pptr >= rng_psize) rng_pptr -= rng_psize;
+}
+
+// Mix in the current time (w/milliseconds) into the pool
+function rng_seed_time() {
+  rng_seed_int(new Date().getTime());
+}
+
+// Initialize the pool with junk if needed.
+if(rng_pool == null) {
+  rng_pool = new Array();
+  rng_pptr = 0;
+  var t;
+  if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) {
+    // Extract entropy (256 bits) from NS4 RNG if available
+    var z = window.crypto.random(32);
+    for(t = 0; t < z.length; ++t)
+      rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;
+  }  
+  while(rng_pptr < rng_psize) {  // extract some randomness from Math.random()
+    t = Math.floor(65536 * Math.random());
+    rng_pool[rng_pptr++] = t >>> 8;
+    rng_pool[rng_pptr++] = t & 255;
+  }
+  rng_pptr = 0;
+  rng_seed_time();
+  //rng_seed_int(window.screenX);
+  //rng_seed_int(window.screenY);
+}
+
+function rng_get_byte() {
+  if(rng_state == null) {
+    rng_seed_time();
+    rng_state = prng_newstate();
+    rng_state.init(rng_pool);
+    for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)
+      rng_pool[rng_pptr] = 0;
+    rng_pptr = 0;
+    //rng_pool = null;
+  }
+  // TODO: allow reseeding after first request
+  return rng_state.next();
+}
+
+function rng_get_bytes(ba) {
+  var i;
+  for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();
+}
+
+function SecureRandom() {}
+
+SecureRandom.prototype.nextBytes = rng_get_bytes;
+
+
+var jwt = {};
+
+var JWTInternals = (function() {
+
+  // convert a base64url string to hex
+  var b64urlmap="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+  function b64urltohex(s) {
+    var ret = ""
+    var i;
+    var k = 0; // b64 state, 0-3
+    var slop;
+    for(i = 0; i < s.length; ++i) {
+      var v = b64urlmap.indexOf(s.charAt(i));
+      if(v < 0) continue;
+      if(k == 0) {
+        ret += int2char(v >> 2);
+        slop = v & 3;
+        k = 1;
+      }
+      else if(k == 1) {
+        ret += int2char((slop << 2) | (v >> 4));
+        slop = v & 0xf;
+        k = 2;
+      }
+      else if(k == 2) {
+        ret += int2char(slop);
+        ret += int2char(v >> 2);
+        slop = v & 3;
+        k = 3;
+      }
+      else {
+        ret += int2char((slop << 2) | (v >> 4));
+        ret += int2char(v & 0xf);
+        k = 0;
+      }
+    }
+    if(k == 1)
+      ret += int2char(slop << 2);
+    return ret;
+  }
+
+  function hex2b64urlencode(arg) {
+    return hex2b64(arg).split('=')[0]
+      .replace(/\+/g, '-')  // 62nd char of encoding
+      .replace(/\//g, '_'); // 63rd char of encoding
+  }
+
+  function base64urlencode(arg)
+  {
+    var s = window.btoa(arg); // Standard base64 encoder
+    s = s.split('=')[0]; // Remove any trailing '='s
+    s = s.replace(/\+/g, '-'); // 62nd char of encoding
+    s = s.replace(/\//g, '_'); // 63rd char of encoding
+    // TODO optimize this; we can do much better
+    return s;
+  }
+
+  function base64urldecode(arg)
+  {
+    var s = arg;
+    s = s.replace(/-/g, '+'); // 62nd char of encoding
+    s = s.replace(/_/g, '/'); // 63rd char of encoding
+    switch (s.length % 4) // Pad with trailing '='s
+    {
+      case 0: break; // No pad chars in this case
+      case 2: s += "=="; break; // Two pad chars
+      case 3: s += "="; break; // One pad char
+      default: throw new InputException("Illegal base64url string!");
+    }
+    return window.atob(s); // Standard base64 decoder
+  }
+
+  function NoSuchAlgorithmException(message) {
+    this.message = message;
+    this.toString = function() { return "No such algorithm: "+this.message; };
+  }
+  function NotImplementedException(message) {
+    this.message = message;
+    this.toString = function() { return "Not implemented: "+this.message; };
+  }
+  function MalformedWebTokenException(message) {
+    this.message = message;
+    this.toString = function() { return "Malformed JSON web token: "+this.message; };
+  }
+  function InputException(message) {
+    this.message = message;
+    this.toString = function() { return "Malformed input: "+this.message; };
+  }
+
+  function HMACAlgorithm(hash, key)
+  {
+    if (hash == "sha256") {
+      this.hash = sjcl.hash.sha256;
+    } else {
+      throw new NoSuchAlgorithmException("HMAC does not support hash " + hash);
+    }
+    this.key = sjcl.codec.utf8String.toBits(key);
+  }
+
+  HMACAlgorithm.prototype = 
+  {
+    update: function _update(data)
+    {
+      this.data = data;
+    },
+    
+    finalize: function _finalize()
+    {
+    },
+    
+    sign: function _sign()
+    {
+      var hmac = new sjcl.misc.hmac(this.key, this.hash);
+      var result = hmac.encrypt(this.data);
+      return base64urlencode(window.atob(sjcl.codec.base64.fromBits(result)));
+    },
+    
+    verify: function _verify(sig)
+    {
+      var hmac = new sjcl.misc.hmac(this.key, this.hash);
+      var result = hmac.encrypt(this.data);
+      
+      return base64urlencode(window.atob(sjcl.codec.base64.fromBits(result))) == sig; 
+    }
+  }
+
+  function RSASHAAlgorithm(hash, keyPEM)
+  {
+    if (hash == "sha1") {
+      this.hash = "sha1";
+    } else if (hash == "sha256") {
+      this.hash = "sha256";
+    } else {
+      throw new NoSuchAlgorithmException("JWT algorithm: " + hash);  
+    }
+    this.keyPEM = keyPEM;
+  }
+  RSASHAAlgorithm.prototype =
+  {
+    update: function _update(data)
+    {
+      this.data = data;
+    },
+    finalize: function _finalize()
+    {
+    
+    },
+    sign: function _sign()
+    {
+      var rsa = new RSAKey();
+      rsa.readPrivateKeyFromPEMString(this.keyPEM);
+      var hSig = rsa.signString(this.data, this.hash);
+      return hex2b64urlencode(hSig);
+    },
+    verify: function _verify(sig)
+    {
+      var result = this.keyPEM.verifyString(this.data, b64urltohex(sig));
+      return result;
+    }
+  }
+
+  function WebToken(objectStr, algorithm)
+  {
+    this.objectStr = objectStr;
+    this.pkAlgorithm = algorithm;
+  }
+
+  var WebTokenParser = {
+
+    parse: function _parse(input)
+    {
+      var parts = input.split(".");
+      if (parts.length != 3) {
+        throw new MalformedWebTokenException("Must have three parts");
+      }
+      var token = new WebToken();
+      token.headerSegment = parts[0];
+      token.payloadSegment = parts[1];
+      token.cryptoSegment = parts[2];
+
+      token.pkAlgorithm = base64urldecode(parts[0]);
+      return token;
+    }
+  }
+
+  function jsonObj(strOrObject)
+  {
+    if (typeof strOrObject == "string") {
+      return JSON.parse(strOrObject);
+    }
+    return strOrObject;
+  }
+
+  function constructAlgorithm(jwtAlgStr, key)
+  {
+    if ("ES256" === jwtAlgStr) {
+      throw new NotImplementedException("ECDSA-SHA256 not yet implemented");
+    } else if ("ES384" === jwtAlgStr) {
+      throw new NotImplementedException("ECDSA-SHA384 not yet implemented");
+    } else if ("ES512" === jwtAlgStr) {
+      throw new NotImplementedException("ECDSA-SHA512 not yet implemented");
+    } else if ("HS256" === jwtAlgStr) {
+      return new HMACAlgorithm("sha256", key);
+    } else if ("HS384" === jwtAlgStr) {
+      throw new NotImplementedException("HMAC-SHA384 not yet implemented");
+    } else if ("HS512" === jwtAlgStr) {
+      throw new NotImplementedException("HMAC-SHA512 not yet implemented");
+    } else if ("RS256" === jwtAlgStr) {
+      return new RSASHAAlgorithm("sha256", key);
+    } else if ("RS384" === jwtAlgStr) {
+      throw new NotImplementedException("RSA-SHA384 not yet implemented");
+    } else if ("RS512" === jwtAlgStr) {
+      throw new NotImplementedException("RSA-SHA512 not yet implemented");
+    } else {
+      throw new NoSuchAlgorithmException("Unknown algorithm: " + jwtAlgStr);
+    }
+  }
+
+  WebToken.prototype =
+  {
+    serialize: function _serialize(key)
+    {
+      var header = jsonObj(this.pkAlgorithm);
+      var jwtAlgStr = header.alg;
+      var algorithm = constructAlgorithm(jwtAlgStr, key);
+      var algBytes = base64urlencode(this.pkAlgorithm);
+      var jsonBytes = base64urlencode(this.objectStr);
+
+      var stringToSign = algBytes + "." + jsonBytes;
+      algorithm.update(stringToSign);
+      var digestValue = algorithm.finalize();
+
+      var signatureValue = algorithm.sign();
+      return algBytes + "." + jsonBytes + "." + signatureValue;
+    },
+    
+    verify: function _verify(key)
+    {
+      var header = jsonObj(this.pkAlgorithm);
+      var jwtAlgStr = header.alg;
+      var algorithm = constructAlgorithm(jwtAlgStr, key);
+      algorithm.update(this.headerSegment + "." + this.payloadSegment);
+      algorithm.finalize();
+      return algorithm.verify(this.cryptoSegment);
+    }
+  }
+  
+  jwt.WebToken = WebToken;
+  jwt.WebTokenParser = WebTokenParser;
+  jwt.base64urlencode = base64urlencode;
+  jwt.base64urldecode = base64urldecode;
+})();
diff --git a/browserid/static/dialog/dialog/resources/jschannel.js b/browserid/static/dialog/dialog/resources/jschannel.js
new file mode 100644
index 0000000000000000000000000000000000000000..8e56c5e91f368ca0f75e8d9edf601a9e331fcb71
--- /dev/null
+++ b/browserid/static/dialog/dialog/resources/jschannel.js
@@ -0,0 +1,552 @@
+/**
+ * js_channel is a very lightweight abstraction on top of
+ * postMessage which defines message formats and semantics
+ * to support interactions more rich than just message passing
+ * js_channel supports:
+ *  + query/response - traditional rpc
+ *  + query/update/response - incremental async return of results
+ *    to a query
+ *  + notifications - fire and forget
+ *  + error handling
+ *
+ * js_channel is based heavily on json-rpc, but is focused at the
+ * problem of inter-iframe RPC.
+ *
+ * Message types:
+ *  There are 5 types of messages that can flow over this channel,
+ *  and you may determine what type of message an object is by
+ *  examining its parameters:
+ *  1. Requests
+ *    + integer id
+ *    + string method
+ *    + (optional) any params
+ *  2. Callback Invocations (or just "Callbacks")
+ *    + integer id
+ *    + string callback
+ *    + (optional) params
+ *  3. Error Responses (or just "Errors)
+ *    + integer id
+ *    + string error
+ *    + (optional) string message
+ *  4. Responses
+ *    + integer id
+ *    + (optional) any result
+ *  5. Notifications
+ *    + string method
+ *    + (optional) any params
+ */
+
+;Channel = (function() {
+    // current transaction id, start out at a random *odd* number between 1 and a million
+    // There is one current transaction counter id per page, and it's shared between
+    // channel instances.  That means of all messages posted from a single javascript
+    // evaluation context, we'll never have two with the same id.
+    var s_curTranId = Math.floor(Math.random()*1000001);
+
+    // no two bound channels in the same javascript evaluation context may have the same origin & scope.
+    // futher if two bound channels have the same scope, they may not have *overlapping* origins
+    // (either one or both support '*').  This restriction allows a single onMessage handler to efficiently
+    // route messages based on origin and scope.  The s_boundChans maps origins to scopes, to message
+    // handlers.  Request and Notification messages are routed using this table.
+    // Finally, channels are inserted into this table when built, and removed when destroyed.
+    var s_boundChans = { };
+
+    // add a channel to s_boundChans, throwing if a dup exists
+    function s_addBoundChan(origin, scope, handler) {
+        // does she exist?
+        var exists = false;
+        if (origin === '*') {
+            // we must check all other origins, sadly.
+            for (var k in s_boundChans) {
+                if (!s_boundChans.hasOwnProperty(k)) continue;
+                if (k === '*') continue;
+                if (typeof s_boundChans[k][scope] === 'object') {
+                    exists = true;
+                }
+            }
+        } else {
+            // we must check only '*'
+            if ((s_boundChans['*'] && s_boundChans['*'][scope]) ||
+                (s_boundChans[origin] && s_boundChans[origin][scope]))
+            {
+                exists = true;
+            }
+        }
+        if (exists) throw "A channel already exists which overlaps with origin '"+ origin +"' and has scope '"+scope+"'";
+
+        if (typeof s_boundChans[origin] != 'object') s_boundChans[origin] = { };
+        s_boundChans[origin][scope] = handler;
+    }
+
+    function s_removeBoundChan(origin, scope) {
+        delete s_boundChans[origin][scope];
+        // possibly leave a empty object around.  whatevs.
+    }
+
+    function s_isArray(obj) {
+      if (Array.isArray) return Array.isArray(obj);
+      else {
+        return (obj.constructor.toString().indexOf("Array") != -1);
+      }
+    }
+
+    // No two outstanding outbound messages may have the same id, period.  Given that, a single table
+    // mapping "transaction ids" to message handlers, allows efficient routing of Callback, Error, and
+    // Response messages.  Entries are added to this table when requests are sent, and removed when
+    // responses are received.
+    var s_transIds = { };
+
+    // class singleton onMessage handler
+    // this function is registered once and all incoming messages route through here.  This
+    // arrangement allows certain efficiencies, message data is only parsed once and dispatch
+    // is more efficient, especially for large numbers of simultaneous channels.
+    var s_onMessage = function(e) {
+        var m = JSON.parse(e.data);
+        if (typeof m !== 'object') return;
+
+        var o = e.origin;
+        var s = null;
+        var i = null;
+        var meth = null;
+
+        if (typeof m.method === 'string') {
+            var ar = m.method.split('::');
+            if (ar.length == 2) {
+                s = ar[0];
+                meth = ar[1];
+            } else {
+                meth = m.method;
+            }
+        }
+
+        if (typeof m.id !== 'undefined') i = m.id;
+
+        // o is message origin
+        // m is parsed message
+        // s is message scope
+        // i is message id (or null)
+        // meth is unscoped method name
+        // ^^ based on these factors we can route the message
+
+        // if it has a method it's either a notification or a request,
+        // route using s_boundChans
+        if (typeof meth === 'string') {
+            if (s_boundChans[o] && s_boundChans[o][s]) {
+                s_boundChans[o][s](o, meth, m);
+            } else if (s_boundChans['*'] && s_boundChans['*'][s]) {
+                s_boundChans['*'][s](o, meth, m);
+            }
+        }
+        // otherwise it must have an id (or be poorly formed
+        else if (typeof i != 'undefined') {
+            if (s_transIds[i]) s_transIds[i](o, meth, m);
+        }
+    };
+
+    // Setup postMessage event listeners
+    if (window.addEventListener) window.addEventListener('message', s_onMessage, false);
+    else if(window.attachEvent) window.attachEvent('onmessage', s_onMessage);
+
+    /* a messaging channel is constructed from a window and an origin.
+     * the channel will assert that all messages received over the
+     * channel match the origin
+     *
+     * Arguments to Channel.build(cfg):
+     *
+     *   cfg.window - the remote window with which we'll communication
+     *   cfg.origin - the expected origin of the remote window, may be '*'
+     *                which matches any origin
+     *   cfg.scope  - the 'scope' of messages.  a scope string that is
+     *                prepended to message names.  local and remote endpoints
+     *                of a single channel must agree upon scope. Scope may
+     *                not contain double colons ('::').
+     *   cfg.debugOutput - A boolean value.  If true and window.console.log is
+     *                a function, then debug strings will be emitted to that
+     *                function.
+     *   cfg.debugOutput - A boolean value.  If true and window.console.log is
+     *                a function, then debug strings will be emitted to that
+     *                function.
+     *   cfg.postMessageObserver - A function that will be passed two arguments,
+     *                an origin and a message.  It will be passed these immediately
+     *                before messages are posted.
+     *   cfg.gotMessageObserver - A function that will be passed two arguments,
+     *                an origin and a message.  It will be passed these arguments
+     *                immediately after they pass scope and origin checks, but before
+     *                they are processed.
+     *   cfg.onReady - A function that will be invoked when a channel becomes "ready",
+     *                this occurs once both sides of the channel have been
+     *                instantiated and an application level handshake is exchanged.
+     *                the onReady function will be passed a single argument which is
+     *                the channel object that was returned from build().
+     */
+    return {
+        build: function(cfg) {
+            var debug = function(m) {
+                if (cfg.debugOutput && window.console && window.console.log) {
+                    // try to stringify, if it doesn't work we'll let javascript's built in toString do its magic
+                    try { if (typeof m !== 'string') m = JSON.stringify(m); } catch(e) { }
+                    console.log("["+chanId+"] " + m);
+                }
+            }
+
+            /* browser capabilities check */
+            if (!window.postMessage) throw("jschannel cannot run this browser, no postMessage");
+            if (!window.JSON || !window.JSON.stringify || ! window.JSON.parse) {
+                throw("jschannel cannot run this browser, no JSON parsing/serialization");
+            }
+
+            /* basic argument validation */
+            if (typeof cfg != 'object') throw("Channel build invoked without a proper object argument");
+
+            if (!cfg.window || !cfg.window.postMessage) throw("Channel.build() called without a valid window argument");
+
+            /* we'd have to do a little more work to be able to run multiple channels that intercommunicate the same
+             * window...  Not sure if we care to support that */
+            if (window === cfg.window) throw("target window is same as present window -- not allowed");
+
+            // let's require that the client specify an origin.  if we just assume '*' we'll be
+            // propagating unsafe practices.  that would be lame.
+            var validOrigin = false;
+            if (typeof cfg.origin === 'string') {
+                var oMatch;
+                if (cfg.origin === "*") validOrigin = true;
+                // allow valid domains under http and https.  Also, trim paths off otherwise valid origins.
+                else if (null !== (oMatch = cfg.origin.match(/^https?:\/\/(?:[-a-zA-Z0-9\.])+(?::\d+)?/))) {
+                    cfg.origin = oMatch[0];
+                    validOrigin = true;
+                }
+            }
+
+            if (!validOrigin) throw ("Channel.build() called with an invalid origin");
+
+            if (typeof cfg.scope !== 'undefined') {
+                if (typeof cfg.scope !== 'string') throw 'scope, when specified, must be a string';
+                if (cfg.scope.split('::').length > 1) throw "scope may not contain double colons: '::'"
+            }
+
+            /* private variables */
+            // generate a random and psuedo unique id for this channel
+            var chanId = (function () {
+                var text = "";
+                var alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+                for(var i=0; i < 5; i++) text += alpha.charAt(Math.floor(Math.random() * alpha.length));
+                return text;
+            })();
+
+            // registrations: mapping method names to call objects
+            var regTbl = { };
+            // current oustanding sent requests
+            var outTbl = { };
+            // current oustanding received requests
+            var inTbl = { };
+            // are we ready yet?  when false we will block outbound messages.
+            var ready = false;
+            var pendingQueue = [ ];
+
+            var createTransaction = function(id,origin,callbacks) {
+                var shouldDelayReturn = false;
+                var completed = false;
+
+                return {
+                    origin: origin,
+                    invoke: function(cbName, v) {
+                        // verify in table
+                        if (!inTbl[id]) throw "attempting to invoke a callback of a non-existant transaction: " + id;
+                        // verify that the callback name is valid
+                        var valid = false;
+                        for (var i = 0; i < callbacks.length; i++) if (cbName === callbacks[i]) { valid = true; break; }
+                        if (!valid) throw "request supports no such callback '" + cbName + "'";
+
+                        // send callback invocation
+                        postMessage({ id: id, callback: cbName, params: v});
+                    },
+                    error: function(error, message) {
+                        completed = true;
+                        // verify in table
+                        if (!inTbl[id]) throw "error called for non-existant message: " + id;
+
+                        // remove transaction from table
+                        delete inTbl[id];
+
+                        // send error
+                        postMessage({ id: id, error: error, message: message });
+                    },
+                    complete: function(v) {
+                        completed = true;
+                        // verify in table
+                        if (!inTbl[id]) throw "complete called for non-existant message: " + id;
+                        // remove transaction from table
+                        delete inTbl[id];
+                        // send complete
+                        postMessage({ id: id, result: v });
+                    },
+                    delayReturn: function(delay) {
+                        if (typeof delay === 'boolean') {
+                            shouldDelayReturn = (delay === true);
+                        }
+                        return shouldDelayReturn;
+                    },
+                    completed: function() {
+                        return completed;
+                    }
+                };
+            }
+
+            var onMessage = function(origin, method, m) {
+                // if an observer was specified at allocation time, invoke it
+                if (typeof cfg.gotMessageObserver === 'function') {
+                    // pass observer a clone of the object so that our
+                    // manipulations are not visible (i.e. method unscoping).
+                    // This is not particularly efficient, but then we expect
+                    // that message observers are primarily for debugging anyway.
+                    try {
+                        cfg.gotMessageObserver(origin, m);
+                    } catch (e) {
+                        debug("gotMessageObserver() raised an exception: " + e.toString());
+                    }
+                }
+
+                // now, what type of message is this?
+                if (m.id && method) {
+                    // a request!  do we have a registered handler for this request?
+                    if (regTbl[method]) {
+                        var trans = createTransaction(m.id, origin, m.callbacks ? m.callbacks : [ ]);
+                        inTbl[m.id] = { };
+                        try {
+                            // callback handling.  we'll magically create functions inside the parameter list for each
+                            // callback
+                            if (m.callbacks && s_isArray(m.callbacks) && m.callbacks.length > 0) {
+                                for (var i = 0; i < m.callbacks.length; i++) {
+                                    var path = m.callbacks[i];
+                                    var obj = m.params;
+                                    var pathItems = path.split('/');
+                                    for (var j = 0; j < pathItems.length - 1; j++) {
+                                        var cp = pathItems[j];
+                                        if (typeof obj[cp] !== 'object') obj[cp] = { };
+                                        obj = obj[cp];
+                                    }
+                                    obj[pathItems[pathItems.length - 1]] = (function() {
+                                        var cbName = path;
+                                        return function(params) {
+                                            return trans.invoke(cbName, params);
+                                        }
+                                    })();
+                                }
+                            }
+                            var resp = regTbl[method](trans, m.params);
+                            if (!trans.delayReturn() && !trans.completed()) trans.complete(resp);
+                        } catch(e) {
+                            // automagic handling of exceptions:
+                            var error = "runtime_error";
+                            var message = null;
+                            // * if its a string then it gets an error code of 'runtime_error' and string is the message
+                            if (typeof e === 'string') {
+                                message = e;
+                            } else if (typeof e === 'object') {
+                                // either an array or an object
+                                // * if its an array of length two, then  array[0] is the code, array[1] is the error message
+                                if (e && s_isArray(e) && e.length == 2) {
+                                    error = e[0];
+                                    message = e[1];
+                                }
+                                // * if its an object then we'll look form error and message parameters
+                                else if (typeof e.error === 'string') {
+                                    error = e.error;
+                                    if (!e.message) message = "";
+                                    else if (typeof e.message === 'string') message = e.message;
+                                    else e = e.message; // let the stringify/toString message give us a reasonable verbose error string
+                                }
+                            }
+
+                            // message is *still* null, let's try harder
+                            if (message === null) {
+                                try {
+                                    message = JSON.stringify(e);
+                                } catch (e2) {
+                                    message = e.toString();
+                                }
+                            }
+
+                            trans.error(error,message);
+                        }
+                    }
+                } else if (m.id && m.callback) {
+                    if (!outTbl[m.id] ||!outTbl[m.id].callbacks || !outTbl[m.id].callbacks[m.callback])
+                    {
+                        debug("ignoring invalid callback, id:"+m.id+ " (" + m.callback +")");
+                    } else {
+                        // XXX: what if client code raises an exception here?
+                        outTbl[m.id].callbacks[m.callback](m.params);
+                    }
+                } else if (m.id) {
+                    if (!outTbl[m.id]) {
+                        debug("ignoring invalid response: " + m.id);
+                    } else {
+                        // XXX: what if client code raises an exception here?
+                        if (m.error) {
+                            (1,outTbl[m.id].error)(m.error, m.message);
+                        } else {
+                          if (m.result !== undefined) (1,outTbl[m.id].success)(m.result);
+                          else (1,outTbl[m.id].success)();
+                        }
+                        delete outTbl[m.id];
+                        delete s_transIds[m.id];
+                    }
+                } else if (method) {
+                    // tis a notification.
+                    if (regTbl[method]) {
+                        // yep, there's a handler for that.
+                        // transaction is null for notifications.
+                        regTbl[method](null, m.params);
+                        // if the client throws, we'll just let it bubble out
+                        // what can we do?  Also, here we'll ignore return values
+                    }
+                }
+            }
+
+            // now register our bound channel for msg routing
+            s_addBoundChan(cfg.origin, ((typeof cfg.scope === 'string') ? cfg.scope : ''), onMessage);
+
+            // scope method names based on cfg.scope specified when the Channel was instantiated
+            var scopeMethod = function(m) {
+                if (typeof cfg.scope === 'string' && cfg.scope.length) m = [cfg.scope, m].join("::");
+                return m;
+            }
+
+            // a small wrapper around postmessage whose primary function is to handle the
+            // case that clients start sending messages before the other end is "ready"
+            var postMessage = function(msg, force) {
+                if (!msg) throw "postMessage called with null message";
+
+                // delay posting if we're not ready yet.
+                var verb = (ready ? "post  " : "queue ");
+                debug(verb + " message: " + JSON.stringify(msg));
+                if (!force && !ready) {
+                    pendingQueue.push(msg);
+                } else {
+                    if (typeof cfg.postMessageObserver === 'function') {
+                        try {
+                            cfg.postMessageObserver(cfg.origin, msg);
+                        } catch (e) {
+                            debug("postMessageObserver() raised an exception: " + e.toString());
+                        }
+                    }
+
+                    cfg.window.postMessage(JSON.stringify(msg), cfg.origin);
+                }
+            }
+
+            var onReady = function(trans, type) {
+                debug('ready msg received');
+                if (ready) throw "received ready message while in ready state.  help!";
+
+                if (type === 'ping') {
+                    chanId += '-R';
+                } else {
+                    chanId += '-L';
+                }
+
+                obj.unbind('__ready'); // now this handler isn't needed any more.
+                ready = true;
+                debug('ready msg accepted.');
+
+                if (type === 'ping') {
+                    obj.notify({ method: '__ready', params: 'pong' });
+                }
+
+                // flush queue
+                while (pendingQueue.length) {
+                    postMessage(pendingQueue.pop());
+                }
+
+                // invoke onReady observer if provided
+                if (typeof cfg.onReady === 'function') cfg.onReady(obj);
+            };
+
+            var obj = {
+                // tries to unbind a bound message handler.  returns false if not possible
+                unbind: function (method) {
+                    if (regTbl[method]) {
+                        if (!(delete regTbl[method])) throw ("can't delete method: " + method);
+                        return true;
+                    }
+                    return false;
+                },
+                bind: function (method, cb) {
+                    if (!method || typeof method !== 'string') throw "'method' argument to bind must be string";
+                    if (!cb || typeof cb !== 'function') throw "callback missing from bind params";
+
+                    if (regTbl[method]) throw "method '"+method+"' is already bound!";
+                    regTbl[method] = cb;
+                },
+                call: function(m) {
+                    if (!m) throw 'missing arguments to call function';
+                    if (!m.method || typeof m.method !== 'string') throw "'method' argument to call must be string";
+                    if (!m.success || typeof m.success !== 'function') throw "'success' callback missing from call";
+
+                    // now it's time to support the 'callback' feature of jschannel.  We'll traverse the argument
+                    // object and pick out all of the functions that were passed as arguments.
+                    var callbacks = { };
+                    var callbackNames = [ ];
+
+                    var pruneFunctions = function (path, obj) {
+                        if (typeof obj === 'object') {
+                            for (var k in obj) {
+                                if (!obj.hasOwnProperty(k)) continue;
+                                var np = path + (path.length ? '/' : '') + k;
+                                if (typeof obj[k] === 'function') {
+                                    callbacks[np] = obj[k];
+                                    callbackNames.push(np);
+                                    delete obj[k];
+                                } else if (typeof obj[k] === 'object') {
+                                    pruneFunctions(np, obj[k]);
+                                }
+                            }
+                        }
+                    };
+                    pruneFunctions("", m.params);
+
+                    // build a 'request' message and send it
+                    var msg = { id: s_curTranId, method: scopeMethod(m.method), params: m.params };
+                    if (callbackNames.length) msg.callbacks = callbackNames;
+
+                    // insert into the transaction table
+                    outTbl[s_curTranId] = { callbacks: callbacks, error: m.error, success: m.success };
+                    s_transIds[s_curTranId] = onMessage;
+
+                    // increment current id
+                    s_curTranId++;
+
+                    postMessage(msg);
+                },
+                notify: function(m) {
+                    if (!m) throw 'missing arguments to notify function';
+                    if (!m.method || typeof m.method !== 'string') throw "'method' argument to notify must be string";
+
+                    // no need to go into any transaction table
+                    postMessage({ method: scopeMethod(m.method), params: m.params });
+                },
+                destroy: function () {
+                    s_removeBoundChan(cfg.origin, ((typeof cfg.scope === 'string') ? cfg.scope : ''));
+                    if (window.removeEventListener) window.removeEventListener('message', onMessage, false);
+                    else if(window.detachEvent) window.detachEvent('onmessage', onMessage);
+                    ready = false;
+                    regTbl = { };
+                    inTbl = { };
+                    outTbl = { };
+                    cfg.origin = null;
+                    pendingQueue = [ ];
+                    debug("channel destroyed");
+                    chanId = "";
+                }
+            };
+
+            obj.bind('__ready', onReady);
+            setTimeout(function() {
+                postMessage({ method: scopeMethod('__ready'), params: "ping" }, true);
+            }, 0);
+
+            return obj;
+        }
+    };
+})();
diff --git a/browserid/static/dialog/dialog/resources/main.js b/browserid/static/dialog/dialog/resources/main.js
new file mode 100644
index 0000000000000000000000000000000000000000..d0777f42e59db68ffec0236f6ddc3b80ec50f43a
--- /dev/null
+++ b/browserid/static/dialog/dialog/resources/main.js
@@ -0,0 +1,778 @@
+// this is the picker code!  it runs in the identity provider's domain, and
+// fiddles the dom expressed by picker.html
+(function() {
+  var chan = Channel.build(
+    {
+      window: window.opener,
+      origin: "*",
+      scope: "mozid"
+    });
+
+  var remoteOrigin = undefined;
+
+  function getLastUsedEmail() {
+    // XXX: really we should keep usage records locally to make this better
+    var emails = JSON.parse(window.localStorage.emails);
+    for (var e in emails) {
+      if (emails.hasOwnProperty(e)) return e;
+    }
+    return undefined;
+  }
+
+  function checkAuthStatus(authcb, notauthcb, onsuccess, onerror) {
+    runWaitingDialog(
+      "Communicating with server",
+      "Just a moment while we talk with the server.",
+      onsuccess, onerror);
+
+    $.ajax({
+      url: '/wsapi/am_authed',
+      success: function(status, textStatus, jqXHR) {
+        var authenticated = JSON.parse(status);
+        if (!authenticated) {
+          notauthcb();
+        } else {
+          authcb();
+        }
+      },
+      error: function() {
+        runErrorDialog(
+          "serverError",
+          "Error Communicating With Server!",
+          "There was a technical problem while trying to log you in.  Yucky!",
+          onsuccess, onerror);
+      }
+    });
+  }
+
+  function persistAddressAndKeyPair(email, keypair, issuer)
+  {
+    var emails = {};
+    if (window.localStorage.emails) {
+      try {
+        emails = JSON.parse(window.localStorage.emails);
+      } catch(e) {
+        // if somehow window.localStorage.emails is populated with bogus
+        // JSON, we'll just purge it.
+      }
+    }
+    if (emails === null || typeof emails !== 'object') emails = {};
+
+    emails[email] = {
+      created: new Date(),
+      pub: keypair.pub,
+      priv: keypair.priv
+    };
+    if (issuer) {
+      emails[email].issuer = issuer;
+    }
+
+    window.localStorage.emails = JSON.stringify(emails);
+  }
+
+  function syncIdentities(onsuccess, onerror) {
+    // send up all email/pubkey pairs to the server, it will response with a
+    // list of emails that need new keys.  This may include emails in the
+    // sent list, and also may include identities registered on other devices.
+    // we'll go through the list and generate new keypairs
+
+    // identities that don't have an issuer are primary authentications,
+    // and we don't need to worry about rekeying them.
+    var issued_identities = { };
+    var emails = {};
+    if (window.localStorage.emails) {
+      emails = JSON.parse(window.localStorage.emails);
+    }
+
+    for (var e in emails) {
+      if (!emails.hasOwnProperty(e)) continue;
+      if (emails[e].issuer) {
+        issued_identities[e] = emails[e].pub;
+      }
+    }
+
+    $.ajax({
+      url: '/wsapi/sync_emails',
+      type: "post",
+      data: JSON.stringify(issued_identities),
+      success: function(resp, textStatus, jqXHR) {
+        // first remove idenitites that the server doesn't know about
+        if (resp.unknown_emails) {
+          for (var i = 0; i < resp.unknown_emails; i++) {
+            if (emails.hasOwnProperty(resp.unknown_emails[i])) {
+              console.log("removed local identity: " + resp.unknown_emails[i]);
+              delete emails[resp.unknown_emails[i]];
+            }
+          }
+        }
+
+        // store changes thus far
+        window.localStorage.emails = JSON.stringify(emails);
+
+        // now let's begin iteratively re-keying the emails mentioned in the server provided list
+        var emailsToAdd = resp.key_refresh;
+
+        function addNextEmail() {
+          if (!emailsToAdd || !emailsToAdd.length) {
+            runSignInDialog(onsuccess, onerror);
+            return;
+          }
+
+          // pop the first email from the list
+          var email = emailsToAdd.shift();
+          var keypair = CryptoStubs.genKeyPair();
+
+          $.ajax({
+            url: '/wsapi/set_key?email=' + encodeURIComponent(email) + '&pubkey=' + encodeURIComponent(keypair.pub),
+            success: function() {
+              // update emails list and commit to local storage, then go do the next email
+              persistAddressAndKeyPair(email, keypair, "browserid.org:443");
+              addNextEmail();
+            },
+            error: function() {
+              runErrorDialog(
+                "serverError",
+                "Error Adding Address!",
+                "There was a technical problem while trying to synchronize your account.  Yucky.",
+                onsuccess, onerror);
+            }
+          });
+        }
+
+        addNextEmail();
+      },
+      error: function(jqXHR, textStatus, errorThrown) {
+        runErrorDialog("serverError", "Login Failed", jqXHR.responseText, onsuccess, onerror);
+      }
+    });
+
+  }
+
+  function runSignInDialog(onsuccess, onerror) {
+    return $('#signin').signin().show();
+
+    $(".dialog").hide();
+
+    $("#back").hide();
+    $("#cancel").show().unbind('click').click(function() {
+      onerror("canceled");
+    });
+    $("#submit").show().unbind('click').click(function() {
+      var email = $("#identities input:checked").parent().find("div").text();
+
+      // yay!  now we need to produce an assertion.
+      var storedID = JSON.parse(window.localStorage.emails)[email];
+
+      var privkey = storedID.priv;
+      var issuer = storedID.issuer;
+      var audience = remoteOrigin.replace(/^(http|https):\/\//, '');
+      var assertion = CryptoStubs.createAssertion(audience, email, privkey, issuer);
+      onsuccess(assertion);
+    }).text("Sign In").removeClass("disabled").focus();
+
+    $("#sign_in_dialog div.actions div.action:first a").unbind('click').click(function() {
+      checkAuthStatus(
+        function() {
+          // the user is authenticated, they can go ahead and try to add a new address
+          runAddNewAddressDialog(onsuccess, onerror);
+        },
+        function() {
+          // the user is not authed, they must enter their email/password
+          runAuthenticateDialog(getLastUsedEmail(), onsuccess, onerror);
+        },
+        onsuccess, onerror);
+    });
+
+    $("#sign_in_dialog div.actions div.action:eq(1) a").unbind('click').click(function() {
+      // not your email addresses?  we'll just purge local storage and click you over
+      // to the login page.
+      window.localStorage.emails = JSON.stringify({});
+      $("input").val("");
+      $.get("/wsapi/logout", function() {
+          runAuthenticateDialog(undefined, onsuccess, onerror);
+      });
+    });
+
+    // now populate the selection list with all available emails
+    // we assume there are identities available, because without them
+    var emails = JSON.parse(window.localStorage.emails);
+    var first = true;
+    $("form#identities").empty();
+    for (var k in emails) {
+      var id = $("<div />")
+        .append($("<input />").attr('type', 'radio').attr('name', 'identity').attr('checked', first))
+        .append($("<div />").text(k));
+      first = false;
+      id.appendTo($("form#identities"));
+    }
+    $("form#identities > div").unbind('click').click(function() {
+      $(this).find(':first').attr('checked', true);
+    });
+
+    $("#sign_in_dialog").fadeIn(500);
+  }
+
+  function runAuthenticateDialog(email, onsuccess, onerror) {
+    $(".dialog").hide();
+    $("#back").hide();
+    $("#cancel").show().unbind('click').click(function() {
+      onerror("canceled");
+    });
+    $("#submit").show().unbind('click').click(function() {
+      if ($(this).hasClass('disabled')) return true;
+
+      var email = $("#authenticate_dialog input:eq(0)").val();
+      var pass = $("#authenticate_dialog input:eq(1)").val();
+
+      $.ajax({
+        url: '/wsapi/authenticate_user?email=' + encodeURIComponent(email) + '&pass=' + encodeURIComponent(pass),
+        success: function(status, textStatus, jqXHR) {
+          var authenticated = JSON.parse(status);
+          if (!authenticated) {
+            $("#authenticate_dialog div.attention_lame").hide().fadeIn(400);
+          } else {
+            runWaitingDialog(
+              "Finishing Log In...",
+              "In just a moment you'll be logged into BrowserID.",
+              onsuccess, onerror);
+
+            syncIdentities(onsuccess, onerror);
+          }
+        },
+        error: function() {
+          runErrorDialog(
+            "serverError",
+            "Error Authenticating!",
+            "There was a technical problem while trying to log you in.  Yucky!",
+            onsuccess, onerror);
+        }
+      });
+    }).text("Sign In").addClass("disabled");;
+
+    // preseed the email input if whoever triggered us told us to
+    if (email) {
+      $("#authenticate_dialog input:eq(0)").val(email);
+    }
+
+    $("#authenticate_dialog div.note > a").unbind('click').click(function() {
+      runCreateDialog(true, onsuccess, onerror);
+    });
+    $("#authenticate_dialog div.actions div.action").unbind('click').click(function() {
+      runCreateDialog(false, onsuccess, onerror);
+    });
+
+    $("#authenticate_dialog div.attention_lame").hide();
+
+    $("#authenticate_dialog input").unbind('keyup').bind('keyup', function() {
+      var email = $("#authenticate_dialog input:eq(0)").val();
+      var pass = $("#authenticate_dialog input:eq(1)").val();
+      if (email.length > 0 && pass.length > 0) $("#submit").removeClass('disabled');
+      else $("#submit").addClass('disabled');
+    });
+
+    $("#authenticate_dialog").fadeIn(
+      500,
+      function() {
+        // where should we put the focus?  On login if empty, else password
+        var email = $("#authenticate_dialog input:eq(0)").val();
+        if (typeof email === 'string' && email.length) {
+          $("#authenticate_dialog input:eq(1)").focus();
+        } else {
+          $("#authenticate_dialog input:eq(0)").focus();
+        }
+      });
+  }
+
+  // a handle to a timeout of a running email check
+  var emailCheckState = undefined;
+  // the next email to check, if one is entered while a check is running
+  var nextEmailToCheck = undefined;
+  // a set of emails that we've checked for this session
+  var checkedEmails = {
+  };
+
+  function runConfirmEmailDialog(email, keypair, onsuccess, onerror) {
+    $(".dialog").hide();
+
+    $("span.email").text(email);
+
+    // now poll every 3s waiting for the user to complete confirmation
+    function setupRegCheck() {
+      return setTimeout(function() {
+        $.ajax({
+          url: '/wsapi/registration_status',
+          success: function(status, textStatus, jqXHR) {
+            // registration status checks the status of the last initiated registration,
+            // it's possible return values are:
+            //   'complete' - registration has been completed
+            //   'pending'  - a registration is in progress
+            //   'noRegistration' - no registration is in progress
+            if (status === 'complete') {
+              // this is a secondary registration from browserid.org, persist
+              // email, keypair, and that fact
+              persistAddressAndKeyPair(email, keypair, "browserid.org:443");
+
+              // and tell the user that everything is really quite awesome.
+              runConfirmedEmailDialog(email, onsuccess, onerror);
+            } else if (status === 'pending') {
+              // try again, what else can we do?
+              pollTimeout = setupRegCheck();
+            } else {
+              runErrorDialog(
+                "serverError",
+                "Registration Failed",
+                "An error was encountered and the sign up cannot be completed, please try again later.",
+                onsuccess,
+                onerror);
+            }
+          },
+          error: function(jqXHR, textStatus, errorThrown) {
+            runErrorDialog("serverError", "Registration Failed", jqXHR.responseText, onsuccess, onerror);
+          }
+        });
+      }, 3000);
+    }
+
+    var pollTimeout = setupRegCheck();
+
+    $("#back").show().unbind('click').click(function() {
+      window.clearTimeout(pollTimeout);
+      runCreateDialog(false, onsuccess, onerror);
+    });
+
+    $("#cancel").show().unbind('click').click(function() {
+      window.clearTimeout(pollTimeout);
+      onerror("canceled");
+    });
+    $("#submit").hide();
+
+    $("#create_email_dialog div.actions div.action a").unbind('click').click(function() {
+      // XXX: resend the email!
+      return true;
+    });
+    $("#confirm_email_dialog").fadeIn(500);
+
+  }
+
+  function runConfirmedEmailDialog(email, onsuccess, onerror) {
+    $(".dialog").hide();
+
+    $("span.email").text(email);
+
+    $("#back").hide();
+
+    $("#cancel").show().unbind('click').click(function() {
+      onerror("canceled");
+    });
+    $("#submit").show().unbind('click').click(function() {
+      runSignInDialog(onsuccess, onerror);
+    }).text("Continue");
+
+    $("#confirmed_email_dialog").show();
+  }
+
+  function runErrorDialog(code, title, message, onsuccess, onerror) {
+    $(".dialog").hide();
+
+    $("#error_dialog div.title").text(title);
+    $("#error_dialog div.content").text(message);
+
+    $("#back").hide();
+    $("#cancel").hide();
+    $("#submit").show().unbind('click').click(function() {
+      onerror(code);
+    }).text("Close");
+
+    $("#error_dialog").fadeIn(500);
+  }
+
+  function runWaitingDialog(title, message, onsuccess, onerror) {
+    $(".dialog").hide();
+
+    $("#waiting_dialog div.title").text(title);
+    $("#waiting_dialog div.content").text(message);
+
+    $("#back").hide();
+    $("#submit").hide();
+    $("#cancel").show().unbind('click').click(function() {
+      onerror("canceled");
+    });
+
+    $("#waiting_dialog").fadeIn(500);
+  }
+
+  function runAddNewAddressDialog(onsuccess, onerror) {
+    $(".dialog").hide();
+
+    $("#back").show().unbind('click').click(function() {
+      runSignInDialog(onsuccess, onerror);
+    });
+    $("#cancel").show().unbind('click').click(function() {
+      onerror("canceled");
+    });
+    $("#submit").show().unbind('click').click(function() {
+      // ignore the click if we're disabled
+      if ($(this).hasClass('disabled')) return true;
+
+      // now we need to actually try to stage the creation of this account.
+      var email = $("#add_email_dialog input:eq(0)").val();
+      var keypair = CryptoStubs.genKeyPair();
+
+      // kick the user to waiting/status page while we talk to the server.
+      runWaitingDialog(
+        "One Moment Please...",
+        "We're adding this email to your account, this should only take a couple seconds.",
+        onsuccess,
+        onerror
+      );
+
+      $.ajax({
+        url: '/wsapi/add_email?email=' + encodeURIComponent(email)
+              + '&pubkey=' + encodeURIComponent(keypair.pub)
+              + '&site=' + encodeURIComponent(remoteOrigin.replace(/^(http|https):\/\//, '')),
+        success: function() {
+          // email successfully staged, now wait for email confirmation
+          runConfirmEmailDialog(email, keypair, onsuccess, onerror);
+        },
+        error: function() {
+          runErrorDialog(
+            "serverError",
+            "Error Adding Address!",
+            "There was a technical problem while trying to add this email to your account.  Yucky.",
+            onsuccess, onerror);
+        }
+      });
+    }).text("Add").addClass('disabled');
+
+    $("#add_email_dialog input").unbind('keyup').bind('keyup', function() {
+      var email = $("#add_email_dialog input:eq(0)").val();
+      if (email.length > 0) {
+        $("#submit").removeClass('disabled');
+      } else {
+        $("#submit").addClass('disabled');
+      }
+    });
+
+    // clear previous input
+    $("#add_email_dialog input:eq(0)").val("");
+
+    $("#add_email_dialog").fadeIn(500);
+  }
+
+  function runCreateDialog(forgot, onsuccess, onerror) {
+    $(".dialog").hide();
+
+    // show the proper summary text
+    $("#create_dialog .content .summary").hide();
+    $("#create_dialog .content " + (forgot ? ".forgot" : ".create")).show();
+
+    $("#back").show().unbind('click').click(function() {
+      runAuthenticateDialog(undefined, onsuccess, onerror);
+    });
+    $("#cancel").show().unbind('click').click(function() {
+      onerror("canceled");
+    });
+    $("#submit").show().unbind('click').click(function() {
+      // ignore the click if we're disabled
+      if ($(this).hasClass('disabled')) return true;
+
+      // now we need to actually try to stage the creation of this account.
+      var email = $("#create_dialog input:eq(0)").val();
+      var pass = $("#create_dialog input:eq(1)").val();
+      var keypair = CryptoStubs.genKeyPair();
+
+      // kick the user to waiting/status page while we talk to the server.
+      runWaitingDialog(
+        "One Moment Please...",
+        "We're creating your account, this should only take a couple seconds",
+        onsuccess,
+        onerror
+      );
+
+      $.ajax({
+        url: '/wsapi/stage_user?email=' + encodeURIComponent(email)
+              + '&pass=' + encodeURIComponent(pass)
+              + '&pubkey=' + encodeURIComponent(keypair.pub)
+              + '&site=' + encodeURIComponent(remoteOrigin.replace(/^(http|https):\/\//, '')),
+        success: function() {
+          // account successfully staged, now wait for email confirmation
+          runConfirmEmailDialog(email, keypair, onsuccess, onerror);
+        },
+        error: function() {
+          runErrorDialog(
+            "serverError",
+            "Error Creating Account!",
+            "There was a technical problem while trying to create your account.  Yucky.",
+            onsuccess, onerror);
+        }
+      });
+    }).text("Continue").addClass("disabled");
+
+    $("#create_dialog div.attention_lame").hide();
+    $("#create_dialog div.attention_lame a").unbind('click').click(function() {
+      var email = $("#create_dialog input:eq(0)").val();
+      runAuthenticateDialog(email, onsuccess, onerror);
+    });
+
+    function checkInput() {
+      $("#submit").removeClass("disabled");
+
+      // check the email address
+      var email = $("#create_dialog input:eq(0)").val();
+      $("#create_dialog div.note:eq(0)").empty();
+      if (typeof email === 'string' && email.length) {
+        var valid = checkedEmails[email];
+        if (typeof valid === 'string') {
+          // oh noes.  we tried to check this email, but it failed.  let's just not tell the
+          // user anything, cause this is a non-critical issue
+
+        } else if (typeof valid === 'boolean') {
+          if (!forgot) {
+            if (valid) {
+              $("#create_dialog div.note:eq(0)").html($('<span class="good"/>').text("Not registered"));
+              $("#create_dialog div.attention_lame").hide();
+            } else {
+              $("#create_dialog div.attention_lame").fadeIn(300);
+              $("#create_dialog div.attention_lame span.email").text(email);
+              $("#submit").addClass("disabled");
+            }
+          }
+        } else {
+          // this is an email that needs to be checked!
+          if (emailCheckState !== 'querying') {
+            if (emailCheckState) window.clearTimeout(emailCheckState);
+            emailCheckState = setTimeout(function() {
+              emailCheckState = 'querying';
+              var checkingNow = nextEmailToCheck;
+              // bounce off the server and enter the 'querying' state
+              $.ajax({
+                url: '/wsapi/have_email?email=' + encodeURIComponent(checkingNow),
+                success: function(data, textStatus, jqXHR) {
+                  checkedEmails[checkingNow] = !JSON.parse(data);
+                  emailCheckState = undefined;
+                  checkInput();
+                }, error: function(jqXHR, textStatus, errorThrown) {
+                  // some kind of error was encountered.  This is non-critical, we'll simply ignore it
+                  // and mark this email check as failed.
+                  checkedEmails[checkingNow] = "server failed";
+                  emailCheckState = undefined;
+                  checkInput();
+                }
+              });
+            }, 700);
+          } else {
+            $("#create_dialog div.note:eq(0)").html($('<span class="warning"/>').text("Checking address"));
+          }
+          nextEmailToCheck = email;
+          $("#submit").addClass("disabled");
+        }
+      } else {
+        $("#submit").addClass("disabled");
+      }
+
+      // next let's check the password entry
+      var pass = $("#create_dialog input:eq(1)").val();
+      var match = pass === $("#create_dialog input:eq(2)").val();
+      if (!match) {
+        $("#submit").addClass("disabled");
+        $("#create_dialog div.note:eq(1)").html($('<span class="bad"/>').text("Passwords different"));
+      } else {
+        if (!pass) {
+          $("#submit").addClass("disabled");
+          $("#create_dialog div.note:eq(1)").html($('<span class="bad"/>').text("Enter a password"));
+        } else if (pass.length < 5) {
+          $("#submit").addClass("disabled");
+          $("#create_dialog div.note:eq(1)").html($('<span class="bad"/>').text("Password too short"));
+        } else {
+          $("#create_dialog div.note:eq(1)").html($('<span class="good"/>').text("Password OK"))
+        }
+      }
+    }
+
+    // watch input dialogs
+    $("#create_dialog input").unbind('keyup').bind('keyup', checkInput);
+
+    // do a check at load time, in case the user is using the back button (enables the continue button!)
+    checkInput();
+
+    $("#create_dialog").fadeIn(500);
+  }
+
+  var kindaLikeEmailPat = /^.*\@.*\..*$/;
+
+  function runForgotDialog(onsuccess, onerror) {
+    $(".dialog").hide();
+
+    $("#back").show().unbind('click').click(function() {
+      runAuthenticateDialog(undefined, onsuccess, onerror);
+    });
+    $("#cancel").show().unbind('click').click(function() {
+      onerror("canceled");
+    });
+    $("#submit").show().unbind('click').click(function() {
+        // ignore the click if we're disabled
+        if ($(this).hasClass('disabled')) return true;
+        onerror("notImplemented");
+    }).text("Send Reset Email").addClass('disabled');
+
+    function checkInput() {
+        // check the email address
+        var email = $("#forgot_password_dialog input").val();
+        // if the entered text has a basic resemblance to an email, we'll
+        // unstick the submit button
+        $("#submit").removeClass('disabled')
+        if (!kindaLikeEmailPat.test(email)) $("#submit").addClass('disabled')
+    }
+
+    // watch input dialogs
+    $("#forgot_password_dialog input").unbind('keyup').bind('keyup', checkInput);
+
+    // do a check at load time, in case the user is using the back button (enables the continue button!)
+    checkInput();
+
+    $("#forgot_password_dialog").fadeIn(500);
+
+    $("#forgot_password_dialog input").focus();
+  }
+
+
+  function errorOut(trans, code) {
+    function getVerboseMessage(code) {
+      var msgs = {
+        "canceled": "user canceled selection",
+        "notImplemented": "the user tried to invoke behavior that's not yet implemented",
+        "serverError": "a technical problem was encountered while trying to communicate with BrowserID servers."
+      };
+      var msg = msgs[code];
+      if (!msg) {
+          alert("need verbose message for " + code);
+          msg = "unknown error"
+      }
+      return msg;
+    }
+    trans.error(code, getVerboseMessage(code));
+    window.self.close();
+  }
+
+  //------------------------------------------------------------------------------------
+  // Begin RPC bindings:
+  //------------------------------------------------------------------------------------
+
+  chan.bind("getSpecificVerifiedEmail", function(trans, params) {
+    var email = params[0], token = params[1];
+    trans.delayReturn(true);
+
+    remoteOrigin = trans.origin;
+
+    // set the requesting site
+    $(".sitename").text(trans.origin.replace(/^.*:\/\//, ""));
+
+    // check to see if there's any pubkeys stored in the browser
+    var haveIDs = false;
+    try {
+      var emails = JSON.parse(window.localStorage.emails);
+      if (typeof emails !== 'object') throw "emails blob bogus!";
+      for (var k in emails) {
+        if (!emails.hasOwnProperty(k)) continue;
+        haveIDs = true;
+        break;
+      }
+    } catch(e) {
+      window.localStorage.emails = JSON.stringify({});
+    }
+
+    function onsuccess(rv) {
+      trans.complete(rv);
+    }
+    function onerror(error) {
+      errorOut(trans, error);
+    }
+
+    // wherever shall we start?
+    if (haveIDs) {
+      // can we pre-approve this?
+      var preauth = null;
+      if (window.localStorage['PREAUTH_' + token]) {
+        preauth = JSON.parse(window.localStorage['PREAUTH_' + token]);
+      }
+      if (token && preauth) {
+          window.localStorage['PREAUTH_' + token] = null;
+          var storedID = JSON.parse(window.localStorage.emails)[email];
+          if (storedID  && (email == preauth.email)) {
+            // ultimate success, pre-approved for an ID we have!
+            var privkey = storedID.priv;
+            var issuer = storedID.issuer;
+            var audience = remoteOrigin.replace(/^(http|https):\/\//, '');
+            var assertion = CryptoStubs.createAssertion(audience, email, privkey, issuer);
+            onsuccess(assertion);
+          } else {
+            runErrorDialog(
+              "identityError",
+              "No matching identity.",
+              "The app you requested is expecting you to authenticate as " + email + " but you don't have those creds",
+              onsuccess, onerror);
+            return;
+          }
+      } else {
+        runSignInDialog(onsuccess, onerror);
+      }
+    } else {
+      // do we even need to authenticate?
+      checkAuthStatus(function() {
+        syncIdentities(onsuccess, onerror);
+      }, function() {
+        runAuthenticateDialog(undefined, onsuccess, onerror);
+      }, onsuccess, onerror);
+    }
+      });
+
+  chan.bind("getVerifiedEmail", function(trans, s) {
+    trans.delayReturn(true);
+
+    remoteOrigin = trans.origin;
+
+    // set the requesting site
+    $(".sitename").text(trans.origin.replace(/^.*:\/\//, ""));
+
+    // check to see if there's any pubkeys stored in the browser
+    var haveIDs = false;
+    try {
+      var emails = JSON.parse(window.localStorage.emails);
+      if (typeof emails !== 'object') throw "emails blob bogus!";
+      for (var k in emails) {
+        if (!emails.hasOwnProperty(k)) continue;
+        haveIDs = true;
+        break;
+      }
+    } catch(e) {
+      window.localStorage.emails = JSON.stringify({});
+    }
+
+    function onsuccess(rv) {
+      trans.complete(rv);
+    }
+    function onerror(error) {
+      errorOut(trans, error);
+    }
+
+    // wherever shall we start?
+    if (haveIDs) {
+      runSignInDialog(onsuccess, onerror);
+    } else {
+      // do we even need to authenticate?
+      checkAuthStatus(function() {
+        syncIdentities(onsuccess, onerror);
+      }, function() {
+        runAuthenticateDialog(undefined, onsuccess, onerror);
+      }, onsuccess, onerror);
+    }
+  });
+
+  // 'Enter' in any input field triggers a click on the submit button
+  $('input').keypress(function(e){
+    if(e.which == 13) {
+      $('#submit').click();
+      e.preventDefault();
+    }
+  });
+})();
diff --git a/browserid/static/dialog/dialog/resources/underscore-min.js b/browserid/static/dialog/dialog/resources/underscore-min.js
new file mode 100644
index 0000000000000000000000000000000000000000..f502cf9f6a03e9fba4530d69ddb69e3be62ee87d
--- /dev/null
+++ b/browserid/static/dialog/dialog/resources/underscore-min.js
@@ -0,0 +1,26 @@
+// Underscore.js 1.1.6
+// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore is freely distributable under the MIT license.
+// Portions of Underscore are inspired or borrowed from Prototype,
+// Oliver Steele's Functional, and John Resig's Micro-Templating.
+// For all details and documentation:
+// http://documentcloud.github.com/underscore
+(function(){var p=this,C=p._,m={},i=Array.prototype,n=Object.prototype,f=i.slice,D=i.unshift,E=n.toString,l=n.hasOwnProperty,s=i.forEach,t=i.map,u=i.reduce,v=i.reduceRight,w=i.filter,x=i.every,y=i.some,o=i.indexOf,z=i.lastIndexOf;n=Array.isArray;var F=Object.keys,q=Function.prototype.bind,b=function(a){return new j(a)};typeof module!=="undefined"&&module.exports?(module.exports=b,b._=b):p._=b;b.VERSION="1.1.6";var h=b.each=b.forEach=function(a,c,d){if(a!=null)if(s&&a.forEach===s)a.forEach(c,d);else if(b.isNumber(a.length))for(var e=
+0,k=a.length;e<k;e++){if(c.call(d,a[e],e,a)===m)break}else for(e in a)if(l.call(a,e)&&c.call(d,a[e],e,a)===m)break};b.map=function(a,c,b){var e=[];if(a==null)return e;if(t&&a.map===t)return a.map(c,b);h(a,function(a,g,G){e[e.length]=c.call(b,a,g,G)});return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var k=d!==void 0;a==null&&(a=[]);if(u&&a.reduce===u)return e&&(c=b.bind(c,e)),k?a.reduce(c,d):a.reduce(c);h(a,function(a,b,f){!k&&b===0?(d=a,k=!0):d=c.call(e,d,a,b,f)});if(!k)throw new TypeError("Reduce of empty array with no initial value");
+return d};b.reduceRight=b.foldr=function(a,c,d,e){a==null&&(a=[]);if(v&&a.reduceRight===v)return e&&(c=b.bind(c,e)),d!==void 0?a.reduceRight(c,d):a.reduceRight(c);a=(b.isArray(a)?a.slice():b.toArray(a)).reverse();return b.reduce(a,c,d,e)};b.find=b.detect=function(a,c,b){var e;A(a,function(a,g,f){if(c.call(b,a,g,f))return e=a,!0});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(w&&a.filter===w)return a.filter(c,b);h(a,function(a,g,f){c.call(b,a,g,f)&&(e[e.length]=a)});return e};
+b.reject=function(a,c,b){var e=[];if(a==null)return e;h(a,function(a,g,f){c.call(b,a,g,f)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=!0;if(a==null)return e;if(x&&a.every===x)return a.every(c,b);h(a,function(a,g,f){if(!(e=e&&c.call(b,a,g,f)))return m});return e};var A=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=!1;if(a==null)return e;if(y&&a.some===y)return a.some(c,d);h(a,function(a,b,f){if(e=c.call(d,a,b,f))return m});return e};b.include=b.contains=function(a,c){var b=
+!1;if(a==null)return b;if(o&&a.indexOf===o)return a.indexOf(c)!=-1;A(a,function(a){if(b=a===c)return!0});return b};b.invoke=function(a,c){var d=f.call(arguments,2);return b.map(a,function(a){return(c.call?c||a:a[c]).apply(a,d)})};b.pluck=function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};h(a,function(a,b,f){b=c?c.call(d,a,b,f):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,
+c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};h(a,function(a,b,f){b=c?c.call(d,a,b,f):a;b<e.computed&&(e={value:a,computed:b})});return e.value};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,f){return{value:a,criteria:c.call(d,a,b,f)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=
+function(a){if(!a)return[];if(a.toArray)return a.toArray();if(b.isArray(a))return a;if(b.isArguments(a))return f.call(a);return b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?f.call(a,0,b):a[0]};b.rest=b.tail=function(a,b,d){return f.call(a,b==null||d?1:b)};b.last=function(a){return a[a.length-1]};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a){return b.reduce(a,function(a,d){if(b.isArray(d))return a.concat(b.flatten(d));
+a[a.length]=d;return a},[])};b.without=function(a){var c=f.call(arguments,1);return b.filter(a,function(a){return!b.include(c,a)})};b.uniq=b.unique=function(a,c){return b.reduce(a,function(a,e,f){if(0==f||(c===!0?b.last(a)!=e:!b.include(a,e)))a[a.length]=e;return a},[])};b.intersect=function(a){var c=f.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.zip=function(){for(var a=f.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),
+e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(o&&a.indexOf===o)return a.indexOf(c);d=0;for(e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(z&&a.lastIndexOf===z)return a.lastIndexOf(b);for(var d=a.length;d--;)if(a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);d=arguments[2]||1;for(var e=Math.max(Math.ceil((b-a)/
+d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};b.bind=function(a,b){if(a.bind===q&&q)return q.apply(a,f.call(arguments,1));var d=f.call(arguments,2);return function(){return a.apply(b,d.concat(f.call(arguments)))}};b.bindAll=function(a){var c=f.call(arguments,1);c.length==0&&(c=b.functions(a));h(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,c){var d={};c||(c=b.identity);return function(){var b=c.apply(this,arguments);return l.call(d,b)?d[b]:d[b]=a.apply(this,arguments)}};b.delay=
+function(a,b){var d=f.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(f.call(arguments,1)))};var B=function(a,b,d){var e;return function(){var f=this,g=arguments,h=function(){e=null;a.apply(f,g)};d&&clearTimeout(e);if(d||!e)e=setTimeout(h,b)}};b.throttle=function(a,b){return B(a,b,!1)};b.debounce=function(a,b){return B(a,b,!0)};b.once=function(a){var b=!1,d;return function(){if(b)return d;b=!0;return d=a.apply(this,arguments)}};
+b.wrap=function(a,b){return function(){var d=[a].concat(f.call(arguments));return b.apply(this,d)}};b.compose=function(){var a=f.call(arguments);return function(){for(var b=f.call(arguments),d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return function(){if(--a<1)return b.apply(this,arguments)}};b.keys=F||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var b=[],d;for(d in a)l.call(a,d)&&(b[b.length]=d);return b};b.values=function(a){return b.map(a,
+b.identity)};b.functions=b.methods=function(a){return b.filter(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a){h(f.call(arguments,1),function(b){for(var d in b)b[d]!==void 0&&(a[d]=b[d])});return a};b.defaults=function(a){h(f.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,c){if(a===c)return!0;var d=typeof a;if(d!=
+typeof c)return!1;if(a==c)return!0;if(!a&&c||a&&!c)return!1;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return!1;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return!1;if(a.length&&a.length!==c.length)return!1;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return!1;
+for(var f in a)if(!(f in c)||!b.isEqual(a[f],c[f]))return!1;return!0};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(l.call(a,c))return!1;return!0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=n||function(a){return E.call(a)==="[object Array]"};b.isArguments=function(a){return!(!a||!l.call(a,"callee"))};b.isFunction=function(a){return!(!a||!a.constructor||!a.call||!a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};
+b.isNumber=function(a){return!!(a===0||a&&a.toExponential&&a.toFixed)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===!0||a===!1};b.isDate=function(a){return!(!a||!a.getTimezoneOffset||!a.setUTCFullYear)};b.isRegExp=function(a){return!(!a||!a.test||!a.exec||!(a.ignoreCase||a.ignoreCase===!1))};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.noConflict=function(){p._=C;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=
+0;e<a;e++)b.call(d,e)};b.mixin=function(a){h(b.functions(a),function(c){H(c,b[c]=a[c])})};var I=0;b.uniqueId=function(a){var b=I++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g};b.template=function(a,c){var d=b.templateSettings;d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.interpolate,function(a,b){return"',"+b.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||
+null,function(a,b){return"');"+b.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+"__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');";d=new Function("obj",d);return c?d(c):d};var j=function(a){this._wrapped=a};b.prototype=j.prototype;var r=function(a,c){return c?b(a).chain():a},H=function(a,c){j.prototype[a]=function(){var a=f.call(arguments);D.call(a,this._wrapped);return r(c.apply(b,a),this._chain)}};b.mixin(b);h(["pop","push","reverse","shift","sort",
+"splice","unshift"],function(a){var b=i[a];j.prototype[a]=function(){b.apply(this._wrapped,arguments);return r(this._wrapped,this._chain)}});h(["concat","join","slice"],function(a){var b=i[a];j.prototype[a]=function(){return r(b.apply(this._wrapped,arguments),this._chain)}});j.prototype.chain=function(){this._chain=!0;return this};j.prototype.value=function(){return this._wrapped}})();
diff --git a/browserid/static/dialog/dialog/scripts/build.html b/browserid/static/dialog/dialog/scripts/build.html
new file mode 100644
index 0000000000000000000000000000000000000000..93ee599fd2f77ab4e5400927ff2ca2fbd4c0fd75
--- /dev/null
+++ b/browserid/static/dialog/dialog/scripts/build.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>dialog Build Page</title>
+	</head>
+	<body>
+	    <h1>dialog Build Page</h1>
+		<p>This is a dummy page that loads your app so steal can
+		   get all the files.  
+		</p>
+		<p>If you built your app
+		   to depend on HTML in the page before DOMContent loaded or 
+		   onload, you can add the HTML here, or you can change the
+		   build.js script to point to a better html file.
+		</p>
+		<script type='text/javascript' 
+	    src='../../../../../../../../steal/steal.js?/web/browserid/browserid/static/dialog/dialog'>	 
+        </script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/dialog/scripts/build.js b/browserid/static/dialog/dialog/scripts/build.js
new file mode 100644
index 0000000000000000000000000000000000000000..83b59be61ba2bfa9801032ea6855c9e2a6d8e323
--- /dev/null
+++ b/browserid/static/dialog/dialog/scripts/build.js
@@ -0,0 +1,6 @@
+//steal/js /web/browserid/browserid/static/dialog/dialog/scripts/compress.js
+
+load("steal/rhino/steal.js");
+steal.plugins('steal/build','steal/build/scripts','steal/build/styles',function(){
+	steal.build('/web/browserid/browserid/static/dialog/dialog/scripts/build.html',{to: '/web/browserid/browserid/static/dialog/dialog'});
+});
diff --git a/browserid/static/dialog/dialog/scripts/clean.js b/browserid/static/dialog/dialog/scripts/clean.js
new file mode 100644
index 0000000000000000000000000000000000000000..83d4a1081728e78afa77d051518c89c167b021b6
--- /dev/null
+++ b/browserid/static/dialog/dialog/scripts/clean.js
@@ -0,0 +1,17 @@
+//steal/js /web/browserid/browserid/static/dialog/dialog/scripts/compress.js
+
+load("steal/rhino/steal.js");
+steal.plugins('steal/clean',function(){
+	steal.clean('/web/browserid/browserid/static/dialog/dialog/dialog.html',{
+		indent_size: 1, 
+		indent_char: '\t', 
+		jslint : false,
+		ignore: /jquery\/jquery.js/,
+		predefined: {
+			steal: true, 
+			jQuery: true, 
+			$ : true,
+			window : true
+			}
+	});
+});
diff --git a/browserid/static/dialog/dialog/scripts/docs.js b/browserid/static/dialog/dialog/scripts/docs.js
new file mode 100644
index 0000000000000000000000000000000000000000..e9f61d1bd4dbfb1eb8f81555d12a0e10b004000b
--- /dev/null
+++ b/browserid/static/dialog/dialog/scripts/docs.js
@@ -0,0 +1,6 @@
+//js /web/browserid/browserid/static/dialog/dialog/scripts/doc.js
+
+load('steal/rhino/steal.js');
+steal.plugins("documentjs").then(function(){
+	DocumentJS('/web/browserid/browserid/static/dialog/dialog/dialog.html');
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/dialog/style.css b/browserid/static/dialog/dialog/style.css
new file mode 100644
index 0000000000000000000000000000000000000000..6e5b5714f357a1de38efa805c905a3babdbdcc23
--- /dev/null
+++ b/browserid/static/dialog/dialog/style.css
@@ -0,0 +1,271 @@
+@font-face {
+  font-family: 'Shadows Into Light';
+  font-style: normal;
+  font-weight: normal;
+  src: local('Shadows Into Light'), local('ShadowsIntoLight'), url('../css/sil.ttf') format('truetype');
+}
+
+@font-face {
+  font-family: 'Tenor Sans';
+  font-style: normal;
+  font-weight: normal;
+  src: local('Tenor Sans'), local('TenorSans'), url('../css/ts.ttf') format('truetype');
+}
+
+body {
+    position: absolute;
+    font-family: 'Tenor Sans', Helvetica Narrow, sans-serif;
+    font-size: 11pt;
+    width: 518px;
+    height: 348px;
+    padding: 0;
+    margin: 0;
+}
+
+span.sitename, span.email {
+    font-weight: bold;
+}
+
+.dialog .title {
+    font-size: 2em;
+    font-weight: bold;
+    margin: auto;
+    margin-top: .5em;
+    margin-bottom: 1em;
+}
+
+#logo {
+    margin: 0;
+    padding: 0;
+    width: 575px;
+    position: fixed;
+    left: 30px;
+    top: 120px;
+    opacity: .1;
+    -moz-transform: rotate(-25deg);
+    -webkit-transform: rotate(-25deg);
+    transform: rotate(-25deg);
+    z-index: -5;
+}
+
+#logo > img {
+    width: 100%;
+}
+
+#bottom-bar {
+    margin: 0;
+    padding: 0;
+    border: 0;
+    position: fixed;
+    left: 0;
+    bottom: 0;
+    height: 60px;
+    width: 100%;
+    border-top: 2px solid rgb(218, 230, 237);
+    background-color: rgb(244, 247, 251);
+}
+
+
+#bottom-bar button {
+    height: 25px;
+    border: 1px solid rgb(145, 145, 145);
+    -moz-border-radius: 4px;
+    -webkit-border-radius: 4px;
+    border-radius: 4px;
+    background-color: rgb(242, 242, 242);
+    padding-left: 2em;
+    padding-right: 2em;
+    margin-left: 1em;
+    margin-right: 1em;
+    margin-top: 16px;
+    display: none;
+    z-index: 0;
+}
+
+#bottom-bar button.righty {
+    float: right;
+}
+
+#bottom-bar button.action {
+    background-color: rgb(0,128,211);
+    color: #fff;
+    font-weight: bold;
+}
+
+div.actions > div.action {
+    float: left;
+    margin-right: 1em;
+}
+
+div.actions > div.action a {
+    cursor: pointer;
+    color: rgb(65, 126, 208);
+    text-decoration: none;
+}
+
+div.actions {
+    position: fixed;
+    bottom: 68px;
+    font-size: .8em;
+    margin-left: 79px;
+}
+
+#identities {
+    width: 450px;
+    margin: auto;
+}
+
+#identities > div {
+    margin-bottom: .5em;
+    height: 1.4em;
+    font-size: .9em;
+}
+
+#identities > div > * {
+    float: left;
+    cursor: pointer;
+}
+
+button {
+    cursor: pointer;
+}
+
+button.disabled {
+    cursor: default;
+    opacity: .3;
+}
+
+.dialog {
+    position: fixed;
+    top: 40px;
+    right: 0;
+    bottom: 60px;
+    left: 0;
+    margin: auto;
+    text-align: center;
+}
+
+div.input > * {
+    float: left;
+}
+
+div.input > div.note {
+    float: right;
+    margin-top: .7em;
+}
+
+div.content {
+    width: 450px;
+    margin: auto;
+    margin-top: 20px;
+    text-align: left;
+}
+
+div.content > div.input {
+    height: 3em;
+    font-size: .8em;
+}
+
+div.content > div.summary {
+    text-align: left;
+    margin-bottom: 2em;
+}
+
+div.content > div.input > div.label {
+    width: 80px;
+    text-align: left;
+    margin-top: .7em;
+}
+
+div.input input {
+    border: 1px solid black;
+    width: 240px;
+    height: 2em;
+    padding: .4em;
+}
+
+a {
+    color: rgb(65, 126, 208);
+    text-decoration: none;
+}
+
+span.warning {
+    color: rgb(153,153,84);
+}
+
+span.bad {
+    color: rgb(149,43,9);
+}
+
+span.good {
+    color: rgb(0,161,51);
+}
+
+div.subtle {
+    opacity: .7;
+}
+
+div.dialog div.attention, div.dialog div.attention_awesome, div.dialog div.attention_lame  {
+    -moz-border-radius: 4px;
+    -webkit-border-radius: 4px;
+    border-radius: 4px 4px 4px 4px;
+    width: 400px;
+    padding:13px;
+    margin: auto;
+    text-align: left;
+    margin-top: 1em;
+}
+
+div.dialog div.attention {
+    border: 1px solid rgb(219,231,238);
+    background-color: rgb(244,247,251);
+}
+
+div.dialog div.attention_awesome {
+    border: 1px solid rgb(0,161,51);
+    background-color: rgb(0,161,51);
+    color: white;
+    font-weight: bold;
+}
+
+div.dialog div.attention_lame {
+    border: 1px solid rgb(224,178,139);
+    background-color: rgb(253,239,208);
+    color: rgb(120,43,9);
+    font-size: .8em;
+}
+
+#header {
+    position: fixed;
+    padding: 0;
+    border: 0;
+    margin: 0;
+    left: 0;
+    top: 0;
+    height: 40px;
+    width: 100%;
+    background: #008;
+    color: #fff;
+}
+
+#header .title {
+    font-size: 1.7em;
+    font-weight: bold;
+    float: left;
+    margin: 4px 16px 0 16px;
+}
+
+#header .subtitle {
+    size: 1.2em;
+    font-family: 'Shadows into light', arial, serif;
+    float: left;
+    margin-top: .6em;
+}
+
+p.prompt {
+    font-size: 1.1em;
+}
+
+p.prompt .sitename {
+    font-size: 1.1em;
+}
\ No newline at end of file
diff --git a/browserid/static/dialog/dialog/test/funcunit/dialog_test.js b/browserid/static/dialog/dialog/test/funcunit/dialog_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..60a273032fa7f937ee6bdf9672bb573057ec6263
--- /dev/null
+++ b/browserid/static/dialog/dialog/test/funcunit/dialog_test.js
@@ -0,0 +1,9 @@
+module("dialog test", { 
+	setup: function(){
+		S.open("///web/browserid/browserid/static/dialog/dialog/dialog.html");
+	}
+});
+
+test("Copy Test", function(){
+	equals(S("h1").text(), "Welcome to JavaScriptMVC 3.0!","welcome text");
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/dialog/test/funcunit/funcunit.js b/browserid/static/dialog/dialog/test/funcunit/funcunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..2d52307c1583c6ea4e040f4acb54f0cfdc52ba9c
--- /dev/null
+++ b/browserid/static/dialog/dialog/test/funcunit/funcunit.js
@@ -0,0 +1,3 @@
+steal
+ .plugins("funcunit")
+ .then("dialog_test");
\ No newline at end of file
diff --git a/browserid/static/dialog/dialog/test/qunit/dialog_test.js b/browserid/static/dialog/dialog/test/qunit/dialog_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..60d7fe33b9a4c7b719dbfb03151d457563641877
--- /dev/null
+++ b/browserid/static/dialog/dialog/test/qunit/dialog_test.js
@@ -0,0 +1,5 @@
+module("dialog");
+
+test("dialog testing works", function(){
+	ok(true,"an assert is run");
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/dialog/test/qunit/qunit.js b/browserid/static/dialog/dialog/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..736315c0ae5d25da0fcb20a90bec0e528936d2be
--- /dev/null
+++ b/browserid/static/dialog/dialog/test/qunit/qunit.js
@@ -0,0 +1,3 @@
+steal
+  .plugins("funcunit/qunit", "/web/browserid/browserid/static/dialog/dialog")
+  .then("dialog_test");
\ No newline at end of file
diff --git a/browserid/static/dialog/dialog/views/signin/index.ejs b/browserid/static/dialog/dialog/views/signin/index.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..4830c69638275af435e504fb6384bfae58b21592
--- /dev/null
+++ b/browserid/static/dialog/dialog/views/signin/index.ejs
@@ -0,0 +1,23 @@
+  <div class="content">
+    <p class="prompt">Logging into <span class="sitename bad">{{sitename}}</span>:</p>
+    <div class="input">
+      <div class="label"> Email </div>
+      <div class="input"> <input type="text"></input></div>
+    </div>
+    <div class="input">
+      <div class="label"> Password </div>
+      <div class="input"> <input type="password"></input></div>
+      <div class="note"> <a href="#">I forgot my password</a> </div>
+    </div>
+    <div class="attention_lame">
+      No such account exists with that email and/or password
+    </div>
+    <div class="actions">
+      <div class="action"><a href="#">Don't have a BrowserID yet?</a></div>
+    </div>
+  </div>
+<div id="bottom-bar">
+  <button id="back">Go Back</button>
+  <button id="submit" class="righty action">Sign In</button>
+  <button id="cancel" class="righty">Cancel</button>
+</div>
diff --git a/browserid/static/dialog/index.html b/browserid/static/dialog/index.html
index a82a72b0bd365f09a6ce85b471b45fe74733e0f1..34b6ba9e8d38449e839d51880103435a2b9ede02 100644
--- a/browserid/static/dialog/index.html
+++ b/browserid/static/dialog/index.html
@@ -2,18 +2,14 @@
 <head>
   <title> BrowserID </title>
   <link href="../dialog/style.css" type="text/css" media="screen" rel="stylesheet"></link>
-  <!-- XXX: jquery shouldn't be used, it's too big.  we're using it now cause this is a proof of concept -->
-  <script src="../dialog/jquery-min.js"></script>
-  <script src="../dialog/underscore-min.js"></script>
-  <script src="../dialog/backbone-min.js"></script>
-  <script src="../dialog/ICanHaz.min.js"></script>
-  <script src="../dialog/jschannel.js"></script>
-  <script src="../dialog/crypto-stubs.js"></script>
-  <script src="../dialog/main.js"></script>
-
-<script id="authenticate_dialog" type="text/html">
+</head>
+<body id="body">
+<div id="header">
+  <div class="title"><img src="../i/browserid_logo_lil.png"></div><div class="subtitle">A better way to log in.</div>
+</div>
+<div id="authenticate_dialog" class="dialog">
   <div class="content">
-    <p class="prompt">Logging into <span class="sitename bad">{{sitename}}</span>:</p>
+    <p class="prompt">Logging into <span class="sitename bad"></span>:</p>
     <div class="input">
       <div class="label"> Email </div>
       <div class="input"> <input type="text"></input></div>
@@ -30,13 +26,8 @@
       <div class="action"><a href="#">Don't have a BrowserID yet?</a></div>
     </div>
   </div>
-<div id="bottom-bar">
-  <button id="back">Go Back</button>
-  <button id="submit" class="righty action">Sign In</button>
-  <button id="cancel" class="righty">Cancel</button>
 </div>
-</script>
-<script id="create_dialog" type="text/html">
+<div id="create_dialog" class="dialog">
   <div class="content">
     <div class="summary create">BrowserID makes logging in <b>safer and easier</b>.  To begin, please provide an email address and pick a password:</div>
     <div class="summary forgot"><b>Forgot your password?</b>  No problem!  Enter your email address, pick a new password, and we'll get you set up again!</div>
@@ -58,11 +49,11 @@
       <span id="in_use_email">Email</span> in use, If this email is yours you can <a href="#">log in</a> with it?
     </div>
   </div>
-</script>
-<script id="confirm_email_dialog" type="text/html">
+</div>
+<div id="confirm_email_dialog" class="dialog">
   <div class="title"> Confirm Your Email </div>
   <div class="content">
-    <div class="summary">Welcome, <span class="email good">{{email}}</span>.  You will receive a <strong>confirmation email</strong> in a few moments.  To activate your BrowserID, please <strong>visit the link</strong> included in the email.</div>
+    <div class="summary">Welcome, <span class="email good"></span>.  You will receive a <strong>confirmation email</strong> in a few moments.  To activate your BrowserID, please <strong>visit the link</strong> included in the email.</div>
     <div class="attention">
       Waiting for email confirmation...
     </div>
@@ -70,17 +61,17 @@
       <div class="action"> No email yet?  <a href="#">Resend it!</a></div>
     </div>
   </div>
-</script>
-<script id="confirmed_email_dialog" type="text/html">
+</div>
+<div id="confirmed_email_dialog" class="dialog">
   <div class="title"> Confirm Your Email </div>
   <div class="content">
-    <div class="summary">Welcome, <span class="email good">{{email}}</span>.  You will receive a <strong>confirmation email</strong> in a few moments.  To prove that this is your email address, please <strong>visit the link</strong> included in the email.</div>
+    <div class="summary">Welcome, <span class="email good"></span>.  You will receive a <strong>confirmation email</strong> in a few moments.  To prove that this is your email address, please <strong>visit the link</strong> included in the email.</div>
     <div class="attention_awesome ">
       Your email has been confirmed! </span>
     </div>
   </div>
-</script>
-<script id="add_email_dialog" type="text/html">
+</div>
+<div id="add_email_dialog" class="dialog">
   <div class="title"> Add a new email address </div>
   <div class="content">
     <div class="summary">Setting up a up a new email address is easy, tell us what it is and we'll get started:</div>
@@ -90,36 +81,37 @@
       <div class="note"></div>
     </div>
   </div>
-</script>
-<script id="sign_in_dialog" type="text/html">
+</div>
+<div id="sign_in_dialog" class="dialog">
   <div class="content">
-    <p class="prompt">What email address would you like to use to log into <span class="sitename bad">{{sitename}}</span>?</p>
+    <p class="prompt">What email address would you like to use to log into <span class="sitename bad"></span>?</p>
     <form id="identities" name="identities">
-      <!-- add identities form -->
     </form>
   </div>
   <div class="actions">
     <div class="action"><a href="#">Add a new email address</a></div>
     <div class="action"><a href="#">This is not me.</a></div>
   </div>
-</script>
-<script id="error_dialog" type="text/html">
+</div>
+<div id="error_dialog" class="dialog">
   <div class="title"> Sign in with BrowserID </div>
   <div class="content">
   </div>
-</script>
-<script id="waiting_dialog" type="text/html">
+</div>
+<div id="waiting_dialog" class="dialog">
   <div class="title"> Sign in with BrowserID </div>
   <div class="content">
   </div>
-</script>
-
-</head>
-<body id="body">
-<div id="header">
-  <div class="title"><img src="../i/browserid_logo_lil.png"></div><div class="subtitle">A better way to log in.</div>
 </div>
-<div id="main" class="dialog">
+<div id="bottom-bar">
+  <button id="back">Go Back</button>
+  <button id="submit" class="righty action">Sign In</button>
+  <button id="cancel" class="righty">Cancel</button>
 </div>
 </body>
+<!-- XXX: jquery shouldn't be used, it's too big.  we're using it now cause this is a proof of concept -->
+<script src="../dialog/jquery-min.js"></script>
+<script src="../dialog/jschannel.js"></script>
+<script src="../dialog/crypto-stubs.js"></script>
+<script src="../dialog/main.js"></script>
 </html>
diff --git a/browserid/static/dialog/jquery/.gitignore b/browserid/static/dialog/jquery/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..96adf415fca31e5f0596e7901226f7c3fc94a25e
--- /dev/null
+++ b/browserid/static/dialog/jquery/.gitignore
@@ -0,0 +1,3 @@
+.tmp*
+dist
+*.swp
diff --git a/browserid/static/dialog/jquery/README b/browserid/static/dialog/jquery/README
new file mode 100644
index 0000000000000000000000000000000000000000..12846a178313bc0f3a42fab10258e442198610c0
--- /dev/null
+++ b/browserid/static/dialog/jquery/README
@@ -0,0 +1,24 @@
+TOC:
+  A.  How to get (and contribute) to JMVC
+
+
+A.  How to get (and contribute) JMVC
+
+  1.  Start a new project in git.
+  
+  2.  Fork ....
+           http://github.com/jupiterjs/steal     and 
+           http://github.com/jupiterjs/jquerymx
+  
+  3.  Add steal and javascriptmvc as submodules of your project...
+           git submodule add git@github.com:_YOU_/steal.git steal
+           git submodule add git@github.com:_YOU_/jquerymx.git jquery
+           
+      * Notice javascriptmvc is under the jquery folder
+  
+  4.  Learn a little more about submodules ...
+           http://johnleach.co.uk/words/archives/2008/10/12/323/git-submodules-in-n-easy-steps
+           
+  5.  Make changes in steal or jmvc, and push them back to your fork.
+  
+  6.  Make a pull request to your fork.
diff --git a/browserid/static/dialog/jquery/build.js b/browserid/static/dialog/jquery/build.js
new file mode 100644
index 0000000000000000000000000000000000000000..607378567df71e62164c7b4eebcf2661afb2fac7
--- /dev/null
+++ b/browserid/static/dialog/jquery/build.js
@@ -0,0 +1,151 @@
+// load('jquery/build.js')
+
+load('steal/rhino/steal.js')
+
+var i, fileName, cmd, 
+	plugins = [
+	"class" , 
+	"controller",
+	{
+		plugin: "controller/subscribe", 
+		exclude: ["jquery/controller/controller.js",
+				  "jquery/class/class.js",
+				  "jquery/lang/lang.js",
+				  "jquery/event/destroyed/destroyed.js",
+				  "jquery/controller/controller.js"]},
+	"event/default",
+	"event/destroyed",
+	"event/drag",
+	{
+		plugin: "event/drag/limit", 
+		exclude: ["jquery/lang/vector/vector.js", "jquery/event/livehack/livehack.js", "jquery/event/drag/drag.js"]},
+	{
+		plugin: "event/drag/scroll", 
+		exclude: ["jquery/dom/within/within.js", "jquery/dom/compare/compare.js", "jquery/event/drop/drop.js","jquery/lang/vector/vector.js", "jquery/event/livehack/livehack.js", "jquery/event/drag/drag.js"]},
+	{
+		plugin: "event/drop",
+		exclude: ["jquery/lang/vector/vector.js", "jquery/event/livehack/livehack.js", "jquery/event/drag/drag.js"]},
+	"event/hover",
+	"view/ejs", 
+	"dom/closest",
+	"dom/compare",
+	{
+		plugin: "dom/dimensions",
+		fileName: "jquery.dimensions.etc.js"
+	},
+	"dom/fixture",
+	"dom/form_params",
+	"dom/within", 
+	"dom/cur_styles",
+	"model",
+	{
+		plugin: "model/associations",
+		exclude: ["jquery/class/class.js",
+				  "jquery/lang/lang.js",
+				  "jquery/event/destroyed/destroyed.js",
+				  "jquery/lang/openajax/openajax.js",
+				  "jquery/model/model.js"]
+	},
+	{
+		plugin: "model/backup",
+		exclude: ["jquery/class/class.js",
+				  "jquery/lang/lang.js",
+				  "jquery/event/destroyed/destroyed.js",
+				  "jquery/lang/openajax/openajax.js",
+				  "jquery/model/model.js"]
+	},
+	{
+		plugin: "model/list",
+		exclude: ["jquery/class/class.js",
+				  "jquery/lang/lang.js",
+				  "jquery/event/destroyed/destroyed.js",
+				  "jquery/lang/openajax/openajax.js",
+				  "jquery/model/model.js"]
+	},
+	{
+		plugin: "model/list/cookie",
+		exclude: ["jquery/class/class.js",
+				  "jquery/lang/lang.js",
+				  "jquery/event/destroyed/destroyed.js",
+				  "jquery/lang/openajax/openajax.js",
+				  "jquery/model/model.js",
+				  "jquery/model/list/list.js"]
+	},
+	{
+		plugin: "model/list/local",
+		exclude: ["jquery/class/class.js",
+				  "jquery/lang/lang.js",
+				  "jquery/event/destroyed/destroyed.js",
+				  "jquery/lang/openajax/openajax.js",
+				  "jquery/model/model.js",
+				  "jquery/model/list/list.js"]
+	},
+	{
+		plugin: "model/validations",
+		exclude: ["jquery/class/class.js",
+				  "jquery/lang/lang.js",
+				  "jquery/event/destroyed/destroyed.js",
+				  "jquery/lang/openajax/openajax.js",
+				  "jquery/model/model.js"]
+	},
+	"view",
+	"view/ejs",
+	"view/jaml",
+	"view/micro",
+	"view/tmpl"
+]
+
+
+steal.plugins('steal/build/pluginify').then( function(s){
+var plugin, exclude, fileDest, fileName;
+	for(i=0; i<plugins.length; i++){
+		plugin = plugins[i];
+		exclude = [];
+		fileName = null;
+		if (typeof plugin != "string") {
+			fileName = plugin.fileName;
+			exclude = plugin.exclude || [];
+			plugin = plugin.plugin;
+		}
+		fileName = fileName || "jquery."+plugin.replace(/\//g, ".").replace(/dom\./, "").replace(/\_/, "")+".js";
+		fileDest = "jquery/dist/"+fileName
+		s.build.pluginify("jquery/"+plugin,{
+			nojquery: true,
+			destination: fileDest,
+			exclude: exclude.length? exclude: false
+		})
+		
+		
+		var outBaos = new java.io.ByteArrayOutputStream();
+		var output = new java.io.PrintStream(outBaos);
+		runCommand("java", "-jar", "steal/build/scripts/compiler.jar", "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--js", fileDest, {
+			output: output
+		});
+		
+		var minFileDest = fileDest.replace(".js", ".min.js")
+		new steal.File(minFileDest).save(outBaos.toString());
+	}
+})
+/*
+for (i = 0; i < plugins.length; i++) {
+	plugin = plugins[i];
+	exclude = [];
+	fileName = null;
+	if (typeof plugin != "string") {
+		fileName = plugin.fileName;
+		exclude = plugin.exclude || [];
+		plugin = plugin.plugin;
+	}
+	fileName = fileName || "jquery." + plugin.replace(/\//g, ".").replace(/dom\./, "").replace(/\_/, "") + ".js";
+	fileDest = "jquery/dist/" + fileName
+	// compress 
+	var outBaos = new java.io.ByteArrayOutputStream();
+	var output = new java.io.PrintStream(outBaos);
+	runCommand("java", "-jar", "steal/build/scripts/compiler.jar", "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--js", fileDest, {
+		output: output
+	});
+	
+	var minFileDest = fileDest.replace(".js", ".min.js")
+	new steal.File(minFileDest).save(outBaos.toString());
+	print("***" + fileName + " pluginified and compressed")
+}*/
diff --git a/browserid/static/dialog/jquery/buildAll.js b/browserid/static/dialog/jquery/buildAll.js
new file mode 100644
index 0000000000000000000000000000000000000000..06cbf45eec6ece65b35eb2df94a313d83b37248d
--- /dev/null
+++ b/browserid/static/dialog/jquery/buildAll.js
@@ -0,0 +1,102 @@
+// load('jquery/build.js')
+
+load('steal/rhino/steal.js')
+
+
+// load every plugin in a single app
+// get dependency graph
+// generate single script
+
+steal.plugins('steal/build/pluginify','steal/build/apps','steal/build/scripts').then( function(s){
+	var ignore = /\.\w+|test|generate|dist|qunit|fixtures|pages/
+	
+	var plugins = [];
+	
+	s.File('jquery').contents(function( name, type, current ) {
+		if (type !== 'file' && !ignore.test(name)) {
+			var folder = current+"/"+name;
+			print(folder);
+			plugins.push(folder);
+			steal.File(folder).contents(arguments.callee, folder)
+			//steal.File(path + "/" + (current ? current + "/" : "") + name).contents(arguments.callee, (current ? current + "/" : "") + name);
+		}
+	},"jquery");
+	
+	// tell it to load all plugins into this page
+	rhinoLoader = {
+		callback: function( s ) {
+			s.plugins.apply(s,plugins);
+		}
+	};
+	
+	steal.win().build_in_progress = true;
+	print("  LOADING APP ")
+	var pageSteal = steal.build.open("steal/rhino/empty.html").steal,
+		steals = pageSteal.total,
+		//hash of names to steals
+		files = {},
+		depends = function(stl, steals){
+			if(stl.dependencies){
+				for (var d = 0; d < stl.dependencies.length; d++) {
+					var depend = stl.dependencies[d];
+					if(!steals[depend.path]){
+						steals[depend.path] = true;
+						print("  " + depend.path);
+						//depends(depend, steals);
+					}
+					
+					
+				}
+			}
+		},
+		all = function(c){
+			for(var i =0; i < steals.length; i++){
+				var pSteal =steals[i];
+				
+				if(!pSteal.func){
+					c(pSteal)
+				}
+				
+			}
+			
+		};
+	print("  LOADED, GETTING DEPENDS");
+	all(function(stl){
+		files[stl.path] = stl;
+	})
+	all(function(stl){
+		print(stl.path)
+		var dependencies = files[stl.path] = [];
+		if(stl.dependencies){
+			for (var d = 0; d < stl.dependencies.length; d++) {
+				var depend = stl.dependencies[d];
+				dependencies.push(depend.path);
+			}
+		}
+	})
+	
+	steal.File("jquery/dist/standalone/dependencies.json").save($.toJSON(files));
+	//get each file ...
+	print("Creating jquery/dist/standalone/")
+	var compressor = steal.build.builders.scripts.compressors[ "localClosure"]()
+	for(var path in files){
+		if(path == "jquery/jquery.js"){
+			continue;
+		}
+		var content = readFile(path);
+		var funcContent = s.build.pluginify.getFunction(content);
+		if(typeof funcContent ==  "undefined"){
+			content = "";
+		} else {
+			content = "("+s.build.pluginify.getFunction(content)+")(jQuery);";
+		}
+		var out = path.replace(/\/\w+\.js/,"").replace(/\//g,".");
+		content = steal.build.builders.scripts.clean(content);
+		print("  "+out+"");
+		content = steal.build.builders.scripts.clean(content);
+		s.File("jquery/dist/standalone/"+out+".js").save(content);
+		s.File("jquery/dist/standalone/"+out+".min.js").save(compressor(content));
+	}
+	
+
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/class/class.html b/browserid/static/dialog/jquery/class/class.html
new file mode 100644
index 0000000000000000000000000000000000000000..a4386612a57be0b1c9301860d0edd1ada8391a1b
--- /dev/null
+++ b/browserid/static/dialog/jquery/class/class.html
@@ -0,0 +1,109 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+    <head>
+        <title>jQuery.Class Demo</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .tabs, .history_tabs {
+                
+                padding: 0px; margin: 20px 0 0 0;
+            }
+            li {
+                float: left;
+                padding: 10px;
+                background-color: #F6F6F6;
+                list-style: none;
+                margin-left: 10px;
+            }
+            li a {
+                color: #1C94C4;
+                font-weight: bold;
+                text-decoration: none;
+            }
+            li.active a {
+                color: #F6A828;
+                cursor: default;
+            }
+            .tab {
+                border: solid 1px #F6A828;
+            }
+            /* clearfix from jQueryUI */
+            .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+            .ui-helper-clearfix { display: inline-block; }
+            /* required comment for clearfix to work in Opera \*/
+            * html .ui-helper-clearfix { height:1%; }
+            .ui-helper-clearfix { display:block; }
+            /* end clearfix */
+        </style>
+    </head>
+    <body>
+<p>jQuery.Class Demo shows a tabs controller extended to work with history.</p>
+<div id="demo-html">
+<h2>Basic Tabs</h2>
+<ul id='tabs1' class='ui-helper-clearfix''>
+    <li><a href='#tab1'>Tab 1</a></li>
+    <li><a href='#tab2'>Tab 2</a></li>
+    <li><a href='#tab3'>Tab 3</a></li>
+</ul>
+<div id='tab1' class='tab'>Tab 1 Content</div>
+<div id='tab2' class='tab'>Tab 2 Content</div>
+<div id='tab3' class='tab'>Tab 3 Content</div>
+<h2>History Tabs</h2>
+<ul id='tabs2' class='ui-helper-clearfix''>
+    <li><a href='#tab4'>Tab 4</a></li>
+    <li><a href='#tab5'>Tab 5</a></li>
+    <li><a href='#tab6'>Tab 6</a></li>
+</ul>
+<div id='tab4' class='tab'>Tab 4 Content</div>
+<div id='tab5' class='tab'>Tab 5 Content</div>
+<div id='tab6' class='tab'>Tab 6 Content</div>
+</div>
+<script type='text/javascript'>DEMO_HTML = document.getElementById('demo-html').innerHTML</script>
+<script type='text/javascript' src='../../steal/steal.js'></script>
+<script type='text/javascript'>
+	steal.plugins('jquery/controller/history').start();
+</script>
+<script type='text/javascript' id="demo-source">
+$.Controller.extend("Tabs",{
+  init : function(){
+    this.element.children("li:first").addClass('active')
+    var tab = this.tab;
+    this.element.children("li:gt(0)").each(function(){
+      tab($(this)).hide()
+    })
+  },
+  tab : function(li){
+    return $(li.find("a").attr("href"))
+  },
+  "li click" : function(el, ev){
+    ev.preventDefault();
+    this.activate(el)
+  },
+  activate : function(el){
+    this.tab(this.find('.active').removeClass('active')).hide()
+    this.tab(el.addClass('active')).show();
+  }
+})
+
+//inherit from tabs
+Tabs.extend("HistoryTabs",{
+  // ignore clicks
+  "li click" : function(){},
+  
+  // listen for history changes
+  "history.** subscribe" : function(called){
+	var hash = window.location.hash;
+	this.activate(hash === '' || hash === '#' ?
+      this.element.find("li:first") : 
+      this.element.find("a[href="+hash+"]").parent()
+    )
+  }
+})
+
+//adds the controller to the element
+$("#tabs1").tabs();
+$("#tabs2").history_tabs();
+</script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/class/class.js b/browserid/static/dialog/jquery/class/class.js
new file mode 100644
index 0000000000000000000000000000000000000000..31db76ee6b3c846b1f370d0f182daf45f1003a84
--- /dev/null
+++ b/browserid/static/dialog/jquery/class/class.js
@@ -0,0 +1,642 @@
+//jQuery.Class 
+// This is a modified version of John Resig's class
+// http://ejohn.org/blog/simple-javascript-inheritance/
+// It provides class level inheritance and callbacks.
+//@steal-clean
+steal.plugins("jquery").then(function( $ ) {
+
+	// if we are initializing a new class
+	var initializing = false,
+
+		// tests if we can get super in .toString()
+		fnTest = /xyz/.test(function() {
+			xyz;
+		}) ? /\b_super\b/ : /.*/,
+
+		// overwrites an object with methods, sets up _super
+		inheritProps = function( newProps, oldProps, addTo ) {
+			addTo = addTo || newProps
+			for ( var name in newProps ) {
+				// Check if we're overwriting an existing function
+				addTo[name] = typeof newProps[name] == "function" && typeof oldProps[name] == "function" && fnTest.test(newProps[name]) ? (function( name, fn ) {
+					return function() {
+						var tmp = this._super,
+							ret;
+
+						// Add a new ._super() method that is the same method
+						// but on the super-class
+						this._super = oldProps[name];
+
+						// The method only need to be bound temporarily, so we
+						// remove it when we're done executing
+						ret = fn.apply(this, arguments);
+						this._super = tmp;
+						return ret;
+					};
+				})(name, newProps[name]) : newProps[name];
+			}
+		};
+
+
+	/**
+	 * @class jQuery.Class
+	 * @plugin jquery/class
+	 * @tag core
+	 * @download dist/jquery/jquery.class.js
+	 * @test jquery/class/qunit.html
+	 * Class provides simulated inheritance in JavaScript. Use $.Class to bridge the gap between
+	 * jQuery's functional programming style and Object Oriented Programming.
+	 * It is based off John Resig's [http://ejohn.org/blog/simple-javascript-inheritance/|Simple Class]
+	 * Inheritance library.  Besides prototypal inheritance, it includes a few important features:
+	 * <ul>
+	 *     <li>Static inheritance</li>
+	 *     <li>Introspection</li>
+	 *     <li>Namespaces</li>
+	 *     <li>Setup and initialization methods</li>
+	 *     <li>Easy callback function creation</li>
+	 * </ul>
+	 * <h2>Static v. Prototype</h2>
+	 * <p>Before learning about Class, it's important to
+	 * understand the difference between
+	 * a class's <b>static</b> and <b>prototype</b> properties.
+	 * </p>
+	 * @codestart
+	 * //STATIC
+	 * MyClass.staticProperty  //shared property
+	 *
+	 * //PROTOTYPE
+	 * myclass = new MyClass()
+	 * myclass.prototypeMethod() //instance method
+	 * @codeend
+	 * <p>A static (or class) property is on the Class constructor
+	 * function itself
+	 * and can be thought of being shared by all instances of the Class.
+	 * Prototype propertes are available only on instances of the Class.
+	 * </p>
+	 * <h2>A Basic Class</h2>
+	 * <p>The following creates a Monster class with a
+	 * name (for introspection), static, and prototype members.
+	 * Every time a monster instance is created, the static
+	 * count is incremented.
+	 *
+	 * </p>
+	 * @codestart
+	 * $.Class.extend('Monster',
+	 * /* @static *|
+	 * {
+	 *   count: 0
+	 * },
+	 * /* @prototype *|
+	 * {
+	 *   init: function( name ) {
+	 *
+	 *     // saves name on the monster instance
+	 *     this.name = name;
+	 *
+	 *     // sets the health
+	 *     this.health = 10;
+	 *
+	 *     // increments count
+	 *     this.Class.count++;
+	 *   },
+	 *   eat: function( smallChildren ){
+	 *     this.health += smallChildren;
+	 *   },
+	 *   fight: function() {
+	 *     this.health -= 2;
+	 *   }
+	 * });
+	 *
+	 * hydra = new Monster('hydra');
+	 *
+	 * dragon = new Monster('dragon');
+	 *
+	 * hydra.name        // -> hydra
+	 * Monster.count     // -> 2
+	 * Monster.shortName // -> 'Monster'
+	 *
+	 * hydra.eat(2);     // health = 12
+	 *
+	 * dragon.fight();   // health = 8
+	 *
+	 * @codeend
+	 *
+	 * <p>
+	 * Notice that the prototype <b>init</b> function is called when a new instance of Monster is created.
+	 * </p>
+	 * <h2>Inheritance</h2>
+	 * <p>When a class is extended, all static and prototype properties are available on the new class.
+	 * If you overwrite a function, you can call the base class's function by calling
+	 * <code>this._super</code>.  Lets create a SeaMonster class.  SeaMonsters are less
+	 * efficient at eating small children, but more powerful fighters.
+	 * </p>
+	 * @codestart
+	 * Monster.extend("SeaMonster",{
+	 *   eat: function( smallChildren ) {
+	 *     this._super(smallChildren / 2);
+	 *   },
+	 *   fight: function() {
+	 *     this.health -= 1;
+	 *   }
+	 * });
+	 *
+	 * lockNess = new SeaMonster('Lock Ness');
+	 * lockNess.eat(4);   //health = 12
+	 * lockNess.fight();  //health = 11
+	 * @codeend
+	 * <h3>Static property inheritance</h3>
+	 * You can also inherit static properties in the same way:
+	 * @codestart
+	 * $.Class.extend("First",
+	 * {
+	 *     staticMethod: function() { return 1;}
+	 * },{})
+	 *
+	 * First.extend("Second",{
+	 *     staticMethod: function() { return this._super()+1;}
+	 * },{})
+	 *
+	 * Second.staticMethod() // -> 2
+	 * @codeend
+	 * <h2>Namespaces</h2>
+	 * <p>Namespaces are a good idea! We encourage you to namespace all of your code.
+	 * It makes it possible to drop your code into another app without problems.
+	 * Making a namespaced class is easy:
+	 * </p>
+	 * @codestart
+	 * $.Class.extend("MyNamespace.MyClass",{},{});
+	 *
+	 * new MyNamespace.MyClass()
+	 * @codeend
+	 * <h2 id='introspection'>Introspection</h2>
+	 * Often, it's nice to create classes whose name helps determine functionality.  Ruby on
+	 * Rails's [http://api.rubyonrails.org/classes/ActiveRecord/Base.html|ActiveRecord] ORM class
+	 * is a great example of this.  Unfortunately, JavaScript doesn't have a way of determining
+	 * an object's name, so the developer must provide a name.  Class fixes this by taking a String name for the class.
+	 * @codestart
+	 * $.Class.extend("MyOrg.MyClass",{},{})
+	 * MyOrg.MyClass.shortName //-> 'MyClass'
+	 * MyOrg.MyClass.fullName //->  'MyOrg.MyClass'
+	 * @codeend
+	 * The fullName (with namespaces) and the shortName (without namespaces) are added to the Class's
+	 * static properties.
+	 *
+	 *
+	 * <h2>Setup and initialization methods</h2>
+	 * <p>
+	 * Class provides static and prototype initialization functions.
+	 * These come in two flavors - setup and init.
+	 * Setup is called before init and
+	 * can be used to 'normalize' init's arguments.
+	 * </p>
+	 * <div class='whisper'>PRO TIP: Typically, you don't need setup methods in your classes. Use Init instead.
+	 * Reserve setup methods for when you need to do complex pre-processing of your class before init is called.
+	 *
+	 * </div>
+	 * @codestart
+	 * $.Class.extend("MyClass",
+	 * {
+	 *   setup: function() {} //static setup
+	 *   init: function() {} //static constructor
+	 * },
+	 * {
+	 *   setup: function() {} //prototype setup
+	 *   init: function() {} //prototype constructor
+	 * })
+	 * @codeend
+	 *
+	 * <h3>Setup</h3>
+	 * <p>Setup functions are called before init functions.  Static setup functions are passed
+	 * the base class followed by arguments passed to the extend function.
+	 * Prototype static functions are passed the Class constructor function arguments.</p>
+	 * <p>If a setup function returns an array, that array will be used as the arguments
+	 * for the following init method.  This provides setup functions the ability to normalize
+	 * arguments passed to the init constructors.  They are also excellent places
+	 * to put setup code you want to almost always run.</p>
+	 * <p>
+	 * The following is similar to how [jQuery.Controller.prototype.setup]
+	 * makes sure init is always called with a jQuery element and merged options
+	 * even if it is passed a raw
+	 * HTMLElement and no second parameter.
+	 * </p>
+	 * @codestart
+	 * $.Class.extend("jQuery.Controller",{
+	 *   ...
+	 * },{
+	 *   setup: function( el, options ) {
+	 *     ...
+	 *     return [$(el),
+	 *             $.extend(true,
+	 *                this.Class.defaults,
+	 *                options || {} ) ]
+	 *   }
+	 * })
+	 * @codeend
+	 * Typically, you won't need to make or overwrite setup functions.
+	 * <h3>Init</h3>
+	 *
+	 * <p>Init functions are called after setup functions.
+	 * Typically, they receive the same arguments
+	 * as their preceding setup function.  The Foo class's <code>init</code> method
+	 * gets called in the following example:
+	 * </p>
+	 * @codestart
+	 * $.Class.Extend("Foo", {
+	 *   init: function( arg1, arg2, arg3 ) {
+	 *     this.sum = arg1+arg2+arg3;
+	 *   }
+	 * })
+	 * var foo = new Foo(1,2,3);
+	 * foo.sum //-> 6
+	 * @codeend
+	 * <h2>Callbacks</h2>
+	 * <p>Similar to jQuery's proxy method, Class provides a
+	 * [jQuery.Class.static.callback callback]
+	 * function that returns a callback to a method that will always
+	 * have
+	 * <code>this</code> set to the class or instance of the class.
+	 * </p>
+	 * The following example uses this.callback to make sure
+	 * <code>this.name</code> is available in <code>show</code>.
+	 * @codestart
+	 * $.Class.extend("Todo",{
+	 *   init: function( name ) { this.name = name }
+	 *   get: function() {
+	 *     $.get("/stuff",this.callback('show'))
+	 *   },
+	 *   show: function( txt ) {
+	 *     alert(this.name+txt)
+	 *   }
+	 * })
+	 * new Todo("Trash").get()
+	 * @codeend
+	 * <p>Callback is available as a static and prototype method.</p>
+	 * <h2>Demo</h2>
+	 * @demo jquery/class/class.html
+	 *
+	 * @constructor Creating a new instance of an object that has extended jQuery.Class
+	 *     calls the init prototype function and returns a new instance of the class.
+	 *
+	 */
+
+	jQuery.Class = function() {
+		if (arguments.length) {
+			jQuery.Class.extend.apply(jQuery.Class, arguments);
+		}
+	};
+
+	/* @Static*/
+	$.extend($.Class, {
+		/**
+		 * @function callback
+		 * Returns a callback function for a function on this Class.
+		 * The callback function ensures that 'this' is set appropriately.  
+		 * @codestart
+		 * $.Class.extend("MyClass",{
+		 *     getData: function() {
+		 *         this.showing = null;
+		 *         $.get("data.json",this.callback('gotData'),'json')
+		 *     },
+		 *     gotData: function( data ) {
+		 *         this.showing = data;
+		 *     }
+		 * },{});
+		 * MyClass.showData();
+		 * @codeend
+		 * <h2>Currying Arguments</h2>
+		 * Additional arguments to callback will fill in arguments on the returning function.
+		 * @codestart
+		 * $.Class.extend("MyClass",{
+		 *    getData: function( <b>callback</b> ) {
+		 *      $.get("data.json",this.callback('process',<b>callback</b>),'json');
+		 *    },
+		 *    process: function( <b>callback</b>, jsonData ) { //callback is added as first argument
+		 *        jsonData.processed = true;
+		 *        callback(jsonData);
+		 *    }
+		 * },{});
+		 * MyClass.getData(showDataFunc)
+		 * @codeend
+		 * <h2>Nesting Functions</h2>
+		 * Callback can take an array of functions to call as the first argument.  When the returned callback function
+		 * is called each function in the array is passed the return value of the prior function.  This is often used
+		 * to eliminate currying initial arguments.
+		 * @codestart
+		 * $.Class.extend("MyClass",{
+		 *    getData: function( callback ) {
+		 *      //calls process, then callback with value from process
+		 *      $.get("data.json",this.callback(['process2',callback]),'json') 
+		 *    },
+		 *    process2: function( type,jsonData ) {
+		 *        jsonData.processed = true;
+		 *        return [jsonData];
+		 *    }
+		 * },{});
+		 * MyClass.getData(showDataFunc);
+		 * @codeend
+		 * @param {String|Array} fname If a string, it represents the function to be called.  
+		 * If it is an array, it will call each function in order and pass the return value of the prior function to the
+		 * next function.
+		 * @return {Function} the callback function.
+		 */
+		callback: function( funcs ) {
+
+			//args that should be curried
+			var args = jQuery.makeArray(arguments),
+				self;
+
+			funcs = args.shift();
+
+			if (!jQuery.isArray(funcs) ) {
+				funcs = [funcs];
+			}
+
+			self = this;
+			//@steal-remove-start
+			for( var i =0; i< funcs.length;i++ ) {
+				if(typeof funcs[i] == "string" && typeof this[funcs[i]] !== 'function'){
+					throw ("class.js "+( this.fullName || this.Class.fullName)+" does not have a "+funcs[i]+"method!");
+				}
+			}
+			//@steal-remove-end
+			return function class_cb() {
+				var cur = args.concat(jQuery.makeArray(arguments)),
+					isString, 
+					length = funcs.length,
+					f = 0,
+					func;
+
+				for (; f < length; f++ ) {
+					func = funcs[f];
+					if (!func ) {
+						continue;
+					}
+
+					isString = typeof func == "string";
+					if ( isString && self._set_called ) {
+						self.called = func;
+					}
+					cur = (isString ? self[func] : func).apply(self, cur || []);
+					if ( f < length - 1 ) {
+						cur = !jQuery.isArray(cur) || cur._use_call ? [cur] : cur
+					}
+				}
+				return cur;
+			}
+		},
+		/**
+		 *   @function getObject 
+		 *   Gets an object from a String.
+		 *   If the object or namespaces the string represent do not
+		 *   exist it will create them.  
+		 *   @codestart
+		 *   Foo = {Bar: {Zar: {"Ted"}}}
+		 *   $.Class.getobject("Foo.Bar.Zar") //-> "Ted"
+		 *   @codeend
+		 *   @param {String} objectName the object you want to get
+		 *   @param {Object} [current=window] the object you want to look in.
+		 *   @return {Object} the object you are looking for.
+		 */
+		getObject: function( objectName, current ) {
+			var current = current || window,
+				parts = objectName ? objectName.split(/\./) : [],
+				i = 0;
+			for (; i < parts.length; i++ ) {
+				current = current[parts[i]] || (current[parts[i]] = {})
+			}
+			return current;
+		},
+		/**
+		 * @function newInstance
+		 * Creates a new instance of the class.  This method is useful for creating new instances
+		 * with arbitrary parameters.
+		 * <h3>Example</h3>
+		 * @codestart
+		 * $.Class.extend("MyClass",{},{})
+		 * var mc = MyClass.newInstance.apply(null, new Array(parseInt(Math.random()*10,10))
+		 * @codeend
+		 * @return {class} instance of the class
+		 */
+		newInstance: function() {
+			var inst = this.rawInstance(),
+				args;
+			if ( inst.setup ) {
+				args = inst.setup.apply(inst, arguments);
+			}
+			if ( inst.init ) {
+				inst.init.apply(inst, $.isArray(args) ? args : arguments);
+			}
+			return inst;
+		},
+		/**
+		 * Copy and overwrite options from old class
+		 * @param {Object} oldClass
+		 * @param {String} fullName
+		 * @param {Object} staticProps
+		 * @param {Object} protoProps
+		 */
+		setup: function( oldClass, fullName ) {
+			this.defaults = $.extend(true, {}, oldClass.defaults, this.defaults);
+			return arguments;
+		},
+		rawInstance: function() {
+			initializing = true;
+			var inst = new this();
+			initializing = false;
+			return inst;
+		},
+		/**
+		 * Extends a class with new static and prototype functions.  There are a variety of ways
+		 * to use extend:
+		 * @codestart
+		 * //with className, static and prototype functions
+		 * $.Class.extend('Task',{ STATIC },{ PROTOTYPE })
+		 * //with just classname and prototype functions
+		 * $.Class.extend('Task',{ PROTOTYPE })
+		 * //With just a className
+		 * $.Class.extend('Task')
+		 * @codeend
+		 * @param {String} [fullName]  the classes name (used for classes w/ introspection)
+		 * @param {Object} [klass]  the new classes static/class functions
+		 * @param {Object} [proto]  the new classes prototype functions
+		 * @return {jQuery.Class} returns the new class
+		 */
+		extend: function( fullName, klass, proto ) {
+			// figure out what was passed
+			if ( typeof fullName != 'string' ) {
+				proto = klass;
+				klass = fullName;
+				fullName = null;
+			}
+			if (!proto ) {
+				proto = klass;
+				klass = null;
+			}
+
+			proto = proto || {};
+			var _super_class = this,
+				_super = this.prototype,
+				name, shortName, namespace, prototype;
+
+			// Instantiate a base class (but only create the instance,
+			// don't run the init constructor)
+			initializing = true;
+			prototype = new this();
+			initializing = false;
+			// Copy the properties over onto the new prototype
+			inheritProps(proto, _super, prototype);
+
+			// The dummy class constructor
+
+			function Class() {
+				// All construction is actually done in the init method
+				if ( initializing ) return;
+
+				if ( this.constructor !== Class && arguments.length ) { //we are being called w/o new
+					return arguments.callee.extend.apply(arguments.callee, arguments)
+				} else { //we are being called w/ new
+					return this.Class.newInstance.apply(this.Class, arguments)
+				}
+			}
+			// Copy old stuff onto class
+			for ( name in this ) {
+				if ( this.hasOwnProperty(name) && $.inArray(name, ['prototype', 'defaults', 'getObject']) == -1 ) {
+					Class[name] = this[name];
+				}
+			}
+
+			// do static inheritance
+			inheritProps(klass, this, Class);
+
+			// do namespace stuff
+			if ( fullName ) {
+
+				var parts = fullName.split(/\./),
+					shortName = parts.pop(),
+					current = $.Class.getObject(parts.join('.')),
+					namespace = current;
+
+				//@steal-remove-start
+				if (!Class.nameOk ) {
+					steal.dev.isHappyName(fullName)
+				}
+				if(current[shortName]){
+					steal.dev.warn("class.js There's already something called "+fullName)
+				}
+				//@steal-remove-end
+				current[shortName] = Class;
+			}
+
+			// set things that can't be overwritten
+			$.extend(Class, {
+				prototype: prototype,
+				namespace: namespace,
+				shortName: shortName,
+				constructor: Class,
+				fullName: fullName
+			});
+
+			//make sure our prototype looks nice
+			Class.prototype.Class = Class.prototype.constructor = Class;
+
+
+			/**
+			 * @attribute fullName 
+			 * The full name of the class, including namespace, provided for introspection purposes.
+			 * @codestart
+			 * $.Class.extend("MyOrg.MyClass",{},{})
+			 * MyOrg.MyClass.shortName //-> 'MyClass'
+			 * MyOrg.MyClass.fullName //->  'MyOrg.MyClass'
+			 * @codeend
+			 */
+
+			var args = Class.setup.apply(Class, [_super_class].concat($.makeArray(arguments)));
+
+			if ( Class.init ) {
+				Class.init.apply(Class, args || []);
+			}
+
+			/* @Prototype*/
+			return Class;
+			/** 
+			 * @function setup
+			 * Called with the same arguments as new Class(arguments ...) when a new instance is created.
+			 * @codestart
+			 * $.Class.extend("MyClass",
+			 * {
+			 *    setup: function( val ) {
+			 *       this.val = val;
+			 *    }
+			 * })
+			 * var mc = new MyClass("Check Check")
+			 * mc.val //-> 'Check Check'
+			 * @codeend
+			 * 
+			 * <div class='whisper'>PRO TIP: 
+			 * Setup functions are used to normalize constructor arguments and provide a place for
+			 * setup code that extending classes don't have to remember to call _super to
+			 * run.
+			 * </div>
+			 * 
+			 * @return {Array|undefined} If an array is return, [jQuery.Class.prototype.init] is 
+			 * called with those arguments; otherwise, the original arguments are used.
+			 */
+			//break up
+			/** 
+			 * @function init
+			 * Called with the same arguments as new Class(arguments ...) when a new instance is created.
+			 * @codestart
+			 * $.Class.extend("MyClass",
+			 * {
+			 *    init: function( val ) {
+			 *       this.val = val;
+			 *    }
+			 * })
+			 * var mc = new MyClass("Check Check")
+			 * mc.val //-> 'Check Check'
+			 * @codeend
+			 */
+			//Breaks up code
+			/**
+			 * @attribute Class
+			 * References the static properties of the instance's class.
+			 * <h3>Quick Example</h3>
+			 * @codestart
+			 * // a class with a static classProperty property
+			 * $.Class.extend("MyClass", {classProperty : true}, {});
+			 * 
+			 * // a new instance of myClass
+			 * var mc1 = new MyClass();
+			 * 
+			 * //
+			 * mc1.Class.classProperty = false;
+			 * 
+			 * // creates a new MyClass
+			 * var mc2 = new mc.Class();
+			 * @codeend
+			 * Getting static properties via the Class property, such as it's 
+			 * [jQuery.Class.static.fullName fullName] is very common.
+			 */
+		}
+
+	})
+
+
+
+
+
+	jQuery.Class.prototype.
+	/**
+	 * @function callback
+	 * Returns a callback function.  This does the same thing as and is described better in [jQuery.Class.static.callback].
+	 * The only difference is this callback works
+	 * on a instance instead of a class.
+	 * @param {String|Array} fname If a string, it represents the function to be called.  
+	 * If it is an array, it will call each function in order and pass the return value of the prior function to the
+	 * next function.
+	 * @return {Function} the callback function
+	 */
+	callback = jQuery.Class.callback;
+
+
+})();
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/class/qunit.html b/browserid/static/dialog/jquery/class/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..255812e463aaaaecd1d7b6da8c584c65ba376869
--- /dev/null
+++ b/browserid/static/dialog/jquery/class/qunit.html
@@ -0,0 +1,15 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../funcunit/qunit/qunit.css" />
+    </head>
+    <body>
+
+    <h1 id="qunit-header">Class Test Suite</h1>
+	<h2 id="qunit-banner"></h2>
+	<div id="qunit-testrunner-toolbar"></div>
+	<h2 id="qunit-userAgent"></h2>
+    <ol id="qunit-tests"></ol>
+	<div id="qunit-test-area"></div>
+    <script type='text/javascript' src='../../steal/steal.js?steal[app]=jquery/class/test/qunit'></script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/class/test/qunit/class_test.js b/browserid/static/dialog/jquery/class/test/qunit/class_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..e3c86cce19d6cdf278b87855b7b844a527027eaa
--- /dev/null
+++ b/browserid/static/dialog/jquery/class/test/qunit/class_test.js
@@ -0,0 +1,180 @@
+module("jquery/class");
+
+test("Creating", function(){
+        
+    jQuery.Class.extend("Animal",
+    {
+        count: 0,
+        test: function() {
+            return this.match ? true : false
+        }
+    },
+    {
+        init: function() {
+            this.Class.count++;
+            this.eyes = false;
+        }
+    }
+    );
+    Animal.extend("Dog",
+    {
+        match : /abc/
+    },
+    {
+        init: function() {
+            this._super();
+        },
+		talk: function() {
+			return "Woof";
+		}
+    });
+    Dog.extend("Ajax",
+    {
+        count : 0
+    },
+    {
+        init: function( hairs ) {
+            this._super();
+            this.hairs = hairs;
+            this.setEyes();
+            
+        },
+        setEyes: function() {
+            this.eyes = true;
+        }
+    });
+    new Dog();
+    new Animal();
+    new Animal();
+    ajax = new Ajax(1000);
+        
+    equals(2, Animal.count, "right number of animals");
+    equals(1, Dog.count, "right number of animals")
+    ok(Dog.match, "right number of animals")
+    ok(!Animal.match, "right number of animals")
+    ok(Dog.test(), "right number of animals")
+    ok(!Animal.test(), "right number of animals")
+    equals(1, Ajax.count, "right number of animals")
+    equals(2, Animal.count, "right number of animals");
+    equals(true, ajax.eyes, "right number of animals");
+    equals(1000, ajax.hairs, "right number of animals");
+})
+
+
+test("new instance",function(){
+    var d = Ajax.newInstance(6);
+    equals(6, d.hairs);
+})
+
+
+test("namespaces",function(){
+	var fb = $.Class.extend("Foo.Bar")
+	ok(Foo.Bar === fb, "returns class")
+	equals(fb.shortName, "Bar", "short name is right");
+	equals(fb.fullName, "Foo.Bar","fullName is right")
+	
+})
+
+test("setups", function(){
+	var order = 0,
+		staticSetup,
+		staticSetupArgs,
+		staticInit,
+		staticInitArgs,
+		protoSetup,
+		protoInitArgs,
+		protoInit,
+		staticProps = {
+			setup: function() {
+				staticSetup = ++order;
+				staticSetupArgs = arguments;
+				return ["something"]
+			},
+			init: function() {
+				staticInit = ++order;
+				staticInitArgs = arguments;
+			}
+		},
+		protoProps = {
+			setup: function( name ) {
+				protoSetup = ++order;
+				return ["Ford: "+name];
+			},
+			init: function() {
+				protoInit = ++order;
+				protoInitArgs = arguments;
+			}
+		}
+	$.Class.extend("Car",staticProps,protoProps);
+	
+	var geo = new Car("geo");
+	equals(staticSetup, 1);
+	equals(staticInit, 2);
+	equals(protoSetup, 3);
+	equals(protoInit, 4);
+	
+	same($.makeArray(staticInitArgs), ["something"] )
+	same($.makeArray(protoInitArgs),["Ford: geo"] )
+	
+	same($.makeArray(staticSetupArgs),[$.Class, "Car",staticProps, protoProps] ,"static construct");
+	
+	
+	//now see if staticSetup gets called again ...
+	Car.extend("Truck");
+	equals(staticSetup, 5, "Static setup is called if overwriting");
+	
+});
+
+test("callback", function(){
+	var curVal = 0;
+	$.Class.extend("Car",{
+		show: function( value ) {
+			equals(curVal, value)
+		}
+	},{
+		show: function( value ) {
+			
+		}
+	})
+	var cb = Car.callback('show');
+	curVal = 1;
+	cb(1)
+	
+	curVal = 2;
+	var cb2 = Car.callback('show',2)
+	cb2();
+});
+
+test("callback error", 1,function(){
+	$.Class.extend("Car",{
+		show: function( value ) {
+			equals(curVal, value)
+		}
+	},{
+		show: function( value ) {
+			
+		}
+	})
+	try{
+		Car.callback('huh');
+		ok(false, "I should have errored")
+	}catch(e){
+		ok(true, "Error was thrown")
+	}
+})
+
+test("Creating without extend", function(){
+	$.Class("Bar",{
+		ok : function(){
+			ok(true, "ok called")
+		}
+	});
+	new Bar().ok();
+	
+	Bar("Foo",{
+		dude : function(){
+			ok(true, "dude called")
+		}
+	});
+	new Foo().dude(true);
+})
diff --git a/browserid/static/dialog/jquery/class/test/qunit/qunit.js b/browserid/static/dialog/jquery/class/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..3a2d2068840250eb895bd842d2eb9cfe61fff14f
--- /dev/null
+++ b/browserid/static/dialog/jquery/class/test/qunit/qunit.js
@@ -0,0 +1,5 @@
+//we probably have to have this only describing where the tests are
+steal
+ .plugins("jquery/class")  //load your app
+ .plugins('funcunit/qunit')  //load qunit
+ .then("class_test")
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/controller/controller.html b/browserid/static/dialog/jquery/controller/controller.html
new file mode 100644
index 0000000000000000000000000000000000000000..e22531663edce2e7ea5c12a40a519fe97a99e79d
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/controller.html
@@ -0,0 +1,89 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+    <head>
+        <title>Controller Example</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .tabs {
+                
+                padding: 0px; margin: 0px;
+            }
+            .tabs li {
+                float: left;
+                padding: 10px;
+                background-color: #F6F6F6;
+                list-style: none;
+                margin-left: 10px;
+            }
+            .tabs li a {
+                color: #1C94C4;
+                font-weight: bold;
+                text-decoration: none;
+            }
+            .tabs li.active a {
+                color: #F6A828;
+                cursor: default;
+            }
+            .tab {
+                border: solid 1px #F6A828;
+            }
+            /* clearfix from jQueryUI */
+            .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+            .ui-helper-clearfix { display: inline-block; }
+            /* required comment for clearfix to work in Opera \*/
+            * html .ui-helper-clearfix { height:1%; }
+            .ui-helper-clearfix { display:block; }
+            /* end clearfix */
+        </style>
+    </head>
+    <body>
+<div id="demo-html">
+<ul id='tabs' class='ui-helper-clearfix''>
+  <li><a href='#tab1'>Tab 1</a></li>
+  <li><a href='#tab2'>Tab 2</a></li>
+  <li><a href='#tab3'>Tab 3</a></li>
+</ul>
+<div id='tab1' class='tab'>Tab 1 Content</div>
+<div id='tab2' class='tab'>Tab 2 Content</div>
+<div id='tab3' class='tab'>Tab 3 Content</div>
+</div>
+<script type='text/javascript' src='../../steal/steal.js'></script>
+<script type='text/javascript'>
+    steal.plugins("jquery/controller").start();
+</script>
+<script type='text/javascript' id="demo-source">
+// create a new Tabs class
+$.Controller.extend("Tabs",{
+  
+  // initialize widget
+  init : function(el){
+    
+    // activate the first tab
+    $(el).children("li:first").addClass('active')
+    
+    // hide the other tabs
+    var tab = this.tab;
+    this.element.children("li:gt(0)").each(function(){
+      tab($(this)).hide()
+    })
+  },
+  
+  // helper function finds the tab for a given li
+  tab : function(li){
+    return $(li.find("a").attr("href"))
+  },
+  
+  // hides old active tab, shows new one
+  "li click" : function(el, ev){
+    ev.preventDefault();
+    this.tab(this.find('.active').removeClass('active')).hide()
+    this.tab(el.addClass('active')).show();
+  }
+})
+  
+// adds the controller to the element
+$("#tabs").tabs();
+</script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/controller/controller.js b/browserid/static/dialog/jquery/controller/controller.js
new file mode 100644
index 0000000000000000000000000000000000000000..2937bd3b6fa072735db377d80bfdcd76c113c2d8
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/controller.js
@@ -0,0 +1,880 @@
+steal.plugins('jquery/class', 'jquery/lang', 'jquery/event/destroyed').then(function( $ ) {
+
+	// ------- helpers  ------
+	// Binds an element, returns a function that unbinds
+	var bind = function( el, ev, callback ) {
+		var wrappedCallback;
+		//this is for events like >click.
+		if ( ev.indexOf(">") === 0 ) {
+			ev = ev.substr(1);
+			wrappedCallback = function( event ) {
+				if ( event.target === el ) {
+					callback.apply(this, arguments);
+				} else {
+					event.handled = null;
+				}
+			};
+		}
+		$(el).bind(ev, wrappedCallback || callback);
+		// if ev name has >, change the name and bind
+		// in the wrapped callback, check that the element matches the actual element
+		return function() {
+			$(el).unbind(ev, wrappedCallback || callback);
+			el = ev = callback = wrappedCallback = null;
+		};
+	},
+		// Binds an element, returns a function that unbinds
+		delegate = function( el, selector, ev, callback ) {
+			$(el).delegate(selector, ev, callback);
+			return function() {
+				$(el).undelegate(selector, ev, callback);
+				el = ev = callback = selector = null;
+			};
+		},
+		binder = function( el, ev, callback, selector ) {
+			return selector ? delegate(el, selector, ev, callback) : bind(el, ev, callback);
+		},
+		/**
+		 * moves 'this' to the first argument 
+		 */
+		shifter = function shifter(cb) {
+			return function() {
+				return cb.apply(null, [$(this)].concat(Array.prototype.slice.call(arguments, 0)));
+			};
+		},
+		// matches dots
+		dotsReg = /\./g,
+		// matches controller
+		controllersReg = /_?controllers?/ig,
+		//used to remove the controller from the name
+		underscoreAndRemoveController = function( className ) {
+			return $.String.underscore(className.replace("jQuery.", "").replace(dotsReg, '_').replace(controllersReg, ""));
+		},
+		// checks if it looks like an action
+		actionMatcher = /[^\w]/,
+		// gets jus the event
+		eventCleaner = /^(>?default\.)|(>)/,
+		// handles parameterized action names
+		parameterReplacer = /\{([^\}]+)\}/g,
+		breaker = /^(?:(.*?)\s)?([\w\.\:>]+)$/,
+		basicProcessor;
+	/**
+	 * @tag core
+	 * @plugin jquery/controller
+	 * @download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/controller/controller.js
+	 * @test jquery/controller/qunit.html
+	 * 
+	 * Controllers organize event handlers using event delegation. 
+	 * If something happens in your application (a user click or a [jQuery.Model|Model] instance being updated), 
+	 * a controller should respond to it.  
+	 * 
+	 * Controllers make your code deterministic, reusable, organized and can tear themselves 
+	 * down auto-magically. Read about [http://jupiterjs.com/news/writing-the-perfect-jquery-plugin 
+	 * the theory behind controller] and 
+	 * a [http://jupiterjs.com/news/organize-jquery-widgets-with-jquery-controller walkthrough of its features]
+	 * on Jupiter's blog.
+	 * 
+	 * 
+	 * ## Basic Example
+	 * 
+	 * Instead of
+	 * 
+	 * @codestart
+	 * $(function(){
+	 *   $('#tabs').click(someCallbackFunction1)
+	 *   $('#tabs .tab').click(someCallbackFunction2)
+	 *   $('#tabs .delete click').click(someCallbackFunction3)
+	 * });
+	 * @codeend
+	 * 
+	 * do this
+	 * 
+	 * @codestart
+	 * $.Controller('Tabs',{
+	 *   click: function() {...},
+	 *   '.tab click' : function() {...},
+	 *   '.delete click' : function() {...}
+	 * })
+	 * $('#tabs').tabs();
+	 * @codeend
+	 * 
+	 * ## Tabs Example
+	 * 
+	 * @demo jquery/controller/controller.html
+	 * 
+	 * 
+	 * ## Using Controller
+	 * 
+	 * Controller helps you build and organize jQuery plugins.  It can be used
+	 * to build simple widgets, like a slider, or organize multiple
+	 * widgets into something greater.
+	 * 
+	 * To understand how to use Controller, you need to understand 
+	 * the typical lifecycle of a jQuery widget and how that maps to
+	 * controller's functionality:
+	 * 
+	 * ### A controller class is created.
+	 *       
+	 *     $.Controller("MyWidget",
+	 *     {
+	 *       defaults :  {
+	 *         message : "Remove Me"
+	 *       }
+	 *     },
+	 *     {
+	 *       init : function(rawEl, rawOptions){ 
+	 *         this.element.append(
+	 *            "<div>"+this.options.message+"</div>"
+	 *           );
+	 *       },
+	 *       "div click" : function(div, ev){ 
+	 *         div.remove();
+	 *       }  
+	 *     }) 
+	 *     
+	 * This creates a <code>$.fn.my_widget</code> [jquery.controller.plugin jQuery helper function]
+	 * that can be used to create a new controller instance on an element.
+	 *       
+	 * ### An instance of controller is created on an element
+	 * 
+	 *     $('.thing').my_widget(options) // calls new MyWidget(el, options)
+	 * 
+	 * This calls <code>new MyWidget(el, options)</code> on 
+	 * each <code>'.thing'</code> element.  
+	 *     
+	 * When a new [jQuery.Class Class] instance is created, it calls the class's
+	 * prototype setup and init methods. Controller's [jQuery.Controller.prototype.setup setup]
+	 * method:
+	 *     
+	 *  - Sets [jQuery.Controller.prototype.element this.element] and adds the controller's name to element's className.
+	 *  - Merges passed in options with defaults object and sets it as [jQuery.Controller.prototype.options this.options]
+	 *  - Saves a reference to the controller in <code>$.data</code>.
+	 *  - [jquery.controller.listening Binds all event handler methods].
+	 *   
+	 * 
+	 * ### The controller responds to events
+	 * 
+	 * Typically, Controller event handlers are automatically bound.  However, there are
+	 * multiple ways to [jquery.controller.listening listen to events] with a controller.
+	 * 
+	 * Once an event does happen, the callback function is always called with 'this' 
+	 * referencing the controller instance.  This makes it easy to use helper functions and
+	 * save state on the controller.
+	 * 
+	 * 
+	 * ### The widget is destroyed
+	 * 
+	 * If the element is removed from the page, the 
+	 * controller's [jQuery.Controller.prototype.destroy] method is called.
+	 * This is a great place to put any additional teardown functionality.
+	 * 
+	 * You can also teardown a controller programatically like:
+	 * 
+	 *     $('.thing').my_widget('destroy');
+	 * 
+	 * ## Todos Example
+	 * 
+	 * Lets look at a very basic example - 
+	 * a list of todos and a button you want to click to create a new todo.
+	 * Your HTML might look like:
+	 * 
+	 * @codestart html
+	 * &lt;div id='todos'>
+	 *  &lt;ol>
+	 *    &lt;li class="todo">Laundry&lt;/li>
+	 *    &lt;li class="todo">Dishes&lt;/li>
+	 *    &lt;li class="todo">Walk Dog&lt;/li>
+	 *  &lt;/ol>
+	 *  &lt;a class="create">Create&lt;/a>
+	 * &lt;/div>
+	 * @codeend
+	 * 
+	 * To add a mousover effect and create todos, your controller might look like:
+	 * 
+	 * @codestart
+	 * $.Controller.extend('Todos',{
+	 *   ".todo mouseover" : function( el, ev ) {
+	 *    el.css("backgroundColor","red")
+	 *   },
+	 *   ".todo mouseout" : function( el, ev ) {
+	 *    el.css("backgroundColor","")
+	 *   },
+	 *   ".create click" : function() {
+	 *    this.find("ol").append("&lt;li class='todo'>New Todo&lt;/li>"); 
+	 *   }
+	 * })
+	 * @codeend
+	 * 
+	 * Now that you've created the controller class, you've must attach the event handlers on the '#todos' div by
+	 * creating [jQuery.Controller.prototype.setup|a new controller instance].  There are 2 ways of doing this.
+	 * 
+	 * @codestart
+	 * //1. Create a new controller directly:
+	 * new Todos($('#todos'));
+	 * //2. Use jQuery function
+	 * $('#todos').todos();
+	 * @codeend
+	 * 
+	 * ## Controller Initialization
+	 * 
+	 * It can be extremely useful to add an init method with 
+	 * setup functionality for your widget.
+	 * 
+	 * In the following example, I create a controller that when created, will put a message as the content of the element:
+	 * 
+	 * @codestart
+	 * $.Controller.extend("SpecialController",
+	 * {
+	 *   init: function( el, message ) {
+	 *      this.element.html(message)
+	 *   }
+	 * })
+	 * $(".special").special("Hello World")
+	 * @codeend
+	 * 
+	 * ## Removing Controllers
+	 * 
+	 * Controller removal is built into jQuery.  So to remove a controller, you just have to remove its element:
+	 * 
+	 * @codestart
+	 * $(".special_controller").remove()
+	 * $("#containsControllers").html("")
+	 * @codeend
+	 * 
+	 * It's important to note that if you use raw DOM methods (<code>innerHTML, removeChild</code>), the controllers won't be destroyed.
+	 * 
+	 * If you just want to remove controller functionality, call destroy on the controller instance:
+	 * 
+	 * @codestart
+	 * $(".special_controller").controller().destroy()
+	 * @codeend
+	 * 
+	 * ## Accessing Controllers
+	 * 
+	 * Often you need to get a reference to a controller, there are a few ways of doing that.  For the 
+	 * following example, we assume there are 2 elements with <code>className="special"</code>.
+	 * 
+	 * @codestart
+	 * //creates 2 foo controllers
+	 * $(".special").foo()
+	 * 
+	 * //creates 2 bar controllers
+	 * $(".special").bar()
+	 * 
+	 * //gets all controllers on all elements:
+	 * $(".special").controllers() //-> [foo, bar, foo, bar]
+	 * 
+	 * //gets only foo controllers
+	 * $(".special").controllers(FooController) //-> [foo, foo]
+	 * 
+	 * //gets all bar controllers
+	 * $(".special").controllers(BarController) //-> [bar, bar]
+	 * 
+	 * //gets first controller
+	 * $(".special").controller() //-> foo
+	 * 
+	 * //gets foo controller via data
+	 * $(".special").data("controllers")["FooController"] //-> foo
+	 * @codeend
+	 * 
+	 * ## Calling methods on Controllers
+	 * 
+	 * Once you have a reference to an element, you can call methods on it.  However, Controller has
+	 * a few shortcuts:
+	 * 
+	 * @codestart
+	 * //creates foo controller
+	 * $(".special").foo({name: "value"})
+	 * 
+	 * //calls FooController.prototype.update
+	 * $(".special").foo({name: "value2"})
+	 * 
+	 * //calls FooController.prototype.bar
+	 * $(".special").foo("bar","something I want to pass")
+	 * @codeend
+	 */
+	$.Class.extend("jQuery.Controller",
+	/** 
+	 * @Static
+	 */
+	{
+		/**
+		 * Does 3 things:
+		 * <ol>
+		 *     <li>Creates a jQuery helper for this controller.</li>
+		 *     <li>Calculates and caches which functions listen for events.</li>
+		 *     <li> and attaches this element to the documentElement if onDocument is true.</li>
+		 * </ol>   
+		 * <h3>jQuery Helper Naming Examples</h3>
+		 * @codestart
+		 * "TaskController" -> $().task_controller()
+		 * "Controllers.Task" -> $().controllers_task()
+		 * @codeend
+		 */
+		init: function() {
+			// if you didn't provide a name, or are controller, don't do anything
+			if (!this.shortName || this.fullName == "jQuery.Controller" ) {
+				return;
+			}
+			// cache the underscored names
+			this._fullName = underscoreAndRemoveController(this.fullName);
+			this._shortName = underscoreAndRemoveController(this.shortName);
+
+			var controller = this,
+				pluginname = this.pluginName || this._fullName,
+				funcName, forLint;
+
+			// create jQuery plugin
+			if (!$.fn[pluginname] ) {
+				$.fn[pluginname] = function( options ) {
+
+					var args = $.makeArray(arguments),
+						//if the arg is a method on this controller
+						isMethod = typeof options == "string" && $.isFunction(controller.prototype[options]),
+						meth = args[0];
+					this.each(function() {
+						//check if created
+						var controllers = $.data(this, "controllers"),
+							//plugin is actually the controller instance
+							plugin = controllers && controllers[pluginname];
+
+						if ( plugin ) {
+							if ( isMethod ) {
+								// call a method on the controller with the remaining args
+								plugin[meth].apply(plugin, args.slice(1));
+							} else {
+								// call the plugin's update method
+								plugin.update.apply(plugin, args);
+							}
+
+						} else {
+							//create a new controller instance
+							controller.newInstance.apply(controller, [this].concat(args));
+						}
+					});
+					//always return the element
+					return this;
+				};
+			}
+
+			// make sure listensTo is an array
+			//@steal-remove-start
+			if (!$.isArray(this.listensTo) ) {
+				throw "listensTo is not an array in " + this.fullName;
+			}
+			//@steal-remove-end
+			// calculate and cache actions
+			this.actions = {};
+
+			for ( funcName in this.prototype ) {
+				if ( this.prototype.hasOwnProperty(funcName) ) {
+					if (!$.isFunction(this.prototype[funcName]) ) {
+						continue;
+					}
+					if ( this._isAction(funcName) ) {
+						this.actions[funcName] = this._getAction(funcName);
+					}
+				}
+			}
+
+			/**
+			 * @attribute onDocument
+			 * Set to true if you want to automatically attach this element to the documentElement.
+			 */
+			if ( this.onDocument ) {
+				forLint = new controller(document.documentElement);
+			}
+		},
+		hookup: function( el ) {
+			return new this(el);
+		},
+
+		/**
+		 * @hide
+		 * @param {String} methodName a prototype function
+		 * @return {Boolean} truthy if an action or not
+		 */
+		_isAction: function( methodName ) {
+			if ( actionMatcher.test(methodName) ) {
+				return true;
+			} else {
+				var cleanedEvent = methodName.replace(eventCleaner, "");
+				return $.inArray(cleanedEvent, this.listensTo) > -1 || $.event.special[cleanedEvent] || $.Controller.processors[cleanedEvent];
+			}
+
+		},
+		/**
+		 * @hide
+		 * @param {Object} methodName the method that will be bound
+		 * @param {Object} [options] first param merged with class default options
+		 * @return {Object} null or the processor and pre-split parts.  
+		 * The processor is what does the binding/subscribing.
+		 */
+		_getAction: function( methodName, options ) {
+			//if we don't have a controller instance, we'll break this guy up later
+			parameterReplacer.lastIndex = 0;
+			if (!options && parameterReplacer.test(methodName) ) {
+				return null;
+			}
+			var convertedName = options ? $.String.sub(methodName, options) : methodName,
+				parts = convertedName.match(breaker),
+				event = parts[2],
+				processor = this.processors[event] || basicProcessor;
+			return {
+				processor: processor,
+				parts: parts
+			};
+		},
+		/**
+		 * @attribute processors
+		 * An object of {eventName : function} pairs that Controller uses to hook up events
+		 * auto-magically.  A processor function looks like:
+		 * 
+		 *     jQuery.Controller.processors.
+		 *       myprocessor = function( el, event, selector, cb, controller ) {
+		 *          //el - the controller's element
+		 *          //event - the event (myprocessor)
+		 *          //selector - the left of the selector
+		 *          //cb - the function to call
+		 *          //controller - the binding controller
+		 *       };
+		 * 
+		 * This would bind anything like: "foo~3242 myprocessor".
+		 * 
+		 * The processor must return a function that when called, 
+		 * unbinds the event handler.
+		 * 
+		 */
+		processors: {},
+		/**
+		 * @attribute listensTo
+		 * A list of special events this controller listens too.  You only need to add event names that
+		 * are whole words (ie have no special characters).
+		 */
+		listensTo: [],
+		/**
+		 * @attribute defaults
+		 * A object of name-value pairs that act as default values for a controller's 
+		 * [jQuery.Controller.prototype.options options].
+		 * 
+		 *     $.Controller("Message",
+		 *     {
+		 *       defaults : {
+		 *         message : "Hello World"
+		 *       }
+		 *     },{
+		 *       init : function(){
+		 *         this.element.text(this.options.message);
+		 *       }
+		 *     })
+		 *     
+		 *     $("#el1").message(); //writes "Hello World"
+		 *     $("#el12").message({message: "hi"}); //writes hi
+		 */
+		defaults: {}
+	},
+	/** 
+	 * @Prototype
+	 */
+	{
+		/**
+		 * Setup is where most of controller's magic happens.  It does the following:
+		 * 
+		 * ### Sets this.element
+		 * 
+		 * The first parameter passed to new Controller(el, options) is expected to be 
+		 * an element.  This gets converted to a jQuery wrapped element and set as
+		 * [jQuery.Controller.prototype.element this.element].
+		 * 
+		 * ### Adds the controller's name to the element's className.
+		 * 
+		 * Controller adds it's plugin name to the element's className for easier 
+		 * debugging.  For example, if your Controller is named "Foo.Bar", it adds
+		 * "foo_bar" to the className.
+		 * 
+		 * ### Saves the controller in $.data
+		 * 
+		 * A reference to the controller instance is saved in $.data.  You can find 
+		 * instances of "Foo.Bar" like: 
+		 * 
+		 *     $("#el").data("controllers")['foo_bar'].
+		 * 
+		 * ### Binds event handlers
+		 * 
+		 * Setup does the event binding described in [jquery.controller.listening Listening To Events].
+		 * 
+		 * ## API
+		 * @param {HTMLElement} element the element this instance operates on.
+		 * @param {Object} [options] option values for the controller.  These get added to
+		 * this.options.
+		 */
+		setup: function( element, options ) {
+			var funcName, ready, cls = this.Class;
+
+			//want the raw element here
+			element = element.jquery ? element[0] : element;
+
+			//set element and className on element
+			this.element = $(element).addClass(cls._fullName);
+
+			//set in data
+			($.data(element, "controllers") || $.data(element, "controllers", {}))[cls._fullName] = this;
+
+			//adds bindings
+			this._bindings = [];
+			/**
+			 * @attribute options
+			 * Options is [jQuery.Controller.static.defaults] merged with the 2nd argument
+			 * passed to a controller (or the first argument passed to the 
+			 * [jquery.controller.plugin controller's jQuery plugin]).
+			 * 
+			 * For example:
+			 * 
+			 *     $.Controller("Tabs", 
+			 *     {
+			 *        defaults : {
+			 *          activeClass: "ui-active-state"
+			 *        }
+			 *     },
+			 *     {
+			 *        init : function(){
+			 *          this.element.addClass(this.options.activeClass);
+			 *        }
+			 *     })
+			 *     
+			 *     $("#tabs1").tabs()                         // adds 'ui-active-state'
+			 *     $("#tabs2").tabs({activeClass : 'active'}) // adds 'active'
+			 *     
+			 *  
+			 */
+			this.options = $.extend($.extend(true, {}, cls.defaults), options);
+
+			//go through the cached list of actions and use the processor to bind
+			for ( funcName in cls.actions ) {
+				if ( cls.actions.hasOwnProperty(funcName) ) {
+					ready = cls.actions[funcName] || cls._getAction(funcName, this.options);
+					this._bindings.push(
+					ready.processor(element, ready.parts[2], ready.parts[1], this.callback(funcName), this));
+				}
+			}
+
+
+			/**
+			 * @attribute called
+			 * String name of current function being called on controller instance.  This is 
+			 * used for picking the right view in render.
+			 * @hide
+			 */
+			this.called = "init";
+
+			//setup to be destroyed ... don't bind b/c we don't want to remove it
+			//this.element.bind('destroyed', this.callback('destroy'))
+			var destroyCB = shifter(this.callback("destroy"));
+			this.element.bind("destroyed", destroyCB);
+			this._bindings.push(function( el ) {
+				destroyCB.removed = true;
+				$(element).unbind("destroyed", destroyCB);
+			});
+
+			/**
+			 * @attribute element
+			 * The controller instance's delegated element. This 
+			 * is set by [jQuery.Controller.prototype.setup setup]. It 
+			 * is a jQuery wrapped element.
+			 * 
+			 * For example, if I add MyWidget to a '#myelement' element like:
+			 * 
+			 *     $.Controller("MyWidget",{
+			 *       init : function(){
+			 *         this.element.css("color","red")
+			 *       }
+			 *     })
+			 *     
+			 *     $("#myelement").my_widget()
+			 * 
+			 * MyWidget will turn #myelement's font color red.
+			 * 
+			 * ## Using a different element.
+			 * 
+			 * Sometimes, you want a different element to be this.element.  A
+			 * very common example is making progressively enhanced form widgets.
+			 * 
+			 * To change this.element, overwrite Controller's setup method like:
+			 * 
+			 *     $.Controller("Combobox",{
+			 *       setup : function(el, options){
+			 *          this.oldElement = $(el);
+			 *          var newEl = $('<div/>');
+			 *          this.oldElement.wrap(newEl);
+			 *          this._super(newEl, options);
+			 *       },
+			 *       init : function(){
+			 *          this.element //-> the div
+			 *       },
+			 *       ".option click" : function(){
+			 *         // event handler bound on the div
+			 *       },
+			 *       destroy : function(){
+			 *          var div = this.element; //save reference
+			 *          this._super();
+			 *          div.replaceWith(this.oldElement);
+			 *       }
+			 *     }
+			 */
+			return this.element;
+		},
+		/**
+		 * Bind attaches event handlers that will be removed when the controller is removed.  
+		 * This is a good way to attach to an element not in the controller's element.
+		 * <br/>
+		 * <h3>Examples:</h3>
+		 * @codestart
+		 * init: function() {
+		 *    // calls somethingClicked(el,ev)
+		 *    this.bind('click','somethingClicked') 
+		 * 
+		 *    // calls function when the window is clicked
+		 *    this.bind(window, 'click', function(ev){
+		 *      //do something
+		 *    })
+		 * },
+		 * somethingClicked: function( el, ev ) {
+		 *   
+		 * }
+		 * @codeend
+		 * @param {HTMLElement|jQuery.fn} [el=this.element] The element to be bound
+		 * @param {String} eventName The event to listen for.
+		 * @param {Function|String} func A callback function or the String name of a controller function.  If a controller
+		 * function name is given, the controller function is called back with the bound element and event as the first
+		 * and second parameter.  Otherwise the function is called back like a normal bind.
+		 * @return {Integer} The id of the binding in this._bindings
+		 */
+		bind: function( el, eventName, func ) {
+			if ( typeof el == 'string' ) {
+				func = eventName;
+				eventName = el;
+				el = this.element;
+			}
+			return this._binder(el, eventName, func);
+		},
+		_binder: function( el, eventName, func, selector ) {
+			if ( typeof func == 'string' ) {
+				func = shifter(this.callback(func));
+			}
+			this._bindings.push(binder(el, eventName, func, selector));
+			return this._bindings.length;
+		},
+		/**
+		 * Delegate will delegate on an elememt and will be undelegated when the controller is removed.
+		 * This is a good way to delegate on elements not in a controller's element.<br/>
+		 * <h3>Example:</h3>
+		 * @codestart
+		 * // calls function when the any 'a.foo' is clicked.
+		 * this.delegate(document.documentElement,'a.foo', 'click', function(ev){
+		 *   //do something
+		 * })
+		 * @codeend
+		 * @param {HTMLElement|jQuery.fn} [element=this.element] the element to delegate from
+		 * @param {String} selector the css selector
+		 * @param {String} eventName the event to bind to
+		 * @param {Function|String} func A callback function or the String name of a controller function.  If a controller
+		 * function name is given, the controller function is called back with the bound element and event as the first
+		 * and second parameter.  Otherwise the function is called back like a normal bind.
+		 * @return {Integer} The id of the binding in this._bindings
+		 */
+		delegate: function( element, selector, eventName, func ) {
+			if ( typeof element == 'string' ) {
+				func = eventName;
+				eventName = selector;
+				selector = element;
+				element = this.element;
+			}
+			return this._binder(element, eventName, func, selector);
+		},
+		/**
+		 * Called if an controller's [jquery.controller.plugin jQuery helper] is called on an element that already has a controller instance
+		 * of the same type.  Extends [jQuery.Controller.prototype.options this.options] with the options passed in.  If you overwrite this, you might want to call
+		 * this._super.
+		 * <h3>Examples</h3>
+		 * @codestart
+		 * $.Controller.extend("Thing",{
+		 * init: function( el, options ) {
+		 *    alert('init')
+		 * },
+		 * update: function( options ) {
+		 *    this._super(options);
+		 *    alert('update')
+		 * }
+		 * });
+		 * $('#myel').thing(); // alerts init
+		 * $('#myel').thing(); // alerts update
+		 * @codeend
+		 * @param {Object} options
+		 */
+		update: function( options ) {
+			$.extend(this.options, options);
+		},
+		/**
+		 * Destroy unbinds and undelegates all event handlers on this controller, 
+		 * and prevents memory leaks.  This is called automatically
+		 * if the element is removed.  You can overwrite it to add your own
+		 * teardown functionality:
+		 * 
+		 *     $.Controller("ChangeText",{
+		 *       init : function(){
+		 *         this.oldText = this.element.text();
+		 *         this.element.text("Changed!!!")
+		 *       },
+		 *       destroy : function(){
+		 *         this.element.text(this.oldText);
+		 *         this._super(); //Always call this!
+		 *     })
+		 * 
+		 * You could call destroy manually on an element with ChangeText
+		 * added like:
+		 * 
+		 *     $("#changed").change_text("destroy");
+		 *     
+		 * ### API
+		 */
+		destroy: function() {
+			if ( this._destroyed ) {
+				throw this.Class.shortName + " controller instance has been deleted";
+			}
+			var self = this,
+				fname = this.Class._fullName,
+				controllers;
+			this._destroyed = true;
+			this.element.removeClass(fname);
+
+			$.each(this._bindings, function( key, value ) {
+				if ( $.isFunction(value) ) {
+					value(self.element[0]);
+				}
+			});
+
+			delete this._actions;
+
+
+			controllers = this.element.data("controllers");
+			if ( controllers && controllers[fname] ) {
+				delete controllers[fname];
+			}
+			$(this).triggerHandler("destroyed"); //in case we want to know if the controller is removed
+			this.element = null;
+		},
+		/**
+		 * Queries from the controller's element.
+		 * @codestart
+		 * ".destroy_all click" : function() {
+		 *    this.find(".todos").remove();
+		 * }
+		 * @codeend
+		 * @param {String} selector selection string
+		 * @return {jQuery.fn} returns the matched elements
+		 */
+		find: function( selector ) {
+			return this.element.find(selector);
+		},
+		//tells callback to set called on this.  I hate this.
+		_set_called: true
+	});
+
+
+	//------------- PROCESSSORS -----------------------------
+	//processors do the binding.  They return a function that
+	//unbinds when called.
+	//the basic processor that binds events
+	basicProcessor = function( el, event, selector, cb, controller ) {
+		var c = controller.Class;
+
+		// document controllers use their name as an ID prefix.
+		if ( c.onDocument && !/^Main(Controller)?$/.test(c.shortName) ) { //prepend underscore name if necessary
+			selector = selector ? "#" + c._shortName + " " + selector : "#" + c._shortName;
+		}
+		return binder(el, event, shifter(cb), selector);
+	};
+
+	var processors = $.Controller.processors,
+
+		//a window event only happens on the window
+		windowEvent = function( el, event, selector, cb ) {
+			return binder(window, event.replace(/window/, ""), shifter(cb));
+		};
+
+	//set commong events to be processed as a basicProcessor
+	$.each("change click contextmenu dblclick keydown keyup keypress mousedown mousemove mouseout mouseover mouseup reset windowresize resize windowscroll scroll select submit dblclick focusin focusout load unload ready hashchange mouseenter mouseleave".split(" "), function( i, v ) {
+		processors[v] = basicProcessor;
+	});
+	$.each(["windowresize", "windowscroll", "load", "ready", "unload", "hashchange"], function( i, v ) {
+		processors[v] = windowEvent;
+	});
+	//the ready processor happens on the document
+	processors.ready = function( el, event, selector, cb ) {
+		$(shifter(cb)); //cant really unbind
+	};
+	/**
+	 *  @add jQuery.fn
+	 */
+
+	$.fn.mixin = function() {
+		//create a bunch of controllers
+		var controllers = $.makeArray(arguments),
+			forLint;
+		return this.each(function() {
+			for ( var i = 0; i < controllers.length; i++ ) {
+				forLint = new controllers[i](this);
+			}
+
+		});
+	};
+	//used to determine if a controller instance is one of controllers
+	//controllers can be strings or classes
+	var i, isAControllerOf = function( instance, controllers ) {
+		for ( i = 0; i < controllers.length; i++ ) {
+			if ( typeof controllers[i] == 'string' ? instance.Class._shortName == controllers[i] : instance instanceof controllers[i] ) {
+				return true;
+			}
+		}
+		return false;
+	};
+
+	/**
+	 * @function controllers
+	 * Gets all controllers in the jQuery element.
+	 * @return {Array} an array of controller instances.
+	 */
+	$.fn.controllers = function() {
+		var controllerNames = $.makeArray(arguments),
+			instances = [],
+			controllers;
+		//check if arguments
+		this.each(function() {
+			var c, cname;
+
+			controllers = $.data(this, "controllers");
+			if (!controllers ) {
+				return;
+			}
+			for ( cname in controllers ) {
+				if ( controllers.hasOwnProperty(cname) ) {
+					c = controllers[cname];
+					if (!controllerNames.length || isAControllerOf(c, controllerNames) ) {
+						instances.push(c);
+					}
+				}
+			}
+		});
+		return instances;
+	};
+	/**
+	 * @function controller
+	 * Gets a controller in the jQuery element.  With no arguments, returns the first one found.
+	 * @param {Object} controller (optional) if exists, the first controller instance with this class type will be returned.
+	 * @return {jQuery.Controller} the first controller.
+	 */
+	$.fn.controller = function( controller ) {
+		return this.controllers.apply(this, arguments)[0];
+	};
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/controller/history/history.html b/browserid/static/dialog/jquery/controller/history/history.html
new file mode 100644
index 0000000000000000000000000000000000000000..3bc6b0a9333564e7f7a5624c7e8410ce1ebe1082
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/history/history.html
@@ -0,0 +1,126 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	    "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>hover</title>
+	<style type='text/css'>
+	    body {font-family: verdana}
+	    .error {border: solid 1px red;}
+	    .error_text { color: red; font-size: 10px;}
+	    td {padding: 3px;}
+	    .list-test, .object-list-test, .nested-object-test {color: blue; cursor: pointer; text-decoration: underline;}
+	</style>
+	</head>
+	<body>
+		<div id="history_demo">
+			<a href="#first&param=I">First</a>
+			<a href="#second&param=love">Second</a>
+			<a href="#third&param=jmvc!">Third</a>
+			<a class="list-test">Fourth</a>
+			<a class="object-list-test">Fifth</a>
+			<a class="nested-object-test">Sixth</a>
+		</div>
+	<script type='text/javascript' src='../../../steal/steal.js?steal[app]=jquery/controller/history&steal[env]=development'>   
+	</script>
+	<script type='text/javascript'>
+	    $.Controller.extend('HistoryDemoController',{
+	    },
+	    {
+			    "history.first.index subscribe" : function(called, data) {
+					alert("First[param] : " + data.param);
+				},
+
+			    "history.second.index subscribe" : function(called, data) {
+					alert("Second[param] : " + data.param);
+				},
+				
+			    "history.third.index subscribe" : function(called, data) {
+					alert("Third[param] : " + data.param);
+				},
+
+			    "history.fourth.index subscribe" : function(called, data) {
+					alert("Fourth[myList] : [" + data.myList.join(', ') + "]");
+				},
+
+			    "history.fifth.index subscribe" : function(called, data) {
+					var obj_list = [];
+					$.each(data.myObjectList, function(i, obj) {
+					    var params = [];
+					    $.each(obj, function(key, val) {params.push(key + ": " + val);});
+					    obj_list.push("{" + params.join(", ") + "}");
+					});
+					alert("Fourth[myObjectList] : [" + obj_list.join(", ") + "]");
+				},
+
+			    "history.sixth.index subscribe" : function(called, data) {
+					var params = [];
+				
+					// myObject.a (object)
+					var vars_a = [];
+					$.each(data.myObject.a, function(key, val) {vars_a.push(key + ": "+val)});
+					params.push("a: {" + vars_a.join(", ") + "}");
+
+					// myObject.b (array)
+					params.push("b: [" + data.myObject.b.join(", ") + "]");
+
+					// myObject.c (array of objects)
+					var obj_list = [];
+					$.each(data.myObject.c, function(i, obj) {
+					    var obj_params = [];
+					    $.each(obj, function(key, val) {obj_params.push(key + ": " + val);});
+					    obj_list.push("\t{" + obj_params.join(", ") + "}");
+					});
+					params.push("c: [\n" + obj_list.join(",\n ") + "\t\n]");
+
+					alert("Fourth[myObject] : {\n" + params.join(",\n") + "\n}");
+				},
+
+			    ".list-test click" : function(el, ev){
+					this.history_add({controller:'fourth', myList:[1,2,3]});
+				},
+
+			    ".object-list-test click" : function(el, ev){
+					var myObjectList = [
+					    {
+						one: 1,
+						two: 2,
+						three: 3
+					    },
+					    {
+						four: 4,
+						five: 5,
+						six: 6
+					    }
+					];
+					this.history_add({controller:'fifth', myObjectList:myObjectList});
+				},
+
+			    ".nested-object-test click" : function(el, ev) {
+					var myObject = {
+					    a: {
+						one: 1,
+						two: 2,
+						three: 3
+					    },
+					    b: [1, 2, 3],
+					    c: [
+						{
+						    one: 1,
+						    two: 2,
+						    three: 3
+						},
+						{
+						    four: 4,
+						    five: 5,
+						    six: 6
+						}
+					    ]
+					};
+					this.history_add({controller:'sixth', myObject:myObject});
+				}
+	    });
+	    
+	    $("#history_demo").history_demo();
+        </script>
+    </body>
+</html>
diff --git a/browserid/static/dialog/jquery/controller/history/history.js b/browserid/static/dialog/jquery/controller/history/history.js
new file mode 100644
index 0000000000000000000000000000000000000000..c17d85264f052be1af52e5c7b4abd2dc44a97d23
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/history/history.js
@@ -0,0 +1,187 @@
+steal.plugins('jquery/controller/subscribe',
+	'jquery/event/hashchange').then(function($){
+
+/**
+ * @page jquery.controller.history History Events
+ * @parent jQuery.Controller
+ * @plugin jquery/controller/history
+ * The jquery/controller/history plugin adds 
+ * browser hash (#) based history support.
+ * 
+ * Typically you subscribe to a history event in your controllers:
+ * 
+ *     $.Controller("MyHistory",{
+ *       "history.pagename subscribe" : function(called, data){
+ *         //called when hash = #pagename
+ *       }
+ *     })
+ * 
+ * The following shows hash values and 
+ * the corresponding published message and data.
+ * 
+ *     "#foo=bar" -> "history.index" {foo: bar}
+ *     "#foo/bar" -> "history.foo.bar" {}
+ *     "#foo&bar=baz" -> "history.foo" {bar: baz}
+ *     
+ */
+
+var keyBreaker = /([^\[\]]+)|(\[\])/g;
+
+$.Controller.History = {
+	/**
+	 * 
+	 * returns the pathname part
+	 * 
+	 * @codestart
+	 * "#foo/bar&foo=bar" ->  'foo/bar'
+	 * @codeend
+	 */
+	pathname : function(path) {
+		var parts =  path.match(/#([^&]*)/);
+		return parts ? parts[1] : null
+	},
+	/**
+	 * returns the search part, but without the first &
+	 * @codestart
+	 * "#foo/bar&foo=bar" ->  'foo=barr'
+	 * @codeend
+	 */
+	search : function(path) {
+		var parts =  path.match(/#[^&]*&(.*)/);
+		return parts ? parts[1] : null
+	},
+	getData: function(path) {
+		var search = $.Controller.History.search(path),
+			digitTest = /^\d+$/;
+		if(! search || ! search.match(/([^?#]*)(#.*)?$/) ) {
+			return {};
+		} 
+	   
+		// Support the legacy format that used MVC.Object.to_query_string that used %20 for
+		// spaces and not the '+' sign;
+		search = search.replace(/\+/g,"%20")
+	   
+		var data = {},
+			pairs = search.split('&'),
+			current;
+			
+		for(var i=0; i < pairs.length; i++){
+			current = data;
+			var pair = pairs[i].split('=');
+			
+			// if we find foo=1+1=2
+			if(pair.length != 2) { 
+				pair = [pair[0], pair.slice(1).join("=")]
+			}
+			
+			var key = decodeURIComponent(pair[0]), 
+				value = decodeURIComponent(pair[1]),
+				parts = key.match(keyBreaker);
+	
+			for ( var j = 0; j < parts.length - 1; j++ ) {
+				var part = parts[j];
+				if (!current[part] ) {
+					current[part] = digitTest.test(part) || parts[j+1] == "[]" ? [] : {}
+				}
+				current = current[part];
+			}
+			lastPart = parts[parts.length - 1];
+			if(lastPart == "[]"){
+				current.push(value)
+			}else{
+				current[lastPart] = value;
+			}
+		}
+		return data;
+	}
+};
+
+
+
+
+
+jQuery(function($) {
+	$(window).bind('hashchange',function() {
+		var data = $.Controller.History.getData(location.href),
+			folders = $.Controller.History.pathname(location.href) || 'index',
+			hasSlash = (folders.indexOf('/') != -1);
+		
+		if( !hasSlash && folders != 'index' ) {
+			folders += '/index';
+		}
+		
+		OpenAjax.hub.publish("history."+folders.replace("/","."), data);
+	});
+	
+	setTimeout(function(){
+		$(window).trigger('hashchange')
+	},1) //immediately after ready
+})
+   
+   
+$.extend($.Controller.prototype, {
+   /**
+	* Redirects to another page.
+	* @plugin 'dom/history'
+	* @param {Object} options an object that will turned into a url like #controller/action&param1=value1
+	*/
+   redirectTo: function(options){
+		var point = this._get_history_point(options);
+		location.hash = point;
+   },
+   /**
+	* Redirects to another page by replacing current URL with the given one.  This
+	* call will not create a new entry in the history.
+	* @plugin 'dom/history'
+	* @param {Object} options an object that will turned into a url like #controller/action&param1=value1
+	*/
+   replaceWith: function(options){
+		var point = this._get_history_point(options);
+		location.replace(location.href.split('#')[0] + point);
+   },
+   /**
+	* Adds history point to browser history.
+	* @plugin 'dom/history'
+	* @param {Object} options an object that will turned into a url like #controller/action&param1=value1
+	* @param {Object} data extra data saved in history	-- NO LONGER SUPPORTED
+	*/
+   historyAdd : function(options, data) {
+	   var point = this._get_history_point(options);
+	  location.hash = point;
+   },
+   /**
+	* Creates a history point from given options. Resultant history point is like #controller/action&param1=value1
+	* @plugin 'dom/history'
+	* @param {Object} options an object that will turned into history point
+	*/
+   _get_history_point: function(options) {
+	   var controller_name = options.controller || this.Class.underscoreName;
+	   var action_name = options.action || 'index';
+	  
+	   /* Convert the options to parameters (removing controller and action if needed) */
+	   if(options.controller)
+		   delete options.controller;
+	   if(options.action)
+		   delete options.action;
+	   
+	   var paramString = (options) ? $.param(options) : '';
+	   if(paramString.length)
+		   paramString = '&' + paramString;
+	   
+	   return '#' + controller_name + '/' + action_name + paramString;
+   },
+
+   /**
+	* Provides current window.location parameters as object properties.
+	* @plugin 'dom/history'
+	*/
+   pathData :function() {
+	   return $.Controller.History.getData(location.href);
+   }
+});
+		
+	
+
+
+   
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/controller/history/qunit.html b/browserid/static/dialog/jquery/controller/history/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..d4edfd1ef9bdb5d00bef63854f91f8b2033aa4f3
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/history/qunit.html
@@ -0,0 +1,21 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../../funcunit/qunit/qunit.css" />
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+		<script type='text/javascript' src='../../../steal/steal.js?steal[app]=jquery/controller/history/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">Model Store Cookie Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/controller/history/qunit/qunit.js b/browserid/static/dialog/jquery/controller/history/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..9a6d5e71251574ee98e65938da2b3bd5bb15ac61
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/history/qunit/qunit.js
@@ -0,0 +1,38 @@
+steal.plugins('funcunit/qunit','jquery/controller/history').then(function($){
+	
+module("jquery/controller/history",{
+	setup: function(){
+		
+	}
+})
+
+test("Basic getData",function(){
+	
+	var data = $.Controller.History.getData("#foo/bar&a=b");
+	equals(data.a,"b")
+	
+	var data = $.Controller.History.getData("#foo/bar&a=b&c=d");
+	equals(data.a,"b")
+	equals(data.c,"d")
+})
+test("Nested getData",function(){
+	
+	var data = $.Controller.History.getData("#foo/bar&a[b]=1&a[c]=2");
+	equals(data.a.b,1)
+	equals(data.a.c,2)
+	
+	var data = $.Controller.History.getData("#foo/bar&a[]=1&a[]=2");
+	equals(data.a[0],1)
+	equals(data.a[1],2)
+	
+	var data = $.Controller.History.getData("#foo/bar&a[b][]=1&a[b][]=2");
+	equals(data.a.b[0],1)
+	equals(data.a.b[1],2)
+	
+	var data = $.Controller.History.getData("#foo/bar&a[0]=1&a[1]=2");
+	equals(data.a[0],1)
+	equals(data.a[1],2)
+})
+
+	
+})
diff --git a/browserid/static/dialog/jquery/controller/pages/document.js b/browserid/static/dialog/jquery/controller/pages/document.js
new file mode 100644
index 0000000000000000000000000000000000000000..fc3fd3285c4274177af7b606b64ded4606dfcff4
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/pages/document.js
@@ -0,0 +1,65 @@
+/**
+@page jquery.controller.documentcontrollers Document Controllers
+@parent jQuery.Controller
+
+Document Controllers delegate on the 
+documentElement.  You don't have to attach an instance as this will be done
+for you when the controller class is created.  Document Controllers, with the 
+exception of MainControllers,
+add an implicit '#CONTROLLERNAME' before every selector.
+
+To create a document controller, you just have to set 
+the controller's [jQuery.Controller.static.onDocument static onDocument]
+property to true.
+
+@codestart
+$.Controller.extend('TodosController',
+{onDocument: true},
+{
+  ".todo mouseover" : function( el, ev ) { //matches #todos .todo
+      el.css("backgroundColor","red")
+  },
+  ".todo mouseout" : function( el, ev ) { //matches #todos .todo
+      el.css("backgroundColor","")
+  },
+  ".create click" : function() {        //matches #todos .create
+      this.find("ol").append("&lt;li class='todo'>New Todo&lt;/li>"); 
+  }
+})
+@codeend
+
+DocumentControllers should be used sparingly.  They are not very reusable.
+They should only be used for glueing together other controllers and page
+layout.
+
+Often, a Document Controller's <b>"ready"</b> event will be used to create
+necessary Element Controllers.
+
+@codestart
+$.Controller.extend('SidebarController',
+{onDocument: true},
+{
+  <b>ready</b> : function() {
+      $(".slider").slider()
+  },
+  "a.tag click" : function() {..}
+})
+@codeend
+
+## MainControllers 
+
+MainControllers are documentControllers that do not add '#CONTROLLERNAME' before every selector.  This controller
+should only be used for page wide functionality and setup.
+
+@codestart
+$.Controller.extend("MainController",{
+  hasActiveElement : document.activeElement || false
+},{
+  focus : funtion(el){
+     if(!this.Class.hasActiveElement)
+         document.activeElement = el[0] //tracks active element
+  }
+})
+@codeend
+ */
+//
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/controller/pages/listening.js b/browserid/static/dialog/jquery/controller/pages/listening.js
new file mode 100644
index 0000000000000000000000000000000000000000..cbd8bf674f2c8ff29c694ffe1ab52bacba0d6b01
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/pages/listening.js
@@ -0,0 +1,114 @@
+/**
+@page jquery.controller.listening Listening To Events
+@parent jQuery.Controller
+
+Controllers organize event handlers and make listening to 
+events really easy.
+
+## Automatic Binding
+
+When a [jQuery.Controller.prototype.setup new controller is created],
+contoller checks its methods for functions that are named like
+an event handler.  It automatically binds these functions to the 
+controller's [jQuery.Controller.prototype.element element] with event delegation.  When
+the controller is destroyed (or it's element is removed from the page), controller
+will unbind all its event handlers automatically.
+
+For example, each of the following controller's functions will automatically
+bound:
+
+    $.Controller("Crazy",{
+    
+      // listens to all clicks on this element
+      "click" : function(){},
+      
+      // listens to all mouseovers on 
+      // li elements withing this controller
+      "li mouseover" : function(){}
+      
+      // listens to the window being resized
+      "windowresize" : function(){}
+    })
+
+Controller will bind function names with spaces, standard DOM events, and 
+event names in $.event.special.
+
+In general, Controller will know automatically when to bind event handler functions except for 
+one case - event names without selectors that are not in $.event.special.
+
+But to correct for this, you just need to add the 
+function to the listensTo property.  Here's how:
+
+	 $.Controller.extend("MyShow",{
+	   listensTo: ["show"]
+	 },{
+	   show: function( el, ev ) {
+	     el.show();
+	   }
+	 })
+	 $('.show').my_show().trigger("show");
+
+## Callback parameters
+
+Event handlers bound with controller are called back with the element and the event 
+as parameters.  <b>this</b> refers to the controller instance.  For example:
+
+    $.Controller("Tabs",{
+    
+      // li - the list element that was clicked
+      // ev - the click event
+      "li click" : function(li, ev){
+         this.tab(li).hide()
+      },
+      tab : function(li){
+        return $(li.find("a").attr("href"))
+      }
+    })
+
+## Parameterized Event Bindings
+
+Controller lets you parameterize event names and selectors.  The following 
+makes 2 buttons.  One says hello on click, the other on mouseenter.
+
+    $.Controller("Hello",{
+      "{helloEvent}" : function(){
+        alert('hello')
+      }
+    })
+    
+    $("#clickMe").hello({helloEvent : "click"});
+    $("#touchMe").hello({helloEvent : "mouseenter"});
+
+You can parameterize any part of the method name.  The following makes two
+lists.  One listens for clicks on divs, the other on lis.
+
+    $.Controller("List",{
+      "{listItem} click" : function(){
+        //do something!
+      }
+    })
+    
+    $("#divs").list({listItem : "div"});
+    $("#lis").list({listItem : "li"});
+
+## Subscribing to OpenAjax messages and custom bindings
+
+The jquery/controller/subscribe plugin allows controllers to listen
+to OpenAjax.hub messages like:
+
+    $.Controller("Listener",{
+      "something.updated subscribe" : function(called, data){
+      
+      }
+    })
+
+You can create your own binders by adding to [jQuery.Controller.static.processors].
+
+## Manually binding to events.
+
+The [jQuery.Controller.prototype.bind] and [jQuery.Controller.prototype.delegate]
+methods let you listen to events on other elements.  These event handlers will
+be unbound when the controller instance is destroyed.
+
+ */
+//
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/controller/pages/plugin.js b/browserid/static/dialog/jquery/controller/pages/plugin.js
new file mode 100644
index 0000000000000000000000000000000000000000..d82e324abc7d65efa9de6aebb0ffa71bd186f400
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/pages/plugin.js
@@ -0,0 +1,104 @@
+/**
+@page jquery.controller.plugin The generated jQuery plugin
+@parent jQuery.Controller
+
+When you create a controller, it creates a jQuery plugin that can be
+used to:
+
+  - Create controllers on an element or elements
+  - Call controller methods
+  - Update a controller
+
+For example, the following controller:
+
+    $.Controller("My.Widget",{
+      say : function(){
+         alert(this.options.message);
+      }
+    })
+    
+creates a <code>jQuery.fn.my_tabs</code> method that you can use like:
+
+    // create my_widget on each .thing
+    $(".thing").my_widget({message : "Hello"}) 
+    
+    // alerts "Hello"
+    $(".thing").my_widget("say");
+
+	// updates the message option
+	$(".thing").my_widget({message : "World"});
+	
+	// alerts "World"
+    $(".thing").my_widget("say");
+    
+Note that in every case, the my_widget plugin
+returns the original jQuery collection for chaining (<code>$('.thing')</code>).  If you want to
+get a value from a controller, use the [jQuery.fn.controllers] or [jQuery.fn.controller].
+
+## Creating controllers
+
+When a controller's jQuery plugin helper is used on a jQuery collection, it goes to each 
+element and tests if it has a controller instance on the element.  If it does not, it creates one.
+
+It calls <code>new YourController</code> with the element and any additional arguments you passed 
+to the jQuery plugin helper.  So for example, say there are 2 elements in <code>$('.thing')</code>.
+
+This:
+
+    $(".thing").my_widget({message : "Hello"})
+    
+Does the exact same thing as:
+
+    var things = $('.thing'),
+        options = {message : "Hello"};
+    new My.Widget(things[0],options);
+    new My.Widget(things[1],options);
+
+Note, when a <code>new Class</code> is created, it calls your 
+class's prototype setup and init methods. Read [jQuery.Controller.prototype.setup controller's setup] 
+for the details on what happens when a new controller is created.
+
+
+## Calling methods on controllers
+
+Once a Controller is already on an element, you can call methods on it with the same jQuery
+helper.  The first param to the helper is the name of the method, the following params are 
+passed to the jQuery function.  For example:
+
+    $.Controller("Adder",{
+      sum : function(first, second, third){
+         this.element.text(first+second+third);
+      }
+    })
+    
+    // add an adder to the page
+    $("#myadder").adder()
+    
+    // show the sum of 1+2+3
+    $("#myadder").adder("sum",1,2,3);
+
+## Naming
+
+By default, a controller's jQuery helper is the controller name:
+
+   - [jQuery.String.underscore underscored]
+   - "." replaced with "_"
+   - with Controllers removed.
+
+Here are some examples:
+
+    $.Controller("Foo")                 // -> .foo()
+    $.Controller("Foo.Bar")             // -> .foo_bar()
+    $.Controller("Foo.Controllers.Bar") // -> .foo_bar()
+
+You can overwrite the Controller's default name by setting a static pluginName property:
+
+    $.Controller("My.Tabs",
+    {
+      pluginName: "tabs"
+    },
+    { ... })
+    
+    $("#tabs").tabs()
+ */
+//
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/controller/qunit.html b/browserid/static/dialog/jquery/controller/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..909f3130bc03cbd220c71789ab576c6a32c36b1a
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/qunit.html
@@ -0,0 +1,21 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../funcunit/qunit/qunit.css" />
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+		<script type='text/javascript' src='../../steal/steal.js?steal[app]=jquery/controller/test/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">Controller Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/controller/subscribe/funcunit.html b/browserid/static/dialog/jquery/controller/subscribe/funcunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..48dda424888486b79a088b1bd34c197f3fd51333
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/subscribe/funcunit.html
@@ -0,0 +1,21 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../../steal/test/qunit/qunit.css" />
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+		<script type='text/javascript' src='../../../steal/steal.js?steal[app]=jquery/controller/subscribe/test/funcunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">subscribe Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/controller/subscribe/subscribe.html b/browserid/static/dialog/jquery/controller/subscribe/subscribe.html
new file mode 100644
index 0000000000000000000000000000000000000000..fd4dc09039a3838ca9d1fe1e09ce35fb27b1b9b8
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/subscribe/subscribe.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>hover</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .error {border: solid 1px red;}
+            .error_text { color: red; font-size: 10px;}
+            td {padding: 3px;}
+			.subscribe, .subscribes {
+				border: solid 1px green;
+			}
+			.subscribed {
+				background-color: yellow;
+			}
+			.mysubscribe {
+				border: solid 1px red;
+			}
+        </style>
+	</head>
+	<body>
+		<div id="testSubscribe">
+            <div id="subscribe1">
+                subscribe me
+            </div>
+            <h2><a href="#" id="off">Turn OFF Above</a></h2>
+        </div>
+        
+        <script type='text/javascript' 
+                src='../../../steal/steal.js?steal[app]=jquery/controller/subscribe&steal[env]=development'
+                package='main.js'
+                compress='false'>   
+        </script>
+        <script type='text/javascript'>
+            $.Controller.extend('subscribeTest',{
+                onDocument: false
+            },
+            {
+                "#subscribe1 click": function(el, ev){
+                    ev.stopPropagation();
+                    this.publish("oaSubscribe1", {"params":"Hola Mundo"});		
+                },
+                "oaSubscribe1 subscribe": function(called, data){
+                    alert("subscribe1 " + data.params + " : " + this.Class.shortName);
+                }
+            });
+            
+            var subscribeController = new subscribeTest($("#testSubscribe")[0]);
+            
+            $("#off").bind("click",function(){
+               subscribeController.destroy(); 
+            })
+        </script>
+    </body>
+</html>
diff --git a/browserid/static/dialog/jquery/controller/subscribe/subscribe.js b/browserid/static/dialog/jquery/controller/subscribe/subscribe.js
new file mode 100644
index 0000000000000000000000000000000000000000..29b9b03fa7b7d4db8000326481c9a87d94c370cb
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/subscribe/subscribe.js
@@ -0,0 +1,53 @@
+/*global OpenAjax: true */
+steal.plugins('jquery/controller', 'jquery/lang/openajax').then(function() {
+
+	/**
+	 * @function jQuery.Controller.static.processors.subscribe
+	 * @parent jQuery.Controller.static.processors
+	 * @plugin jquery/controller/subscribe
+	 * Adds OpenAjax.Hub subscribing to controllers.
+	 * 
+	 *     $.Controller("Subscriber",{
+	 *       "recipe.updated subscribe" : function(called, recipe){
+	 *         
+	 *       },
+	 *       "todo.* subscribe" : function(called, todo){
+	 *       
+	 *       }
+	 *     })
+	 * 
+	 * You should typically be listening to jQuery triggered events when communicating between
+	 * controllers.  Subscribe should be used for listening to model changes.
+	 * 
+	 * ### API
+	 * 
+	 * This is the call signiture for the processor, not the controller subscription callbacks.
+	 * 
+	 * @param {HTMLElement} el the element being bound.  This isn't used.
+	 * @param {String} event the event type (subscribe).
+	 * @param {String} selector the subscription name
+	 * @param {Function} cb the callback function
+	 */
+	jQuery.Controller.processors.subscribe = function( el, event, selector, cb ) {
+		var subscription = OpenAjax.hub.subscribe(selector, cb);
+		return function() {
+			var sub = subscription;
+			OpenAjax.hub.unsubscribe(sub);
+		};
+	};
+
+	/**
+	 * @add jQuery.Controller.prototype
+	 */
+	//breaker
+	/**
+	 * @function publish
+	 * @hide
+	 * Publishes a message to OpenAjax.hub.
+	 * @param {String} message Message name, ex: "Something.Happened".
+	 * @param {Object} data The data sent.
+	 */
+	jQuery.Controller.prototype.publish = function() {
+		OpenAjax.hub.publish.apply(OpenAjax.hub, arguments);
+	};
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/controller/test/qunit/controller_test.js b/browserid/static/dialog/jquery/controller/test/qunit/controller_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..210685a00456dde2d73e02bc6a2aeee6bbc80a09
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/test/qunit/controller_test.js
@@ -0,0 +1,170 @@
+module("jquery/controller")
+test("subscribe testing works", function(){
+	
+	var ta = $("<div/>").appendTo( $("#qunit-test-area") )
+	
+	ta.html("click here")
+
+	var clicks = 0, destroys = 0;
+	var subscribes = 0;
+	$.Controller.extend("MyTest",{
+		click: function() {
+			clicks++
+		},
+		"a.b subscribe" : function() {
+			subscribes++
+		},
+		destroy: function() {
+			
+			this._super()
+			destroys++;
+		}
+	})
+	ta.my_test();
+	ta.trigger("click")
+	equals(clicks,1, "can listen to clicks")
+	
+	OpenAjax.hub.publish("a.b",{})
+	equals(subscribes,1, "can subscribe")
+	var controllerInstance = ta.controller('my_test')
+	ok( controllerInstance.Class == MyTest, "can get controller" )
+	controllerInstance.destroy()
+	
+	equals(destroys,1, "destroy called once")
+	ok(!ta.controller(), "controller is removed")
+	
+	OpenAjax.hub.publish("a.b",{})
+	equals(subscribes,1, "subscription is torn down")
+	ta.trigger("click")
+	equals(clicks,1, "No longer listening")
+	
+	
+	
+	ta.my_test();
+	ta.trigger("click")
+	OpenAjax.hub.publish("a.b",{})
+	equals(clicks,2, "can listen again to clicks")
+	equals(subscribes,2, "can listen again to subscription")
+	
+	ta.remove();
+	
+	ta.trigger("click")
+	OpenAjax.hub.publish("a.b",{})
+	equals(clicks,2, "Clicks stopped")
+	equals(subscribes,2, "Subscribes stopped")
+})
+
+
+test("document and main controllers", function(){
+	var a = $("<div id='test'><span/></div>").appendTo($("#qunit-test-area")),
+		a_inner = a.find('span'),
+		b = $("<div><span/></div>").appendTo($("#qunit-test-area")),
+		b_inner = b.find('span'),
+		doc_outer_clicks = 0,
+		doc_inner_clicks = 0,
+		main_outer_clicks = 0,
+		main_inner_clicks = 0;
+
+	$.Controller.extend("TestController", { onDocument: true }, {
+		click: function() {
+			doc_outer_clicks++;
+		},
+		"span click" : function() {
+			doc_inner_clicks++;
+		}
+	})
+
+	a_inner.trigger("click");
+	equals(doc_outer_clicks,1,"document controller handled (no-selector) click inside listening element");
+	equals(doc_inner_clicks,1,"document controller handled (selector) click inside listening element");
+
+	b_inner.trigger("click");
+	equals(doc_outer_clicks,1,"document controller ignored (no-selector) click outside listening element");
+	equals(doc_inner_clicks,1,"document controller ignored (selector) click outside listening element");
+
+	$(document.documentElement).controller('test').destroy();
+
+	$.Controller.extend("MainController", { onDocument: true }, {
+		click: function() {
+			main_outer_clicks++;
+		},
+		"span click" : function() {
+			main_inner_clicks++;
+		}
+	})
+
+	b_inner.trigger("click");
+	equals(main_outer_clicks,1,"main controller handled (no-selector) click");
+	equals(main_inner_clicks,1,"main controller handled (selector) click");
+
+	$(document.documentElement).controller('main').destroy();
+
+	a.remove();
+	b.remove();
+})
+
+
+test("bind to any special", function(){
+	jQuery.event.special.crazyEvent = {
+		
+	}
+	var called = false;
+	jQuery.Controller.extend("WeirdBind",{
+		crazyEvent: function() {
+			called = true;
+		}
+	})
+	var a = $("<div id='crazy'></div>").appendTo($("#qunit-test-area"))
+	a.weird_bind();
+	a.trigger("crazyEvent")
+	ok(called, "heard the trigger");
+	
+	$("#qunit-test-area").html("")
+	
+})
+
+test("parameterized actions", function(){
+	var called = false;
+	jQuery.Controller.extend("WeirderBind",{
+		"{parameterized}" : function() {
+			called = true;
+		}
+	})
+	var a = $("<div id='crazy'></div>").appendTo($("#qunit-test-area"))
+	a.weirder_bind({parameterized: "sillyEvent"});
+	a.trigger("sillyEvent")
+	ok(called, "heard the trigger")
+	
+	$("#qunit-test-area").html("")
+})
+
+test("windowresize", function(){
+	var called = false;
+	jQuery.Controller.extend("WindowBind",{
+		"windowresize" : function() {
+			called = true;
+		}
+	})
+	$("#qunit-test-area").html("<div id='weird'>")
+	$("#weird").window_bind();
+	$(window).trigger('resize')
+	ok(called,"got window resize event");
+	
+	$("#qunit-test-area").html("")
+})
+
+// this.delegate(this.cached.header.find('tr'), "th", "mousemove", "th_mousemove"); 
+test("delegate", function(){
+	var called = false;
+	jQuery.Controller.extend("DelegateTest",{
+		click: function() {}
+	})
+	var els = $("<div><span><a href='#'>click me</a></span></div>").appendTo($("#qunit-test-area"))
+	var c = els.delegate_test();
+	c.controller().delegate(els.find("span"), "a", "click", function(){
+		called = true;
+	})
+	els.find("a").trigger('click')
+	ok(called, "delegate works")
+	$("#qunit-test-area").html("")
+})
diff --git a/browserid/static/dialog/jquery/controller/test/qunit/qunit.js b/browserid/static/dialog/jquery/controller/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..611a85199d4813a68e7c21b330c1b3a4cc72746c
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/test/qunit/qunit.js
@@ -0,0 +1,9 @@
+//we probably have to have this only describing where the tests are
+steal
+ .plugins("jquery/controller",'jquery/controller/subscribe')  //load your app
+ .plugins('funcunit/qunit')  //load qunit
+ .then("controller_test")
+ 
+if(steal.browser.rhino){
+  steal.plugins('funcunit/qunit/env')
+}
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/controller/view/qunit.html b/browserid/static/dialog/jquery/controller/view/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..cfb5649af91d98a0a9d321976f889ff4fe73f63e
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/view/qunit.html
@@ -0,0 +1,21 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../../funcunit/qunit/qunit.css" />
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+		<script type='text/javascript' src='../../../steal/steal.js?steal[app]=jquery/controller/view/test/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">Controller Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/controller/view/test/qunit/controller_view_test.js b/browserid/static/dialog/jquery/controller/view/test/qunit/controller_view_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..d35ce47c2984585fcbdeb897aac8c7610d073cc7
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/view/test/qunit/controller_view_test.js
@@ -0,0 +1,15 @@
+module("jquery/controller/view")
+test("this.view", function(){
+	
+	$.Controller.extend("jquery.Controller.View.Test.Qunit",{
+		init: function() {
+			this.element.html(this.view())
+		}
+	})
+	jQuery.View.ext = ".micro";
+	$("#qunit-test-area").append("<div id='cont_view'/>");
+	
+	new jquery.Controller.View.Test.Qunit( $('#cont_view') );
+	
+	ok(/Hello World/i.test($('#cont_view').text()),"view rendered")
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/controller/view/test/qunit/qunit.js b/browserid/static/dialog/jquery/controller/view/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..38255d8c19f89045d5ef1902dd75629b48bbdfd1
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/view/test/qunit/qunit.js
@@ -0,0 +1,6 @@
+//we probably have to have this only describing where the tests are
+steal
+ .plugins('jquery/controller/view','jquery/view/micro')  //load your app
+ .plugins('funcunit/qunit')  //load qunit
+ .then("controller_view_test")
+ 
diff --git a/browserid/static/dialog/jquery/controller/view/test/qunit/views/init.micro b/browserid/static/dialog/jquery/controller/view/test/qunit/views/init.micro
new file mode 100644
index 0000000000000000000000000000000000000000..9a1eb8d21571ffcbc58add63b4645094c6b29c58
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/view/test/qunit/views/init.micro
@@ -0,0 +1 @@
+<h1>Hello World</h1>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/controller/view/view.js b/browserid/static/dialog/jquery/controller/view/view.js
new file mode 100644
index 0000000000000000000000000000000000000000..8872d138a2e142f040c9b5fe84e6482c37223d3c
--- /dev/null
+++ b/browserid/static/dialog/jquery/controller/view/view.js
@@ -0,0 +1,110 @@
+steal.plugins('jquery/controller', 'jquery/view').then(function( $ ) {
+	jQuery.Controller.getFolder = function() {
+		return jQuery.String.underscore(this.fullName.replace(/\./g, "/")).replace("/Controllers", "");
+	};
+
+	var calculatePosition = function( Class, view, action_name ) {
+		var slashes = Class.fullName.replace(/\./g, "/"),
+			hasControllers = slashes.indexOf("/Controllers/" + Class.shortName) != -1,
+			path = jQuery.String.underscore(slashes.replace("/Controllers/" + Class.shortName, "")),
+			controller_name = Class._shortName,
+			suffix = (typeof view == "string" && view.match(/\.[\w\d]+$/)) || jQuery.View.ext;
+
+		//calculate view
+		if ( typeof view == "string" ) {
+			if ( view.substr(0, 2) == "//" ) { //leave where it is
+			} else {
+				view = "//" + new steal.File('views/' + (view.indexOf('/') !== -1 ? view : (hasControllers ? controller_name + '/' : "") + view)).joinFrom(path) + suffix;
+			}
+		} else if (!view ) {
+			view = "//" + new steal.File('views/' + (hasControllers ? controller_name + '/' : "") + action_name.replace(/\.|#/g, '').replace(/ /g, '_')).joinFrom(path) + suffix;
+		}
+		return view;
+	};
+	var calculateHelpers = function( myhelpers ) {
+		var helpers = {};
+		if ( myhelpers ) {
+			if ( jQuery.isArray(myhelpers) ) {
+				for ( var h = 0; h < myhelpers.length; h++ ) {
+					jQuery.extend(helpers, myhelpers[h]);
+				}
+			}
+			else {
+				jQuery.extend(helpers, myhelpers);
+			}
+		} else {
+			if ( this._default_helpers ) {
+				helpers = this._default_helpers;
+			}
+			//load from name
+			var current = window;
+			var parts = this.Class.fullName.split(/\./);
+			for ( var i = 0; i < parts.length; i++ ) {
+				if ( typeof current.Helpers == 'object' ) {
+					jQuery.extend(helpers, current.Helpers);
+				}
+				current = current[parts[i]];
+			}
+			if ( typeof current.Helpers == 'object' ) {
+				jQuery.extend(helpers, current.Helpers);
+			}
+			this._default_helpers = helpers;
+		}
+		return helpers;
+	};
+
+	/**
+	 * @add jQuery.Controller.prototype
+	 */
+
+	jQuery.Controller.prototype.
+	/**
+	 * @tag view
+	 * Renders a View template with the controller instance. If the first argument
+	 * is not supplied, 
+	 * it looks for a view in /views/controller_name/action_name.ejs.
+	 * If data is not provided, it uses the controller instance as data.
+	 * @codestart
+	 * TasksController = $.Controller.extend('TasksController',{
+	 *   click: function( el ) {
+	 *     // renders with views/tasks/click.ejs
+	 *     el.html( this.view() ) 
+	 *     // renders with views/tasks/under.ejs
+	 *     el.after( this.view("under", [1,2]) );
+	 *     // renders with views/shared/top.ejs
+	 *     el.before( this.view("shared/top", {phrase: "hi"}) );
+	 *   }
+	 * })
+	 * @codeend
+	 * @plugin controller/view
+	 * @return {String} the rendered result of the view.
+	 * @param {String} [optional1] view The view you are going to render.  If a view isn't explicity given
+	 * this function will try to guess at the correct view as show in the example code above.
+	 * @param {Object} [optional2] data data to be provided to the view.  If not present, the controller instance 
+	 * is used.
+	 * @param {Object} [optional3] myhelpers an object of helpers that will be available in the view.  If not present
+	 * this controller class's "Helpers" property will be used.
+	 *
+	 */
+	view = function( view, data, myhelpers ) {
+		//shift args if no view is provided
+		if ( typeof view != "string" && !myhelpers ) {
+			myhelpers = data;
+			data = view;
+			view = null;
+		}
+		//guess from controller name
+		view = calculatePosition(this.Class, view, this.called);
+
+		//calculate data
+		data = data || this;
+
+		//calculate helpers
+		var helpers = calculateHelpers.call(this, myhelpers);
+
+
+		return jQuery.View(view, data, helpers); //what about controllers in other folders?
+	};
+
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/closest/closest.js b/browserid/static/dialog/jquery/dom/closest/closest.js
new file mode 100644
index 0000000000000000000000000000000000000000..906e865cbf4104a42d3d3cffb5e4045c774cee3f
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/closest/closest.js
@@ -0,0 +1,47 @@
+/**
+ *  @add jQuery.fn
+ */
+steal.plugins('jquery/dom').then(function(){
+	/**
+	 * @function closest
+	 * @parent dom
+	 * Overwrites closest to allow open > selectors.  This allows controller actions such as:
+	 * @codestart
+	 * ">li click" : function( el, ev ) { ... }
+	 * @codeend
+	 */
+	var oldClosest = jQuery.fn.closest;
+	jQuery.fn.closest = function(selectors, context){
+		var rooted = {}, res, result, thing, i, j, selector, rootedIsEmpty = true, selector, selectorsArr = selectors;
+		if(typeof selectors == "string") selectorsArr = [selectors];
+		
+		$.each(selectorsArr, function(i, selector){
+		    if(selector.indexOf(">") == 0 ){
+				if(selector.indexOf(" ") != -1){
+					throw " closest does not work with > followed by spaces!"
+				}
+				rooted[( selectorsArr[i] = selector.substr(1)  )] = selector;
+				if(typeof selectors == "string") selectors = selector.substr(1);
+				rootedIsEmpty = false;
+			}
+		})
+		
+		res = oldClosest.call(this, selectors, context);
+		
+		if(rootedIsEmpty) return res;
+		i =0;
+		while(i < res.length){
+			result = res[i], selector = result.selector;
+			if (rooted[selector] !== undefined) {
+				result.selector = rooted[selector];
+				rooted[selector] = false;
+				if(typeof result.selector !== "string"  || result.elem.parentNode !== context ){
+					res.splice(i,1);
+						continue;
+				}
+			}
+			i++;
+		}
+		return res;
+	}
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/compare/compare.html b/browserid/static/dialog/jquery/dom/compare/compare.html
new file mode 100644
index 0000000000000000000000000000000000000000..4e744c69b83fcc698a82857923c68cac8e0d7c6a
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/compare/compare.html
@@ -0,0 +1,88 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>Compare Element Positions</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            div {
+            	border: solid 1px black;
+				margin: 5px;
+				padding: 5px;
+				font-size: 12px;
+            }
+			.red {
+				background-color: red;
+			}
+			.green {
+				background-color: green;
+			}
+			.hide {
+				display: none;
+			}
+			h3 {
+				margin: 20px 0px 0px 0px;
+			}
+			th {
+				padding: 0px 5px;
+				color: gray;
+			}
+			td {
+				padding: 0px 5px;
+			}
+        </style>
+	</head>
+	<body>
+<p>Click 2 elements to compare them.</p>
+<pre>
+<code>$('.red').compare($('.green')) = <span id='result'></span></code>
+</pre>
+<div id="demo-html">
+<div>
+	A
+	<div>A.1</div>
+	<div>A.2</div>
+</div>
+<div>
+	B
+</div>
+</div>
+<h3 class='hide'>Key</h3>
+<table class='hide'>
+	<tr><th>Bits</th><th>Number</th><th>Meaning</th></tr>
+	<tr><td>000000</td><td>0</td><td>Elements are identical.</td></tr>
+	<tr><td>000001</td><td>1</td><td>The nodes are in different documents (or one is outside of a document).</td></tr>
+	<tr><td>000010</td><td>2</td><td>Node B precedes Node A.</td></tr>
+	<tr><td>000100</td><td>4</td><td>Node A precedes Node B.</td></tr>
+	<tr><td>001000</td><td>8</td><td>Node B contains Node A.</td></tr>
+	<tr><td>010000</td><td>16</td><td>Node A contains Node B.</td></tr>
+	
+</table>
+
+		<script type='text/javascript' 
+                src='../../../steal/steal.js?jquery/dom/compare/compare.js'>   
+        </script>
+<script id="demo-source" type='text/javascript'>
+var placing = 'red'
+//on click, set red and green and compare positions
+$('div').click(function(ev){
+  var next = placing == 'red' ? 'green' : 'red';
+  $('.'+placing).removeClass(placing)
+  $(this).addClass(placing) 
+  placing = next
+  ev.stopPropagation();
+  //don't worry about repeat queries for simple example
+  if($('.green').length){
+    $("#result").text(  $('.red').compare($('.green')) )
+  }
+})
+</script>
+<script type='text/javascript'>
+	$(function(){
+		if(window.parent == window){
+			$('.hide').show()
+		}
+	})
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/compare/compare.js b/browserid/static/dialog/jquery/dom/compare/compare.js
new file mode 100644
index 0000000000000000000000000000000000000000..76813043e9c8bf18f98ebf534baa9b4ec1ee5704
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/compare/compare.js
@@ -0,0 +1,67 @@
+/**
+ *  @add jQuery.fn
+ */
+steal.plugins('jquery/dom').then(function($){
+/**
+ * @function compare
+ * @parent dom
+ * @download http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/dom/compare/compare.js 
+ * Compares the position of two nodes and returns a bitmask detailing how they are positioned 
+ * relative to each other.  You can expect it to return the same results as 
+ * [http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-compareDocumentPosition | compareDocumentPosition].
+ * Parts of this documentation and source come from [http://ejohn.org/blog/comparing-document-position | John Resig].
+ * <h2>Demo</h2>
+ * @demo jquery/dom/compare/compare.html
+ * @test jquery/dom/compare/qunit.html
+ * @plugin dom/compare
+ * @param {HTMLElement} a the first node
+ * @param {HTMLElement} b the second node
+ * @return {Number} A bitmap with the following digit values:
+ * <table class='options'>
+ *     <tr><th>Bits</th><th>Number</th><th>Meaning</th></tr>
+ *     <tr><td>000000</td><td>0</td><td>Elements are identical.</td></tr>
+ *     <tr><td>000001</td><td>1</td><td>The nodes are in different documents (or one is outside of a document).</td></tr>
+ *     <tr><td>000010</td><td>2</td><td>Node B precedes Node A.</td></tr>
+ *     <tr><td>000100</td><td>4</td><td>Node A precedes Node B.</td></tr>
+ *     <tr><td>001000</td><td>8</td><td>Node B contains Node A.</td></tr>
+ *     <tr><td>010000</td><td>16</td><td>Node A contains Node B.</td></tr>
+ * </table>
+ */
+jQuery.fn.compare = function(b){ //usually 
+	//b is usually a relatedTarget, but b/c it is we have to avoid a few FF errors
+	
+	try{ //FF3 freaks out with XUL
+		b = b.jquery ? b[0] : b;
+	}catch(e){
+		return null;
+	}
+	if (window.HTMLElement) { //make sure we aren't coming from XUL element
+		var s = HTMLElement.prototype.toString.call(b)
+		if (s == '[xpconnect wrapped native prototype]' || s == '[object XULElement]') return null;
+	}
+	if(this[0].compareDocumentPosition){
+		return this[0].compareDocumentPosition(b);
+	}
+	if(this[0] == document && b != document) return 8;
+	var number = (this[0] !== b && this[0].contains(b) && 16) + (this[0] != b && b.contains(this[0]) && 8),
+		docEl = document.documentElement;
+	if(this[0].sourceIndex){
+		number += (this[0].sourceIndex < b.sourceIndex && 4)
+		number += (this[0].sourceIndex > b.sourceIndex && 2)
+		number += (this[0].ownerDocument !== b.ownerDocument ||
+			(this[0] != docEl && this[0].sourceIndex <= 0 ) ||
+			(b != docEl && b.sourceIndex <= 0 )) && 1
+	}else{
+		var range = document.createRange(), 
+			sourceRange = document.createRange(),
+			compare;
+		range.selectNode(this[0]);
+		sourceRange.selectNode(b);
+		compare = range.compareBoundaryPoints(Range.START_TO_START, sourceRange);
+		
+	}
+
+	return number;
+}
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/compare/qunit.html b/browserid/static/dialog/jquery/dom/compare/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..1f2208f1cedb254789ecb1a6856aacfecaa7c8a9
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/compare/qunit.html
@@ -0,0 +1,20 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../../funcunit/qunit/qunit.css" />
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">jQuery Dom Compare Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+        <ol id="qunit-tests"></ol>
+
+    <script type='text/javascript' src='../../../steal/steal.js?steal[app]=jquery/dom/compare/test/qunit'></script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/compare/test/qunit/compare_test.js b/browserid/static/dialog/jquery/dom/compare/test/qunit/compare_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..056bf7b5c22b4aa99bd81ae7e54253b7c582da93
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/compare/test/qunit/compare_test.js
@@ -0,0 +1,19 @@
+module("jquery/dom/compare")
+test("Compare cases", function(){
+    $(document.body).append("<div id='outer'><div class='first'></div><div class='second'></div>")
+    var outer = $("#outer"), 
+		first= outer.find(".first"), second = outer.find('.second')
+    equals(outer.compare(outer) , 0, "identical elements")
+    var outside = document.createElement("div")
+    ok(outer.compare(outside) & 1, "different documents")
+    
+    equals(outer.compare(first), 20, "A container element");
+    equals(outer.compare(second), 20, "A container element");
+    
+    equals(first.compare(outer), 10, "A parent element");
+    equals(second.compare(outer), 10, "A parent element");
+    
+    equals(first.compare(second), 4, "A sibling elements");
+    equals(second.compare(first), 2, "A sibling elements");
+    outer.remove()
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/compare/test/qunit/qunit.js b/browserid/static/dialog/jquery/dom/compare/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..8ac2c35feef50280e654084338293e8924e4c9f7
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/compare/test/qunit/qunit.js
@@ -0,0 +1,5 @@
+//we probably have to have this only describing where the tests are
+steal
+ .plugins("jquery/dom/compare")  //load your app
+ .plugins('funcunit/qunit')  //load qunit
+ .then("compare_test")
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/cookie/cookie.js b/browserid/static/dialog/jquery/dom/cookie/cookie.js
new file mode 100644
index 0000000000000000000000000000000000000000..38c03e876dfde0e42f30160cdaee944734538683
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/cookie/cookie.js
@@ -0,0 +1,119 @@
+steal.plugins('jquery/lang/json').then(function() {
+    // break
+    /**
+     * @function jQuery.cookie
+     * @parent dom
+     * @author Klaus Hartl/klaus.hartl@stilbuero.de
+     *
+     * <h3>Cookie plugin</h3>
+     *
+     *
+	 *  <p>
+	 *  Copyright (c) 2006 Klaus Hartl (stilbuero.de)<br />
+	 *  Dual licensed under the MIT and GPL licenses:<br />
+	 *  http://www.opensource.org/licenses/mit-license.php<br />
+	 *  http://www.gnu.org/licenses/gpl.html
+	 *  </p>
+	 *  <p>
+	 *  Create a cookie with the given name and value and other optional parameters.
+	 *  / Get the value of a cookie with the given name.
+	 *  </p>
+	 *  <h3>Quick Examples</h3>
+	 * 
+	 *  Set the value of a cookie.
+	 *  @codestart
+	 *  * $.cookie('the_cookie', 'the_value');
+	 *  @codeend
+	 * 
+	 *  Create a cookie with all available options.
+	 *  @codestart
+	 *  $.cookie('the_cookie', 'the_value',
+	 *  { expires: 7, path: '/', domain: 'jquery.com', secure: true });
+	 *  @codeend
+	 * 
+	 *  Create a session cookie.
+	 *  @codestart
+	 *  $.cookie('the_cookie', 'the_value');
+	 *  @codeend
+	 * 
+	 *  Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
+	 *  used when the cookie was set.
+	 *  @codestart
+	 *  $.cookie('the_cookie', null);
+	 *  @codeend
+	 * 
+	 *  Get the value of a cookie.
+	 *  @codestart
+	 *  $.cookie('the_cookie');
+	 *  @codeend
+	 * 
+     *
+     * @param {String} [name] The name of the cookie.
+     * @param {String} [value] The value of the cookie.
+     * @param {Object} [options] An object literal containing key/value pairs to provide optional cookie attributes.<br />
+     * @param {Number|Date} [expires] Either an integer specifying the expiration date from now on in days or a Date object.
+     *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
+     *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
+     *                             when the the browser exits.<br />
+     * @param {String} [path] The value of the path atribute of the cookie (default: path of page that created the cookie).<br />
+     * @param {String} [domain] The value of the domain attribute of the cookie (default: domain of page that created the cookie).<br />
+     * @param {Boolean} secure If true, the secure attribute of the cookie will be set and the cookie transmission will
+     *                        require a secure protocol (like HTTPS).<br />
+     * @return {String} or {undefined} when setting the cookie.
+     */
+    jQuery.cookie = function(name, value, options) {
+        if (typeof value != 'undefined') { // name and value given, set cookie
+            options = options ||
+            {};
+            if (value === null) {
+                value = '';
+                options.expires = -1;
+            }
+            if (typeof value == 'object' && jQuery.toJSON) {
+                value = jQuery.toJSON(value);
+            }
+            var expires = '';
+            if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
+                var date;
+                if (typeof options.expires == 'number') {
+                    date = new Date();
+                    date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
+                }
+                else {
+                    date = options.expires;
+                }
+                expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
+            }
+            // CAUTION: Needed to parenthesize options.path and options.domain
+            // in the following expressions, otherwise they evaluate to undefined
+            // in the packed version for some reason...
+            var path = options.path ? '; path=' + (options.path) : '';
+            var domain = options.domain ? '; domain=' + (options.domain) : '';
+            var secure = options.secure ? '; secure' : '';
+            document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
+        }
+        else { // only name given, get cookie
+            var cookieValue = null;
+            if (document.cookie && document.cookie != '') {
+                var cookies = document.cookie.split(';');
+                for (var i = 0; i < cookies.length; i++) {
+                    var cookie = jQuery.trim(cookies[i]);
+                    // Does this cookie string begin with the name we want?
+                    if (cookie.substring(0, name.length + 1) == (name + '=')) {
+                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+                        break;
+                    }
+                }
+            }
+            if (jQuery.evalJSON && cookieValue && cookieValue.match(/^\s*\{/)) {
+                try {
+                    cookieValue = jQuery.evalJSON(cookieValue);
+                }
+                catch (e) {
+                }
+            }
+            return cookieValue;
+        }
+    };
+
+});
diff --git a/browserid/static/dialog/jquery/dom/cur_styles/cur_styles.html b/browserid/static/dialog/jquery/dom/cur_styles/cur_styles.html
new file mode 100644
index 0000000000000000000000000000000000000000..51e11c41adb26091ab814fb933460204f4f70044
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/cur_styles/cur_styles.html
@@ -0,0 +1,71 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+    <head>
+        <title>CurStyles Performance Test/Demo</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+			#content {height: 100px; width: 300px; 
+			margin: 20px; 
+			padding: 10px; 
+			border: solid 1px black;
+			cursor: pointer;
+			}
+        </style>
+    </head>
+    <body>
+    	<h1>CurStyles Performance</h1>
+		<p>This demo shows how $.curStyles out-performs $.curCSS</p>
+<div id="demo-html">
+<div id='content'>
+	Click To Run
+</div>
+</div>
+<script type='text/javascript'  
+        src='../../../steal/steal.js'></script>
+<script type='text/javascript'>
+steal.plugins('jquery/dom/cur_styles').start()
+</script>
+
+<script type='text/javascript' id="demo-source">
+
+$.fn.fastHeight = function(){
+	var sum = this[0] && this[0].offsetHeight;
+	$.each(this.curStyles(
+		"borderTopWidth",
+		"borderBottomWidth",
+		"paddingTop",
+		"paddingBottom"), function(name, val){
+			sum -= parseInt(val) || 0;
+		});
+	return sum;
+}
+
+
+var test = function(func){
+	var start = new Date(),
+		content = $("#content");
+	for(var i =0; i < 2000; i++){
+		content[func]()
+	}
+	return ( new Date() - start );
+}
+
+
+$("#content").click(function(){
+	var height = test("height"),
+		fastheight = test("fastHeight");
+	$("#content").html("jQuery's height: <b>"+
+		height+
+		"</b>ms<br/>fastHeight: <b>"+
+		fastheight+
+		"</b>ms"
+		)
+})
+
+
+
+
+</script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/cur_styles/cur_styles.js b/browserid/static/dialog/jquery/dom/cur_styles/cur_styles.js
new file mode 100644
index 0000000000000000000000000000000000000000..b44590e58f6ab8ab7ccd27e937a2f5dcdb68ab8c
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/cur_styles/cur_styles.js
@@ -0,0 +1,117 @@
+steal.plugins('jquery/dom').then(function( $ ) {
+
+	var getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
+		rupper = /([A-Z])/g,
+		rdashAlpha = /-([a-z])/ig,
+		fcamelCase = function( all, letter ) {
+			return letter.toUpperCase();
+		},
+		getStyle = function( elem ) {
+			if ( getComputedStyle ) {
+				return getComputedStyle(elem, null);
+			}
+			else if ( elem.currentStyle ) {
+				return elem.currentStyle;
+			}
+		},
+		rfloat = /float/i,
+		rnumpx = /^-?\d+(?:px)?$/i,
+		rnum = /^-?\d/;
+	/**
+	 * @add jQuery
+	 */
+	//
+	/**
+	 * @function curStyles
+	 * @param {HTMLElement} el
+	 * @param {Array} styles An array of style names like <code>['marginTop','borderLeft']</code>
+	 * @return {Object} an object of style:value pairs.  Style names are camelCase.
+	 */
+	$.curStyles = function( el, styles ) {
+		if (!el ) {
+			return null;
+		}
+		var currentS = getStyle(el),
+			oldName, val, style = el.style,
+			results = {},
+			i = 0,
+			left, rsLeft, camelCase, name;
+
+		for (; i < styles.length; i++ ) {
+			name = styles[i];
+			oldName = name.replace(rdashAlpha, fcamelCase);
+
+			if ( rfloat.test(name) ) {
+				name = jQuery.support.cssFloat ? "float" : "styleFloat";
+				oldName = "cssFloat";
+			}
+
+			if ( getComputedStyle ) {
+				name = name.replace(rupper, "-$1").toLowerCase();
+				val = currentS.getPropertyValue(name);
+				if ( name === "opacity" && val === "" ) {
+					val = "1";
+				}
+				results[oldName] = val;
+			} else {
+				camelCase = name.replace(rdashAlpha, fcamelCase);
+				results[oldName] = currentS[name] || currentS[camelCase];
+
+
+				if (!rnumpx.test(results[oldName]) && rnum.test(results[oldName]) ) { //convert to px
+					// Remember the original values
+					left = style.left;
+					rsLeft = el.runtimeStyle.left;
+
+					// Put in the new values to get a computed value out
+					el.runtimeStyle.left = el.currentStyle.left;
+					style.left = camelCase === "fontSize" ? "1em" : (results[oldName] || 0);
+					results[oldName] = style.pixelLeft + "px";
+
+					// Revert the changed values
+					style.left = left;
+					el.runtimeStyle.left = rsLeft;
+				}
+
+			}
+		}
+
+		return results;
+	};
+	/**
+	 *  @add jQuery.fn
+	 */
+
+
+	$.fn
+	/**
+	 * @parent dom
+	 * @plugin jquery/dom/cur_styles
+	 * @download http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/dom/cur_styles/cur_styles.js
+	 * @test jquery/dom/cur_styles/qunit.html
+	 * Use curStyles to rapidly get a bunch of computed styles from an element.
+	 * <h3>Quick Example</h3>
+	 * @codestart
+	 * $("#foo").curStyles('float','display') //->
+	 * // {
+	 * //  cssFloat: "left", display: "block"
+	 * // }
+	 * @codeend
+	 * <h2>Use</h2>
+	 * <p>An element's <b>computed</b> style is the current calculated style of the property.
+	 * This is different than the values on <code>element.style</code> as
+	 * <code>element.style</code> doesn't reflect styles provided by css or the browser's default
+	 * css properties.</p>
+	 * <p>Getting computed values individually is expensive! This plugin lets you get all
+	 * the style properties you need all at once.</p>
+	 * <h2>Demo</h2>
+	 * <p>The following demo illustrates the performance improvement curStyle provides by providing
+	 * a faster 'height' jQuery function called 'fastHeight'.</p>
+	 * @demo jquery/dom/cur_styles/cur_styles.html
+	 * @param {String} style pass style names as arguments
+	 * @return {Object} an object of style:value pairs
+	 */
+	.curStyles = function() {
+		return $.curStyles(this[0], $.makeArray(arguments));
+	};
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/cur_styles/qunit.html b/browserid/static/dialog/jquery/dom/cur_styles/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..813417974e6c7215e7d20a9cbb7e9ee417cc105d
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/cur_styles/qunit.html
@@ -0,0 +1,22 @@
+<html>
+    <head>
+    	<title>CurStyles Test Suite</title>
+        <link rel="stylesheet" type="text/css" href="../../../funcunit/qunit/qunit.css" />
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+		<script type='text/javascript' src='../../../steal/steal.js?steal[app]=jquery/dom/cur_styles/test/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">CurStyles Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/cur_styles/test/qunit/curStyles.micro b/browserid/static/dialog/jquery/dom/cur_styles/test/qunit/curStyles.micro
new file mode 100644
index 0000000000000000000000000000000000000000..7c7503ca4479987f4c476ff6a79127af5cff8f2b
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/cur_styles/test/qunit/curStyles.micro
@@ -0,0 +1,3 @@
+<div style='margin-top: 10px; padding-left: 5px; position: relative; float: left; border: solid 2px black;' id='styled'>
+Here is some content;
+</div>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/cur_styles/test/qunit/cur_styles_test.js b/browserid/static/dialog/jquery/dom/cur_styles/test/qunit/cur_styles_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..ce5ac756a67baa59e971f9fda8132eaf205ee3a2
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/cur_styles/test/qunit/cur_styles_test.js
@@ -0,0 +1,22 @@
+module("jquery/dom/curStyles");
+
+
+test("reading", function(){
+	$("#qunit-test-area").html("//jquery/dom/cur_styles/test/qunit/curStyles.micro",{})
+
+	var res = $.curStyles( $("#styled")[0], 
+	   ["padding-left",
+		'position',
+		'display',
+		"margin-top", 
+		"borderTopWidth",
+		"float"] );
+	equals(res.borderTopWidth, "2px","border top");
+	equals(res.display, "block","display");
+	equals(res.cssFloat, "left","float");
+	equals(res.marginTop, "10px","margin top");
+	equals(res.paddingLeft, "5px","padding left");
+	equals(res.position, "relative","position");
+	$("#qunit-test-area").html("")
+})
+
diff --git a/browserid/static/dialog/jquery/dom/cur_styles/test/qunit/outer.micro b/browserid/static/dialog/jquery/dom/cur_styles/test/qunit/outer.micro
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/browserid/static/dialog/jquery/dom/cur_styles/test/qunit/qunit.js b/browserid/static/dialog/jquery/dom/cur_styles/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..e51bcaaf704ce23cdb4342a93a4756939fe9a502
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/cur_styles/test/qunit/qunit.js
@@ -0,0 +1,4 @@
+steal
+ .plugins("jquery/dom/dimensions",'jquery/view/micro')  //load your app
+ .plugins('funcunit/qunit')  //load qunit
+ .then("cur_styles_test")
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/dimensions/dimensions.html b/browserid/static/dialog/jquery/dom/dimensions/dimensions.html
new file mode 100644
index 0000000000000000000000000000000000000000..6e2e31502a81891d8bbc7275a5e18bc8232553fa
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/dimensions/dimensions.html
@@ -0,0 +1,132 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+    <head>
+        <title>Dimensions Demo</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            #inner {
+                height: 100%;
+                width: 100%;
+                background-color: red;
+            }
+            #block {
+                height: 200px;
+                width: 200px;
+                padding: 0 40px 40px 0;
+                margin: 0 10px 10px 0;
+                background-color: blue;
+                border-right: solid 20px green;
+                border-bottom: solid 20px green;
+            }
+            #wrapper {
+                border: dashed 1px gray;
+                float: left;
+                clear: left;
+                background-color: yellow;
+            }
+            #width { background-color: red;}
+            #paddingRight {background-color: blue;}
+            #borderRightWidth {background-color: green;}
+            #innerWidth {color: #000080;}
+            #outerWidth {color: #008000;}
+            #marginRight {background-color: yellow}
+            input {
+                text-align: right;
+                font-size: 14pt;
+                font-weight: bold;
+                width: 100px;
+            }
+            label {
+                display: inline-block;
+                width: 100px;
+                text-align: right;
+            }
+        </style>
+    </head>
+    <body>
+
+    
+<div id="demo-html">
+<p>Adjust The red box's layout properties.</p>
+<label>  Width</label> <input id='width'/><br/>
+<label>+ Padding </label> <input id='paddingRight'/><br/>
+<label>= Inner</label> <input id='innerWidth'/><br/>
+<label>+ Border</label> <input id='borderRightWidth'/><br/>
+<label>= Outer</label> <input id='outerWidth'/><br/>
+<label>  Margin</label> <input id='marginRight'/><br/>
+<br/>
+    
+<div id='wrapper'>
+    <div id='block'>
+        <div id='inner'>
+            Adjust My Layout Properties
+        </div>
+    </div>
+</div>
+</div>
+<div style='clear:both'></div>
+        <script type='text/javascript' 
+                src='../../../steal/steal.js'>   
+        </script>
+<script type='text/javascript'>
+    steal.plugins('jquery/dom/dimensions').start()
+</script>
+<script type='text/javascript' id="demo-source">
+// sets the values in the input boxes
+var set = function() {
+    
+  var block =  $('#block');
+    
+  //get with .fn helpers
+  $("#outerWidth, #innerWidth, #width").each(function(){
+    $(this).val( block[this.id]() )
+  })
+    
+  //use curStyles
+  $.each($('#block').curStyles("paddingRight",
+    "borderRightWidth",
+    "marginRight"), function(name, val){
+    $("#"+name).val( parseInt(val)  )
+  });
+}
+set();
+
+// updates the dimensions of the block
+var update = function( ev ) {
+  var name = ev.target.id,
+      val = parseInt( $(ev.target).val() ),
+      opposite = {Width: "Height", Right: "Bottom"},
+      // the opposite dimension name
+      otherName = name.replace(/width|right/i, function(part, i){
+        return i == 0 ? "height" : opposite[part];
+      }),
+      block = $('#block'),
+      css = {};
+
+  if( block[name] ) { 
+    // set with innerHeight, outerHeight, etc
+    block[name]( val )[otherName](val)
+  }else{
+    // set as css property
+    css[name] = val+"px"
+    css[otherName] = val+"px"
+    block.css(css)
+  }
+
+  set();
+};
+
+// call update on change or after  
+// typing has stopped for a second
+var timer;
+$("input").live('change',update)
+$("input").live('keyup',function(ev) {
+  clearTimeout(timer)
+  timer = setTimeout(function() {
+    update(ev)
+  },1400)
+})
+</script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/dimensions/dimensions.js b/browserid/static/dialog/jquery/dom/dimensions/dimensions.js
new file mode 100644
index 0000000000000000000000000000000000000000..2d4b0f17b81a1400cfde92c4f2930fadfc66f786
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/dimensions/dimensions.js
@@ -0,0 +1,140 @@
+
+steal.plugins('jquery/dom/cur_styles').then(function($) {
+/**
+ * @page dimensions dimensions
+ * @parent dom
+ * <h1>jquery/dom/dimensions <span class="Constructor type">Plugin</span></h1>
+ * The dimensions plugin adds support for setting+animating inner+outer height and widths.
+ * <h3>Quick Examples</h3>
+@codestart
+$('#foo').outerWidth(100).innerHeight(50);
+$('#bar').animate({outerWidth: 500});
+@codeend
+ * <h2>Use</h2>
+ * <p>When writing reusable plugins, you often want to 
+ * set or animate an element's width and height that include its padding,
+ * border, or margin.  This is especially important in plugins that
+ * allow custom styling.
+ * The dimensions plugin overwrites [jQuery.fn.outerHeight outerHeight],
+ * [jQuery.fn.outerWidth outerWidth], [jQuery.fn.innerHeight innerHeight] 
+ * and [jQuery.fn.innerWidth innerWidth]
+ * to let you set and animate these properties.
+ * </p>
+ * <h2>Demo</h2>
+ * @demo jquery/dom/dimensions/dimensions.html
+ */
+
+var weird = /button|select/i, //margin is inside border
+	getBoxes = {},
+    checks = {
+        width: ["Left", "Right"],
+        height: ['Top', 'Bottom'],
+        oldOuterHeight: $.fn.outerHeight,
+        oldOuterWidth: $.fn.outerWidth,
+        oldInnerWidth: $.fn.innerWidth,
+        oldInnerHeight: $.fn.innerHeight
+    };
+/**
+ *  @add jQuery.fn
+ */
+$.each({ 
+
+/*
+ * @function outerWidth
+ * @parent dimensions
+ * Lets you set the outer height on an object
+ * @param {Number} [height] 
+ * @param {Boolean} [includeMargin]
+ */
+width: 
+/*
+ * @function innerWidth
+ * @parent dimensions
+ * Lets you set the inner height of an object
+ * @param {Number} [height] 
+ */
+"Width", 
+/*
+ * @function outerHeight
+ * @parent dimensions
+ * Lets you set the outer height of an object where: <br/> 
+ * <code>outerHeight = height + padding + border + (margin)</code>.  
+ * @codestart
+ * $("#foo").outerHeight(100); //sets outer height
+ * $("#foo").outerHeight(100, true); //uses margins
+ * $("#foo").outerHeight(); //returns outer height
+ * $("#foo").outerHeight(true); //returns outer height with margins
+ * @codeend
+ * When setting the outerHeight, it adjusts the height of the element.
+ * @param {Number|Boolean} [height] If a number is provided -> sets the outer height of the object.<br/>
+ * If true is given ->  returns the outer height and includes margins.<br/>
+ * If no value is given -> returns the outer height without margin.
+ * @param {Boolean} [includeMargin] Makes setting the outerHeight adjust for margin.
+ * @return {jQuery|Number} If you are setting the value, returns the jQuery wrapped elements.
+ * Otherwise, returns outerHeight in pixels.
+ */
+height: 
+/*
+ * @function innerHeight
+ * @parent dimensions
+ * Lets you set the outer width on an object
+ * @param {Number} [height] 
+ */
+"Height" }, function(lower, Upper) {
+
+    //used to get the padding and border for an element in a given direction
+    getBoxes[lower] = function(el, boxes) {
+        var val = 0;
+        if (!weird.test(el.nodeName)) {
+            //make what to check for ....
+            var myChecks = [];
+            $.each(checks[lower], function() {
+                var direction = this;
+                $.each(boxes, function(name, val) {
+                    if (val)
+                        myChecks.push(name + direction+ (name == 'border' ? "Width" : "") );
+                })
+            })
+            $.each($.curStyles(el, myChecks), function(name, value) {
+                val += (parseFloat(value) || 0);
+            })
+        }
+        return val;
+    }
+
+    //getter / setter
+    $.fn["outer" + Upper] = function(v, margin) {
+        if (typeof v == 'number') {
+            this[lower](v - getBoxes[lower](this[0], {padding: true, border: true, margin: margin}))
+            return this;
+        } else {
+            return checks["oldOuter" + Upper].call(this, v)
+        }
+    }
+    $.fn["inner" + Upper] = function(v) {
+        if (typeof v == 'number') {
+            this[lower](v - getBoxes[lower](this[0], { padding: true }))
+            return this;
+        } else {
+            return checks["oldInner" + Upper].call(this, v)
+        }
+    }
+    //provides animations
+	var animate = function(boxes){
+		return function(fx){
+			if (fx.state == 0) {
+	            fx.start = $(fx.elem)[lower]();
+	            fx.end = fx.end - getBoxes[lower](fx.elem,boxes);
+	        }
+	        fx.elem.style[lower] = (fx.pos * (fx.end - fx.start) + fx.start) + "px"
+		}
+	}
+    $.fx.step["outer" + Upper] = animate({padding: true, border: true})
+	
+	$.fx.step["outer" + Upper+"Margin"] =  animate({padding: true, border: true, margin: true})
+	
+	$.fx.step["inner" + Upper] = animate({padding: true})
+
+})
+
+})
diff --git a/browserid/static/dialog/jquery/dom/dimensions/qunit.html b/browserid/static/dialog/jquery/dom/dimensions/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..3636028fb114e53f29d8429b084e1e2cf657529f
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/dimensions/qunit.html
@@ -0,0 +1,22 @@
+<html>
+    <head>
+    	<title>Dimensions Test Suite</title>
+        <link rel="stylesheet" type="text/css" href="../../../funcunit/qunit/qunit.css" />
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+		<script type='text/javascript' src='../../../steal/steal.js?steal[app]=jquery/dom/dimensions/test/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">Dimensions Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/dimensions/test/qunit/curStyles.micro b/browserid/static/dialog/jquery/dom/dimensions/test/qunit/curStyles.micro
new file mode 100644
index 0000000000000000000000000000000000000000..7c7503ca4479987f4c476ff6a79127af5cff8f2b
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/dimensions/test/qunit/curStyles.micro
@@ -0,0 +1,3 @@
+<div style='margin-top: 10px; padding-left: 5px; position: relative; float: left; border: solid 2px black;' id='styled'>
+Here is some content;
+</div>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/dimensions/test/qunit/dimensions_test.js b/browserid/static/dialog/jquery/dom/dimensions/test/qunit/dimensions_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..9d34e7e8f96f405bed4a5e5b8ac1e72341115a10
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/dimensions/test/qunit/dimensions_test.js
@@ -0,0 +1,8 @@
+module("jquery/dom/dimensions");
+
+
+
+
+test("outerHeight and width",function(){
+	$("#qunit-test-area").html("//jquery/dom/dimensions/test/qunit/curStyles.micro",{})
+})
diff --git a/browserid/static/dialog/jquery/dom/dimensions/test/qunit/outer.micro b/browserid/static/dialog/jquery/dom/dimensions/test/qunit/outer.micro
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/browserid/static/dialog/jquery/dom/dimensions/test/qunit/qunit.js b/browserid/static/dialog/jquery/dom/dimensions/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..d842c596544b1d34d2e7c1306554b37797de544b
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/dimensions/test/qunit/qunit.js
@@ -0,0 +1,4 @@
+steal
+ .plugins("jquery/dom/dimensions",'jquery/view/micro')  //load your app
+ .plugins('funcunit/qunit')  //load qunit
+ .then("dimensions_test")
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/dom.js b/browserid/static/dialog/jquery/dom/dom.js
new file mode 100644
index 0000000000000000000000000000000000000000..f964832fa0752f94a2be656486aed408c351e3ac
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/dom.js
@@ -0,0 +1,7 @@
+/**
+ * @page dom DOM Helpers
+ * @tag core
+ * JavaScriptMVC adds a bunch of useful jQuery extensions for the dom.  Check them out on the left.
+ * 
+ */
+steal.plugins('jquery');
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/fixture/fixture.html b/browserid/static/dialog/jquery/dom/fixture/fixture.html
new file mode 100644
index 0000000000000000000000000000000000000000..75a7d6de1dda32baf79a32466a5786969156a17f
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/fixture/fixture.html
@@ -0,0 +1,143 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+    <head>
+        <title>Fixture Demo</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            #messages {height: 200px; overflow-y: auto;}
+			#content {height: 551px; overflow: hidden;}
+        </style>
+    </head>
+    <body>
+<div id="demo-html">
+<div id='content'></div>
+</div>
+<script type='text/javascript'  
+        src='../../../steal/steal.js'></script>
+<script type='text/javascript'>
+steal.plugins('jquery/dom/fixture','jquery/dom/form_params').start()
+</script>
+
+<script type='text/javascript' id="demo-source">
+
+// gets content from a fixture
+$.get("/messages.php",
+  function(html){
+    // put the result in content
+    $('#content').html(html)
+  }, 
+  'text',
+  'fixtures/messages.html');
+
+
+// makes 20 messages in a fixture
+$.fixture.make(["messages","message"],20, function(i, messages){
+  return {
+    subject: "This is message "+i,
+    body: "Here is some text for this message",
+    user: "Justin",
+    createdAt: String(new Date( Math.random() *  new Date().getTime()   ))
+  }
+});
+
+// gets messages on submit
+$("#getMessages").live("submit",function(ev){
+    
+  ev.preventDefault();
+    
+  //get the limit and offset
+  var params = $(this).formParams().params;
+    
+  //use -messages fixture created by make
+  $.ajax({
+    url: "/messages.json",
+    data: params,
+    success: function(json){
+      $("#messages").html( messagesHTML(json) )
+    },
+    dataType: "json",
+    fixture: "-messages"
+  })
+});
+
+
+// a fixture for creating messages
+$.fixture["-createMessage"] = function(settings, cbType){
+  // add to the message data what the server would add
+  var message = $.extend({
+    id: arguments.callee.count++,
+    user: "Justin",
+    createdAt: String(new Date())
+  }, settings.data);
+  
+  message.id = $.fixture["~messages"].length;
+    
+  // adds the message to the fixture data
+  $.fixture["~messages"].push(message);
+    
+  // return the data for the callback
+  return [message];
+};
+
+
+// creates a message on submit
+$("#message").live("submit", function(ev){
+  ev.preventDefault();
+    
+  // get message data
+  var message = $(this).formParams().message;
+    
+  // uses -createMessage fixture
+  $.post("/message.json", message,function(json){
+        
+    //clear the message form
+    $('[name*=message]').val("");
+    
+    //show the new message
+    $('[name*=offset]').val(json.id)
+    $('[name*=limit]').val(1)
+    $("#getMessages").submit();
+        
+  },'json',"-createMessage")
+})
+
+//creates the html from message data
+var messagesHTML = function(json){
+  var html = ["<h4>Messages (count=", 
+              json.count,
+              ")</h4>",
+              "<table>",
+              "<tr>"],
+      cols = ["subject",
+	          "body",
+			  "user",
+			  "createdAt"];
+  
+  // html for the column headers		  
+  $.each(cols, function(i, prop){
+    html.push("<th>"+prop+"</th>")
+  })
+  
+  html.push("</tr>")
+  
+  // html for the messages
+  $.each(json.data, function(m, message){
+    html.push("<tr>")
+    $.each(cols, function(i, prop){
+        html.push("<td>"+message[prop]+"</td>")
+    })
+    html.push("</tr>")
+  })
+  
+  html.push("</table>");
+  return html.join("");
+}
+
+
+
+
+
+</script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/fixture/fixture.js b/browserid/static/dialog/jquery/dom/fixture/fixture.js
new file mode 100644
index 0000000000000000000000000000000000000000..787fae0066c2f5336648dc453beb0010d6ee50a9
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/fixture/fixture.js
@@ -0,0 +1,518 @@
+steal.plugins('jquery/dom').then(function( $ ) {
+
+	var ajax = $.ajax;
+
+	/**
+	 * @class jQuery.fixture
+	 * @plugin jquery/dom/fixture
+	 * @download http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/dom/fixture/fixture.js
+	 * @test jquery/dom/fixture/qunit.html
+	 * @parent dom
+	 * 
+	 * Fixtures simulate AJAX responses by overwriting 
+	 * [jQuery.ajax $.ajax], 
+	 * [jQuery.get $.get], and 
+	 * [jQuery.post $.post].  
+	 * Instead of making a request to a server, fixtures simulate 
+	 * the repsonse with a file or function.
+	 * 
+	 * They are a great technique when you want to develop JavaScript 
+	 * independently of the backend. 
+	 * 
+	 * <h3>Quick Example</h3>
+	 * <p>Instead of making a request to <code>/tasks.json</code>,
+	 *    $.ajax will look in <code>fixtures/tasks.json</code>.
+	 *    It's expected that a static <code>fixtures/tasks.json</code> 
+	 *    file exists relative to the current page. 
+	 * </p>
+	 * @codestart
+	 * $.ajax({url: "/tasks.json",
+	 *   dataType: "json",
+	 *   type: "get",
+	 *   fixture: "fixtures/tasks.json",
+	 *   success: myCallback});
+	 * @codeend
+	 * <h2>Using Fixtures</h2>
+	 * To enable fixtures, you must add this plugin to your page and 
+	 * set the fixture property.  
+	 * 
+	 * The fixture property is set as ...
+	 * @codestart
+	 * //... a property with $.ajax
+	 * $.ajax({fixture: FIXTURE_VALUE})
+	 * 
+	 * //... a parameter in $.get and $.post
+	 * $.get (  url, data, callback, type, FIXTURE_VALUE )
+	 * $.post(  url, data, callback, type, FIXTURE_VALUE )
+	 * @codeend
+	 * <h3>Turning Off Fixtures</h3>
+	 * <p>To turn off fixtures, simply remove the fixture plugin from 
+	 *  your page.  The Ajax methods will ignore <code>FIXTURE_VALUE</code>
+	 *  and revert to their normal behavior.  If you want to ignore a single
+	 *  fixture, we suggest commenting it out.
+	 * </p>
+	 * <div class='whisper'>
+	 * PRO TIP:  Don't worry about leaving the fixture values in your source.  
+	 * They don't take up many characters and won't impact how jQuery makes
+	 * requests.  They can be useful even after the service they simulate
+	 * is created.
+	 * </div>
+	 * <h2>Types of Fixtures</h2>
+	 * <p>There are 2 types of fixtures</p>
+	 * <ul>
+	 *  <li><b>Static</b> - the response is in a file.
+	 *  </li>
+	 *  <li>
+	 *   <b>Dynamic</b> - the response is generated by a function.
+	 *  </li>
+	 * </ul>
+	 * There are different ways to lookup static and dynamic fixtures.
+	 * <h3>Static Fixtures</h3>
+	 * Static fixture locations can be calculated:
+	 * @codestart
+	 * // looks in test/fixtures/tasks/1.get
+	 * $.ajax({type:"get", 
+	 *        url: "tasks/1", 
+	 *        fixture: true}) 
+	 * @codeend
+	 * Or provided:
+	 * @codestart
+	 * // looks in fixtures/tasks1.json relative to page
+	 * $.ajax({type:"get", 
+	 *        url: "tasks/1", 
+	 *        fixture: "fixtures/task1.json"})
+	 * 
+	 * // looks in fixtures/tasks1.json relative to jmvc root
+	 * // this assumes you are using steal
+	 * $.ajax({type:"get", 
+	 *        url: "tasks/1", 
+	 *        fixture: "//fixtures/task1.json"})` 
+	 * @codeend
+	 * <div class='whisper'>
+	 *   PRO TIP: Use provided fixtures.  It's easier to understand what it is going.
+	 *   Also, create a fixtures folder in your app to hold your fixtures.
+	 * </div>
+	 * <h3>Dynamic Fixtures</h3>
+	 * <p>Dynamic Fixtures are functions that return the arguments the $.ajax callbacks 
+	 *   (<code>beforeSend</code>, <code>success</code>, <code>complete</code>, 
+	 *    <code>error</code>) expect.  </p>
+	 * <p>For example, the "<code>success</code>" of a json request is called with 
+	 * <code>[data, textStatus, XMLHttpRequest].</p>
+	 * <p>There are 2 ways to lookup dynamic fixtures.<p>
+	 * They can provided:
+	 * @codestart
+	 * //just use a function as the fixture property
+	 * $.ajax({
+	 *   type:     "get", 
+	 *   url:      "tasks",
+	 *   data:     {id: 5},
+	 *   dataType: "json",
+	 *   fixture: function( settings, callbackType ) {
+	 *     var xhr = {responseText: "{id:"+settings.data.id+"}"}
+	 *     switch(callbackType){
+	 *       case "success": 
+	 *         return [{id: settings.data.id},"success",xhr]
+	 *       case "complete":
+	 *         return [xhr,"success"]
+	 *     }
+	 *   }
+	 * })
+	 * @codeend
+	 * Or found by name on $.fixture:
+	 * @codestart
+	 * // add your function on $.fixture
+	 * // We use -FUNC by convention
+	 * $.fixture["-myGet"] = function(settings, cbType){...}
+	 * 
+	 * // reference it
+	 * $.ajax({
+	 *   type:"get", 
+	 *   url: "tasks/1", 
+	 *   dataType: "json", 
+	 *   fixture: "-myGet"})
+	 * @codeend
+	 * <p>Dynamic fixture functions are called with:</p>
+	 * <ul>
+	 * <li> settings - the settings data passed to <code>$.ajax()</code>
+	 * <li> calbackType - the type of callback about to be called: 
+	 *  <code>"beforeSend"</code>, <code>"success"</code>, <code>"complete"</code>, 
+	 *    <code>"error"</code></li>
+	 * </ul>
+	 * and should return an array of arguments for the callback.<br/><br/>
+	 * <div class='whisper'>PRO TIP: 
+	 * Dynamic fixtures are awesome for performance testing.  Want to see what 
+	 * 10000 files does to your app's performance?  Make a fixture that returns 10000 items.
+	 * 
+	 * What to see what the app feels like when a request takes 5 seconds to return?  Set
+	 * [jQuery.fixture.delay] to 5000.
+	 * </div>
+	 * <h2>Helpers</h2>
+	 * <p>The fixture plugin comes with a few ready-made dynamic fixtures and 
+	 * fixture helpers:</p>
+	 * <ul>
+	 * <li>[jQuery.fixture.make] - creates fixtures for findAll, findOne.</li>
+	 * <li>[jQuery.fixture.-restCreate] - a fixture for restful creates.</li>
+	 * <li>[jQuery.fixture.-restDestroy] - a fixture for restful updates.</li>
+	 * <li>[jQuery.fixture.-restUpdate] - a fixture for restful destroys.</li>
+	 * </ul>
+	 * @demo jquery/dom/fixture/fixture.html
+	 * @constructor
+	 * Takes an ajax settings and returns a url to look for a fixture.  Overwrite this if you want a custom lookup method.
+	 * @param {Object} settings
+	 * @return {String} the url that will be used for the fixture
+	 */
+	$.fixture = function( settings ) {
+		var url = settings.url,
+			match, left, right;
+		url = url.replace(/%2F/g, "~").replace(/%20/g, "_");
+
+		if ( settings.data && settings.processData && typeof settings.data !== "string" ) {
+			settings.data = jQuery.param(settings.data);
+		}
+
+
+		if ( settings.data && settings.type.toLowerCase() == "get" ) {
+			url += ($.String.include(url, '?') ? '&' : '?') + settings.data;
+		}
+
+		match = url.match(/^(?:https?:\/\/[^\/]*)?\/?([^\?]*)\??(.*)?/);
+		left = match[1];
+
+		right = settings.type ? '.' + settings.type.toLowerCase() : '.post';
+		if ( match[2] ) {
+			left += '/';
+			right = match[2].replace(/\#|&/g, '-').replace(/\//g, '~') + right;
+		}
+		return left + right;
+	};
+
+	$.extend($.fixture, {
+		/**
+		 * Provides a rest update fixture function
+		 */
+		"-restUpdate": function( settings, cbType ) {
+			switch ( cbType ) {
+			case "success":
+				return [$.extend({
+					id: parseInt(settings.url, 10)
+				}, settings.data), "success", $.fixture.xhr()];
+			case "complete":
+				return [$.fixture.xhr(), "success"];
+			}
+		},
+		/**
+		 * Provides a rest destroy fixture function
+		 */
+		"-restDestroy": function( settings, cbType ) {
+			switch ( cbType ) {
+			case "success":
+				return [true, "success", $.fixture.xhr()];
+			case "complete":
+				return [$.fixture.xhr(), "success"];
+			}
+		},
+		/**
+		 * Provides a rest create fixture function
+		 */
+		"-restCreate": function( settings, cbType ) {
+			switch ( cbType ) {
+			case "success":
+				return [{
+					id: parseInt(Math.random() * 1000, 10)
+				}, "success", $.fixture.xhr()];
+			case "complete":
+				return [$.fixture.xhr({
+					getResponseHeader: function() {
+						return settings.url + "/" + parseInt(Math.random() * 1000, 10);
+					}
+				}), "success"];
+			}
+
+
+		},
+		/**
+		 * Used to make fixtures for findAll / findOne style requests.
+		 * @codestart
+		 * //makes a threaded list of messages
+		 * $.fixture.make(["messages","message"],1000, function(i, messages){
+		 *   return {
+		 *     subject: "This is message "+i,
+		 *     body: "Here is some text for this message",
+		 *     date: Math.floor( new Date().getTime() ),
+		 *     parentId : i < 100 ? null : Math.floor(Math.random()*i)
+		 *   }
+		 * })
+		 * //uses the message fixture to return messages limited by offset, limit, order, etc.
+		 * $.ajax({
+		 *   url: "messages",
+		 *   data:{ 
+		 *      offset: 100, 
+		 *      limit: 50, 
+		 *      order: "date ASC",
+		 *      parentId: 5},
+		 *    },
+		 *    fixture: "-messages",
+		 *    success: function( messages ) {  ... }
+		 * });
+		 * @codeend
+		 * @param {Array} types An array of the fixture names
+		 * @param {Number} count the number of items to create
+		 * @param {Function} make a function that will return json data representing the object.
+		 */
+		make: function( types, count, make ) {
+			// make all items
+			var items = ($.fixture["~" + types[0]] = []);
+			for ( var i = 0; i < (count); i++ ) {
+				//call back provided make
+				var item = make(i, items);
+
+				if (!item.id ) {
+					item.id = i;
+				}
+				items.push(item);
+			}
+			//set plural fixture for findAll
+			$.fixture["-" + types[0]] = function( settings ) {
+
+				//copy array of items
+				var retArr = items.slice(0);
+
+				//sort using order
+				//order looks like ["age ASC","gender DESC"]
+				$.each((settings.data.order || []).slice(0).reverse(), function( i, name ) {
+					var split = name.split(" ");
+					retArr = retArr.sort(function( a, b ) {
+						if ( split[1].toUpperCase() !== "ASC" ) {
+							return a[split[0]] < b[split[0]];
+						}
+						else {
+							return a[split[0]] > b[split[0]];
+						}
+					});
+				});
+
+				//group is just like a sort
+				$.each((settings.data.group || []).slice(0).reverse(), function( i, name ) {
+					var split = name.split(" ");
+					retArr = retArr.sort(function( a, b ) {
+						return a[split[0]] > b[split[0]];
+					});
+				});
+
+
+				var offset = parseInt(settings.data.offset, 10) || 0,
+					limit = parseInt(settings.data.limit, 10) || (count - offset),
+					i = 0;
+
+				//filter results if someone added an attr like parentId
+				for ( var param in settings.data ) {
+					if ( param.indexOf("Id") != -1 || param.indexOf("_id") != -1 ) {
+						while ( i < retArr.length ) {
+							if ( settings.data[param] != retArr[i][param] ) {
+								retArr.splice(i, 1);
+							} else {
+								i++;
+							}
+						}
+					}
+				}
+
+				//return data spliced with limit and offset
+				return [{
+					"count": retArr.length,
+					"limit": settings.data.limit,
+					"offset": settings.data.offset,
+					"data": retArr.slice(offset, offset + limit)
+				}];
+			};
+
+			$.fixture["-" + types[1]] = function( settings ) {
+				for ( var i = 0; i < (count); i++ ) {
+					if ( settings.data.id == items[i].id ) {
+						return [items[i]];
+					}
+				}
+			};
+
+		},
+		/**
+		 * Use $.fixture.xhr to create an object that looks like an xhr object. 
+		 * <h3>Example</h3>
+		 * The following example shows how the -restCreate fixture uses xhr to return 
+		 * a simulated xhr object:
+		 * @codestart
+		 * "-restCreate" : function( settings, cbType ) {
+		 *   switch(cbType){
+		 *     case "success": 
+		 *       return [
+		 *         {id: parseInt(Math.random()*1000)}, 
+		 *         "success", 
+		 *         $.fixture.xhr()];
+		 *     case "complete":
+		 *       return [ 
+		 *         $.fixture.xhr({
+		 *           getResponseHeader: function() { 
+		 *             return settings.url+"/"+parseInt(Math.random()*1000);
+		 *           }
+		 *         }),
+		 *         "success"];
+		 *   }
+		 * }
+		 * @codeend
+		 * @param {Object} [xhr] properties that you want to overwrite
+		 * @return {Object} an object that looks like a successful XHR object.
+		 */
+		xhr: function( xhr ) {
+			return $.extend({}, {
+				abort: $.noop,
+				getAllResponseHeaders: function() {
+					return "";
+				},
+				getResponseHeader: function() {
+					return "";
+				},
+				open: $.noop,
+				overrideMimeType: $.noop,
+				readyState: 4,
+				responseText: "",
+				responseXML: null,
+				send: $.noop,
+				setRequestHeader: $.noop,
+				status: 200,
+				statusText: "OK"
+			}, xhr);
+		}
+	});
+	/**
+	 * @attribute delay
+	 * Sets the delay in milliseconds between an ajax request is made and
+	 * the success and complete handlers are called.  This only sets
+	 * functional fixtures.  By default, the delay is 200ms.
+	 * @codestart
+	 * steal.plugins('jquery/dom/fixtures').then(function(){
+	 *   $.fixture.delay = 1000;
+	 * })
+	 * @codeend
+	 */
+	$.fixture.delay = 200;
+
+	$.fixture["-handleFunction"] = function( settings ) {
+		if ( typeof settings.fixture === "string" && $.fixture[settings.fixture] ) {
+			settings.fixture = $.fixture[settings.fixture];
+		}
+		if ( typeof settings.fixture == "function" ) {
+			setTimeout(function() {
+				if ( settings.success ) {
+					settings.success.apply(null, settings.fixture(settings, "success"));
+				}
+				if ( settings.complete ) {
+					settings.complete.apply(null, settings.fixture(settings, "complete"));
+				}
+			}, $.fixture.delay);
+			return true;
+		}
+		return false;
+	};
+
+	/**
+	 *  @add jQuery
+	 */
+	// break
+	$.
+	/**
+	 * Adds the fixture option to settings. If present, loads from fixture location instead
+	 * of provided url.  This is useful for simulating ajax responses before the server is done.
+	 * @param {Object} settings
+	 */
+	ajax = function( settings ) {
+		var func = $.fixture;
+		if (!settings.fixture ) {
+			return ajax.apply($, arguments);
+		}
+		if ( $.fixture["-handleFunction"](settings) ) {
+			return;
+		}
+		if ( typeof settings.fixture == "string" ) {
+			var url = settings.fixture;
+			if (/^\/\//.test(url) ) {
+				url = steal.root.join(settings.fixture.substr(2));
+			}
+			//@steal-remove-start
+			steal.dev.log("looking for fixture in " + url);
+			//@steal-remove-end
+			settings.url = url;
+			settings.data = null;
+			settings.type = "GET";
+			if (!settings.error ) {
+				settings.error = function( xhr, error, message ) {
+					throw "fixtures.js Error " + error + " " + message;
+				};
+			}
+			return ajax(settings);
+
+		}
+		settings = jQuery.extend(true, settings, jQuery.extend(true, {}, jQuery.ajaxSettings, settings));
+
+		settings.url = steal.root.join('test/fixtures/' + func(settings)); // convert settings
+		settings.data = null;
+		settings.type = 'GET';
+		return ajax(settings);
+	};
+
+	$.extend($.ajax, ajax);
+
+	$.
+	/**
+	 * Adds a fixture param.  
+	 * @param {Object} url
+	 * @param {Object} data
+	 * @param {Object} callback
+	 * @param {Object} type
+	 * @param {Object} fixture
+	 */
+	get = function( url, data, callback, type, fixture ) {
+		// shift arguments if data argument was ommited
+		if ( jQuery.isFunction(data) ) {
+			fixture = type;
+			type = callback;
+			callback = data;
+			data = null;
+		}
+
+		return jQuery.ajax({
+			type: "GET",
+			url: url,
+			data: data,
+			success: callback,
+			dataType: type,
+			fixture: fixture
+		});
+	};
+
+	$.
+	/**
+	 * Adds a fixture param.
+	 * @param {Object} url
+	 * @param {Object} data
+	 * @param {Object} callback
+	 * @param {Object} type
+	 * @param {Object} fixture
+	 */
+	post = function( url, data, callback, type, fixture ) {
+		if ( jQuery.isFunction(data) ) {
+			fixture = type;
+			type = callback;
+			callback = data;
+			data = {};
+		}
+
+		return jQuery.ajax({
+			type: "POST",
+			url: url,
+			data: data,
+			success: callback,
+			dataType: type,
+			fixture: fixture
+		});
+	};
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/fixture/fixtures/messages.html b/browserid/static/dialog/jquery/dom/fixture/fixtures/messages.html
new file mode 100644
index 0000000000000000000000000000000000000000..19cf14922778fa7e53d35190eab6b90282f2a97d
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/fixture/fixtures/messages.html
@@ -0,0 +1,31 @@
+
+<h2>Create a Message</h2>
+<p>Create a message, it will show up in "Get Messages".</p>
+<form id='message'>
+  <table>
+    <tr>
+      <td>From:</td>
+      <td><input type='text' name='message[user]' value=''/></td>
+    </tr>
+    <tr>
+      <td>Subject:</td>
+      <td><input type='text' name='message[subject]' value=''/></td>
+    </tr>
+    <tr>
+	  <td>Body:</td>
+	  <td><textarea name='message[body]'></textarea></td>
+	</tr>
+	<tr>
+      <td></td><td><input type='submit' value="Create"></td>
+    </tr>
+  </table>
+</form>
+<h2>Get Messages</h2>
+<p>Enter a limit and offset to get a range of messages.
+</p>
+<form id='getMessages'>
+    Offset <input type='text' name='params[offset]' value='0'/>
+    Limit <input type='text' name='params[limit]' value='5'/>
+    <input type="submit" value="Get Messages"/>
+</form>
+<div id='messages'></div>
diff --git a/browserid/static/dialog/jquery/dom/fixture/fixtures/test.json b/browserid/static/dialog/jquery/dom/fixture/fixtures/test.json
new file mode 100644
index 0000000000000000000000000000000000000000..6be2ce4f6fb070ec8a0df803e67326c9bb7a0fdf
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/fixture/fixtures/test.json
@@ -0,0 +1,3 @@
+{
+  "sweet" :"ness"
+}
diff --git a/browserid/static/dialog/jquery/dom/fixture/qunit.html b/browserid/static/dialog/jquery/dom/fixture/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..9a6ba526a24a3850919c5f512e5e98c9f137ff49
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/fixture/qunit.html
@@ -0,0 +1,22 @@
+<html>
+    <head>
+    	<title>Fixtures Test Suite</title>
+        <link rel="stylesheet" type="text/css" href="../../../funcunit/qunit/qunit.css" />
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+		<script type='text/javascript' src='../../../steal/steal.js?steal[app]=jquery/dom/fixture/test/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">Fixtures Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/fixture/test/qunit/fixture_test.js b/browserid/static/dialog/jquery/dom/fixture/test/qunit/fixture_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..a6499ae174912e7658f782f7dedffa2c7b3182c9
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/fixture/test/qunit/fixture_test.js
@@ -0,0 +1,50 @@
+module("jquery/dom/fixture");
+
+
+test("static fixtures", function(){
+	stop();
+	$.get("something",function(data){
+		equals(data.sweet,"ness","$.get works");
+		$.post("something",function(data){
+			
+			equals(data.sweet,"ness","$.post works");
+			
+			$.ajax({
+				url: "something",
+				dataType: "json",
+				success: function( data ) {
+					equals(data.sweet,"ness","$.ajax works");
+					start();
+				},
+				fixture: "//jquery/dom/fixture/fixtures/test.json"
+			})
+			
+		},"json","//jquery/dom/fixture/fixtures/test.json");
+	},'json',"//jquery/dom/fixture/fixtures/test.json");
+})
+
+test("dynamic fixtures",function(){
+	stop();
+	$.fixture.delay = 10;
+	var fix = function(){
+		return [{sweet: "ness"}]
+	}
+	$.get("something",function(data){
+		equals(data.sweet,"ness","$.get works");
+		$.post("something",function(data){
+			
+			equals(data.sweet,"ness","$.post works");
+			
+			$.ajax({
+				url: "something",
+				dataType: "json",
+				success: function( data ) {
+					equals(data.sweet,"ness","$.ajax works");
+					start();
+				},
+				fixture: fix
+			})
+			
+		},"json",fix);
+	},'json',fix);
+})
diff --git a/browserid/static/dialog/jquery/dom/fixture/test/qunit/qunit.js b/browserid/static/dialog/jquery/dom/fixture/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..9750a4ae9241d4ce13cb8751ba302d0668b2c796
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/fixture/test/qunit/qunit.js
@@ -0,0 +1,4 @@
+steal
+ .plugins("jquery/dom/fixture")  //load your app
+ .plugins('funcunit/qunit')  //load qunit
+ .then("fixture_test")
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/form_params/form_params.html b/browserid/static/dialog/jquery/dom/form_params/form_params.html
new file mode 100644
index 0000000000000000000000000000000000000000..59b9a754fec503b0bed710d7a90ac235765ea9ca
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/form_params/form_params.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>Form Params</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            
+        </style>
+	</head>
+	<body>
+<p>Change the inputs to change the object</p>
+<pre>Result = <span id='result'></span></pre>
+<div id="demo-html">
+<form id='fp' action="">
+  <label>People Count</label><br/>
+  <input name='talk[peopleCount]'/><br/>
+  <label>Audience Rating</label><br/>
+  <select name='talk[audienceRating]'>
+    <option value='3'>3</option>
+    <option value='2'>2</option>
+    <option value='1'>1</option>
+  </select><br/>
+  <label>Time Left</label><br/>
+  <input type='radio' name='talk[timeLeft]' value='1'/> 1 min<br/>
+  <input type='radio' name='talk[timeLeft]' value='5'/> 5 min<br/>
+  <input type='radio' name='talk[timeLeft]' value='10'/> 10 min<br/>
+  <input type='checkbox' name='talk[abool]'/> 10 min<br/>
+</form>
+</div>
+		<script type='text/javascript' 
+                src='../../../steal/steal.js'>   
+        </script>
+<script type='text/javascript'>
+steal.plugins('jquery/dom/form_params','jquery/lang/json').start()
+</script>
+<script type='text/javascript' id="demo-source">
+// updates the JSON text
+var update = function(){
+  
+  // get form data 
+  var json = $('#fp').formParams(),
+  
+      //convert it to JSON
+      jsonString = $.toJSON( json );
+  
+  // show JSON
+  $("#result").text( jsonString )
+}
+
+// listen for changes and update
+$('#fp').change(update);
+
+// show json right away
+update(); 
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/form_params/form_params.js b/browserid/static/dialog/jquery/dom/form_params/form_params.js
new file mode 100644
index 0000000000000000000000000000000000000000..7197c7f10c23c9683c1663b6ed542c66780e2165
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/form_params/form_params.js
@@ -0,0 +1,111 @@
+/**
+ *  @add jQuery.fn
+ */
+steal.plugins("jquery/dom").then(function( $ ) {
+	var radioCheck = /radio|checkbox/i,
+		keyBreaker = /[^\[\]]+/g,
+		numberMatcher = /^[\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?$/;
+
+	var isNumber = function( value ) {
+		if ( typeof value == 'number' ) {
+			return true;
+		}
+
+		if ( typeof value != 'string' ) {
+			return false;
+		}
+
+		return value.match(numberMatcher);
+	};
+
+	$.fn.extend({
+		/**
+		 * @parent dom
+		 * @download http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/dom/form_params/form_params.js
+		 * @plugin jquery/dom/form_params
+		 * @test jquery/dom/form_params/qunit.html
+		 * <p>Returns an object of name-value pairs that represents values in a form.  
+		 * It is able to nest values whose element's name has square brackets. </p>
+		 * Example html:
+		 * @codestart html
+		 * &lt;form>
+		 *   &lt;input name="foo[bar]" value='2'/>
+		 *   &lt;input name="foo[ced]" value='4'/>
+		 * &lt;form/>
+		 * @codeend
+		 * Example code:
+		 * @codestart
+		 * $('form').formParams() //-> { foo:{bar:2, ced: 4} }
+		 * @codeend
+		 * 
+		 * @demo jquery/dom/form_params/form_params.html
+		 * 
+		 * @param {Boolean} [convert] True if strings that look like numbers and booleans should be converted.  Defaults to true.
+		 * @return {Object} An object of name-value pairs.
+		 */
+		formParams: function( convert ) {
+			if ( this[0].nodeName.toLowerCase() == 'form' && this[0].elements ) {
+
+				return jQuery(jQuery.makeArray(this[0].elements)).getParams(convert);
+			}
+			return jQuery("input[name], textarea[name], select[name]", this[0]).getParams(convert);
+		},
+		getParams: function( convert ) {
+			var data = {},
+				current;
+
+			convert = convert === undefined ? true : convert;
+
+			this.each(function() {
+				var el = this,
+					type = el.type && el.type.toLowerCase();
+				//if we are submit, ignore
+				if ((type == 'submit') || !el.name ) {
+					return;
+				}
+
+				var key = el.name,
+					value = $.fn.val.call([el]) || $.data(el, "value"),
+					isRadioCheck = radioCheck.test(el.type),
+					parts = key.match(keyBreaker),
+					write = !isRadioCheck || !! el.checked,
+					//make an array of values
+					lastPart;
+
+				if ( convert ) {
+					if ( isNumber(value) ) {
+						value = parseFloat(value);
+					} else if ( value === 'true' || value === 'false' ) {
+						value = Boolean(value);
+					}
+
+				}
+
+				// go through and create nested objects
+				current = data;
+				for ( var i = 0; i < parts.length - 1; i++ ) {
+					if (!current[parts[i]] ) {
+						current[parts[i]] = {};
+					}
+					current = current[parts[i]];
+				}
+				lastPart = parts[parts.length - 1];
+
+				//now we are on the last part, set the value
+				if ( lastPart in current && type === "checkbox" ) {
+					if (!$.isArray(current[lastPart]) ) {
+						current[lastPart] = current[lastPart] === undefined ? [] : [current[lastPart]];
+					}
+					if ( write ) {
+						current[lastPart].push(value);
+					}
+				} else if ( write || !current[lastPart] ) {
+					current[lastPart] = write ? value : undefined;
+				}
+
+			});
+			return data;
+		}
+	});
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/form_params/qunit.html b/browserid/static/dialog/jquery/dom/form_params/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..1223df9fcd14daa3cc3b8faf16e3bf3c1644023b
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/form_params/qunit.html
@@ -0,0 +1,22 @@
+<html>
+    <head>
+    	<title>Form Params Test Suite</title>
+        <link rel="stylesheet" type="text/css" href="../../../funcunit/qunit/qunit.css" />
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+		<script type='text/javascript' src='../../../steal/steal.js?steal[app]=jquery/dom/form_params/test/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">Fixtures Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/form_params/test/qunit/basics.micro b/browserid/static/dialog/jquery/dom/form_params/test/qunit/basics.micro
new file mode 100644
index 0000000000000000000000000000000000000000..61dea977c9a90e956feee32205a036a162f3aa75
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/form_params/test/qunit/basics.micro
@@ -0,0 +1,27 @@
+<form id='fp' action="">
+
+  <input name='params[one]' value='1'/>
+
+  <select name='params[two]'>
+    <option value='3'>3</option>
+    <option value='2' selected="selected">2</option>
+    <option value='1'>1</option>
+  </select>
+
+  <input type='radio' name='params[three]' value='1'/> 
+  <input type='radio' name='params[three]' value='2'/>
+  <input type='radio' name='params[three]' value='3' checked="checked"/>
+  
+  
+  <select name='params[four]' multiple="multiple">
+    <option value='4' selected="selected">4</option>
+    <option value='3'>3</option>
+    <option value='2'>2</option>
+    <option value='1' selected="selected">1</option>
+  </select>
+  
+  <input type='checkbox' name='params[five]' value='1'/> 
+  <input type='checkbox' name='params[five]' value='2' checked="checked"/>
+  <input type='checkbox' name='params[five]' value='3' checked="checked"/>
+  
+</form>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/form_params/test/qunit/checkbox.micro b/browserid/static/dialog/jquery/dom/form_params/test/qunit/checkbox.micro
new file mode 100644
index 0000000000000000000000000000000000000000..f421437332ab7e58894a6e5817de178bf8ecdd69
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/form_params/test/qunit/checkbox.micro
@@ -0,0 +1,20 @@
+<form name="jq-form" id="fp"> 
+    <fieldset> 
+        <div class="question_container"> 
+            <label>Question</label> 
+            <div> 
+                    <textarea name="q_content"></textarea> 
+            </div> 
+            <div class="linebreak"></div> 
+            <div>Reference <input type="text" name="q_ref" value="q_ref" /></div> 
+        </div> 
+
+        <div id="answers"> 
+            <label>Correct: <input type="checkbox" name="correct"/></label> 
+
+            <textarea name="answer_content"></textarea> 
+        </div> 
+    </fieldset> 
+    <input type="button" value="Cancel"/> 
+    <input type="button" value="Save" /> 
+</form> 
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/form_params/test/qunit/form_params_test.js b/browserid/static/dialog/jquery/dom/form_params/test/qunit/form_params_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..18da8cc6c7c7de70431ff050606efff5c78a3b6d
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/form_params/test/qunit/form_params_test.js
@@ -0,0 +1,43 @@
+module("jquery/dom/form_params")
+test("with a form", function(){
+
+	$("#qunit-test-area").html("//jquery/dom/form_params/test/qunit/basics.micro",{})
+	
+	var formParams =  $("#qunit-test-area form").formParams() ;
+	ok(formParams.params.one === 1,"one is right");
+	ok(formParams.params.two === 2,"two is right");
+	ok(formParams.params.three === 3,"three is right");
+	same(formParams.params.four,["4","1"],"four is right");
+	same(formParams.params.five,[2,3],"five is right");
+	
+	
+});
+
+
+test("with true false", function(){
+	$("#qunit-test-area").html("//jquery/dom/form_params/test/qunit/truthy.micro",{});
+	
+	var formParams =  $("#qunit-test-area form").formParams();
+	ok(formParams.foo === undefined, "foo is undefined")
+	ok(formParams.bar.abc === true, "form bar is true");
+	ok(formParams.bar.def === true, "form def is true");
+	ok(formParams.bar.ghi === undefined, "form def is undefined");
+
+});
+
+test("just strings",function(){
+	$("#qunit-test-area").html("//jquery/dom/form_params/test/qunit/basics.micro",{});
+	var formParams =  $("#qunit-test-area form").formParams(false) ;
+	ok(formParams.params.one === "1","one is right");
+	ok(formParams.params.two === '2',"two is right");
+	ok(formParams.params.three === '3',"three is right");
+	same(formParams.params.four,["4","1"],"four is right");
+	same(formParams.params.five,['2','3'],"five is right");
+	$("#qunit-test-area").html('')
+})
+
+test("missing names",function(){
+	$("#qunit-test-area").html("//jquery/dom/form_params/test/qunit/checkbox.micro",{});
+	var formParams =  $("#qunit-test-area form").formParams() ;
+	ok(true, "does not break")
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/form_params/test/qunit/qunit.js b/browserid/static/dialog/jquery/dom/form_params/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..933e2e7cd8440ce0aad1ec79436b3d4ece2589c0
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/form_params/test/qunit/qunit.js
@@ -0,0 +1,4 @@
+steal
+ .plugins("jquery/dom/form_params")  //load your app
+ .plugins('funcunit/qunit','jquery/view/micro')  //load qunit
+ .then("form_params_test")
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/form_params/test/qunit/truthy.micro b/browserid/static/dialog/jquery/dom/form_params/test/qunit/truthy.micro
new file mode 100644
index 0000000000000000000000000000000000000000..f45de9a0798c9136b895abffcb4348c5e9628f45
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/form_params/test/qunit/truthy.micro
@@ -0,0 +1,8 @@
+<form id='fp' action="">
+
+  
+  <input type='checkbox' name='foo'  value='true'/> 
+  <input type='checkbox' name='bar[abc]' checked="checked" value='true'/>
+  <input type='checkbox' name='bar[def]' checked="checked" value='true'/>
+  <input type='checkbox' name='bar[ghi]' value='true'/>
+</form>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/dom/within/within.js b/browserid/static/dialog/jquery/dom/within/within.js
new file mode 100644
index 0000000000000000000000000000000000000000..b846f4b1b85d9a315ed7ab6b5d0ee9ce9c9db221
--- /dev/null
+++ b/browserid/static/dialog/jquery/dom/within/within.js
@@ -0,0 +1,67 @@
+/**
+ *  @add jQuery.fn
+ */
+steal.plugins('jquery/dom').then(function($){
+   var withinBox = function(x, y, left, top, width, height ){
+        return (y >= top &&
+                y <  top + height &&
+                x >= left &&
+                x <  left + width);
+    } 
+/**
+ * @function within
+ * @parent dom
+ * Returns if the elements are within the position
+ * @param {Object} x
+ * @param {Object} y
+ * @param {Object} cache
+ */
+$.fn.within= function(x, y, cache) {
+    var ret = []
+    this.each(function(){
+        var q = jQuery(this);
+
+        if(this == document.documentElement) return ret.push(this);
+
+        var offset = cache ? jQuery.data(this,"offset", q.offset()) : q.offset();
+
+        var res =  withinBox(x, y, 
+                                      offset.left, offset.top,
+                                      this.offsetWidth, this.offsetHeight );
+
+        if(res) ret.push(this);
+    });
+    
+    return this.pushStack( jQuery.unique( ret ), "within", x+","+y );
+}
+
+
+/**
+ * @function withinBox
+ * returns if elements are within the box
+ * @param {Object} left
+ * @param {Object} top
+ * @param {Object} width
+ * @param {Object} height
+ * @param {Object} cache
+ */
+$.fn.withinBox = function(left, top, width, height, cache){
+  	var ret = []
+    this.each(function(){
+        var q = jQuery(this);
+
+        if(this == document.documentElement) return  this.ret.push(this);
+
+        var offset = cache ? jQuery.data(this,"offset", q.offset()) : q.offset();
+
+        var ew = q.width(), eh = q.height();
+
+		res =  !( (offset.top > top+height) || (offset.top +eh < top) || (offset.left > left+width ) || (offset.left+ew < left));
+
+        if(res)
+            ret.push(this);
+    });
+    return this.pushStack( jQuery.unique( ret ), "withinBox", jQuery.makeArray(arguments).join(",") );
+}
+    
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/download/btn.png b/browserid/static/dialog/jquery/download/btn.png
new file mode 100644
index 0000000000000000000000000000000000000000..316698236f801820c3bd27cfe4bc555e60b74bcb
Binary files /dev/null and b/browserid/static/dialog/jquery/download/btn.png differ
diff --git a/browserid/static/dialog/jquery/download/download.css b/browserid/static/dialog/jquery/download/download.css
new file mode 100644
index 0000000000000000000000000000000000000000..4766d66155da29492fd894a3bd437415d1b01252
--- /dev/null
+++ b/browserid/static/dialog/jquery/download/download.css
@@ -0,0 +1,88 @@
+body {
+	margin: 0px; padding: 0px;
+	overflow: hidden;
+}
+#plugins .dl_btn_container{
+	background: url(btn.png);
+	border: none;
+	color: #fff;
+	font-size: 2em;
+	float: right;
+	line-height: 56px;
+	margin: 20px;
+	height: 55px;
+	text-align: center;
+	width: 171px;
+}
+
+#plugins .dl_btn_container:hover{
+		color: #bbb;
+		cursor: pointer
+}
+
+#plugins #pluginForm {
+	border-top: dotted 1px #000;
+	padding: 0px;
+	width: 100%;
+	overflow: auto;
+}
+
+#plugins .section{
+	clear: both;
+	overflow: auto;
+	border-bottom: dotted 1px #000;
+	padding: 16px 16px 18px;
+	
+	background: #eee;
+}
+
+#plugins .section .section-desc{
+	float: left;
+	width: 125px;
+}
+
+#plugins .section .section-desc h3{
+	font-size: 1.0em;
+	margin: 0px 0px 6px;
+}
+
+#plugins .section .section-desc p{
+	font-size: 0.7em;
+}
+
+#plugins .plugin{
+	float: right;
+	padding: 0px;
+	overflow: auto;
+	width: 422px;
+	
+}
+
+#plugins .plugin input {
+    float:left;
+}
+
+#plugins .plugin label{
+	color: #5387BD;
+	display: block;
+	float: left;
+	font-size: 0.7em;
+	font-weight: bold;
+	margin-left: 10px;
+	width: 175px;
+	word-wrap: break-word;
+}
+
+#plugins .plugin .desc{
+	float: left;
+	font-size: 0.7em;
+	margin: 0px 0px 0px 20px;
+	width: 194px;
+}
+
+#plugins .select-all-container{
+	text-align: right;
+	font-size: 0.7em;
+	font-weight: bold;
+	margin: 0px 6px 12px 0px;
+}
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/download/download.html b/browserid/static/dialog/jquery/download/download.html
new file mode 100644
index 0000000000000000000000000000000000000000..89b112e1702cadea1c07794970a6088c0ed959e7
--- /dev/null
+++ b/browserid/static/dialog/jquery/download/download.html
@@ -0,0 +1,411 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>Download Builder</title>
+		<link rel="stylesheet" type='text/css' href='../../documentjs/jmvcdoc/style.css' />
+		<link rel="stylesheet" type='text/css' href='download.css' />
+	</head>
+	<body>
+		
+		<div id="plugins">
+
+		
+			<form type="POST" action="http://jmvcsite.heroku.com/pluginify" id="pluginForm">
+			
+			
+			
+			<div class="section">
+				
+				<div class="section-desc">
+					<h3>Class</h3>
+				</div>
+				
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/class/class.js" type="checkbox">
+					<label>jquery/class/class.js</label>
+					<div class="desc">Simulated inheritance in JavaScript</div>
+				</div>
+				
+				
+			</div>
+			
+			<div class="section">
+				
+				<div class="section-desc">
+					<h3>Controller</h3>
+					<p>jQuery widget factory</p>
+				</div>
+			
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/controller/controller.js" type="checkbox">
+					<label>jquery/controller/controller.js</label>
+					<div class="desc">Organize event handlers using event delegation</div>
+				</div>
+				
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/controller/history/history.js" type="checkbox">
+					<label>jquery/controller/history/history.js</label>
+					<div class="desc">Add page history support to Controller</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/controller/subscribe/subscribe.js" type="checkbox">
+					<label>jquery/controller/subscribe/subscribe.js</label>
+					<div class="desc">Add pub/sub support to Controller</div>
+				</div>
+				
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/controller/view/view.js" type="checkbox">
+					<label>jquery/controller/view/view.js</label>
+					<div class="desc">Helpers that tie view templates to a controller instance</div>
+				</div>
+			</div>
+		
+			
+			<div class="section">
+				
+				<div class="section-desc">
+					<h3>Model</h3>
+					<p>Wrap an application's data layer</p>
+				</div>
+		
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/model/model.js" type="checkbox">
+					<label>jquery/model/model.js</label>
+					<div class="desc">A basic skeleton to organize pieces of your application's data layer</div>
+				</div>
+
+				<div class="plugin">
+
+					<input name="plugins[]" value="jquery/model/associations/associations.js" type="checkbox">
+					<label>jquery/model/associations/associations.js</label>
+					<div class="desc">Get data for related records</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/model/backup/backup.js" type="checkbox">
+					<label>jquery/model/backup/backup.js</label>
+					<div class="desc">Backup and restore instance data</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/model/list/list.js" type="checkbox">
+					<label>jquery/model/list/list.js</label>
+					<div class="desc">Type of model that provides methods for multiple model instances</div>
+
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/model/list/cookie/cookie.js" type="checkbox">
+					<label>jquery/model/list/cookie/cookie.js</label>
+					<div class="desc">A storeable list of model instances</div>
+				</div>
+
+				<!--<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/model/list/local/local.js" type="checkbox">
+					<label>jquery/model/list/local/local.js</label>
+					<div class="desc">Uses a local store instead of cookies</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/model/service/json_rest/json_rest.js" type="checkbox">
+					<label>jquery/model/service/json_rest/json_rest.js</label>
+					<div class="desc">Basic wrapper for JSON REST services</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/model/service/twitter/twitter.js" type="checkbox">
+					<label>jquery/model/service/twitter/twitter.js</label>
+					<div class="desc">Basic wrapper for Twitter services</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/model/service/yql/yql.js" type="checkbox">
+					<label>jquery/model/service/yql/yql.js</label>
+					<div class="desc">Basic wrapper for YQL services</div>
+				</div>-->
+
+				<div class="plugin">
+
+					<input name="plugins[]" value="jquery/model/validations/validations.js" type="checkbox">
+					<label>jquery/model/validations/validations.js</label>
+					<div class="desc">Validate data before sending it to the server</div>
+				</div>
+			</div>
+			
+			
+			<div class="section">
+				
+				<div class="section-desc">
+					<h3>Event</h3>
+					<p>Helper functions used for managing events</p>
+				</div>
+				
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/event/destroyed/destroyed.js" type="checkbox">
+					<label>jquery/event/destroyed/destroyed.js</label>
+					<div class="desc">Provides a destroyed event on an element</div>
+				</div>
+				
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/event/hashchange/hashchange.js" type="checkbox">
+					<label>jquery/event/hashchange/hashchange.js</label>
+					<div class="desc">An event when the browser hash changes (for history management)</div>
+				</div>
+				
+			
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/event/default/default.js" type="checkbox">
+					<label>jquery/event/default/default.js</label>
+					<div class="desc">Allows you to perform default actions as a result of an event</div>
+				</div>
+
+				<div class="plugin">
+
+					<input name="plugins[]" value="jquery/event/drag/drag.js" type="checkbox">
+					<label>jquery/event/drag/drag.js</label>
+					<div class="desc">Provides drag events as a special events to jQuery</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/event/drag/limit/limit.js" type="checkbox">
+					<label>jquery/event/drag/limit/limit.js</label>
+					<div class="desc">Limits the drag to a containing element</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/event/drag/scroll/scroll.js" type="checkbox">
+					<label>jquery/event/drag/scroll/scroll.js</label>
+					<div class="desc">Will scroll elements with a scroll bar as the drag moves to borders</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/event/drop/drop.js" type="checkbox">
+					<label>jquery/event/drop/drop.js</label>
+					<div class="desc">Provides drop events as a special event to jQuery</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/event/drag/step/step.js" type="checkbox">
+					<label>jquery/event/drag/step/step.js</label>
+					<div class="desc">Drag in defined pixel increments</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/event/hover/hover.js" type="checkbox">
+					<label>jquery/event/hover/hover.js</label>
+					<div class="desc">Provides delegate-able hover events</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/event/resize/resize.js" type="checkbox">
+					<label>jquery/event/resize/resize.js</label>
+					<div class="desc">Normalizes resize events cross browser</div>
+				</div>
+
+				<!--<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/event/select/select.js" type="checkbox">
+					<label>jquery/event/select/select.js</label>
+					<div class="desc">An event that fires when some element is selected by the user (lasso)</div>
+				</div>-->
+			</div>
+			
+			
+			<div class="section">
+				
+				<div class="section-desc">
+					<h3>View</h3>
+					<p>Client side template engines with production build support.</p>
+				</div>
+				
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/view/view.js" type="checkbox">
+					<label>jquery/view/view.js</label>
+					<div class="desc">A uniform interface for using templates with jQuery</div>
+				</div>
+				
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/view/ejs/ejs.js" type="checkbox">
+					<label>jquery/view/ejs/ejs.js</label>
+					<div class="desc">EJS templates</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/view/helpers/helpers.js" type="checkbox">
+					<label>jquery/view/helpers/helpers.js</label>
+					<div class="desc">Rails like view helpers</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/view/jaml/jaml.js" type="checkbox">
+					<label>jquery/view/jaml/jaml.js</label>
+					<div class="desc">JAML templates</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/view/micro/micro.js" type="checkbox">
+					<label>jquery/view/micro/micro.js</label>
+					<div class="desc">Micro templates</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/view/tmpl/tmpl.js" type="checkbox">
+					<label>jquery/view/tmpl/tmpl.js</label>
+					<div class="desc">jQuery tmpl templates</div>
+				</div>
+				
+			</div>
+			
+			
+			<div class="section">
+				
+				<div class="section-desc">
+					<h3>DOM</h3>
+					<p>Useful jQuery extensions for the DOM</p>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/dom/closest/closest.js" type="checkbox">
+					<label>jquery/dom/closest/closest.js</label>
+					<div class="desc">Overwrites closest to allow open > selectors</div>
+				</div>
+
+				<div class="plugin">
+				
+					<input name="plugins[]" value="jquery/dom/compare/compare.js" type="checkbox">
+					<label>jquery/dom/compare/compare.js</label>
+					<div class="desc">Compares the position of two nodes</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/dom/cookie/cookie.js" type="checkbox">
+					<label>jquery/dom/cookie/cookie.js</label>
+					<div class="desc">Cookie management helpers</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/dom/cur_styles/cur_styles.js" type="checkbox">
+					<label>jquery/dom/cur_styles/cur_styles.js</label>
+					<div class="desc">Rapidly get a bunch of computed styles from an element</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/dom/dimensions/dimensions.js" type="checkbox">
+					<label>jquery/dom/dimensions/dimensions.js</label>
+					<div class="desc">Support for setting+animating inner+outer height and widths</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/dom/fixture/fixture.js" type="checkbox">
+					<label>jquery/dom/fixture/fixture.js</label>
+					<div class="desc">Simulate AJAX responses</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/dom/form_params/form_params.js" type="checkbox">
+					<label>jquery/dom/form_params/form_params.js</label>
+					<div class="desc">Name-value pairs that represents values in a form</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/dom/within/within.js" type="checkbox">
+					<label>jquery/dom/within/within.js</label>
+					<div class="desc">Returns if the elements are within the position</div>
+				</div>
+				
+			</div>
+			
+			
+			<div class="section">
+				
+				<div class="section-desc">
+					<h3>Lang</h3>
+					<p>JavaScript language helpers</p>
+				</div>
+				
+				<div class="plugin">
+
+					<input name="plugins[]" value="jquery/lang/lang.js" type="checkbox">
+					<label>jquery/lang/lang.js</label>
+					<div class="desc">String helpers</div>
+				</div>
+
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/lang/vector/vector.js" type="checkbox">
+					<label>jquery/lang/vector/vector.js</label>
+					<div class="desc">A vector class</div>
+				</div>
+
+				<div class="plugin">
+
+					<input name="plugins[]" value="jquery/lang/rsplit/rsplit.js" type="checkbox">
+					<label>jquery/lang/rsplit/rsplit.js</label>
+					<div class="desc">Splits a string with a regex correctly cross browser</div>
+				</div>				
+				
+			</div>
+			
+			
+			<div class="section">
+				
+				<div class="section-desc">
+					<h3>Tie</h3>
+				</div>
+				
+				<div class="plugin">
+					
+					<input name="plugins[]" value="jquery/tie/tie.js" type="checkbox">
+					<label>jquery/tie/tie.js</label>
+					<div class="desc">Bi-direction binding between Controllers and Models.</div>
+				</div>
+				
+				
+			</div>
+			<div class="download-builder">
+        		<input type="submit" class="dl_btn_container" value="Download">
+            </div>
+			
+		</form>
+		<script type='text/javascript' src='../jquery.js'></script>
+		<script type='text/javascript' src='../dist/jquery.formparams.js'></script>
+		<script type='text/javascript' src='download.js'></script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/download/download.js b/browserid/static/dialog/jquery/download/download.js
new file mode 100644
index 0000000000000000000000000000000000000000..f1c37cc21fa8be927468f9e1c04cf19bd82d29b1
--- /dev/null
+++ b/browserid/static/dialog/jquery/download/download.js
@@ -0,0 +1,98 @@
+(function(){
+	$.Downloader = {
+		dependencies: [],
+		pluginData: null,
+		ready: function(){
+			$.getJSON('../dist/standalone/dependencies.json', 
+				function(data){
+					$.Downloader.pluginData = data;
+				});
+			$('#pluginForm').delegate("input[type=checkbox]", "change", 
+				$.proxy($.Downloader.changeHandler, $.Downloader));
+				
+			// append css if necessary
+			if(location.search && /csspath/.test(location.search)){
+				var path = location.search.split("=")[1];
+				var headID = document.getElementsByTagName("head")[0],
+					cssNode = document.createElement('link');
+				cssNode.type = 'text/css';
+				cssNode.rel = 'stylesheet';
+				cssNode.href = path;
+				cssNode.media = 'screen';
+				headID.appendChild(cssNode);
+			}
+			
+			$.Downloader.setupWordbreaks();
+		},
+		// inject <wbr> characters in labels
+		setupWordbreaks: function(){
+			var text, newText;
+			$(".plugin label").each(function(i){
+				text = $(this).text();
+				newText = text.replace(/\//g, "<wbr>/")
+				$(this).html(newText);
+			})
+		},
+		changeHandler: function(ev){
+			var $target = $(ev.target);
+			// if they unclicked, ignore it
+			if(!$target.attr('checked')) {
+				return;
+			}
+		 	this.dependencies = [];
+		 	var $form = $target.closest('form'),
+				params = $form.formParams(), i;
+			for(i=0; i<params.plugins.length; i++){
+				this._pushPlugins(this._getDependencies(params.plugins[i]));
+			}
+			$('#pluginForm input[type=checkbox]').attr('checked', false);
+			for(i=0; i<this.dependencies.length; i++){
+				$('input[value='+this.dependencies[i]+']').attr('checked', true);
+			}
+		 },
+		 /**
+		  * Push a list of plugins to the current list.  If there's a duplicate, 
+		  * delete the other one first.
+		  * @param {Object} dependencies an array of plugins to add to the list
+		  */
+		 _pushPlugins: function(dependencies){
+		 	var dep, i, index;
+		 	for(i=0; i<dependencies.length; i++){
+				dep = dependencies[i];
+				if(!$.inArray(dep, this.dependencies)) {
+					this.dependencies.splice(index, 1);
+				}
+				this.dependencies.push(dep);
+			}
+		 },
+		 /**
+		  * Recursively gets the array of dependencies for each plugin
+		  * @param {String} name the name of the plugin
+		  * @param {Boolean} includeSelf whether it should return with its own 
+		  * plugin name included
+		  */
+		 _getDependencies: function(name){
+		 	var dependencies = this.pluginData[name],
+				totalDependencies = [],
+				lowerDependencies, i, j;
+			if(!dependencies.length || 
+				(dependencies.length == 1 && dependencies[0] == "jquery/jquery.js")) {
+				return [name];
+			}
+		 	for(i=0; i<dependencies.length; i++){
+				lowerDependencies = this._getDependencies(dependencies[i]);
+				for (j = 0; j < lowerDependencies.length; j++) {
+					// TODO if you find a duplicate, remove the other one first
+					totalDependencies.push(lowerDependencies[j])
+				}
+			}
+			totalDependencies.push(name)
+			return totalDependencies;
+		 }
+	};
+	$(document).ready($.Downloader.ready);
+	$("a.down",top.document.documentElement).click(function(ev){
+		ev.preventDefault();
+		$('form')[0].submit();
+	})
+})()
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/download/test/controllerpage.html b/browserid/static/dialog/jquery/download/test/controllerpage.html
new file mode 100644
index 0000000000000000000000000000000000000000..ee3f49ab009d498446837629723bb39194e67c2e
--- /dev/null
+++ b/browserid/static/dialog/jquery/download/test/controllerpage.html
@@ -0,0 +1,15 @@
+<html>
+    <head>
+        <title>Test</title>
+    </head>
+    <body>
+		<script type='text/javascript' src='jquery-1.4.3.js'></script>
+		<script type='text/javascript' src='../../dist/standalone/jquery.lang.js'></script>
+		<script type='text/javascript' src='../../dist/standalone/jquery.class.js'></script>
+		<script type='text/javascript' src='../../dist/standalone/jquery.event.destroyed.js'></script>
+		<script type='text/javascript' src='../../dist/standalone/jquery.controller.js'></script>
+		<script type='text/javascript'>
+			$.Controller.extend('MyController', {}, {});
+		</script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/download/test/jquery-1.4.3.js b/browserid/static/dialog/jquery/download/test/jquery-1.4.3.js
new file mode 100644
index 0000000000000000000000000000000000000000..ad9a79c433071ee5f165e424a37e7506f8492a4f
--- /dev/null
+++ b/browserid/static/dialog/jquery/download/test/jquery-1.4.3.js
@@ -0,0 +1,6883 @@
+/*!
+ * jQuery JavaScript Library v1.4.3
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Thu Oct 14 23:10:06 2010 -0400
+ */
+(function( window, undefined ) {
+
+// Use the correct document accordingly with window argument (sandbox)
+var document = window.document;
+var jQuery = (function() {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
+		// The jQuery object is actually just the init constructor 'enhanced'
+		return new jQuery.fn.init( selector, context );
+	},
+
+	// Map over jQuery in case of overwrite
+	_jQuery = window.jQuery,
+
+	// Map over the $ in case of overwrite
+	_$ = window.$,
+
+	// A central reference to the root jQuery(document)
+	rootjQuery,
+
+	// A simple way to check for HTML strings or ID strings
+	// (both of which we optimize for)
+	quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,
+
+	// Is it a simple selector
+	isSimple = /^.[^:#\[\.,]*$/,
+
+	// Check if a string has a non-whitespace character in it
+	rnotwhite = /\S/,
+	rwhite = /\s/,
+
+	// Used for trimming whitespace
+	trimLeft = /^\s+/,
+	trimRight = /\s+$/,
+
+	// Check for non-word characters
+	rnonword = /\W/,
+
+	// Check for digits
+	rdigit = /\d/,
+
+	// Match a standalone tag
+	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+	// JSON RegExp
+	rvalidchars = /^[\],:{}\s]*$/,
+	rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
+	rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
+	rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+
+	// Useragent RegExp
+	rwebkit = /(webkit)[ \/]([\w.]+)/,
+	ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
+	rmsie = /(msie) ([\w.]+)/,
+	rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
+
+	// Keep a UserAgent string for use with jQuery.browser
+	userAgent = navigator.userAgent,
+
+	// For matching the engine and version of the browser
+	browserMatch,
+	
+	// Has the ready events already been bound?
+	readyBound = false,
+	
+	// The functions to execute on DOM ready
+	readyList = [],
+
+	// The ready event handler
+	DOMContentLoaded,
+
+	// Save a reference to some core methods
+	toString = Object.prototype.toString,
+	hasOwn = Object.prototype.hasOwnProperty,
+	push = Array.prototype.push,
+	slice = Array.prototype.slice,
+	trim = String.prototype.trim,
+	indexOf = Array.prototype.indexOf,
+	
+	// [[Class]] -> type pairs
+	class2type = {};
+
+jQuery.fn = jQuery.prototype = {
+	init: function( selector, context ) {
+		var match, elem, ret, doc;
+
+		// Handle $(""), $(null), or $(undefined)
+		if ( !selector ) {
+			return this;
+		}
+
+		// Handle $(DOMElement)
+		if ( selector.nodeType ) {
+			this.context = this[0] = selector;
+			this.length = 1;
+			return this;
+		}
+		
+		// The body element only exists once, optimize finding it
+		if ( selector === "body" && !context && document.body ) {
+			this.context = document;
+			this[0] = document.body;
+			this.selector = "body";
+			this.length = 1;
+			return this;
+		}
+
+		// Handle HTML strings
+		if ( typeof selector === "string" ) {
+			// Are we dealing with HTML string or an ID?
+			match = quickExpr.exec( selector );
+
+			// Verify a match, and that no context was specified for #id
+			if ( match && (match[1] || !context) ) {
+
+				// HANDLE: $(html) -> $(array)
+				if ( match[1] ) {
+					doc = (context ? context.ownerDocument || context : document);
+
+					// If a single string is passed in and it's a single tag
+					// just do a createElement and skip the rest
+					ret = rsingleTag.exec( selector );
+
+					if ( ret ) {
+						if ( jQuery.isPlainObject( context ) ) {
+							selector = [ document.createElement( ret[1] ) ];
+							jQuery.fn.attr.call( selector, context, true );
+
+						} else {
+							selector = [ doc.createElement( ret[1] ) ];
+						}
+
+					} else {
+						ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
+						selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
+					}
+					
+					return jQuery.merge( this, selector );
+					
+				// HANDLE: $("#id")
+				} else {
+					elem = document.getElementById( match[2] );
+
+					// Check parentNode to catch when Blackberry 4.6 returns
+					// nodes that are no longer in the document #6963
+					if ( elem && elem.parentNode ) {
+						// Handle the case where IE and Opera return items
+						// by name instead of ID
+						if ( elem.id !== match[2] ) {
+							return rootjQuery.find( selector );
+						}
+
+						// Otherwise, we inject the element directly into the jQuery object
+						this.length = 1;
+						this[0] = elem;
+					}
+
+					this.context = document;
+					this.selector = selector;
+					return this;
+				}
+
+			// HANDLE: $("TAG")
+			} else if ( !context && !rnonword.test( selector ) ) {
+				this.selector = selector;
+				this.context = document;
+				selector = document.getElementsByTagName( selector );
+				return jQuery.merge( this, selector );
+
+			// HANDLE: $(expr, $(...))
+			} else if ( !context || context.jquery ) {
+				return (context || rootjQuery).find( selector );
+
+			// HANDLE: $(expr, context)
+			// (which is just equivalent to: $(context).find(expr)
+			} else {
+				return jQuery( context ).find( selector );
+			}
+
+		// HANDLE: $(function)
+		// Shortcut for document ready
+		} else if ( jQuery.isFunction( selector ) ) {
+			return rootjQuery.ready( selector );
+		}
+
+		if (selector.selector !== undefined) {
+			this.selector = selector.selector;
+			this.context = selector.context;
+		}
+
+		return jQuery.makeArray( selector, this );
+	},
+
+	// Start with an empty selector
+	selector: "",
+
+	// The current version of jQuery being used
+	jquery: "1.4.3",
+
+	// The default length of a jQuery object is 0
+	length: 0,
+
+	// The number of elements contained in the matched element set
+	size: function() {
+		return this.length;
+	},
+
+	toArray: function() {
+		return slice.call( this, 0 );
+	},
+
+	// Get the Nth element in the matched element set OR
+	// Get the whole matched element set as a clean array
+	get: function( num ) {
+		return num == null ?
+
+			// Return a 'clean' array
+			this.toArray() :
+
+			// Return just the object
+			( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
+	},
+
+	// Take an array of elements and push it onto the stack
+	// (returning the new matched element set)
+	pushStack: function( elems, name, selector ) {
+		// Build a new jQuery matched element set
+		var ret = jQuery();
+
+		if ( jQuery.isArray( elems ) ) {
+			push.apply( ret, elems );
+		
+		} else {
+			jQuery.merge( ret, elems );
+		}
+
+		// Add the old object onto the stack (as a reference)
+		ret.prevObject = this;
+
+		ret.context = this.context;
+
+		if ( name === "find" ) {
+			ret.selector = this.selector + (this.selector ? " " : "") + selector;
+		} else if ( name ) {
+			ret.selector = this.selector + "." + name + "(" + selector + ")";
+		}
+
+		// Return the newly-formed element set
+		return ret;
+	},
+
+	// Execute a callback for every element in the matched set.
+	// (You can seed the arguments with an array of args, but this is
+	// only used internally.)
+	each: function( callback, args ) {
+		return jQuery.each( this, callback, args );
+	},
+	
+	ready: function( fn ) {
+		// Attach the listeners
+		jQuery.bindReady();
+
+		// If the DOM is already ready
+		if ( jQuery.isReady ) {
+			// Execute the function immediately
+			fn.call( document, jQuery );
+
+		// Otherwise, remember the function for later
+		} else if ( readyList ) {
+			// Add the function to the wait list
+			readyList.push( fn );
+		}
+
+		return this;
+	},
+	
+	eq: function( i ) {
+		return i === -1 ?
+			this.slice( i ) :
+			this.slice( i, +i + 1 );
+	},
+
+	first: function() {
+		return this.eq( 0 );
+	},
+
+	last: function() {
+		return this.eq( -1 );
+	},
+
+	slice: function() {
+		return this.pushStack( slice.apply( this, arguments ),
+			"slice", slice.call(arguments).join(",") );
+	},
+
+	map: function( callback ) {
+		return this.pushStack( jQuery.map(this, function( elem, i ) {
+			return callback.call( elem, i, elem );
+		}));
+	},
+	
+	end: function() {
+		return this.prevObject || jQuery(null);
+	},
+
+	// For internal use only.
+	// Behaves like an Array's method, not like a jQuery method.
+	push: push,
+	sort: [].sort,
+	splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+	// copy reference to target object
+	var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy, copyIsArray;
+
+	// Handle a deep copy situation
+	if ( typeof target === "boolean" ) {
+		deep = target;
+		target = arguments[1] || {};
+		// skip the boolean and the target
+		i = 2;
+	}
+
+	// Handle case when target is a string or something (possible in deep copy)
+	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+		target = {};
+	}
+
+	// extend jQuery itself if only one argument is passed
+	if ( length === i ) {
+		target = this;
+		--i;
+	}
+
+	for ( ; i < length; i++ ) {
+		// Only deal with non-null/undefined values
+		if ( (options = arguments[ i ]) != null ) {
+			// Extend the base object
+			for ( name in options ) {
+				src = target[ name ];
+				copy = options[ name ];
+
+				// Prevent never-ending loop
+				if ( target === copy ) {
+					continue;
+				}
+
+				// Recurse if we're merging plain objects or arrays
+				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+					if ( copyIsArray ) {
+						copyIsArray = false;
+						clone = src && jQuery.isArray(src) ? src : [];
+
+					} else {
+						clone = src && jQuery.isPlainObject(src) ? src : {};
+					}
+
+					// Never move original objects, clone them
+					target[ name ] = jQuery.extend( deep, clone, copy );
+
+				// Don't bring in undefined values
+				} else if ( copy !== undefined ) {
+					target[ name ] = copy;
+				}
+			}
+		}
+	}
+
+	// Return the modified object
+	return target;
+};
+
+jQuery.extend({
+	noConflict: function( deep ) {
+		window.$ = _$;
+
+		if ( deep ) {
+			window.jQuery = _jQuery;
+		}
+
+		return jQuery;
+	},
+	
+	// Is the DOM ready to be used? Set to true once it occurs.
+	isReady: false,
+
+	// A counter to track how many items to wait for before
+	// the ready event fires. See #6781
+	readyWait: 1,
+	
+	// Handle when the DOM is ready
+	ready: function( wait ) {
+		// A third-party is pushing the ready event forwards
+		if ( wait === true ) {
+			jQuery.readyWait--;
+		}
+
+		// Make sure that the DOM is not already loaded
+		if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) {
+			// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+			if ( !document.body ) {
+				return setTimeout( jQuery.ready, 1 );
+			}
+
+			// Remember that the DOM is ready
+			jQuery.isReady = true;
+
+			// If a normal DOM Ready event fired, decrement, and wait if need be
+			if ( wait !== true && --jQuery.readyWait > 0 ) {
+				return;
+			}
+
+			// If there are functions bound, to execute
+			if ( readyList ) {
+				// Execute all of them
+				var fn, i = 0;
+				while ( (fn = readyList[ i++ ]) ) {
+					fn.call( document, jQuery );
+				}
+
+				// Reset the list of functions
+				readyList = null;
+			}
+
+			// Trigger any bound ready events
+			if ( jQuery.fn.triggerHandler ) {
+				jQuery( document ).triggerHandler( "ready" );
+			}
+		}
+	},
+	
+	bindReady: function() {
+		if ( readyBound ) {
+			return;
+		}
+
+		readyBound = true;
+
+		// Catch cases where $(document).ready() is called after the
+		// browser event has already occurred.
+		if ( document.readyState === "complete" ) {
+			// Handle it asynchronously to allow scripts the opportunity to delay ready
+			return setTimeout( jQuery.ready, 1 );
+		}
+
+		// Mozilla, Opera and webkit nightlies currently support this event
+		if ( document.addEventListener ) {
+			// Use the handy event callback
+			document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+			
+			// A fallback to window.onload, that will always work
+			window.addEventListener( "load", jQuery.ready, false );
+
+		// If IE event model is used
+		} else if ( document.attachEvent ) {
+			// ensure firing before onload,
+			// maybe late but safe also for iframes
+			document.attachEvent("onreadystatechange", DOMContentLoaded);
+			
+			// A fallback to window.onload, that will always work
+			window.attachEvent( "onload", jQuery.ready );
+
+			// If IE and not a frame
+			// continually check to see if the document is ready
+			var toplevel = false;
+
+			try {
+				toplevel = window.frameElement == null;
+			} catch(e) {}
+
+			if ( document.documentElement.doScroll && toplevel ) {
+				doScrollCheck();
+			}
+		}
+	},
+
+	// See test/unit/core.js for details concerning isFunction.
+	// Since version 1.3, DOM methods and functions like alert
+	// aren't supported. They return false on IE (#2968).
+	isFunction: function( obj ) {
+		return jQuery.type(obj) === "function";
+	},
+
+	isArray: Array.isArray || function( obj ) {
+		return jQuery.type(obj) === "array";
+	},
+
+	// A crude way of determining if an object is a window
+	isWindow: function( obj ) {
+		return obj && typeof obj === "object" && "setInterval" in obj;
+	},
+
+	isNaN: function( obj ) {
+		return obj == null || !rdigit.test( obj ) || isNaN( obj );
+	},
+
+	type: function( obj ) {
+		return obj == null ?
+			String( obj ) :
+			class2type[ toString.call(obj) ] || "object";
+	},
+
+	isPlainObject: function( obj ) {
+		// Must be an Object.
+		// Because of IE, we also have to check the presence of the constructor property.
+		// Make sure that DOM nodes and window objects don't pass through, as well
+		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+			return false;
+		}
+		
+		// Not own constructor property must be Object
+		if ( obj.constructor &&
+			!hasOwn.call(obj, "constructor") &&
+			!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+			return false;
+		}
+		
+		// Own properties are enumerated firstly, so to speed up,
+		// if last one is own, then all properties are own.
+	
+		var key;
+		for ( key in obj ) {}
+		
+		return key === undefined || hasOwn.call( obj, key );
+	},
+
+	isEmptyObject: function( obj ) {
+		for ( var name in obj ) {
+			return false;
+		}
+		return true;
+	},
+	
+	error: function( msg ) {
+		throw msg;
+	},
+	
+	parseJSON: function( data ) {
+		if ( typeof data !== "string" || !data ) {
+			return null;
+		}
+
+		// Make sure leading/trailing whitespace is removed (IE can't handle it)
+		data = jQuery.trim( data );
+		
+		// Make sure the incoming data is actual JSON
+		// Logic borrowed from http://json.org/json2.js
+		if ( rvalidchars.test(data.replace(rvalidescape, "@")
+			.replace(rvalidtokens, "]")
+			.replace(rvalidbraces, "")) ) {
+
+			// Try to use the native JSON parser first
+			return window.JSON && window.JSON.parse ?
+				window.JSON.parse( data ) :
+				(new Function("return " + data))();
+
+		} else {
+			jQuery.error( "Invalid JSON: " + data );
+		}
+	},
+
+	noop: function() {},
+
+	// Evalulates a script in a global context
+	globalEval: function( data ) {
+		if ( data && rnotwhite.test(data) ) {
+			// Inspired by code by Andrea Giammarchi
+			// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+			var head = document.getElementsByTagName("head")[0] || document.documentElement,
+				script = document.createElement("script");
+
+			script.type = "text/javascript";
+
+			if ( jQuery.support.scriptEval ) {
+				script.appendChild( document.createTextNode( data ) );
+			} else {
+				script.text = data;
+			}
+
+			// Use insertBefore instead of appendChild to circumvent an IE6 bug.
+			// This arises when a base node is used (#2709).
+			head.insertBefore( script, head.firstChild );
+			head.removeChild( script );
+		}
+	},
+
+	nodeName: function( elem, name ) {
+		return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+	},
+
+	// args is for internal usage only
+	each: function( object, callback, args ) {
+		var name, i = 0,
+			length = object.length,
+			isObj = length === undefined || jQuery.isFunction(object);
+
+		if ( args ) {
+			if ( isObj ) {
+				for ( name in object ) {
+					if ( callback.apply( object[ name ], args ) === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( ; i < length; ) {
+					if ( callback.apply( object[ i++ ], args ) === false ) {
+						break;
+					}
+				}
+			}
+
+		// A special, fast, case for the most common use of each
+		} else {
+			if ( isObj ) {
+				for ( name in object ) {
+					if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( var value = object[0];
+					i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
+			}
+		}
+
+		return object;
+	},
+
+	// Use native String.trim function wherever possible
+	trim: trim ?
+		function( text ) {
+			return text == null ?
+				"" :
+				trim.call( text );
+		} :
+
+		// Otherwise use our own trimming functionality
+		function( text ) {
+			return text == null ?
+				"" :
+				text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
+		},
+
+	// results is for internal usage only
+	makeArray: function( array, results ) {
+		var ret = results || [];
+
+		if ( array != null ) {
+			// The window, strings (and functions) also have 'length'
+			// The extra typeof function check is to prevent crashes
+			// in Safari 2 (See: #3039)
+			// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
+			var type = jQuery.type(array);
+
+			if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
+				push.call( ret, array );
+			} else {
+				jQuery.merge( ret, array );
+			}
+		}
+
+		return ret;
+	},
+
+	inArray: function( elem, array ) {
+		if ( array.indexOf ) {
+			return array.indexOf( elem );
+		}
+
+		for ( var i = 0, length = array.length; i < length; i++ ) {
+			if ( array[ i ] === elem ) {
+				return i;
+			}
+		}
+
+		return -1;
+	},
+
+	merge: function( first, second ) {
+		var i = first.length, j = 0;
+
+		if ( typeof second.length === "number" ) {
+			for ( var l = second.length; j < l; j++ ) {
+				first[ i++ ] = second[ j ];
+			}
+		
+		} else {
+			while ( second[j] !== undefined ) {
+				first[ i++ ] = second[ j++ ];
+			}
+		}
+
+		first.length = i;
+
+		return first;
+	},
+
+	grep: function( elems, callback, inv ) {
+		var ret = [], retVal;
+		inv = !!inv;
+
+		// Go through the array, only saving the items
+		// that pass the validator function
+		for ( var i = 0, length = elems.length; i < length; i++ ) {
+			retVal = !!callback( elems[ i ], i );
+			if ( inv !== retVal ) {
+				ret.push( elems[ i ] );
+			}
+		}
+
+		return ret;
+	},
+
+	// arg is for internal usage only
+	map: function( elems, callback, arg ) {
+		var ret = [], value;
+
+		// Go through the array, translating each of the items to their
+		// new value (or values).
+		for ( var i = 0, length = elems.length; i < length; i++ ) {
+			value = callback( elems[ i ], i, arg );
+
+			if ( value != null ) {
+				ret[ ret.length ] = value;
+			}
+		}
+
+		return ret.concat.apply( [], ret );
+	},
+
+	// A global GUID counter for objects
+	guid: 1,
+
+	proxy: function( fn, proxy, thisObject ) {
+		if ( arguments.length === 2 ) {
+			if ( typeof proxy === "string" ) {
+				thisObject = fn;
+				fn = thisObject[ proxy ];
+				proxy = undefined;
+
+			} else if ( proxy && !jQuery.isFunction( proxy ) ) {
+				thisObject = proxy;
+				proxy = undefined;
+			}
+		}
+
+		if ( !proxy && fn ) {
+			proxy = function() {
+				return fn.apply( thisObject || this, arguments );
+			};
+		}
+
+		// Set the guid of unique handler to the same of original handler, so it can be removed
+		if ( fn ) {
+			proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+		}
+
+		// So proxy can be declared as an argument
+		return proxy;
+	},
+
+	// Mutifunctional method to get and set values to a collection
+	// The value/s can be optionally by executed if its a function
+	access: function( elems, key, value, exec, fn, pass ) {
+		var length = elems.length;
+	
+		// Setting many attributes
+		if ( typeof key === "object" ) {
+			for ( var k in key ) {
+				jQuery.access( elems, k, key[k], exec, fn, value );
+			}
+			return elems;
+		}
+	
+		// Setting one attribute
+		if ( value !== undefined ) {
+			// Optionally, function values get executed if exec is true
+			exec = !pass && exec && jQuery.isFunction(value);
+		
+			for ( var i = 0; i < length; i++ ) {
+				fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+			}
+		
+			return elems;
+		}
+	
+		// Getting an attribute
+		return length ? fn( elems[0], key ) : undefined;
+	},
+
+	now: function() {
+		return (new Date()).getTime();
+	},
+
+	// Use of jQuery.browser is frowned upon.
+	// More details: http://docs.jquery.com/Utilities/jQuery.browser
+	uaMatch: function( ua ) {
+		ua = ua.toLowerCase();
+
+		var match = rwebkit.exec( ua ) ||
+			ropera.exec( ua ) ||
+			rmsie.exec( ua ) ||
+			ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
+			[];
+
+		return { browser: match[1] || "", version: match[2] || "0" };
+	},
+
+	browser: {}
+});
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
+	class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+	jQuery.browser[ browserMatch.browser ] = true;
+	jQuery.browser.version = browserMatch.version;
+}
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+	jQuery.browser.safari = true;
+}
+
+if ( indexOf ) {
+	jQuery.inArray = function( elem, array ) {
+		return indexOf.call( array, elem );
+	};
+}
+
+// Verify that \s matches non-breaking spaces
+// (IE fails on this test)
+if ( !rwhite.test( "\xA0" ) ) {
+	trimLeft = /^[\s\xA0]+/;
+	trimRight = /[\s\xA0]+$/;
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+	DOMContentLoaded = function() {
+		document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+		jQuery.ready();
+	};
+
+} else if ( document.attachEvent ) {
+	DOMContentLoaded = function() {
+		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+		if ( document.readyState === "complete" ) {
+			document.detachEvent( "onreadystatechange", DOMContentLoaded );
+			jQuery.ready();
+		}
+	};
+}
+
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+	if ( jQuery.isReady ) {
+		return;
+	}
+
+	try {
+		// If IE is used, use the trick by Diego Perini
+		// http://javascript.nwbox.com/IEContentLoaded/
+		document.documentElement.doScroll("left");
+	} catch(e) {
+		setTimeout( doScrollCheck, 1 );
+		return;
+	}
+
+	// and execute any waiting functions
+	jQuery.ready();
+}
+
+// Expose jQuery to the global object
+return (window.jQuery = window.$ = jQuery);
+
+})();
+
+
+(function() {
+
+	jQuery.support = {};
+
+	var root = document.documentElement,
+		script = document.createElement("script"),
+		div = document.createElement("div"),
+		id = "script" + jQuery.now();
+
+	div.style.display = "none";
+	div.innerHTML = "   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
+	var all = div.getElementsByTagName("*"),
+		a = div.getElementsByTagName("a")[0],
+		select = document.createElement("select"),
+		opt = select.appendChild( document.createElement("option") );
+
+	// Can't get basic test support
+	if ( !all || !all.length || !a ) {
+		return;
+	}
+
+	jQuery.support = {
+		// IE strips leading whitespace when .innerHTML is used
+		leadingWhitespace: div.firstChild.nodeType === 3,
+
+		// Make sure that tbody elements aren't automatically inserted
+		// IE will insert them into empty tables
+		tbody: !div.getElementsByTagName("tbody").length,
+
+		// Make sure that link elements get serialized correctly by innerHTML
+		// This requires a wrapper element in IE
+		htmlSerialize: !!div.getElementsByTagName("link").length,
+
+		// Get the style information from getAttribute
+		// (IE uses .cssText insted)
+		style: /red/.test( a.getAttribute("style") ),
+
+		// Make sure that URLs aren't manipulated
+		// (IE normalizes it by default)
+		hrefNormalized: a.getAttribute("href") === "/a",
+
+		// Make sure that element opacity exists
+		// (IE uses filter instead)
+		// Use a regex to work around a WebKit issue. See #5145
+		opacity: /^0.55$/.test( a.style.opacity ),
+
+		// Verify style float existence
+		// (IE uses styleFloat instead of cssFloat)
+		cssFloat: !!a.style.cssFloat,
+
+		// Make sure that if no value is specified for a checkbox
+		// that it defaults to "on".
+		// (WebKit defaults to "" instead)
+		checkOn: div.getElementsByTagName("input")[0].value === "on",
+
+		// Make sure that a selected-by-default option has a working selected property.
+		// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+		optSelected: opt.selected,
+
+		// Will be defined later
+		optDisabled: false,
+		checkClone: false,
+		scriptEval: false,
+		noCloneEvent: true,
+		boxModel: null,
+		inlineBlockNeedsLayout: false,
+		shrinkWrapBlocks: false,
+		reliableHiddenOffsets: true
+	};
+
+	// Make sure that the options inside disabled selects aren't marked as disabled
+	// (WebKit marks them as diabled)
+	select.disabled = true;
+	jQuery.support.optDisabled = !opt.disabled;
+
+	script.type = "text/javascript";
+	try {
+		script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
+	} catch(e) {}
+
+	root.insertBefore( script, root.firstChild );
+
+	// Make sure that the execution of code works by injecting a script
+	// tag with appendChild/createTextNode
+	// (IE doesn't support this, fails, and uses .text instead)
+	if ( window[ id ] ) {
+		jQuery.support.scriptEval = true;
+		delete window[ id ];
+	}
+
+	root.removeChild( script );
+
+	if ( div.attachEvent && div.fireEvent ) {
+		div.attachEvent("onclick", function click() {
+			// Cloning a node shouldn't copy over any
+			// bound event handlers (IE does this)
+			jQuery.support.noCloneEvent = false;
+			div.detachEvent("onclick", click);
+		});
+		div.cloneNode(true).fireEvent("onclick");
+	}
+
+	div = document.createElement("div");
+	div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
+
+	var fragment = document.createDocumentFragment();
+	fragment.appendChild( div.firstChild );
+
+	// WebKit doesn't clone checked state correctly in fragments
+	jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
+
+	// Figure out if the W3C box model works as expected
+	// document.body must exist before we can do this
+	jQuery(function() {
+		var div = document.createElement("div");
+		div.style.width = div.style.paddingLeft = "1px";
+
+		document.body.appendChild( div );
+		jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
+
+		if ( "zoom" in div.style ) {
+			// Check if natively block-level elements act like inline-block
+			// elements when setting their display to 'inline' and giving
+			// them layout
+			// (IE < 8 does this)
+			div.style.display = "inline";
+			div.style.zoom = 1;
+			jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;
+
+			// Check if elements with layout shrink-wrap their children
+			// (IE 6 does this)
+			div.style.display = "";
+			div.innerHTML = "<div style='width:4px;'></div>";
+			jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
+		}
+
+		div.innerHTML = "<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";
+		var tds = div.getElementsByTagName("td");
+
+		// Check if table cells still have offsetWidth/Height when they are set
+		// to display:none and there are still other visible table cells in a
+		// table row; if so, offsetWidth/Height are not reliable for use when
+		// determining if an element has been hidden directly using
+		// display:none (it is still safe to use offsets if a parent element is
+		// hidden; don safety goggles and see bug #4512 for more information).
+		// (only IE 8 fails this test)
+		jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;
+
+		tds[0].style.display = "";
+		tds[1].style.display = "none";
+
+		// Check if empty table cells still have offsetWidth/Height
+		// (IE < 8 fail this test)
+		jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
+		div.innerHTML = "";
+
+		document.body.removeChild( div ).style.display = "none";
+		div = tds = null;
+	});
+
+	// Technique from Juriy Zaytsev
+	// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+	var eventSupported = function( eventName ) {
+		var el = document.createElement("div");
+		eventName = "on" + eventName;
+
+		var isSupported = (eventName in el);
+		if ( !isSupported ) {
+			el.setAttribute(eventName, "return;");
+			isSupported = typeof el[eventName] === "function";
+		}
+		el = null;
+
+		return isSupported;
+	};
+
+	jQuery.support.submitBubbles = eventSupported("submit");
+	jQuery.support.changeBubbles = eventSupported("change");
+
+	// release memory in IE
+	root = script = div = all = a = null;
+})();
+
+jQuery.props = {
+	"for": "htmlFor",
+	"class": "className",
+	readonly: "readOnly",
+	maxlength: "maxLength",
+	cellspacing: "cellSpacing",
+	rowspan: "rowSpan",
+	colspan: "colSpan",
+	tabindex: "tabIndex",
+	usemap: "useMap",
+	frameborder: "frameBorder"
+};
+
+
+
+
+var windowData = {},
+	rbrace = /^(?:\{.*\}|\[.*\])$/;
+
+jQuery.extend({
+	cache: {},
+
+	// Please use with caution
+	uuid: 0,
+
+	// Unique for each copy of jQuery on the page	
+	expando: "jQuery" + jQuery.now(),
+
+	// The following elements throw uncatchable exceptions if you
+	// attempt to add expando properties to them.
+	noData: {
+		"embed": true,
+		// Ban all objects except for Flash (which handle expandos)
+		"object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
+		"applet": true
+	},
+
+	data: function( elem, name, data ) {
+		if ( !jQuery.acceptData( elem ) ) {
+			return;
+		}
+
+		elem = elem == window ?
+			windowData :
+			elem;
+
+		var isNode = elem.nodeType,
+			id = isNode ? elem[ jQuery.expando ] : null,
+			cache = jQuery.cache, thisCache;
+
+		if ( isNode && !id && typeof name === "string" && data === undefined ) {
+			return;
+		}
+
+		// Get the data from the object directly
+		if ( !isNode ) {
+			cache = elem;
+
+		// Compute a unique ID for the element
+		} else if ( !id ) {
+			elem[ jQuery.expando ] = id = ++jQuery.uuid;
+		}
+
+		// Avoid generating a new cache unless none exists and we
+		// want to manipulate it.
+		if ( typeof name === "object" ) {
+			if ( isNode ) {
+				cache[ id ] = jQuery.extend(cache[ id ], name);
+
+			} else {
+				jQuery.extend( cache, name );
+			}
+
+		} else if ( isNode && !cache[ id ] ) {
+			cache[ id ] = {};
+		}
+
+		thisCache = isNode ? cache[ id ] : cache;
+
+		// Prevent overriding the named cache with undefined values
+		if ( data !== undefined ) {
+			thisCache[ name ] = data;
+		}
+
+		return typeof name === "string" ? thisCache[ name ] : thisCache;
+	},
+
+	removeData: function( elem, name ) {
+		if ( !jQuery.acceptData( elem ) ) {
+			return;
+		}
+
+		elem = elem == window ?
+			windowData :
+			elem;
+
+		var isNode = elem.nodeType,
+			id = isNode ? elem[ jQuery.expando ] : elem,
+			cache = jQuery.cache,
+			thisCache = isNode ? cache[ id ] : id;
+
+		// If we want to remove a specific section of the element's data
+		if ( name ) {
+			if ( thisCache ) {
+				// Remove the section of cache data
+				delete thisCache[ name ];
+
+				// If we've removed all the data, remove the element's cache
+				if ( isNode && jQuery.isEmptyObject(thisCache) ) {
+					jQuery.removeData( elem );
+				}
+			}
+
+		// Otherwise, we want to remove all of the element's data
+		} else {
+			if ( isNode && jQuery.support.deleteExpando ) {
+				delete elem[ jQuery.expando ];
+
+			} else if ( elem.removeAttribute ) {
+				elem.removeAttribute( jQuery.expando );
+
+			// Completely remove the data cache
+			} else if ( isNode ) {
+				delete cache[ id ];
+
+			// Remove all fields from the object
+			} else {
+				for ( var n in elem ) {
+					delete elem[ n ];
+				}
+			}
+		}
+	},
+
+	// A method for determining if a DOM node can handle the data expando
+	acceptData: function( elem ) {
+		if ( elem.nodeName ) {
+			var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
+
+			if ( match ) {
+				return !(match === true || elem.getAttribute("classid") !== match);
+			}
+		}
+
+		return true;
+	}
+});
+
+jQuery.fn.extend({
+	data: function( key, value ) {
+		if ( typeof key === "undefined" ) {
+			return this.length ? jQuery.data( this[0] ) : null;
+
+		} else if ( typeof key === "object" ) {
+			return this.each(function() {
+				jQuery.data( this, key );
+			});
+		}
+
+		var parts = key.split(".");
+		parts[1] = parts[1] ? "." + parts[1] : "";
+
+		if ( value === undefined ) {
+			var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+			// Try to fetch any internally stored data first
+			if ( data === undefined && this.length ) {
+				data = jQuery.data( this[0], key );
+
+				// If nothing was found internally, try to fetch any
+				// data from the HTML5 data-* attribute
+				if ( data === undefined && this[0].nodeType === 1 ) {
+					data = this[0].getAttribute( "data-" + key );
+
+					if ( typeof data === "string" ) {
+						try {
+							data = data === "true" ? true :
+								data === "false" ? false :
+								data === "null" ? null :
+								!jQuery.isNaN( data ) ? parseFloat( data ) :
+								rbrace.test( data ) ? jQuery.parseJSON( data ) :
+								data;
+						} catch( e ) {}
+
+					} else {
+						data = undefined;
+					}
+				}
+			}
+
+			return data === undefined && parts[1] ?
+				this.data( parts[0] ) :
+				data;
+
+		} else {
+			return this.each(function() {
+				var $this = jQuery( this ), args = [ parts[0], value ];
+
+				$this.triggerHandler( "setData" + parts[1] + "!", args );
+				jQuery.data( this, key, value );
+				$this.triggerHandler( "changeData" + parts[1] + "!", args );
+			});
+		}
+	},
+
+	removeData: function( key ) {
+		return this.each(function() {
+			jQuery.removeData( this, key );
+		});
+	}
+});
+
+
+
+
+jQuery.extend({
+	queue: function( elem, type, data ) {
+		if ( !elem ) {
+			return;
+		}
+
+		type = (type || "fx") + "queue";
+		var q = jQuery.data( elem, type );
+
+		// Speed up dequeue by getting out quickly if this is just a lookup
+		if ( !data ) {
+			return q || [];
+		}
+
+		if ( !q || jQuery.isArray(data) ) {
+			q = jQuery.data( elem, type, jQuery.makeArray(data) );
+
+		} else {
+			q.push( data );
+		}
+
+		return q;
+	},
+
+	dequeue: function( elem, type ) {
+		type = type || "fx";
+
+		var queue = jQuery.queue( elem, type ), fn = queue.shift();
+
+		// If the fx queue is dequeued, always remove the progress sentinel
+		if ( fn === "inprogress" ) {
+			fn = queue.shift();
+		}
+
+		if ( fn ) {
+			// Add a progress sentinel to prevent the fx queue from being
+			// automatically dequeued
+			if ( type === "fx" ) {
+				queue.unshift("inprogress");
+			}
+
+			fn.call(elem, function() {
+				jQuery.dequeue(elem, type);
+			});
+		}
+	}
+});
+
+jQuery.fn.extend({
+	queue: function( type, data ) {
+		if ( typeof type !== "string" ) {
+			data = type;
+			type = "fx";
+		}
+
+		if ( data === undefined ) {
+			return jQuery.queue( this[0], type );
+		}
+		return this.each(function( i ) {
+			var queue = jQuery.queue( this, type, data );
+
+			if ( type === "fx" && queue[0] !== "inprogress" ) {
+				jQuery.dequeue( this, type );
+			}
+		});
+	},
+	dequeue: function( type ) {
+		return this.each(function() {
+			jQuery.dequeue( this, type );
+		});
+	},
+
+	// Based off of the plugin by Clint Helfers, with permission.
+	// http://blindsignals.com/index.php/2009/07/jquery-delay/
+	delay: function( time, type ) {
+		time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+		type = type || "fx";
+
+		return this.queue( type, function() {
+			var elem = this;
+			setTimeout(function() {
+				jQuery.dequeue( elem, type );
+			}, time );
+		});
+	},
+
+	clearQueue: function( type ) {
+		return this.queue( type || "fx", [] );
+	}
+});
+
+
+
+
+var rclass = /[\n\t]/g,
+	rspaces = /\s+/,
+	rreturn = /\r/g,
+	rspecialurl = /^(?:href|src|style)$/,
+	rtype = /^(?:button|input)$/i,
+	rfocusable = /^(?:button|input|object|select|textarea)$/i,
+	rclickable = /^a(?:rea)?$/i,
+	rradiocheck = /^(?:radio|checkbox)$/i;
+
+jQuery.fn.extend({
+	attr: function( name, value ) {
+		return jQuery.access( this, name, value, true, jQuery.attr );
+	},
+
+	removeAttr: function( name, fn ) {
+		return this.each(function(){
+			jQuery.attr( this, name, "" );
+			if ( this.nodeType === 1 ) {
+				this.removeAttribute( name );
+			}
+		});
+	},
+
+	addClass: function( value ) {
+		if ( jQuery.isFunction(value) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.addClass( value.call(this, i, self.attr("class")) );
+			});
+		}
+
+		if ( value && typeof value === "string" ) {
+			var classNames = (value || "").split( rspaces );
+
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				var elem = this[i];
+
+				if ( elem.nodeType === 1 ) {
+					if ( !elem.className ) {
+						elem.className = value;
+
+					} else {
+						var className = " " + elem.className + " ", setClass = elem.className;
+						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+							if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
+								setClass += " " + classNames[c];
+							}
+						}
+						elem.className = jQuery.trim( setClass );
+					}
+				}
+			}
+		}
+
+		return this;
+	},
+
+	removeClass: function( value ) {
+		if ( jQuery.isFunction(value) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.removeClass( value.call(this, i, self.attr("class")) );
+			});
+		}
+
+		if ( (value && typeof value === "string") || value === undefined ) {
+			var classNames = (value || "").split( rspaces );
+
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				var elem = this[i];
+
+				if ( elem.nodeType === 1 && elem.className ) {
+					if ( value ) {
+						var className = (" " + elem.className + " ").replace(rclass, " ");
+						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+							className = className.replace(" " + classNames[c] + " ", " ");
+						}
+						elem.className = jQuery.trim( className );
+
+					} else {
+						elem.className = "";
+					}
+				}
+			}
+		}
+
+		return this;
+	},
+
+	toggleClass: function( value, stateVal ) {
+		var type = typeof value, isBool = typeof stateVal === "boolean";
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
+			});
+		}
+
+		return this.each(function() {
+			if ( type === "string" ) {
+				// toggle individual class names
+				var className, i = 0, self = jQuery(this),
+					state = stateVal,
+					classNames = value.split( rspaces );
+
+				while ( (className = classNames[ i++ ]) ) {
+					// check each className given, space seperated list
+					state = isBool ? state : !self.hasClass( className );
+					self[ state ? "addClass" : "removeClass" ]( className );
+				}
+
+			} else if ( type === "undefined" || type === "boolean" ) {
+				if ( this.className ) {
+					// store className if set
+					jQuery.data( this, "__className__", this.className );
+				}
+
+				// toggle whole className
+				this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
+			}
+		});
+	},
+
+	hasClass: function( selector ) {
+		var className = " " + selector + " ";
+		for ( var i = 0, l = this.length; i < l; i++ ) {
+			if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+				return true;
+			}
+		}
+
+		return false;
+	},
+
+	val: function( value ) {
+		if ( !arguments.length ) {
+			var elem = this[0];
+
+			if ( elem ) {
+				if ( jQuery.nodeName( elem, "option" ) ) {
+					// attributes.value is undefined in Blackberry 4.7 but
+					// uses .value. See #6932
+					var val = elem.attributes.value;
+					return !val || val.specified ? elem.value : elem.text;
+				}
+
+				// We need to handle select boxes special
+				if ( jQuery.nodeName( elem, "select" ) ) {
+					var index = elem.selectedIndex,
+						values = [],
+						options = elem.options,
+						one = elem.type === "select-one";
+
+					// Nothing was selected
+					if ( index < 0 ) {
+						return null;
+					}
+
+					// Loop through all the selected options
+					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+						var option = options[ i ];
+
+						// Don't return options that are disabled or in a disabled optgroup
+						if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && 
+								(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
+
+							// Get the specific value for the option
+							value = jQuery(option).val();
+
+							// We don't need an array for one selects
+							if ( one ) {
+								return value;
+							}
+
+							// Multi-Selects return an array
+							values.push( value );
+						}
+					}
+
+					return values;
+				}
+
+				// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+				if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
+					return elem.getAttribute("value") === null ? "on" : elem.value;
+				}
+				
+
+				// Everything else, we just grab the value
+				return (elem.value || "").replace(rreturn, "");
+
+			}
+
+			return undefined;
+		}
+
+		var isFunction = jQuery.isFunction(value);
+
+		return this.each(function(i) {
+			var self = jQuery(this), val = value;
+
+			if ( this.nodeType !== 1 ) {
+				return;
+			}
+
+			if ( isFunction ) {
+				val = value.call(this, i, self.val());
+			}
+
+			// Treat null/undefined as ""; convert numbers to string
+			if ( val == null ) {
+				val = "";
+			} else if ( typeof val === "number" ) {
+				val += "";
+			} else if ( jQuery.isArray(val) ) {
+				val = jQuery.map(val, function (value) {
+					return value == null ? "" : value + "";
+				});
+			}
+
+			if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
+				this.checked = jQuery.inArray( self.val(), val ) >= 0;
+
+			} else if ( jQuery.nodeName( this, "select" ) ) {
+				var values = jQuery.makeArray(val);
+
+				jQuery( "option", this ).each(function() {
+					this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+				});
+
+				if ( !values.length ) {
+					this.selectedIndex = -1;
+				}
+
+			} else {
+				this.value = val;
+			}
+		});
+	}
+});
+
+jQuery.extend({
+	attrFn: {
+		val: true,
+		css: true,
+		html: true,
+		text: true,
+		data: true,
+		width: true,
+		height: true,
+		offset: true
+	},
+		
+	attr: function( elem, name, value, pass ) {
+		// don't set attributes on text and comment nodes
+		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return undefined;
+		}
+
+		if ( pass && name in jQuery.attrFn ) {
+			return jQuery(elem)[name](value);
+		}
+
+		var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
+			// Whether we are setting (or getting)
+			set = value !== undefined;
+
+		// Try to normalize/fix the name
+		name = notxml && jQuery.props[ name ] || name;
+
+		// Only do all the following if this is a node (faster for style)
+		if ( elem.nodeType === 1 ) {
+			// These attributes require special treatment
+			var special = rspecialurl.test( name );
+
+			// Safari mis-reports the default selected property of an option
+			// Accessing the parent's selectedIndex property fixes it
+			if ( name === "selected" && !jQuery.support.optSelected ) {
+				var parent = elem.parentNode;
+				if ( parent ) {
+					parent.selectedIndex;
+	
+					// Make sure that it also works with optgroups, see #5701
+					if ( parent.parentNode ) {
+						parent.parentNode.selectedIndex;
+					}
+				}
+			}
+
+			// If applicable, access the attribute via the DOM 0 way
+			// 'in' checks fail in Blackberry 4.7 #6931
+			if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
+				if ( set ) {
+					// We can't allow the type property to be changed (since it causes problems in IE)
+					if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
+						jQuery.error( "type property can't be changed" );
+					}
+
+					if ( value === null ) {
+						if ( elem.nodeType === 1 ) {
+							elem.removeAttribute( name );
+						}
+
+					} else {
+						elem[ name ] = value;
+					}
+				}
+
+				// browsers index elements by id/name on forms, give priority to attributes.
+				if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
+					return elem.getAttributeNode( name ).nodeValue;
+				}
+
+				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+				if ( name === "tabIndex" ) {
+					var attributeNode = elem.getAttributeNode( "tabIndex" );
+
+					return attributeNode && attributeNode.specified ?
+						attributeNode.value :
+						rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+							0 :
+							undefined;
+				}
+
+				return elem[ name ];
+			}
+
+			if ( !jQuery.support.style && notxml && name === "style" ) {
+				if ( set ) {
+					elem.style.cssText = "" + value;
+				}
+
+				return elem.style.cssText;
+			}
+
+			if ( set ) {
+				// convert the value to a string (all browsers do this but IE) see #1070
+				elem.setAttribute( name, "" + value );
+			}
+
+			// Ensure that missing attributes return undefined
+			// Blackberry 4.7 returns "" from getAttribute #6938
+			if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
+				return undefined;
+			}
+
+			var attr = !jQuery.support.hrefNormalized && notxml && special ?
+					// Some attributes require a special call on IE
+					elem.getAttribute( name, 2 ) :
+					elem.getAttribute( name );
+
+			// Non-existent attributes return null, we normalize to undefined
+			return attr === null ? undefined : attr;
+		}
+	}
+});
+
+
+
+
+var rnamespaces = /\.(.*)$/,
+	rformElems = /^(?:textarea|input|select)$/i,
+	rperiod = /\./g,
+	rspace = / /g,
+	rescape = /[^\w\s.|`]/g,
+	fcleanup = function( nm ) {
+		return nm.replace(rescape, "\\$&");
+	},
+	focusCounts = { focusin: 0, focusout: 0 };
+
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+	// Bind an event to an element
+	// Original by Dean Edwards
+	add: function( elem, types, handler, data ) {
+		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return;
+		}
+
+		// For whatever reason, IE has trouble passing the window object
+		// around, causing it to be cloned in the process
+		if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) {
+			elem = window;
+		}
+
+		if ( handler === false ) {
+			handler = returnFalse;
+		}
+
+		var handleObjIn, handleObj;
+
+		if ( handler.handler ) {
+			handleObjIn = handler;
+			handler = handleObjIn.handler;
+		}
+
+		// Make sure that the function being executed has a unique ID
+		if ( !handler.guid ) {
+			handler.guid = jQuery.guid++;
+		}
+
+		// Init the element's event structure
+		var elemData = jQuery.data( elem );
+
+		// If no elemData is found then we must be trying to bind to one of the
+		// banned noData elements
+		if ( !elemData ) {
+			return;
+		}
+
+		// Use a key less likely to result in collisions for plain JS objects.
+		// Fixes bug #7150.
+		var eventKey = elem.nodeType ? "events" : "__events__",
+			events = elemData[ eventKey ],
+			eventHandle = elemData.handle;
+			
+		if ( typeof events === "function" ) {
+			// On plain objects events is a fn that holds the the data
+			// which prevents this data from being JSON serialized
+			// the function does not need to be called, it just contains the data
+			eventHandle = events.handle;
+			events = events.events;
+
+		} else if ( !events ) {
+			if ( !elem.nodeType ) {
+				// On plain objects, create a fn that acts as the holder
+				// of the values to avoid JSON serialization of event data
+				elemData[ eventKey ] = elemData = function(){};
+			}
+
+			elemData.events = events = {};
+		}
+
+		if ( !eventHandle ) {
+			elemData.handle = eventHandle = function() {
+				// Handle the second event of a trigger and when
+				// an event is called after a page has unloaded
+				return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+					jQuery.event.handle.apply( eventHandle.elem, arguments ) :
+					undefined;
+			};
+		}
+
+		// Add elem as a property of the handle function
+		// This is to prevent a memory leak with non-native events in IE.
+		eventHandle.elem = elem;
+
+		// Handle multiple events separated by a space
+		// jQuery(...).bind("mouseover mouseout", fn);
+		types = types.split(" ");
+
+		var type, i = 0, namespaces;
+
+		while ( (type = types[ i++ ]) ) {
+			handleObj = handleObjIn ?
+				jQuery.extend({}, handleObjIn) :
+				{ handler: handler, data: data };
+
+			// Namespaced event handlers
+			if ( type.indexOf(".") > -1 ) {
+				namespaces = type.split(".");
+				type = namespaces.shift();
+				handleObj.namespace = namespaces.slice(0).sort().join(".");
+
+			} else {
+				namespaces = [];
+				handleObj.namespace = "";
+			}
+
+			handleObj.type = type;
+			if ( !handleObj.guid ) {
+				handleObj.guid = handler.guid;
+			}
+
+			// Get the current list of functions bound to this event
+			var handlers = events[ type ],
+				special = jQuery.event.special[ type ] || {};
+
+			// Init the event handler queue
+			if ( !handlers ) {
+				handlers = events[ type ] = [];
+
+				// Check for a special event handler
+				// Only use addEventListener/attachEvent if the special
+				// events handler returns false
+				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+					// Bind the global event handler to the element
+					if ( elem.addEventListener ) {
+						elem.addEventListener( type, eventHandle, false );
+
+					} else if ( elem.attachEvent ) {
+						elem.attachEvent( "on" + type, eventHandle );
+					}
+				}
+			}
+			
+			if ( special.add ) { 
+				special.add.call( elem, handleObj ); 
+
+				if ( !handleObj.handler.guid ) {
+					handleObj.handler.guid = handler.guid;
+				}
+			}
+
+			// Add the function to the element's handler list
+			handlers.push( handleObj );
+
+			// Keep track of which events have been used, for global triggering
+			jQuery.event.global[ type ] = true;
+		}
+
+		// Nullify elem to prevent memory leaks in IE
+		elem = null;
+	},
+
+	global: {},
+
+	// Detach an event or set of events from an element
+	remove: function( elem, types, handler, pos ) {
+		// don't do events on text and comment nodes
+		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return;
+		}
+
+		if ( handler === false ) {
+			handler = returnFalse;
+		}
+
+		var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
+			eventKey = elem.nodeType ? "events" : "__events__",
+			elemData = jQuery.data( elem ),
+			events = elemData && elemData[ eventKey ];
+
+		if ( !elemData || !events ) {
+			return;
+		}
+		
+		if ( typeof events === "function" ) {
+			elemData = events;
+			events = events.events;
+		}
+
+		// types is actually an event object here
+		if ( types && types.type ) {
+			handler = types.handler;
+			types = types.type;
+		}
+
+		// Unbind all events for the element
+		if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
+			types = types || "";
+
+			for ( type in events ) {
+				jQuery.event.remove( elem, type + types );
+			}
+
+			return;
+		}
+
+		// Handle multiple events separated by a space
+		// jQuery(...).unbind("mouseover mouseout", fn);
+		types = types.split(" ");
+
+		while ( (type = types[ i++ ]) ) {
+			origType = type;
+			handleObj = null;
+			all = type.indexOf(".") < 0;
+			namespaces = [];
+
+			if ( !all ) {
+				// Namespaced event handlers
+				namespaces = type.split(".");
+				type = namespaces.shift();
+
+				namespace = new RegExp("(^|\\.)" + 
+					jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
+			}
+
+			eventType = events[ type ];
+
+			if ( !eventType ) {
+				continue;
+			}
+
+			if ( !handler ) {
+				for ( j = 0; j < eventType.length; j++ ) {
+					handleObj = eventType[ j ];
+
+					if ( all || namespace.test( handleObj.namespace ) ) {
+						jQuery.event.remove( elem, origType, handleObj.handler, j );
+						eventType.splice( j--, 1 );
+					}
+				}
+
+				continue;
+			}
+
+			special = jQuery.event.special[ type ] || {};
+
+			for ( j = pos || 0; j < eventType.length; j++ ) {
+				handleObj = eventType[ j ];
+
+				if ( handler.guid === handleObj.guid ) {
+					// remove the given handler for the given type
+					if ( all || namespace.test( handleObj.namespace ) ) {
+						if ( pos == null ) {
+							eventType.splice( j--, 1 );
+						}
+
+						if ( special.remove ) {
+							special.remove.call( elem, handleObj );
+						}
+					}
+
+					if ( pos != null ) {
+						break;
+					}
+				}
+			}
+
+			// remove generic event handler if no more handlers exist
+			if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
+				if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
+					jQuery.removeEvent( elem, type, elemData.handle );
+				}
+
+				ret = null;
+				delete events[ type ];
+			}
+		}
+
+		// Remove the expando if it's no longer used
+		if ( jQuery.isEmptyObject( events ) ) {
+			var handle = elemData.handle;
+			if ( handle ) {
+				handle.elem = null;
+			}
+
+			delete elemData.events;
+			delete elemData.handle;
+
+			if ( typeof elemData === "function" ) {
+				jQuery.removeData( elem, eventKey );
+
+			} else if ( jQuery.isEmptyObject( elemData ) ) {
+				jQuery.removeData( elem );
+			}
+		}
+	},
+
+	// bubbling is internal
+	trigger: function( event, data, elem /*, bubbling */ ) {
+		// Event object or event type
+		var type = event.type || event,
+			bubbling = arguments[3];
+
+		if ( !bubbling ) {
+			event = typeof event === "object" ?
+				// jQuery.Event object
+				event[ jQuery.expando ] ? event :
+				// Object literal
+				jQuery.extend( jQuery.Event(type), event ) :
+				// Just the event type (string)
+				jQuery.Event(type);
+
+			if ( type.indexOf("!") >= 0 ) {
+				event.type = type = type.slice(0, -1);
+				event.exclusive = true;
+			}
+
+			// Handle a global trigger
+			if ( !elem ) {
+				// Don't bubble custom events when global (to avoid too much overhead)
+				event.stopPropagation();
+
+				// Only trigger if we've ever bound an event for it
+				if ( jQuery.event.global[ type ] ) {
+					jQuery.each( jQuery.cache, function() {
+						if ( this.events && this.events[type] ) {
+							jQuery.event.trigger( event, data, this.handle.elem );
+						}
+					});
+				}
+			}
+
+			// Handle triggering a single element
+
+			// don't do events on text and comment nodes
+			if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+				return undefined;
+			}
+
+			// Clean up in case it is reused
+			event.result = undefined;
+			event.target = elem;
+
+			// Clone the incoming data, if any
+			data = jQuery.makeArray( data );
+			data.unshift( event );
+		}
+
+		event.currentTarget = elem;
+
+		// Trigger the event, it is assumed that "handle" is a function
+		var handle = elem.nodeType ?
+			jQuery.data( elem, "handle" ) :
+			(jQuery.data( elem, "__events__" ) || {}).handle;
+
+		if ( handle ) {
+			handle.apply( elem, data );
+		}
+
+		var parent = elem.parentNode || elem.ownerDocument;
+
+		// Trigger an inline bound script
+		try {
+			if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
+				if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
+					event.result = false;
+					event.preventDefault();
+				}
+			}
+
+		// prevent IE from throwing an error for some elements with some event types, see #3533
+		} catch (inlineError) {}
+
+		if ( !event.isPropagationStopped() && parent ) {
+			jQuery.event.trigger( event, data, parent, true );
+
+		} else if ( !event.isDefaultPrevented() ) {
+			var target = event.target, old, targetType = type.replace(rnamespaces, ""),
+				isClick = jQuery.nodeName(target, "a") && targetType === "click",
+				special = jQuery.event.special[ targetType ] || {};
+
+			if ( (!special._default || special._default.call( elem, event ) === false) && 
+				!isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
+
+				try {
+					if ( target[ targetType ] ) {
+						// Make sure that we don't accidentally re-trigger the onFOO events
+						old = target[ "on" + targetType ];
+
+						if ( old ) {
+							target[ "on" + targetType ] = null;
+						}
+
+						jQuery.event.triggered = true;
+						target[ targetType ]();
+					}
+
+				// prevent IE from throwing an error for some elements with some event types, see #3533
+				} catch (triggerError) {}
+
+				if ( old ) {
+					target[ "on" + targetType ] = old;
+				}
+
+				jQuery.event.triggered = false;
+			}
+		}
+	},
+
+	handle: function( event ) {
+		var all, handlers, namespaces, namespace_sort = [], namespace_re, events, args = jQuery.makeArray( arguments );
+
+		event = args[0] = jQuery.event.fix( event || window.event );
+		event.currentTarget = this;
+
+		// Namespaced event handlers
+		all = event.type.indexOf(".") < 0 && !event.exclusive;
+
+		if ( !all ) {
+			namespaces = event.type.split(".");
+			event.type = namespaces.shift();
+			namespace_sort = namespaces.slice(0).sort();
+			namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
+		}
+
+		event.namespace = event.namespace || namespace_sort.join(".");
+
+		events = jQuery.data(this, this.nodeType ? "events" : "__events__");
+
+		if ( typeof events === "function" ) {
+			events = events.events;
+		}
+
+		handlers = (events || {})[ event.type ];
+
+		if ( events && handlers ) {
+			// Clone the handlers to prevent manipulation
+			handlers = handlers.slice(0);
+
+			for ( var j = 0, l = handlers.length; j < l; j++ ) {
+				var handleObj = handlers[ j ];
+
+				// Filter the functions by class
+				if ( all || namespace_re.test( handleObj.namespace ) ) {
+					// Pass in a reference to the handler function itself
+					// So that we can later remove it
+					event.handler = handleObj.handler;
+					event.data = handleObj.data;
+					event.handleObj = handleObj;
+	
+					var ret = handleObj.handler.apply( this, args );
+
+					if ( ret !== undefined ) {
+						event.result = ret;
+						if ( ret === false ) {
+							event.preventDefault();
+							event.stopPropagation();
+						}
+					}
+
+					if ( event.isImmediatePropagationStopped() ) {
+						break;
+					}
+				}
+			}
+		}
+
+		return event.result;
+	},
+
+	props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+	fix: function( event ) {
+		if ( event[ jQuery.expando ] ) {
+			return event;
+		}
+
+		// store a copy of the original event object
+		// and "clone" to set read-only properties
+		var originalEvent = event;
+		event = jQuery.Event( originalEvent );
+
+		for ( var i = this.props.length, prop; i; ) {
+			prop = this.props[ --i ];
+			event[ prop ] = originalEvent[ prop ];
+		}
+
+		// Fix target property, if necessary
+		if ( !event.target ) {
+			event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
+		}
+
+		// check if target is a textnode (safari)
+		if ( event.target.nodeType === 3 ) {
+			event.target = event.target.parentNode;
+		}
+
+		// Add relatedTarget, if necessary
+		if ( !event.relatedTarget && event.fromElement ) {
+			event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
+		}
+
+		// Calculate pageX/Y if missing and clientX/Y available
+		if ( event.pageX == null && event.clientX != null ) {
+			var doc = document.documentElement, body = document.body;
+			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
+			event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
+		}
+
+		// Add which for key events
+		if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
+			event.which = event.charCode != null ? event.charCode : event.keyCode;
+		}
+
+		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+		if ( !event.metaKey && event.ctrlKey ) {
+			event.metaKey = event.ctrlKey;
+		}
+
+		// Add which for click: 1 === left; 2 === middle; 3 === right
+		// Note: button is not normalized, so don't use it
+		if ( !event.which && event.button !== undefined ) {
+			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+		}
+
+		return event;
+	},
+
+	// Deprecated, use jQuery.guid instead
+	guid: 1E8,
+
+	// Deprecated, use jQuery.proxy instead
+	proxy: jQuery.proxy,
+
+	special: {
+		ready: {
+			// Make sure the ready event is setup
+			setup: jQuery.bindReady,
+			teardown: jQuery.noop
+		},
+
+		live: {
+			add: function( handleObj ) {
+				jQuery.event.add( this,
+					liveConvert( handleObj.origType, handleObj.selector ),
+					jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) ); 
+			},
+
+			remove: function( handleObj ) {
+				jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
+			}
+		},
+
+		beforeunload: {
+			setup: function( data, namespaces, eventHandle ) {
+				// We only want to do this special case on windows
+				if ( jQuery.isWindow( this ) ) {
+					this.onbeforeunload = eventHandle;
+				}
+			},
+
+			teardown: function( namespaces, eventHandle ) {
+				if ( this.onbeforeunload === eventHandle ) {
+					this.onbeforeunload = null;
+				}
+			}
+		}
+	}
+};
+
+jQuery.removeEvent = document.removeEventListener ?
+	function( elem, type, handle ) {
+		if ( elem.removeEventListener ) {
+			elem.removeEventListener( type, handle, false );
+		}
+	} : 
+	function( elem, type, handle ) {
+		if ( elem.detachEvent ) {
+			elem.detachEvent( "on" + type, handle );
+		}
+	};
+
+jQuery.Event = function( src ) {
+	// Allow instantiation without the 'new' keyword
+	if ( !this.preventDefault ) {
+		return new jQuery.Event( src );
+	}
+
+	// Event object
+	if ( src && src.type ) {
+		this.originalEvent = src;
+		this.type = src.type;
+	// Event type
+	} else {
+		this.type = src;
+	}
+
+	// timeStamp is buggy for some events on Firefox(#3843)
+	// So we won't rely on the native value
+	this.timeStamp = jQuery.now();
+
+	// Mark it as fixed
+	this[ jQuery.expando ] = true;
+};
+
+function returnFalse() {
+	return false;
+}
+function returnTrue() {
+	return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+	preventDefault: function() {
+		this.isDefaultPrevented = returnTrue;
+
+		var e = this.originalEvent;
+		if ( !e ) {
+			return;
+		}
+		
+		// if preventDefault exists run it on the original event
+		if ( e.preventDefault ) {
+			e.preventDefault();
+
+		// otherwise set the returnValue property of the original event to false (IE)
+		} else {
+			e.returnValue = false;
+		}
+	},
+	stopPropagation: function() {
+		this.isPropagationStopped = returnTrue;
+
+		var e = this.originalEvent;
+		if ( !e ) {
+			return;
+		}
+		// if stopPropagation exists run it on the original event
+		if ( e.stopPropagation ) {
+			e.stopPropagation();
+		}
+		// otherwise set the cancelBubble property of the original event to true (IE)
+		e.cancelBubble = true;
+	},
+	stopImmediatePropagation: function() {
+		this.isImmediatePropagationStopped = returnTrue;
+		this.stopPropagation();
+	},
+	isDefaultPrevented: returnFalse,
+	isPropagationStopped: returnFalse,
+	isImmediatePropagationStopped: returnFalse
+};
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function( event ) {
+	// Check if mouse(over|out) are still within the same parent element
+	var parent = event.relatedTarget;
+
+	// Firefox sometimes assigns relatedTarget a XUL element
+	// which we cannot access the parentNode property of
+	try {
+		// Traverse up the tree
+		while ( parent && parent !== this ) {
+			parent = parent.parentNode;
+		}
+
+		if ( parent !== this ) {
+			// set the correct event type
+			event.type = event.data;
+
+			// handle event if we actually just moused on to a non sub-element
+			jQuery.event.handle.apply( this, arguments );
+		}
+
+	// assuming we've left the element since we most likely mousedover a xul element
+	} catch(e) { }
+},
+
+// In case of event delegation, we only need to rename the event.type,
+// liveHandler will take care of the rest.
+delegate = function( event ) {
+	event.type = event.data;
+	jQuery.event.handle.apply( this, arguments );
+};
+
+// Create mouseenter and mouseleave events
+jQuery.each({
+	mouseenter: "mouseover",
+	mouseleave: "mouseout"
+}, function( orig, fix ) {
+	jQuery.event.special[ orig ] = {
+		setup: function( data ) {
+			jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
+		},
+		teardown: function( data ) {
+			jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
+		}
+	};
+});
+
+// submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+	jQuery.event.special.submit = {
+		setup: function( data, namespaces ) {
+			if ( this.nodeName.toLowerCase() !== "form" ) {
+				jQuery.event.add(this, "click.specialSubmit", function( e ) {
+					var elem = e.target, type = elem.type;
+
+					if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
+						e.liveFired = undefined;
+						return trigger( "submit", this, arguments );
+					}
+				});
+	 
+				jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
+					var elem = e.target, type = elem.type;
+
+					if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
+						e.liveFired = undefined;
+						return trigger( "submit", this, arguments );
+					}
+				});
+
+			} else {
+				return false;
+			}
+		},
+
+		teardown: function( namespaces ) {
+			jQuery.event.remove( this, ".specialSubmit" );
+		}
+	};
+
+}
+
+// change delegation, happens here so we have bind.
+if ( !jQuery.support.changeBubbles ) {
+
+	var changeFilters,
+
+	getVal = function( elem ) {
+		var type = elem.type, val = elem.value;
+
+		if ( type === "radio" || type === "checkbox" ) {
+			val = elem.checked;
+
+		} else if ( type === "select-multiple" ) {
+			val = elem.selectedIndex > -1 ?
+				jQuery.map( elem.options, function( elem ) {
+					return elem.selected;
+				}).join("-") :
+				"";
+
+		} else if ( elem.nodeName.toLowerCase() === "select" ) {
+			val = elem.selectedIndex;
+		}
+
+		return val;
+	},
+
+	testChange = function testChange( e ) {
+		var elem = e.target, data, val;
+
+		if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
+			return;
+		}
+
+		data = jQuery.data( elem, "_change_data" );
+		val = getVal(elem);
+
+		// the current data will be also retrieved by beforeactivate
+		if ( e.type !== "focusout" || elem.type !== "radio" ) {
+			jQuery.data( elem, "_change_data", val );
+		}
+		
+		if ( data === undefined || val === data ) {
+			return;
+		}
+
+		if ( data != null || val ) {
+			e.type = "change";
+			e.liveFired = undefined;
+			return jQuery.event.trigger( e, arguments[1], elem );
+		}
+	};
+
+	jQuery.event.special.change = {
+		filters: {
+			focusout: testChange, 
+
+			beforedeactivate: testChange,
+
+			click: function( e ) {
+				var elem = e.target, type = elem.type;
+
+				if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
+					return testChange.call( this, e );
+				}
+			},
+
+			// Change has to be called before submit
+			// Keydown will be called before keypress, which is used in submit-event delegation
+			keydown: function( e ) {
+				var elem = e.target, type = elem.type;
+
+				if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
+					(e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
+					type === "select-multiple" ) {
+					return testChange.call( this, e );
+				}
+			},
+
+			// Beforeactivate happens also before the previous element is blurred
+			// with this event you can't trigger a change event, but you can store
+			// information
+			beforeactivate: function( e ) {
+				var elem = e.target;
+				jQuery.data( elem, "_change_data", getVal(elem) );
+			}
+		},
+
+		setup: function( data, namespaces ) {
+			if ( this.type === "file" ) {
+				return false;
+			}
+
+			for ( var type in changeFilters ) {
+				jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
+			}
+
+			return rformElems.test( this.nodeName );
+		},
+
+		teardown: function( namespaces ) {
+			jQuery.event.remove( this, ".specialChange" );
+
+			return rformElems.test( this.nodeName );
+		}
+	};
+
+	changeFilters = jQuery.event.special.change.filters;
+
+	// Handle when the input is .focus()'d
+	changeFilters.focus = changeFilters.beforeactivate;
+}
+
+function trigger( type, elem, args ) {
+	args[0].type = type;
+	return jQuery.event.handle.apply( elem, args );
+}
+
+// Create "bubbling" focus and blur events
+if ( document.addEventListener ) {
+	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+		jQuery.event.special[ fix ] = {
+			setup: function() {
+				if ( focusCounts[fix]++ === 0 ) {
+					document.addEventListener( orig, handler, true );
+				}
+			}, 
+			teardown: function() { 
+				if ( --focusCounts[fix] === 0 ) {
+					document.removeEventListener( orig, handler, true );
+				}
+			}
+		};
+
+		function handler( e ) { 
+			e = jQuery.event.fix( e );
+			e.type = fix;
+			return jQuery.event.trigger( e, null, e.target );
+		}
+	});
+}
+
+jQuery.each(["bind", "one"], function( i, name ) {
+	jQuery.fn[ name ] = function( type, data, fn ) {
+		// Handle object literals
+		if ( typeof type === "object" ) {
+			for ( var key in type ) {
+				this[ name ](key, data, type[key], fn);
+			}
+			return this;
+		}
+		
+		if ( jQuery.isFunction( data ) || data === false ) {
+			fn = data;
+			data = undefined;
+		}
+
+		var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
+			jQuery( this ).unbind( event, handler );
+			return fn.apply( this, arguments );
+		}) : fn;
+
+		if ( type === "unload" && name !== "one" ) {
+			this.one( type, data, fn );
+
+		} else {
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				jQuery.event.add( this[i], type, handler, data );
+			}
+		}
+
+		return this;
+	};
+});
+
+jQuery.fn.extend({
+	unbind: function( type, fn ) {
+		// Handle object literals
+		if ( typeof type === "object" && !type.preventDefault ) {
+			for ( var key in type ) {
+				this.unbind(key, type[key]);
+			}
+
+		} else {
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				jQuery.event.remove( this[i], type, fn );
+			}
+		}
+
+		return this;
+	},
+	
+	delegate: function( selector, types, data, fn ) {
+		return this.live( types, data, fn, selector );
+	},
+	
+	undelegate: function( selector, types, fn ) {
+		if ( arguments.length === 0 ) {
+				return this.unbind( "live" );
+		
+		} else {
+			return this.die( types, null, fn, selector );
+		}
+	},
+	
+	trigger: function( type, data ) {
+		return this.each(function() {
+			jQuery.event.trigger( type, data, this );
+		});
+	},
+
+	triggerHandler: function( type, data ) {
+		if ( this[0] ) {
+			var event = jQuery.Event( type );
+			event.preventDefault();
+			event.stopPropagation();
+			jQuery.event.trigger( event, data, this[0] );
+			return event.result;
+		}
+	},
+
+	toggle: function( fn ) {
+		// Save reference to arguments for access in closure
+		var args = arguments, i = 1;
+
+		// link all the functions, so any of them can unbind this click handler
+		while ( i < args.length ) {
+			jQuery.proxy( fn, args[ i++ ] );
+		}
+
+		return this.click( jQuery.proxy( fn, function( event ) {
+			// Figure out which function to execute
+			var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+			jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+			// Make sure that clicks stop
+			event.preventDefault();
+
+			// and execute the function
+			return args[ lastToggle ].apply( this, arguments ) || false;
+		}));
+	},
+
+	hover: function( fnOver, fnOut ) {
+		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+	}
+});
+
+var liveMap = {
+	focus: "focusin",
+	blur: "focusout",
+	mouseenter: "mouseover",
+	mouseleave: "mouseout"
+};
+
+jQuery.each(["live", "die"], function( i, name ) {
+	jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
+		var type, i = 0, match, namespaces, preType,
+			selector = origSelector || this.selector,
+			context = origSelector ? this : jQuery( this.context );
+		
+		if ( typeof types === "object" && !types.preventDefault ) {
+			for ( var key in types ) {
+				context[ name ]( key, data, types[key], selector );
+			}
+			
+			return this;
+		}
+
+		if ( jQuery.isFunction( data ) ) {
+			fn = data;
+			data = undefined;
+		}
+
+		types = (types || "").split(" ");
+
+		while ( (type = types[ i++ ]) != null ) {
+			match = rnamespaces.exec( type );
+			namespaces = "";
+
+			if ( match )  {
+				namespaces = match[0];
+				type = type.replace( rnamespaces, "" );
+			}
+
+			if ( type === "hover" ) {
+				types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
+				continue;
+			}
+
+			preType = type;
+
+			if ( type === "focus" || type === "blur" ) {
+				types.push( liveMap[ type ] + namespaces );
+				type = type + namespaces;
+
+			} else {
+				type = (liveMap[ type ] || type) + namespaces;
+			}
+
+			if ( name === "live" ) {
+				// bind live handler
+				for ( var j = 0, l = context.length; j < l; j++ ) {
+					jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
+						{ data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
+				}
+
+			} else {
+				// unbind live handler
+				context.unbind( "live." + liveConvert( type, selector ), fn );
+			}
+		}
+		
+		return this;
+	};
+});
+
+function liveHandler( event ) {
+	var stop, maxLevel, elems = [], selectors = [],
+		related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
+		events = jQuery.data( this, this.nodeType ? "events" : "__events__" );
+
+	if ( typeof events === "function" ) {
+		events = events.events;
+	}
+
+	// Make sure we avoid non-left-click bubbling in Firefox (#3861)
+	if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
+		return;
+	}
+
+	if ( event.namespace ) {
+		namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
+	}
+
+	event.liveFired = this;
+
+	var live = events.live.slice(0);
+
+	for ( j = 0; j < live.length; j++ ) {
+		handleObj = live[j];
+
+		if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
+			selectors.push( handleObj.selector );
+
+		} else {
+			live.splice( j--, 1 );
+		}
+	}
+
+	match = jQuery( event.target ).closest( selectors, event.currentTarget );
+
+	for ( i = 0, l = match.length; i < l; i++ ) {
+		close = match[i];
+
+		for ( j = 0; j < live.length; j++ ) {
+			handleObj = live[j];
+
+			if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) {
+				elem = close.elem;
+				related = null;
+
+				// Those two events require additional checking
+				if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
+					event.type = handleObj.preType;
+					related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
+				}
+
+				if ( !related || related !== elem ) {
+					elems.push({ elem: elem, handleObj: handleObj, level: close.level });
+				}
+			}
+		}
+	}
+
+	for ( i = 0, l = elems.length; i < l; i++ ) {
+		match = elems[i];
+
+		if ( maxLevel && match.level > maxLevel ) {
+			break;
+		}
+
+		event.currentTarget = match.elem;
+		event.data = match.handleObj.data;
+		event.handleObj = match.handleObj;
+
+		ret = match.handleObj.origHandler.apply( match.elem, arguments );
+
+		if ( ret === false || event.isPropagationStopped() ) {
+			maxLevel = match.level;
+
+			if ( ret === false ) {
+				stop = false;
+			}
+		}
+	}
+
+	return stop;
+}
+
+function liveConvert( type, selector ) {
+	return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&");
+}
+
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+	"change select submit keydown keypress keyup error").split(" "), function( i, name ) {
+
+	// Handle event binding
+	jQuery.fn[ name ] = function( data, fn ) {
+		if ( fn == null ) {
+			fn = data;
+			data = null;
+		}
+
+		return arguments.length > 0 ?
+			this.bind( name, data, fn ) :
+			this.trigger( name );
+	};
+
+	if ( jQuery.attrFn ) {
+		jQuery.attrFn[ name ] = true;
+	}
+});
+
+// Prevent memory leaks in IE
+// Window isn't included so as not to unbind existing unload events
+// More info:
+//  - http://isaacschlueter.com/2006/10/msie-memory-leaks/
+if ( window.attachEvent && !window.addEventListener ) {
+	jQuery(window).bind("unload", function() {
+		for ( var id in jQuery.cache ) {
+			if ( jQuery.cache[ id ].handle ) {
+				// Try/Catch is to handle iframes being unloaded, see #4280
+				try {
+					jQuery.event.remove( jQuery.cache[ id ].handle.elem );
+				} catch(e) {}
+			}
+		}
+	});
+}
+
+
+/*!
+ * Sizzle CSS Selector Engine - v1.0
+ *  Copyright 2009, The Dojo Foundation
+ *  Released under the MIT, BSD, and GPL Licenses.
+ *  More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+	done = 0,
+	toString = Object.prototype.toString,
+	hasDuplicate = false,
+	baseHasDuplicate = true;
+
+// Here we check if the JavaScript engine is using some sort of
+// optimization where it does not always call our comparision
+// function. If that is the case, discard the hasDuplicate value.
+//   Thus far that includes Google Chrome.
+[0, 0].sort(function(){
+	baseHasDuplicate = false;
+	return 0;
+});
+
+var Sizzle = function(selector, context, results, seed) {
+	results = results || [];
+	context = context || document;
+
+	var origContext = context;
+
+	if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+		return [];
+	}
+	
+	if ( !selector || typeof selector !== "string" ) {
+		return results;
+	}
+
+	var parts = [], m, set, checkSet, extra, prune = true, contextXML = Sizzle.isXML(context),
+		soFar = selector, ret, cur, pop, i;
+	
+	// Reset the position of the chunker regexp (start from head)
+	do {
+		chunker.exec("");
+		m = chunker.exec(soFar);
+
+		if ( m ) {
+			soFar = m[3];
+		
+			parts.push( m[1] );
+		
+			if ( m[2] ) {
+				extra = m[3];
+				break;
+			}
+		}
+	} while ( m );
+
+	if ( parts.length > 1 && origPOS.exec( selector ) ) {
+		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+			set = posProcess( parts[0] + parts[1], context );
+		} else {
+			set = Expr.relative[ parts[0] ] ?
+				[ context ] :
+				Sizzle( parts.shift(), context );
+
+			while ( parts.length ) {
+				selector = parts.shift();
+
+				if ( Expr.relative[ selector ] ) {
+					selector += parts.shift();
+				}
+				
+				set = posProcess( selector, set );
+			}
+		}
+	} else {
+		// Take a shortcut and set the context if the root selector is an ID
+		// (but not if it'll be faster if the inner selector is an ID)
+		if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+				Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+			ret = Sizzle.find( parts.shift(), context, contextXML );
+			context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
+		}
+
+		if ( context ) {
+			ret = seed ?
+				{ expr: parts.pop(), set: makeArray(seed) } :
+				Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+			set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
+
+			if ( parts.length > 0 ) {
+				checkSet = makeArray(set);
+			} else {
+				prune = false;
+			}
+
+			while ( parts.length ) {
+				cur = parts.pop();
+				pop = cur;
+
+				if ( !Expr.relative[ cur ] ) {
+					cur = "";
+				} else {
+					pop = parts.pop();
+				}
+
+				if ( pop == null ) {
+					pop = context;
+				}
+
+				Expr.relative[ cur ]( checkSet, pop, contextXML );
+			}
+		} else {
+			checkSet = parts = [];
+		}
+	}
+
+	if ( !checkSet ) {
+		checkSet = set;
+	}
+
+	if ( !checkSet ) {
+		Sizzle.error( cur || selector );
+	}
+
+	if ( toString.call(checkSet) === "[object Array]" ) {
+		if ( !prune ) {
+			results.push.apply( results, checkSet );
+		} else if ( context && context.nodeType === 1 ) {
+			for ( i = 0; checkSet[i] != null; i++ ) {
+				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
+					results.push( set[i] );
+				}
+			}
+		} else {
+			for ( i = 0; checkSet[i] != null; i++ ) {
+				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+					results.push( set[i] );
+				}
+			}
+		}
+	} else {
+		makeArray( checkSet, results );
+	}
+
+	if ( extra ) {
+		Sizzle( extra, origContext, results, seed );
+		Sizzle.uniqueSort( results );
+	}
+
+	return results;
+};
+
+Sizzle.uniqueSort = function(results){
+	if ( sortOrder ) {
+		hasDuplicate = baseHasDuplicate;
+		results.sort(sortOrder);
+
+		if ( hasDuplicate ) {
+			for ( var i = 1; i < results.length; i++ ) {
+				if ( results[i] === results[i-1] ) {
+					results.splice(i--, 1);
+				}
+			}
+		}
+	}
+
+	return results;
+};
+
+Sizzle.matches = function(expr, set){
+	return Sizzle(expr, null, null, set);
+};
+
+Sizzle.matchesSelector = function(node, expr){
+	return Sizzle(expr, null, null, [node]).length > 0;
+};
+
+Sizzle.find = function(expr, context, isXML){
+	var set;
+
+	if ( !expr ) {
+		return [];
+	}
+
+	for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+		var type = Expr.order[i], match;
+		
+		if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+			var left = match[1];
+			match.splice(1,1);
+
+			if ( left.substr( left.length - 1 ) !== "\\" ) {
+				match[1] = (match[1] || "").replace(/\\/g, "");
+				set = Expr.find[ type ]( match, context, isXML );
+				if ( set != null ) {
+					expr = expr.replace( Expr.match[ type ], "" );
+					break;
+				}
+			}
+		}
+	}
+
+	if ( !set ) {
+		set = context.getElementsByTagName("*");
+	}
+
+	return {set: set, expr: expr};
+};
+
+Sizzle.filter = function(expr, set, inplace, not){
+	var old = expr, result = [], curLoop = set, match, anyFound,
+		isXMLFilter = set && set[0] && Sizzle.isXML(set[0]);
+
+	while ( expr && set.length ) {
+		for ( var type in Expr.filter ) {
+			if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
+				var filter = Expr.filter[ type ], found, item, left = match[1];
+				anyFound = false;
+
+				match.splice(1,1);
+
+				if ( left.substr( left.length - 1 ) === "\\" ) {
+					continue;
+				}
+
+				if ( curLoop === result ) {
+					result = [];
+				}
+
+				if ( Expr.preFilter[ type ] ) {
+					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+					if ( !match ) {
+						anyFound = found = true;
+					} else if ( match === true ) {
+						continue;
+					}
+				}
+
+				if ( match ) {
+					for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+						if ( item ) {
+							found = filter( item, match, i, curLoop );
+							var pass = not ^ !!found;
+
+							if ( inplace && found != null ) {
+								if ( pass ) {
+									anyFound = true;
+								} else {
+									curLoop[i] = false;
+								}
+							} else if ( pass ) {
+								result.push( item );
+								anyFound = true;
+							}
+						}
+					}
+				}
+
+				if ( found !== undefined ) {
+					if ( !inplace ) {
+						curLoop = result;
+					}
+
+					expr = expr.replace( Expr.match[ type ], "" );
+
+					if ( !anyFound ) {
+						return [];
+					}
+
+					break;
+				}
+			}
+		}
+
+		// Improper expression
+		if ( expr === old ) {
+			if ( anyFound == null ) {
+				Sizzle.error( expr );
+			} else {
+				break;
+			}
+		}
+
+		old = expr;
+	}
+
+	return curLoop;
+};
+
+Sizzle.error = function( msg ) {
+	throw "Syntax error, unrecognized expression: " + msg;
+};
+
+var Expr = Sizzle.selectors = {
+	order: [ "ID", "NAME", "TAG" ],
+	match: {
+		ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+		CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
+		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+		TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
+		CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
+		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
+		PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
+	},
+	leftMatch: {},
+	attrMap: {
+		"class": "className",
+		"for": "htmlFor"
+	},
+	attrHandle: {
+		href: function(elem){
+			return elem.getAttribute("href");
+		}
+	},
+	relative: {
+		"+": function(checkSet, part){
+			var isPartStr = typeof part === "string",
+				isTag = isPartStr && !/\W/.test(part),
+				isPartStrNotTag = isPartStr && !isTag;
+
+			if ( isTag ) {
+				part = part.toLowerCase();
+			}
+
+			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+				if ( (elem = checkSet[i]) ) {
+					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+					checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
+						elem || false :
+						elem === part;
+				}
+			}
+
+			if ( isPartStrNotTag ) {
+				Sizzle.filter( part, checkSet, true );
+			}
+		},
+		">": function(checkSet, part){
+			var isPartStr = typeof part === "string",
+				elem, i = 0, l = checkSet.length;
+
+			if ( isPartStr && !/\W/.test(part) ) {
+				part = part.toLowerCase();
+
+				for ( ; i < l; i++ ) {
+					elem = checkSet[i];
+					if ( elem ) {
+						var parent = elem.parentNode;
+						checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
+					}
+				}
+			} else {
+				for ( ; i < l; i++ ) {
+					elem = checkSet[i];
+					if ( elem ) {
+						checkSet[i] = isPartStr ?
+							elem.parentNode :
+							elem.parentNode === part;
+					}
+				}
+
+				if ( isPartStr ) {
+					Sizzle.filter( part, checkSet, true );
+				}
+			}
+		},
+		"": function(checkSet, part, isXML){
+			var doneName = done++, checkFn = dirCheck, nodeCheck;
+
+			if ( typeof part === "string" && !/\W/.test(part) ) {
+				part = part.toLowerCase();
+				nodeCheck = part;
+				checkFn = dirNodeCheck;
+			}
+
+			checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
+		},
+		"~": function(checkSet, part, isXML){
+			var doneName = done++, checkFn = dirCheck, nodeCheck;
+
+			if ( typeof part === "string" && !/\W/.test(part) ) {
+				part = part.toLowerCase();
+				nodeCheck = part;
+				checkFn = dirNodeCheck;
+			}
+
+			checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
+		}
+	},
+	find: {
+		ID: function(match, context, isXML){
+			if ( typeof context.getElementById !== "undefined" && !isXML ) {
+				var m = context.getElementById(match[1]);
+				// Check parentNode to catch when Blackberry 4.6 returns
+				// nodes that are no longer in the document #6963
+				return m && m.parentNode ? [m] : [];
+			}
+		},
+		NAME: function(match, context){
+			if ( typeof context.getElementsByName !== "undefined" ) {
+				var ret = [], results = context.getElementsByName(match[1]);
+
+				for ( var i = 0, l = results.length; i < l; i++ ) {
+					if ( results[i].getAttribute("name") === match[1] ) {
+						ret.push( results[i] );
+					}
+				}
+
+				return ret.length === 0 ? null : ret;
+			}
+		},
+		TAG: function(match, context){
+			return context.getElementsByTagName(match[1]);
+		}
+	},
+	preFilter: {
+		CLASS: function(match, curLoop, inplace, result, not, isXML){
+			match = " " + match[1].replace(/\\/g, "") + " ";
+
+			if ( isXML ) {
+				return match;
+			}
+
+			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+				if ( elem ) {
+					if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
+						if ( !inplace ) {
+							result.push( elem );
+						}
+					} else if ( inplace ) {
+						curLoop[i] = false;
+					}
+				}
+			}
+
+			return false;
+		},
+		ID: function(match){
+			return match[1].replace(/\\/g, "");
+		},
+		TAG: function(match, curLoop){
+			return match[1].toLowerCase();
+		},
+		CHILD: function(match){
+			if ( match[1] === "nth" ) {
+				// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+				var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+					match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
+					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+				// calculate the numbers (first)n+(last) including if they are negative
+				match[2] = (test[1] + (test[2] || 1)) - 0;
+				match[3] = test[3] - 0;
+			}
+
+			// TODO: Move to normal caching system
+			match[0] = done++;
+
+			return match;
+		},
+		ATTR: function(match, curLoop, inplace, result, not, isXML){
+			var name = match[1].replace(/\\/g, "");
+			
+			if ( !isXML && Expr.attrMap[name] ) {
+				match[1] = Expr.attrMap[name];
+			}
+
+			if ( match[2] === "~=" ) {
+				match[4] = " " + match[4] + " ";
+			}
+
+			return match;
+		},
+		PSEUDO: function(match, curLoop, inplace, result, not){
+			if ( match[1] === "not" ) {
+				// If we're dealing with a complex expression, or a simple one
+				if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+					match[3] = Sizzle(match[3], null, null, curLoop);
+				} else {
+					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+					if ( !inplace ) {
+						result.push.apply( result, ret );
+					}
+					return false;
+				}
+			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+				return true;
+			}
+			
+			return match;
+		},
+		POS: function(match){
+			match.unshift( true );
+			return match;
+		}
+	},
+	filters: {
+		enabled: function(elem){
+			return elem.disabled === false && elem.type !== "hidden";
+		},
+		disabled: function(elem){
+			return elem.disabled === true;
+		},
+		checked: function(elem){
+			return elem.checked === true;
+		},
+		selected: function(elem){
+			// Accessing this property makes selected-by-default
+			// options in Safari work properly
+			elem.parentNode.selectedIndex;
+			return elem.selected === true;
+		},
+		parent: function(elem){
+			return !!elem.firstChild;
+		},
+		empty: function(elem){
+			return !elem.firstChild;
+		},
+		has: function(elem, i, match){
+			return !!Sizzle( match[3], elem ).length;
+		},
+		header: function(elem){
+			return (/h\d/i).test( elem.nodeName );
+		},
+		text: function(elem){
+			return "text" === elem.type;
+		},
+		radio: function(elem){
+			return "radio" === elem.type;
+		},
+		checkbox: function(elem){
+			return "checkbox" === elem.type;
+		},
+		file: function(elem){
+			return "file" === elem.type;
+		},
+		password: function(elem){
+			return "password" === elem.type;
+		},
+		submit: function(elem){
+			return "submit" === elem.type;
+		},
+		image: function(elem){
+			return "image" === elem.type;
+		},
+		reset: function(elem){
+			return "reset" === elem.type;
+		},
+		button: function(elem){
+			return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
+		},
+		input: function(elem){
+			return (/input|select|textarea|button/i).test(elem.nodeName);
+		}
+	},
+	setFilters: {
+		first: function(elem, i){
+			return i === 0;
+		},
+		last: function(elem, i, match, array){
+			return i === array.length - 1;
+		},
+		even: function(elem, i){
+			return i % 2 === 0;
+		},
+		odd: function(elem, i){
+			return i % 2 === 1;
+		},
+		lt: function(elem, i, match){
+			return i < match[3] - 0;
+		},
+		gt: function(elem, i, match){
+			return i > match[3] - 0;
+		},
+		nth: function(elem, i, match){
+			return match[3] - 0 === i;
+		},
+		eq: function(elem, i, match){
+			return match[3] - 0 === i;
+		}
+	},
+	filter: {
+		PSEUDO: function(elem, match, i, array){
+			var name = match[1], filter = Expr.filters[ name ];
+
+			if ( filter ) {
+				return filter( elem, i, match, array );
+			} else if ( name === "contains" ) {
+				return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
+			} else if ( name === "not" ) {
+				var not = match[3];
+
+				for ( var j = 0, l = not.length; j < l; j++ ) {
+					if ( not[j] === elem ) {
+						return false;
+					}
+				}
+
+				return true;
+			} else {
+				Sizzle.error( "Syntax error, unrecognized expression: " + name );
+			}
+		},
+		CHILD: function(elem, match){
+			var type = match[1], node = elem;
+			switch (type) {
+				case 'only':
+				case 'first':
+					while ( (node = node.previousSibling) )	 {
+						if ( node.nodeType === 1 ) { 
+							return false; 
+						}
+					}
+					if ( type === "first" ) { 
+						return true; 
+					}
+					node = elem;
+				case 'last':
+					while ( (node = node.nextSibling) )	 {
+						if ( node.nodeType === 1 ) { 
+							return false; 
+						}
+					}
+					return true;
+				case 'nth':
+					var first = match[2], last = match[3];
+
+					if ( first === 1 && last === 0 ) {
+						return true;
+					}
+					
+					var doneName = match[0],
+						parent = elem.parentNode;
+	
+					if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+						var count = 0;
+						for ( node = parent.firstChild; node; node = node.nextSibling ) {
+							if ( node.nodeType === 1 ) {
+								node.nodeIndex = ++count;
+							}
+						} 
+						parent.sizcache = doneName;
+					}
+					
+					var diff = elem.nodeIndex - last;
+					if ( first === 0 ) {
+						return diff === 0;
+					} else {
+						return ( diff % first === 0 && diff / first >= 0 );
+					}
+			}
+		},
+		ID: function(elem, match){
+			return elem.nodeType === 1 && elem.getAttribute("id") === match;
+		},
+		TAG: function(elem, match){
+			return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
+		},
+		CLASS: function(elem, match){
+			return (" " + (elem.className || elem.getAttribute("class")) + " ")
+				.indexOf( match ) > -1;
+		},
+		ATTR: function(elem, match){
+			var name = match[1],
+				result = Expr.attrHandle[ name ] ?
+					Expr.attrHandle[ name ]( elem ) :
+					elem[ name ] != null ?
+						elem[ name ] :
+						elem.getAttribute( name ),
+				value = result + "",
+				type = match[2],
+				check = match[4];
+
+			return result == null ?
+				type === "!=" :
+				type === "=" ?
+				value === check :
+				type === "*=" ?
+				value.indexOf(check) >= 0 :
+				type === "~=" ?
+				(" " + value + " ").indexOf(check) >= 0 :
+				!check ?
+				value && result !== false :
+				type === "!=" ?
+				value !== check :
+				type === "^=" ?
+				value.indexOf(check) === 0 :
+				type === "$=" ?
+				value.substr(value.length - check.length) === check :
+				type === "|=" ?
+				value === check || value.substr(0, check.length + 1) === check + "-" :
+				false;
+		},
+		POS: function(elem, match, i, array){
+			var name = match[2], filter = Expr.setFilters[ name ];
+
+			if ( filter ) {
+				return filter( elem, i, match, array );
+			}
+		}
+	}
+};
+
+var origPOS = Expr.match.POS,
+	fescape = function(all, num){
+		return "\\" + (num - 0 + 1);
+	};
+
+for ( var type in Expr.match ) {
+	Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
+	Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
+}
+
+var makeArray = function(array, results) {
+	array = Array.prototype.slice.call( array, 0 );
+
+	if ( results ) {
+		results.push.apply( results, array );
+		return results;
+	}
+	
+	return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+// Also verifies that the returned array holds DOM nodes
+// (which is not the case in the Blackberry browser)
+try {
+	Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
+
+// Provide a fallback method if it does not work
+} catch(e){
+	makeArray = function(array, results) {
+		var ret = results || [], i = 0;
+
+		if ( toString.call(array) === "[object Array]" ) {
+			Array.prototype.push.apply( ret, array );
+		} else {
+			if ( typeof array.length === "number" ) {
+				for ( var l = array.length; i < l; i++ ) {
+					ret.push( array[i] );
+				}
+			} else {
+				for ( ; array[i]; i++ ) {
+					ret.push( array[i] );
+				}
+			}
+		}
+
+		return ret;
+	};
+}
+
+var sortOrder, siblingCheck;
+
+if ( document.documentElement.compareDocumentPosition ) {
+	sortOrder = function( a, b ) {
+		if ( a === b ) {
+			hasDuplicate = true;
+			return 0;
+		}
+
+		if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+			return a.compareDocumentPosition ? -1 : 1;
+		}
+
+		return a.compareDocumentPosition(b) & 4 ? -1 : 1;
+	};
+} else {
+	sortOrder = function( a, b ) {
+		var ap = [], bp = [], aup = a.parentNode, bup = b.parentNode,
+			cur = aup, al, bl;
+
+		// The nodes are identical, we can exit early
+		if ( a === b ) {
+			hasDuplicate = true;
+			return 0;
+
+		// If the nodes are siblings (or identical) we can do a quick check
+		} else if ( aup === bup ) {
+			return siblingCheck( a, b );
+
+		// If no parents were found then the nodes are disconnected
+		} else if ( !aup ) {
+			return -1;
+
+		} else if ( !bup ) {
+			return 1;
+		}
+
+		// Otherwise they're somewhere else in the tree so we need
+		// to build up a full list of the parentNodes for comparison
+		while ( cur ) {
+			ap.unshift( cur );
+			cur = cur.parentNode;
+		}
+
+		cur = bup;
+
+		while ( cur ) {
+			bp.unshift( cur );
+			cur = cur.parentNode;
+		}
+
+		al = ap.length;
+		bl = bp.length;
+
+		// Start walking down the tree looking for a discrepancy
+		for ( var i = 0; i < al && i < bl; i++ ) {
+			if ( ap[i] !== bp[i] ) {
+				return siblingCheck( ap[i], bp[i] );
+			}
+		}
+
+		// We ended someplace up the tree so do a sibling check
+		return i === al ?
+			siblingCheck( a, bp[i], -1 ) :
+			siblingCheck( ap[i], b, 1 );
+	};
+
+	siblingCheck = function( a, b, ret ) {
+		if ( a === b ) {
+			return ret;
+		}
+
+		var cur = a.nextSibling;
+
+		while ( cur ) {
+			if ( cur === b ) {
+				return -1;
+			}
+
+			cur = cur.nextSibling;
+		}
+
+		return 1;
+	};
+}
+
+// Utility function for retreiving the text value of an array of DOM nodes
+Sizzle.getText = function( elems ) {
+	var ret = "", elem;
+
+	for ( var i = 0; elems[i]; i++ ) {
+		elem = elems[i];
+
+		// Get the text from text nodes and CDATA nodes
+		if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
+			ret += elem.nodeValue;
+
+		// Traverse everything else, except comment nodes
+		} else if ( elem.nodeType !== 8 ) {
+			ret += Sizzle.getText( elem.childNodes );
+		}
+	}
+
+	return ret;
+};
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+	// We're going to inject a fake input element with a specified name
+	var form = document.createElement("div"),
+		id = "script" + (new Date()).getTime();
+	form.innerHTML = "<a name='" + id + "'/>";
+
+	// Inject it into the root element, check its status, and remove it quickly
+	var root = document.documentElement;
+	root.insertBefore( form, root.firstChild );
+
+	// The workaround has to do additional checks after a getElementById
+	// Which slows things down for other browsers (hence the branching)
+	if ( document.getElementById( id ) ) {
+		Expr.find.ID = function(match, context, isXML){
+			if ( typeof context.getElementById !== "undefined" && !isXML ) {
+				var m = context.getElementById(match[1]);
+				return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
+			}
+		};
+
+		Expr.filter.ID = function(elem, match){
+			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+			return elem.nodeType === 1 && node && node.nodeValue === match;
+		};
+	}
+
+	root.removeChild( form );
+	root = form = null; // release memory in IE
+})();
+
+(function(){
+	// Check to see if the browser returns only elements
+	// when doing getElementsByTagName("*")
+
+	// Create a fake element
+	var div = document.createElement("div");
+	div.appendChild( document.createComment("") );
+
+	// Make sure no comments are found
+	if ( div.getElementsByTagName("*").length > 0 ) {
+		Expr.find.TAG = function(match, context){
+			var results = context.getElementsByTagName(match[1]);
+
+			// Filter out possible comments
+			if ( match[1] === "*" ) {
+				var tmp = [];
+
+				for ( var i = 0; results[i]; i++ ) {
+					if ( results[i].nodeType === 1 ) {
+						tmp.push( results[i] );
+					}
+				}
+
+				results = tmp;
+			}
+
+			return results;
+		};
+	}
+
+	// Check to see if an attribute returns normalized href attributes
+	div.innerHTML = "<a href='#'></a>";
+	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+			div.firstChild.getAttribute("href") !== "#" ) {
+		Expr.attrHandle.href = function(elem){
+			return elem.getAttribute("href", 2);
+		};
+	}
+
+	div = null; // release memory in IE
+})();
+
+if ( document.querySelectorAll ) {
+	(function(){
+		var oldSizzle = Sizzle, div = document.createElement("div");
+		div.innerHTML = "<p class='TEST'></p>";
+
+		// Safari can't handle uppercase or unicode characters when
+		// in quirks mode.
+		if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+			return;
+		}
+	
+		Sizzle = function(query, context, extra, seed){
+			context = context || document;
+
+			// Only use querySelectorAll on non-XML documents
+			// (ID selectors don't work in non-HTML documents)
+			if ( !seed && !Sizzle.isXML(context) ) {
+				if ( context.nodeType === 9 ) {
+					try {
+						return makeArray( context.querySelectorAll(query), extra );
+					} catch(qsaError) {}
+
+				// qSA works strangely on Element-rooted queries
+				// We can work around this by specifying an extra ID on the root
+				// and working up from there (Thanks to Andrew Dupont for the technique)
+				// IE 8 doesn't work on object elements
+				} else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+					var old = context.id, id = context.id = "__sizzle__";
+
+					try {
+						return makeArray( context.querySelectorAll( "#" + id + " " + query ), extra );
+
+					} catch(pseudoError) {
+					} finally {
+						if ( old ) {
+							context.id = old;
+
+						} else {
+							context.removeAttribute( "id" );
+						}
+					}
+				}
+			}
+		
+			return oldSizzle(query, context, extra, seed);
+		};
+
+		for ( var prop in oldSizzle ) {
+			Sizzle[ prop ] = oldSizzle[ prop ];
+		}
+
+		div = null; // release memory in IE
+	})();
+}
+
+(function(){
+	var html = document.documentElement,
+		matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector,
+		pseudoWorks = false;
+
+	try {
+		// This should fail with an exception
+		// Gecko does not error, returns false instead
+		matches.call( document.documentElement, ":sizzle" );
+	
+	} catch( pseudoError ) {
+		pseudoWorks = true;
+	}
+
+	if ( matches ) {
+		Sizzle.matchesSelector = function( node, expr ) {
+				try { 
+					if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) ) {
+						return matches.call( node, expr );
+					}
+				} catch(e) {}
+
+				return Sizzle(expr, null, null, [node]).length > 0;
+		};
+	}
+})();
+
+(function(){
+	var div = document.createElement("div");
+
+	div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+	// Opera can't find a second classname (in 9.6)
+	// Also, make sure that getElementsByClassName actually exists
+	if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
+		return;
+	}
+
+	// Safari caches class attributes, doesn't catch changes (in 3.2)
+	div.lastChild.className = "e";
+
+	if ( div.getElementsByClassName("e").length === 1 ) {
+		return;
+	}
+	
+	Expr.order.splice(1, 0, "CLASS");
+	Expr.find.CLASS = function(match, context, isXML) {
+		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+			return context.getElementsByClassName(match[1]);
+		}
+	};
+
+	div = null; // release memory in IE
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+		var elem = checkSet[i];
+		if ( elem ) {
+			elem = elem[dir];
+			var match = false;
+
+			while ( elem ) {
+				if ( elem.sizcache === doneName ) {
+					match = checkSet[elem.sizset];
+					break;
+				}
+
+				if ( elem.nodeType === 1 && !isXML ){
+					elem.sizcache = doneName;
+					elem.sizset = i;
+				}
+
+				if ( elem.nodeName.toLowerCase() === cur ) {
+					match = elem;
+					break;
+				}
+
+				elem = elem[dir];
+			}
+
+			checkSet[i] = match;
+		}
+	}
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+		var elem = checkSet[i];
+		if ( elem ) {
+			elem = elem[dir];
+			var match = false;
+
+			while ( elem ) {
+				if ( elem.sizcache === doneName ) {
+					match = checkSet[elem.sizset];
+					break;
+				}
+
+				if ( elem.nodeType === 1 ) {
+					if ( !isXML ) {
+						elem.sizcache = doneName;
+						elem.sizset = i;
+					}
+					if ( typeof cur !== "string" ) {
+						if ( elem === cur ) {
+							match = true;
+							break;
+						}
+
+					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+						match = elem;
+						break;
+					}
+				}
+
+				elem = elem[dir];
+			}
+
+			checkSet[i] = match;
+		}
+	}
+}
+
+Sizzle.contains = document.documentElement.contains ? function(a, b){
+	return a !== b && (a.contains ? a.contains(b) : true);
+} : function(a, b){
+	return !!(a.compareDocumentPosition(b) & 16);
+};
+
+Sizzle.isXML = function(elem){
+	// documentElement is verified for cases where it doesn't yet exist
+	// (such as loading iframes in IE - #4833) 
+	var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
+	return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+var posProcess = function(selector, context){
+	var tmpSet = [], later = "", match,
+		root = context.nodeType ? [context] : context;
+
+	// Position selectors must be done after the filter
+	// And so must :not(positional) so we move all PSEUDOs to the end
+	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+		later += match[0];
+		selector = selector.replace( Expr.match.PSEUDO, "" );
+	}
+
+	selector = Expr.relative[selector] ? selector + "*" : selector;
+
+	for ( var i = 0, l = root.length; i < l; i++ ) {
+		Sizzle( selector, root[i], tmpSet );
+	}
+
+	return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+})();
+
+
+var runtil = /Until$/,
+	rparentsprev = /^(?:parents|prevUntil|prevAll)/,
+	// Note: This RegExp should be improved, or likely pulled from Sizzle
+	rmultiselector = /,/,
+	isSimple = /^.[^:#\[\.,]*$/,
+	slice = Array.prototype.slice,
+	POS = jQuery.expr.match.POS;
+
+jQuery.fn.extend({
+	find: function( selector ) {
+		var ret = this.pushStack( "", "find", selector ), length = 0;
+
+		for ( var i = 0, l = this.length; i < l; i++ ) {
+			length = ret.length;
+			jQuery.find( selector, this[i], ret );
+
+			if ( i > 0 ) {
+				// Make sure that the results are unique
+				for ( var n = length; n < ret.length; n++ ) {
+					for ( var r = 0; r < length; r++ ) {
+						if ( ret[r] === ret[n] ) {
+							ret.splice(n--, 1);
+							break;
+						}
+					}
+				}
+			}
+		}
+
+		return ret;
+	},
+
+	has: function( target ) {
+		var targets = jQuery( target );
+		return this.filter(function() {
+			for ( var i = 0, l = targets.length; i < l; i++ ) {
+				if ( jQuery.contains( this, targets[i] ) ) {
+					return true;
+				}
+			}
+		});
+	},
+
+	not: function( selector ) {
+		return this.pushStack( winnow(this, selector, false), "not", selector);
+	},
+
+	filter: function( selector ) {
+		return this.pushStack( winnow(this, selector, true), "filter", selector );
+	},
+	
+	is: function( selector ) {
+		return !!selector && jQuery.filter( selector, this ).length > 0;
+	},
+
+	closest: function( selectors, context ) {
+		var ret = [], i, l, cur = this[0];
+
+		if ( jQuery.isArray( selectors ) ) {
+			var match, matches = {}, selector, level = 1;
+
+			if ( cur && selectors.length ) {
+				for ( i = 0, l = selectors.length; i < l; i++ ) {
+					selector = selectors[i];
+
+					if ( !matches[selector] ) {
+						matches[selector] = jQuery.expr.match.POS.test( selector ) ? 
+							jQuery( selector, context || this.context ) :
+							selector;
+					}
+				}
+
+				while ( cur && cur.ownerDocument && cur !== context ) {
+					for ( selector in matches ) {
+						match = matches[selector];
+
+						if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
+							ret.push({ selector: selector, elem: cur, level: level });
+						}
+					}
+
+					cur = cur.parentNode;
+					level++;
+				}
+			}
+
+			return ret;
+		}
+
+		var pos = POS.test( selectors ) ? 
+			jQuery( selectors, context || this.context ) : null;
+
+		for ( i = 0, l = this.length; i < l; i++ ) {
+			cur = this[i];
+
+			while ( cur ) {
+				if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
+					ret.push( cur );
+					break;
+
+				} else {
+					cur = cur.parentNode;
+					if ( !cur || !cur.ownerDocument || cur === context ) {
+						break;
+					}
+				}
+			}
+		}
+
+		ret = ret.length > 1 ? jQuery.unique(ret) : ret;
+		
+		return this.pushStack( ret, "closest", selectors );
+	},
+	
+	// Determine the position of an element within
+	// the matched set of elements
+	index: function( elem ) {
+		if ( !elem || typeof elem === "string" ) {
+			return jQuery.inArray( this[0],
+				// If it receives a string, the selector is used
+				// If it receives nothing, the siblings are used
+				elem ? jQuery( elem ) : this.parent().children() );
+		}
+		// Locate the position of the desired element
+		return jQuery.inArray(
+			// If it receives a jQuery object, the first element is used
+			elem.jquery ? elem[0] : elem, this );
+	},
+
+	add: function( selector, context ) {
+		var set = typeof selector === "string" ?
+				jQuery( selector, context || this.context ) :
+				jQuery.makeArray( selector ),
+			all = jQuery.merge( this.get(), set );
+
+		return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
+			all :
+			jQuery.unique( all ) );
+	},
+
+	andSelf: function() {
+		return this.add( this.prevObject );
+	}
+});
+
+// A painfully simple check to see if an element is disconnected
+// from a document (should be improved, where feasible).
+function isDisconnected( node ) {
+	return !node || !node.parentNode || node.parentNode.nodeType === 11;
+}
+
+jQuery.each({
+	parent: function( elem ) {
+		var parent = elem.parentNode;
+		return parent && parent.nodeType !== 11 ? parent : null;
+	},
+	parents: function( elem ) {
+		return jQuery.dir( elem, "parentNode" );
+	},
+	parentsUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "parentNode", until );
+	},
+	next: function( elem ) {
+		return jQuery.nth( elem, 2, "nextSibling" );
+	},
+	prev: function( elem ) {
+		return jQuery.nth( elem, 2, "previousSibling" );
+	},
+	nextAll: function( elem ) {
+		return jQuery.dir( elem, "nextSibling" );
+	},
+	prevAll: function( elem ) {
+		return jQuery.dir( elem, "previousSibling" );
+	},
+	nextUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "nextSibling", until );
+	},
+	prevUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "previousSibling", until );
+	},
+	siblings: function( elem ) {
+		return jQuery.sibling( elem.parentNode.firstChild, elem );
+	},
+	children: function( elem ) {
+		return jQuery.sibling( elem.firstChild );
+	},
+	contents: function( elem ) {
+		return jQuery.nodeName( elem, "iframe" ) ?
+			elem.contentDocument || elem.contentWindow.document :
+			jQuery.makeArray( elem.childNodes );
+	}
+}, function( name, fn ) {
+	jQuery.fn[ name ] = function( until, selector ) {
+		var ret = jQuery.map( this, fn, until );
+		
+		if ( !runtil.test( name ) ) {
+			selector = until;
+		}
+
+		if ( selector && typeof selector === "string" ) {
+			ret = jQuery.filter( selector, ret );
+		}
+
+		ret = this.length > 1 ? jQuery.unique( ret ) : ret;
+
+		if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
+			ret = ret.reverse();
+		}
+
+		return this.pushStack( ret, name, slice.call(arguments).join(",") );
+	};
+});
+
+jQuery.extend({
+	filter: function( expr, elems, not ) {
+		if ( not ) {
+			expr = ":not(" + expr + ")";
+		}
+
+		return elems.length === 1 ?
+			jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
+			jQuery.find.matches(expr, elems);
+	},
+	
+	dir: function( elem, dir, until ) {
+		var matched = [], cur = elem[dir];
+		while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+			if ( cur.nodeType === 1 ) {
+				matched.push( cur );
+			}
+			cur = cur[dir];
+		}
+		return matched;
+	},
+
+	nth: function( cur, result, dir, elem ) {
+		result = result || 1;
+		var num = 0;
+
+		for ( ; cur; cur = cur[dir] ) {
+			if ( cur.nodeType === 1 && ++num === result ) {
+				break;
+			}
+		}
+
+		return cur;
+	},
+
+	sibling: function( n, elem ) {
+		var r = [];
+
+		for ( ; n; n = n.nextSibling ) {
+			if ( n.nodeType === 1 && n !== elem ) {
+				r.push( n );
+			}
+		}
+
+		return r;
+	}
+});
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, keep ) {
+	if ( jQuery.isFunction( qualifier ) ) {
+		return jQuery.grep(elements, function( elem, i ) {
+			var retVal = !!qualifier.call( elem, i, elem );
+			return retVal === keep;
+		});
+
+	} else if ( qualifier.nodeType ) {
+		return jQuery.grep(elements, function( elem, i ) {
+			return (elem === qualifier) === keep;
+		});
+
+	} else if ( typeof qualifier === "string" ) {
+		var filtered = jQuery.grep(elements, function( elem ) {
+			return elem.nodeType === 1;
+		});
+
+		if ( isSimple.test( qualifier ) ) {
+			return jQuery.filter(qualifier, filtered, !keep);
+		} else {
+			qualifier = jQuery.filter( qualifier, filtered );
+		}
+	}
+
+	return jQuery.grep(elements, function( elem, i ) {
+		return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
+	});
+}
+
+
+
+
+var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
+	rleadingWhitespace = /^\s+/,
+	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
+	rtagName = /<([\w:]+)/,
+	rtbody = /<tbody/i,
+	rhtml = /<|&#?\w+;/,
+	rnocache = /<(?:script|object|embed|option|style)/i,
+	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,  // checked="checked" or checked (html5)
+	raction = /\=([^="'>\s]+\/)>/g,
+	wrapMap = {
+		option: [ 1, "<select multiple='multiple'>", "</select>" ],
+		legend: [ 1, "<fieldset>", "</fieldset>" ],
+		thead: [ 1, "<table>", "</table>" ],
+		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+		area: [ 1, "<map>", "</map>" ],
+		_default: [ 0, "", "" ]
+	};
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// IE can't serialize <link> and <script> tags normally
+if ( !jQuery.support.htmlSerialize ) {
+	wrapMap._default = [ 1, "div<div>", "</div>" ];
+}
+
+jQuery.fn.extend({
+	text: function( text ) {
+		if ( jQuery.isFunction(text) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.text( text.call(this, i, self.text()) );
+			});
+		}
+
+		if ( typeof text !== "object" && text !== undefined ) {
+			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+		}
+
+		return jQuery.text( this );
+	},
+
+	wrapAll: function( html ) {
+		if ( jQuery.isFunction( html ) ) {
+			return this.each(function(i) {
+				jQuery(this).wrapAll( html.call(this, i) );
+			});
+		}
+
+		if ( this[0] ) {
+			// The elements to wrap the target around
+			var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+			if ( this[0].parentNode ) {
+				wrap.insertBefore( this[0] );
+			}
+
+			wrap.map(function() {
+				var elem = this;
+
+				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+					elem = elem.firstChild;
+				}
+
+				return elem;
+			}).append(this);
+		}
+
+		return this;
+	},
+
+	wrapInner: function( html ) {
+		if ( jQuery.isFunction( html ) ) {
+			return this.each(function(i) {
+				jQuery(this).wrapInner( html.call(this, i) );
+			});
+		}
+
+		return this.each(function() {
+			var self = jQuery( this ), contents = self.contents();
+
+			if ( contents.length ) {
+				contents.wrapAll( html );
+
+			} else {
+				self.append( html );
+			}
+		});
+	},
+
+	wrap: function( html ) {
+		return this.each(function() {
+			jQuery( this ).wrapAll( html );
+		});
+	},
+
+	unwrap: function() {
+		return this.parent().each(function() {
+			if ( !jQuery.nodeName( this, "body" ) ) {
+				jQuery( this ).replaceWith( this.childNodes );
+			}
+		}).end();
+	},
+
+	append: function() {
+		return this.domManip(arguments, true, function( elem ) {
+			if ( this.nodeType === 1 ) {
+				this.appendChild( elem );
+			}
+		});
+	},
+
+	prepend: function() {
+		return this.domManip(arguments, true, function( elem ) {
+			if ( this.nodeType === 1 ) {
+				this.insertBefore( elem, this.firstChild );
+			}
+		});
+	},
+
+	before: function() {
+		if ( this[0] && this[0].parentNode ) {
+			return this.domManip(arguments, false, function( elem ) {
+				this.parentNode.insertBefore( elem, this );
+			});
+		} else if ( arguments.length ) {
+			var set = jQuery(arguments[0]);
+			set.push.apply( set, this.toArray() );
+			return this.pushStack( set, "before", arguments );
+		}
+	},
+
+	after: function() {
+		if ( this[0] && this[0].parentNode ) {
+			return this.domManip(arguments, false, function( elem ) {
+				this.parentNode.insertBefore( elem, this.nextSibling );
+			});
+		} else if ( arguments.length ) {
+			var set = this.pushStack( this, "after", arguments );
+			set.push.apply( set, jQuery(arguments[0]).toArray() );
+			return set;
+		}
+	},
+	
+	// keepData is for internal use only--do not document
+	remove: function( selector, keepData ) {
+		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+			if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
+				if ( !keepData && elem.nodeType === 1 ) {
+					jQuery.cleanData( elem.getElementsByTagName("*") );
+					jQuery.cleanData( [ elem ] );
+				}
+
+				if ( elem.parentNode ) {
+					 elem.parentNode.removeChild( elem );
+				}
+			}
+		}
+		
+		return this;
+	},
+
+	empty: function() {
+		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+			// Remove element nodes and prevent memory leaks
+			if ( elem.nodeType === 1 ) {
+				jQuery.cleanData( elem.getElementsByTagName("*") );
+			}
+
+			// Remove any remaining nodes
+			while ( elem.firstChild ) {
+				elem.removeChild( elem.firstChild );
+			}
+		}
+		
+		return this;
+	},
+
+	clone: function( events ) {
+		// Do the clone
+		var ret = this.map(function() {
+			if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
+				// IE copies events bound via attachEvent when
+				// using cloneNode. Calling detachEvent on the
+				// clone will also remove the events from the orignal
+				// In order to get around this, we use innerHTML.
+				// Unfortunately, this means some modifications to
+				// attributes in IE that are actually only stored
+				// as properties will not be copied (such as the
+				// the name attribute on an input).
+				var html = this.outerHTML, ownerDocument = this.ownerDocument;
+				if ( !html ) {
+					var div = ownerDocument.createElement("div");
+					div.appendChild( this.cloneNode(true) );
+					html = div.innerHTML;
+				}
+
+				return jQuery.clean([html.replace(rinlinejQuery, "")
+					// Handle the case in IE 8 where action=/test/> self-closes a tag
+					.replace(raction, '="$1">')
+					.replace(rleadingWhitespace, "")], ownerDocument)[0];
+			} else {
+				return this.cloneNode(true);
+			}
+		});
+
+		// Copy the events from the original to the clone
+		if ( events === true ) {
+			cloneCopyEvent( this, ret );
+			cloneCopyEvent( this.find("*"), ret.find("*") );
+		}
+
+		// Return the cloned set
+		return ret;
+	},
+
+	html: function( value ) {
+		if ( value === undefined ) {
+			return this[0] && this[0].nodeType === 1 ?
+				this[0].innerHTML.replace(rinlinejQuery, "") :
+				null;
+
+		// See if we can take a shortcut and just use innerHTML
+		} else if ( typeof value === "string" && !rnocache.test( value ) &&
+			(jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
+			!wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
+
+			value = value.replace(rxhtmlTag, "<$1></$2>");
+
+			try {
+				for ( var i = 0, l = this.length; i < l; i++ ) {
+					// Remove element nodes and prevent memory leaks
+					if ( this[i].nodeType === 1 ) {
+						jQuery.cleanData( this[i].getElementsByTagName("*") );
+						this[i].innerHTML = value;
+					}
+				}
+
+			// If using innerHTML throws an exception, use the fallback method
+			} catch(e) {
+				this.empty().append( value );
+			}
+
+		} else if ( jQuery.isFunction( value ) ) {
+			this.each(function(i){
+				var self = jQuery(this);
+				self.html( value.call(this, i, self.html()) );
+			});
+
+		} else {
+			this.empty().append( value );
+		}
+
+		return this;
+	},
+
+	replaceWith: function( value ) {
+		if ( this[0] && this[0].parentNode ) {
+			// Make sure that the elements are removed from the DOM before they are inserted
+			// this can help fix replacing a parent with child elements
+			if ( jQuery.isFunction( value ) ) {
+				return this.each(function(i) {
+					var self = jQuery(this), old = self.html();
+					self.replaceWith( value.call( this, i, old ) );
+				});
+			}
+
+			if ( typeof value !== "string" ) {
+				value = jQuery(value).detach();
+			}
+
+			return this.each(function() {
+				var next = this.nextSibling, parent = this.parentNode;
+
+				jQuery(this).remove();
+
+				if ( next ) {
+					jQuery(next).before( value );
+				} else {
+					jQuery(parent).append( value );
+				}
+			});
+		} else {
+			return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
+		}
+	},
+
+	detach: function( selector ) {
+		return this.remove( selector, true );
+	},
+
+	domManip: function( args, table, callback ) {
+		var results, first, value = args[0], scripts = [], fragment, parent;
+
+		// We can't cloneNode fragments that contain checked, in WebKit
+		if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
+			return this.each(function() {
+				jQuery(this).domManip( args, table, callback, true );
+			});
+		}
+
+		if ( jQuery.isFunction(value) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				args[0] = value.call(this, i, table ? self.html() : undefined);
+				self.domManip( args, table, callback );
+			});
+		}
+
+		if ( this[0] ) {
+			parent = value && value.parentNode;
+
+			// If we're in a fragment, just use that instead of building a new one
+			if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
+				results = { fragment: parent };
+
+			} else {
+				results = jQuery.buildFragment( args, this, scripts );
+			}
+			
+			fragment = results.fragment;
+			
+			if ( fragment.childNodes.length === 1 ) {
+				first = fragment = fragment.firstChild;
+			} else {
+				first = fragment.firstChild;
+			}
+
+			if ( first ) {
+				table = table && jQuery.nodeName( first, "tr" );
+
+				for ( var i = 0, l = this.length; i < l; i++ ) {
+					callback.call(
+						table ?
+							root(this[i], first) :
+							this[i],
+						i > 0 || results.cacheable || this.length > 1  ?
+							fragment.cloneNode(true) :
+							fragment
+					);
+				}
+			}
+
+			if ( scripts.length ) {
+				jQuery.each( scripts, evalScript );
+			}
+		}
+
+		return this;
+	}
+});
+
+function root( elem, cur ) {
+	return jQuery.nodeName(elem, "table") ?
+		(elem.getElementsByTagName("tbody")[0] ||
+		elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+		elem;
+}
+
+function cloneCopyEvent(orig, ret) {
+	var i = 0;
+
+	ret.each(function() {
+		if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
+			return;
+		}
+
+		var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;
+
+		if ( events ) {
+			delete curData.handle;
+			curData.events = {};
+
+			for ( var type in events ) {
+				for ( var handler in events[ type ] ) {
+					jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
+				}
+			}
+		}
+	});
+}
+
+jQuery.buildFragment = function( args, nodes, scripts ) {
+	var fragment, cacheable, cacheresults,
+		doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
+
+	// Only cache "small" (1/2 KB) strings that are associated with the main document
+	// Cloning options loses the selected state, so don't cache them
+	// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
+	// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
+	if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
+		!rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
+
+		cacheable = true;
+		cacheresults = jQuery.fragments[ args[0] ];
+		if ( cacheresults ) {
+			if ( cacheresults !== 1 ) {
+				fragment = cacheresults;
+			}
+		}
+	}
+
+	if ( !fragment ) {
+		fragment = doc.createDocumentFragment();
+		jQuery.clean( args, doc, fragment, scripts );
+	}
+
+	if ( cacheable ) {
+		jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
+	}
+
+	return { fragment: fragment, cacheable: cacheable };
+};
+
+jQuery.fragments = {};
+
+jQuery.each({
+	appendTo: "append",
+	prependTo: "prepend",
+	insertBefore: "before",
+	insertAfter: "after",
+	replaceAll: "replaceWith"
+}, function( name, original ) {
+	jQuery.fn[ name ] = function( selector ) {
+		var ret = [], insert = jQuery( selector ),
+			parent = this.length === 1 && this[0].parentNode;
+		
+		if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
+			insert[ original ]( this[0] );
+			return this;
+			
+		} else {
+			for ( var i = 0, l = insert.length; i < l; i++ ) {
+				var elems = (i > 0 ? this.clone(true) : this).get();
+				jQuery( insert[i] )[ original ]( elems );
+				ret = ret.concat( elems );
+			}
+		
+			return this.pushStack( ret, name, insert.selector );
+		}
+	};
+});
+
+jQuery.extend({
+	clean: function( elems, context, fragment, scripts ) {
+		context = context || document;
+
+		// !context.createElement fails in IE with an error but returns typeof 'object'
+		if ( typeof context.createElement === "undefined" ) {
+			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+		}
+
+		var ret = [];
+
+		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+			if ( typeof elem === "number" ) {
+				elem += "";
+			}
+
+			if ( !elem ) {
+				continue;
+			}
+
+			// Convert html string into DOM nodes
+			if ( typeof elem === "string" && !rhtml.test( elem ) ) {
+				elem = context.createTextNode( elem );
+
+			} else if ( typeof elem === "string" ) {
+				// Fix "XHTML"-style tags in all browsers
+				elem = elem.replace(rxhtmlTag, "<$1></$2>");
+
+				// Trim whitespace, otherwise indexOf won't work as expected
+				var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
+					wrap = wrapMap[ tag ] || wrapMap._default,
+					depth = wrap[0],
+					div = context.createElement("div");
+
+				// Go to html and back, then peel off extra wrappers
+				div.innerHTML = wrap[1] + elem + wrap[2];
+
+				// Move to the right depth
+				while ( depth-- ) {
+					div = div.lastChild;
+				}
+
+				// Remove IE's autoinserted <tbody> from table fragments
+				if ( !jQuery.support.tbody ) {
+
+					// String was a <table>, *may* have spurious <tbody>
+					var hasBody = rtbody.test(elem),
+						tbody = tag === "table" && !hasBody ?
+							div.firstChild && div.firstChild.childNodes :
+
+							// String was a bare <thead> or <tfoot>
+							wrap[1] === "<table>" && !hasBody ?
+								div.childNodes :
+								[];
+
+					for ( var j = tbody.length - 1; j >= 0 ; --j ) {
+						if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
+							tbody[ j ].parentNode.removeChild( tbody[ j ] );
+						}
+					}
+
+				}
+
+				// IE completely kills leading whitespace when innerHTML is used
+				if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+					div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
+				}
+
+				elem = div.childNodes;
+			}
+
+			if ( elem.nodeType ) {
+				ret.push( elem );
+			} else {
+				ret = jQuery.merge( ret, elem );
+			}
+		}
+
+		if ( fragment ) {
+			for ( i = 0; ret[i]; i++ ) {
+				if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+					scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+				
+				} else {
+					if ( ret[i].nodeType === 1 ) {
+						ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
+					}
+					fragment.appendChild( ret[i] );
+				}
+			}
+		}
+
+		return ret;
+	},
+	
+	cleanData: function( elems ) {
+		var data, id, cache = jQuery.cache,
+			special = jQuery.event.special,
+			deleteExpando = jQuery.support.deleteExpando;
+		
+		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+			if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+				continue;
+			}
+
+			id = elem[ jQuery.expando ];
+			
+			if ( id ) {
+				data = cache[ id ];
+				
+				if ( data && data.events ) {
+					for ( var type in data.events ) {
+						if ( special[ type ] ) {
+							jQuery.event.remove( elem, type );
+
+						} else {
+							jQuery.removeEvent( elem, type, data.handle );
+						}
+					}
+				}
+				
+				if ( deleteExpando ) {
+					delete elem[ jQuery.expando ];
+
+				} else if ( elem.removeAttribute ) {
+					elem.removeAttribute( jQuery.expando );
+				}
+				
+				delete cache[ id ];
+			}
+		}
+	}
+});
+
+function evalScript( i, elem ) {
+	if ( elem.src ) {
+		jQuery.ajax({
+			url: elem.src,
+			async: false,
+			dataType: "script"
+		});
+	} else {
+		jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+	}
+
+	if ( elem.parentNode ) {
+		elem.parentNode.removeChild( elem );
+	}
+}
+
+
+
+
+var ralpha = /alpha\([^)]*\)/i,
+	ropacity = /opacity=([^)]*)/,
+	rdashAlpha = /-([a-z])/ig,
+	rupper = /([A-Z])/g,
+	rnumpx = /^-?\d+(?:px)?$/i,
+	rnum = /^-?\d/,
+
+	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+	cssWidth = [ "Left", "Right" ],
+	cssHeight = [ "Top", "Bottom" ],
+	curCSS,
+
+	// cache check for defaultView.getComputedStyle
+	getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
+
+	fcamelCase = function( all, letter ) {
+		return letter.toUpperCase();
+	};
+
+jQuery.fn.css = function( name, value ) {
+	// Setting 'undefined' is a no-op
+	if ( arguments.length === 2 && value === undefined ) {
+		return this;
+	}
+
+	return jQuery.access( this, name, value, true, function( elem, name, value ) {
+		return value !== undefined ?
+			jQuery.style( elem, name, value ) :
+			jQuery.css( elem, name );
+	});
+};
+
+jQuery.extend({
+	// Add in style property hooks for overriding the default
+	// behavior of getting and setting a style property
+	cssHooks: {
+		opacity: {
+			get: function( elem, computed ) {
+				if ( computed ) {
+					// We should always get a number back from opacity
+					var ret = curCSS( elem, "opacity", "opacity" );
+					return ret === "" ? "1" : ret;
+
+				} else {
+					return elem.style.opacity;
+				}
+			}
+		}
+	},
+
+	// Exclude the following css properties to add px
+	cssNumber: {
+		"zIndex": true,
+		"fontWeight": true,
+		"opacity": true,
+		"zoom": true,
+		"lineHeight": true
+	},
+
+	// Add in properties whose names you wish to fix before
+	// setting or getting the value
+	cssProps: {
+		// normalize float css property
+		"float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
+	},
+
+	// Get and set the style property on a DOM Node
+	style: function( elem, name, value, extra ) {
+		// Don't set styles on text and comment nodes
+		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+			return;
+		}
+
+		// Make sure that we're working with the right name
+		var ret, origName = jQuery.camelCase( name ),
+			style = elem.style, hooks = jQuery.cssHooks[ origName ];
+
+		name = jQuery.cssProps[ origName ] || origName;
+
+		// Check if we're setting a value
+		if ( value !== undefined ) {
+			// Make sure that NaN and null values aren't set. See: #7116
+			if ( typeof value === "number" && isNaN( value ) || value == null ) {
+				return;
+			}
+
+			// If a number was passed in, add 'px' to the (except for certain CSS properties)
+			if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) {
+				value += "px";
+			}
+
+			// If a hook was provided, use that value, otherwise just set the specified value
+			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
+				// Wrapped to prevent IE from throwing errors when 'invalid' values are provided
+				// Fixes bug #5509
+				try {
+					style[ name ] = value;
+				} catch(e) {}
+			}
+
+		} else {
+			// If a hook was provided get the non-computed value from there
+			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
+				return ret;
+			}
+
+			// Otherwise just get the value from the style object
+			return style[ name ];
+		}
+	},
+
+	css: function( elem, name, extra ) {
+		// Make sure that we're working with the right name
+		var ret, origName = jQuery.camelCase( name ),
+			hooks = jQuery.cssHooks[ origName ];
+
+		name = jQuery.cssProps[ origName ] || origName;
+
+		// If a hook was provided get the computed value from there
+		if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
+			return ret;
+
+		// Otherwise, if a way to get the computed value exists, use that
+		} else if ( curCSS ) {
+			return curCSS( elem, name, origName );
+		}
+	},
+
+	// A method for quickly swapping in/out CSS properties to get correct calculations
+	swap: function( elem, options, callback ) {
+		var old = {};
+
+		// Remember the old values, and insert the new ones
+		for ( var name in options ) {
+			old[ name ] = elem.style[ name ];
+			elem.style[ name ] = options[ name ];
+		}
+
+		callback.call( elem );
+
+		// Revert the old values
+		for ( name in options ) {
+			elem.style[ name ] = old[ name ];
+		}
+	},
+
+	camelCase: function( string ) {
+		return string.replace( rdashAlpha, fcamelCase );
+	}
+});
+
+// DEPRECATED, Use jQuery.css() instead
+jQuery.curCSS = jQuery.css;
+
+jQuery.each(["height", "width"], function( i, name ) {
+	jQuery.cssHooks[ name ] = {
+		get: function( elem, computed, extra ) {
+			var val;
+
+			if ( computed ) {
+				if ( elem.offsetWidth !== 0 ) {
+					val = getWH( elem, name, extra );
+
+				} else {
+					jQuery.swap( elem, cssShow, function() {
+						val = getWH( elem, name, extra );
+					});
+				}
+
+				return val + "px";
+			}
+		},
+
+		set: function( elem, value ) {
+			if ( rnumpx.test( value ) ) {
+				// ignore negative width and height values #1599
+				value = parseFloat(value);
+
+				if ( value >= 0 ) {
+					return value + "px";
+				}
+
+			} else {
+				return value;
+			}
+		}
+	};
+});
+
+if ( !jQuery.support.opacity ) {
+	jQuery.cssHooks.opacity = {
+		get: function( elem, computed ) {
+			// IE uses filters for opacity
+			return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ?
+				(parseFloat(RegExp.$1) / 100) + "" :
+				computed ? "1" : "";
+		},
+
+		set: function( elem, value ) {
+			var style = elem.style;
+
+			// IE has trouble with opacity if it does not have layout
+			// Force it by setting the zoom level
+			style.zoom = 1;
+
+			// Set the alpha filter to set the opacity
+			var opacity = jQuery.isNaN(value) ?
+				"" :
+				"alpha(opacity=" + value * 100 + ")",
+				filter = style.filter || "";
+
+			style.filter = ralpha.test(filter) ?
+				filter.replace(ralpha, opacity) :
+				style.filter + ' ' + opacity;
+		}
+	};
+}
+
+if ( getComputedStyle ) {
+	curCSS = function( elem, newName, name ) {
+		var ret, defaultView, computedStyle;
+
+		name = name.replace( rupper, "-$1" ).toLowerCase();
+
+		if ( !(defaultView = elem.ownerDocument.defaultView) ) {
+			return undefined;
+		}
+
+		if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
+			ret = computedStyle.getPropertyValue( name );
+			if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
+				ret = jQuery.style( elem, name );
+			}
+		}
+
+		return ret;
+	};
+
+} else if ( document.documentElement.currentStyle ) {
+	curCSS = function( elem, name ) {
+		var left, rsLeft, ret = elem.currentStyle && elem.currentStyle[ name ], style = elem.style;
+
+		// From the awesome hack by Dean Edwards
+		// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+		// If we're not dealing with a regular pixel number
+		// but a number that has a weird ending, we need to convert it to pixels
+		if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
+			// Remember the original values
+			left = style.left;
+			rsLeft = elem.runtimeStyle.left;
+
+			// Put in the new values to get a computed value out
+			elem.runtimeStyle.left = elem.currentStyle.left;
+			style.left = name === "fontSize" ? "1em" : (ret || 0);
+			ret = style.pixelLeft + "px";
+
+			// Revert the changed values
+			style.left = left;
+			elem.runtimeStyle.left = rsLeft;
+		}
+
+		return ret;
+	};
+}
+
+function getWH( elem, name, extra ) {
+	var which = name === "width" ? cssWidth : cssHeight,
+		val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
+
+	if ( extra === "border" ) {
+		return val;
+	}
+
+	jQuery.each( which, function() {
+		if ( !extra ) {
+			val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
+		}
+
+		if ( extra === "margin" ) {
+			val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
+
+		} else {
+			val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
+		}
+	});
+
+	return val;
+}
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+	jQuery.expr.filters.hidden = function( elem ) {
+		var width = elem.offsetWidth, height = elem.offsetHeight;
+
+		return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
+	};
+
+	jQuery.expr.filters.visible = function( elem ) {
+		return !jQuery.expr.filters.hidden( elem );
+	};
+}
+
+
+
+
+var jsc = jQuery.now(),
+	rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
+	rselectTextarea = /^(?:select|textarea)/i,
+	rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
+	rnoContent = /^(?:GET|HEAD|DELETE)$/,
+	rbracket = /\[\]$/,
+	jsre = /\=\?(&|$)/,
+	rquery = /\?/,
+	rts = /([?&])_=[^&]*/,
+	rurl = /^(\w+:)?\/\/([^\/?#]+)/,
+	r20 = /%20/g,
+	rhash = /#.*$/,
+
+	// Keep a copy of the old load method
+	_load = jQuery.fn.load;
+
+jQuery.fn.extend({
+	load: function( url, params, callback ) {
+		if ( typeof url !== "string" && _load ) {
+			return _load.apply( this, arguments );
+
+		// Don't do a request if no elements are being requested
+		} else if ( !this.length ) {
+			return this;
+		}
+
+		var off = url.indexOf(" ");
+		if ( off >= 0 ) {
+			var selector = url.slice(off, url.length);
+			url = url.slice(0, off);
+		}
+
+		// Default to a GET request
+		var type = "GET";
+
+		// If the second parameter was provided
+		if ( params ) {
+			// If it's a function
+			if ( jQuery.isFunction( params ) ) {
+				// We assume that it's the callback
+				callback = params;
+				params = null;
+
+			// Otherwise, build a param string
+			} else if ( typeof params === "object" ) {
+				params = jQuery.param( params, jQuery.ajaxSettings.traditional );
+				type = "POST";
+			}
+		}
+
+		var self = this;
+
+		// Request the remote document
+		jQuery.ajax({
+			url: url,
+			type: type,
+			dataType: "html",
+			data: params,
+			complete: function( res, status ) {
+				// If successful, inject the HTML into all the matched elements
+				if ( status === "success" || status === "notmodified" ) {
+					// See if a selector was specified
+					self.html( selector ?
+						// Create a dummy div to hold the results
+						jQuery("<div>")
+							// inject the contents of the document in, removing the scripts
+							// to avoid any 'Permission Denied' errors in IE
+							.append(res.responseText.replace(rscript, ""))
+
+							// Locate the specified elements
+							.find(selector) :
+
+						// If not, just inject the full result
+						res.responseText );
+				}
+
+				if ( callback ) {
+					self.each( callback, [res.responseText, status, res] );
+				}
+			}
+		});
+
+		return this;
+	},
+
+	serialize: function() {
+		return jQuery.param(this.serializeArray());
+	},
+
+	serializeArray: function() {
+		return this.map(function() {
+			return this.elements ? jQuery.makeArray(this.elements) : this;
+		})
+		.filter(function() {
+			return this.name && !this.disabled &&
+				(this.checked || rselectTextarea.test(this.nodeName) ||
+					rinput.test(this.type));
+		})
+		.map(function( i, elem ) {
+			var val = jQuery(this).val();
+
+			return val == null ?
+				null :
+				jQuery.isArray(val) ?
+					jQuery.map( val, function( val, i ) {
+						return { name: elem.name, value: val };
+					}) :
+					{ name: elem.name, value: val };
+		}).get();
+	}
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
+	jQuery.fn[o] = function( f ) {
+		return this.bind(o, f);
+	};
+});
+
+jQuery.extend({
+	get: function( url, data, callback, type ) {
+		// shift arguments if data argument was omited
+		if ( jQuery.isFunction( data ) ) {
+			type = type || callback;
+			callback = data;
+			data = null;
+		}
+
+		return jQuery.ajax({
+			type: "GET",
+			url: url,
+			data: data,
+			success: callback,
+			dataType: type
+		});
+	},
+
+	getScript: function( url, callback ) {
+		return jQuery.get(url, null, callback, "script");
+	},
+
+	getJSON: function( url, data, callback ) {
+		return jQuery.get(url, data, callback, "json");
+	},
+
+	post: function( url, data, callback, type ) {
+		// shift arguments if data argument was omited
+		if ( jQuery.isFunction( data ) ) {
+			type = type || callback;
+			callback = data;
+			data = {};
+		}
+
+		return jQuery.ajax({
+			type: "POST",
+			url: url,
+			data: data,
+			success: callback,
+			dataType: type
+		});
+	},
+
+	ajaxSetup: function( settings ) {
+		jQuery.extend( jQuery.ajaxSettings, settings );
+	},
+
+	ajaxSettings: {
+		url: location.href,
+		global: true,
+		type: "GET",
+		contentType: "application/x-www-form-urlencoded",
+		processData: true,
+		async: true,
+		/*
+		timeout: 0,
+		data: null,
+		username: null,
+		password: null,
+		traditional: false,
+		*/
+		// This function can be overriden by calling jQuery.ajaxSetup
+		xhr: function() {
+			return new window.XMLHttpRequest();
+		},
+		accepts: {
+			xml: "application/xml, text/xml",
+			html: "text/html",
+			script: "text/javascript, application/javascript",
+			json: "application/json, text/javascript",
+			text: "text/plain",
+			_default: "*/*"
+		}
+	},
+
+	ajax: function( origSettings ) {
+		var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings),
+			jsonp, status, data, type = s.type.toUpperCase(), noContent = rnoContent.test(type);
+
+		s.url = s.url.replace( rhash, "" );
+
+		// Use original (not extended) context object if it was provided
+		s.context = origSettings && origSettings.context != null ? origSettings.context : s;
+
+		// convert data if not already a string
+		if ( s.data && s.processData && typeof s.data !== "string" ) {
+			s.data = jQuery.param( s.data, s.traditional );
+		}
+
+		// Handle JSONP Parameter Callbacks
+		if ( s.dataType === "jsonp" ) {
+			if ( type === "GET" ) {
+				if ( !jsre.test( s.url ) ) {
+					s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+				}
+			} else if ( !s.data || !jsre.test(s.data) ) {
+				s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+			}
+			s.dataType = "json";
+		}
+
+		// Build temporary JSONP function
+		if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
+			jsonp = s.jsonpCallback || ("jsonp" + jsc++);
+
+			// Replace the =? sequence both in the query string and the data
+			if ( s.data ) {
+				s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+			}
+
+			s.url = s.url.replace(jsre, "=" + jsonp + "$1");
+
+			// We need to make sure
+			// that a JSONP style response is executed properly
+			s.dataType = "script";
+
+			// Handle JSONP-style loading
+			var customJsonp = window[ jsonp ];
+
+			window[ jsonp ] = function( tmp ) {
+				data = tmp;
+				jQuery.handleSuccess( s, xhr, status, data );
+				jQuery.handleComplete( s, xhr, status, data );
+
+				if ( jQuery.isFunction( customJsonp ) ) {
+					customJsonp( tmp );
+
+				} else {
+					// Garbage collect
+					window[ jsonp ] = undefined;
+
+					try {
+						delete window[ jsonp ];
+					} catch( jsonpError ) {}
+				}
+				
+				if ( head ) {
+					head.removeChild( script );
+				}
+			};
+		}
+
+		if ( s.dataType === "script" && s.cache === null ) {
+			s.cache = false;
+		}
+
+		if ( s.cache === false && type === "GET" ) {
+			var ts = jQuery.now();
+
+			// try replacing _= if it is there
+			var ret = s.url.replace(rts, "$1_=" + ts);
+
+			// if nothing was replaced, add timestamp to the end
+			s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
+		}
+
+		// If data is available, append data to url for get requests
+		if ( s.data && type === "GET" ) {
+			s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
+		}
+
+		// Watch for a new set of requests
+		if ( s.global && jQuery.active++ === 0 ) {
+			jQuery.event.trigger( "ajaxStart" );
+		}
+
+		// Matches an absolute URL, and saves the domain
+		var parts = rurl.exec( s.url ),
+			remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
+
+		// If we're requesting a remote document
+		// and trying to load JSON or Script with a GET
+		if ( s.dataType === "script" && type === "GET" && remote ) {
+			var head = document.getElementsByTagName("head")[0] || document.documentElement;
+			var script = document.createElement("script");
+			if ( s.scriptCharset ) {
+				script.charset = s.scriptCharset;
+			}
+			script.src = s.url;
+
+			// Handle Script loading
+			if ( !jsonp ) {
+				var done = false;
+
+				// Attach handlers for all browsers
+				script.onload = script.onreadystatechange = function() {
+					if ( !done && (!this.readyState ||
+							this.readyState === "loaded" || this.readyState === "complete") ) {
+						done = true;
+						jQuery.handleSuccess( s, xhr, status, data );
+						jQuery.handleComplete( s, xhr, status, data );
+
+						// Handle memory leak in IE
+						script.onload = script.onreadystatechange = null;
+						if ( head && script.parentNode ) {
+							head.removeChild( script );
+						}
+					}
+				};
+			}
+
+			// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
+			// This arises when a base node is used (#2709 and #4378).
+			head.insertBefore( script, head.firstChild );
+
+			// We handle everything using the script element injection
+			return undefined;
+		}
+
+		var requestDone = false;
+
+		// Create the request object
+		var xhr = s.xhr();
+
+		if ( !xhr ) {
+			return;
+		}
+
+		// Open the socket
+		// Passing null username, generates a login popup on Opera (#2865)
+		if ( s.username ) {
+			xhr.open(type, s.url, s.async, s.username, s.password);
+		} else {
+			xhr.open(type, s.url, s.async);
+		}
+
+		// Need an extra try/catch for cross domain requests in Firefox 3
+		try {
+			// Set content-type if data specified and content-body is valid for this type
+			if ( (s.data != null && !noContent) || (origSettings && origSettings.contentType) ) {
+				xhr.setRequestHeader("Content-Type", s.contentType);
+			}
+
+			// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+			if ( s.ifModified ) {
+				if ( jQuery.lastModified[s.url] ) {
+					xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
+				}
+
+				if ( jQuery.etag[s.url] ) {
+					xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
+				}
+			}
+
+			// Set header so the called script knows that it's an XMLHttpRequest
+			// Only send the header if it's not a remote XHR
+			if ( !remote ) {
+				xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+			}
+
+			// Set the Accepts header for the server, depending on the dataType
+			xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+				s.accepts[ s.dataType ] + ", */*; q=0.01" :
+				s.accepts._default );
+		} catch( headerError ) {}
+
+		// Allow custom headers/mimetypes and early abort
+		if ( s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false ) {
+			// Handle the global AJAX counter
+			if ( s.global && jQuery.active-- === 1 ) {
+				jQuery.event.trigger( "ajaxStop" );
+			}
+
+			// close opended socket
+			xhr.abort();
+			return false;
+		}
+
+		if ( s.global ) {
+			jQuery.triggerGlobal( s, "ajaxSend", [xhr, s] );
+		}
+
+		// Wait for a response to come back
+		var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
+			// The request was aborted
+			if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
+				// Opera doesn't call onreadystatechange before this point
+				// so we simulate the call
+				if ( !requestDone ) {
+					jQuery.handleComplete( s, xhr, status, data );
+				}
+
+				requestDone = true;
+				if ( xhr ) {
+					xhr.onreadystatechange = jQuery.noop;
+				}
+
+			// The transfer is complete and the data is available, or the request timed out
+			} else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
+				requestDone = true;
+				xhr.onreadystatechange = jQuery.noop;
+
+				status = isTimeout === "timeout" ?
+					"timeout" :
+					!jQuery.httpSuccess( xhr ) ?
+						"error" :
+						s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
+							"notmodified" :
+							"success";
+
+				var errMsg;
+
+				if ( status === "success" ) {
+					// Watch for, and catch, XML document parse errors
+					try {
+						// process the data (runs the xml through httpData regardless of callback)
+						data = jQuery.httpData( xhr, s.dataType, s );
+					} catch( parserError ) {
+						status = "parsererror";
+						errMsg = parserError;
+					}
+				}
+
+				// Make sure that the request was successful or notmodified
+				if ( status === "success" || status === "notmodified" ) {
+					// JSONP handles its own success callback
+					if ( !jsonp ) {
+						jQuery.handleSuccess( s, xhr, status, data );
+					}
+				} else {
+					jQuery.handleError( s, xhr, status, errMsg );
+				}
+
+				// Fire the complete handlers
+				if ( !jsonp ) {
+					jQuery.handleComplete( s, xhr, status, data );
+				}
+
+				if ( isTimeout === "timeout" ) {
+					xhr.abort();
+				}
+
+				// Stop memory leaks
+				if ( s.async ) {
+					xhr = null;
+				}
+			}
+		};
+
+		// Override the abort handler, if we can (IE 6 doesn't allow it, but that's OK)
+		// Opera doesn't fire onreadystatechange at all on abort
+		try {
+			var oldAbort = xhr.abort;
+			xhr.abort = function() {
+				// xhr.abort in IE7 is not a native JS function
+				// and does not have a call property
+				if ( xhr && oldAbort.call ) {
+					oldAbort.call( xhr );
+				}
+
+				onreadystatechange( "abort" );
+			};
+		} catch( abortError ) {}
+
+		// Timeout checker
+		if ( s.async && s.timeout > 0 ) {
+			setTimeout(function() {
+				// Check to see if the request is still happening
+				if ( xhr && !requestDone ) {
+					onreadystatechange( "timeout" );
+				}
+			}, s.timeout);
+		}
+
+		// Send the data
+		try {
+			xhr.send( noContent || s.data == null ? null : s.data );
+
+		} catch( sendError ) {
+			jQuery.handleError( s, xhr, null, sendError );
+
+			// Fire the complete handlers
+			jQuery.handleComplete( s, xhr, status, data );
+		}
+
+		// firefox 1.5 doesn't fire statechange for sync requests
+		if ( !s.async ) {
+			onreadystatechange();
+		}
+
+		// return XMLHttpRequest to allow aborting the request etc.
+		return xhr;
+	},
+
+	// Serialize an array of form elements or a set of
+	// key/values into a query string
+	param: function( a, traditional ) {
+		var s = [], add = function( key, value ) {
+			// If value is a function, invoke it and return its value
+			value = jQuery.isFunction(value) ? value() : value;
+			s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
+		};
+		
+		// Set traditional to true for jQuery <= 1.3.2 behavior.
+		if ( traditional === undefined ) {
+			traditional = jQuery.ajaxSettings.traditional;
+		}
+		
+		// If an array was passed in, assume that it is an array of form elements.
+		if ( jQuery.isArray(a) || a.jquery ) {
+			// Serialize the form elements
+			jQuery.each( a, function() {
+				add( this.name, this.value );
+			});
+			
+		} else {
+			// If traditional, encode the "old" way (the way 1.3.2 or older
+			// did it), otherwise encode params recursively.
+			for ( var prefix in a ) {
+				buildParams( prefix, a[prefix], traditional, add );
+			}
+		}
+
+		// Return the resulting serialization
+		return s.join("&").replace(r20, "+");
+	}
+});
+
+function buildParams( prefix, obj, traditional, add ) {
+	if ( jQuery.isArray(obj) && obj.length ) {
+		// Serialize array item.
+		jQuery.each( obj, function( i, v ) {
+			if ( traditional || rbracket.test( prefix ) ) {
+				// Treat each array item as a scalar.
+				add( prefix, v );
+
+			} else {
+				// If array item is non-scalar (array or object), encode its
+				// numeric index to resolve deserialization ambiguity issues.
+				// Note that rack (as of 1.0.0) can't currently deserialize
+				// nested arrays properly, and attempting to do so may cause
+				// a server error. Possible fixes are to modify rack's
+				// deserialization algorithm or to provide an option or flag
+				// to force array serialization to be shallow.
+				buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
+			}
+		});
+			
+	} else if ( !traditional && obj != null && typeof obj === "object" ) {
+		if ( jQuery.isEmptyObject( obj ) ) {
+			add( prefix, "" );
+
+		// Serialize object item.
+		} else {
+			jQuery.each( obj, function( k, v ) {
+				buildParams( prefix + "[" + k + "]", v, traditional, add );
+			});
+		}
+					
+	} else {
+		// Serialize scalar item.
+		add( prefix, obj );
+	}
+}
+
+// This is still on the jQuery object... for now
+// Want to move this to jQuery.ajax some day
+jQuery.extend({
+
+	// Counter for holding the number of active queries
+	active: 0,
+
+	// Last-Modified header cache for next request
+	lastModified: {},
+	etag: {},
+
+	handleError: function( s, xhr, status, e ) {
+		// If a local callback was specified, fire it
+		if ( s.error ) {
+			s.error.call( s.context, xhr, status, e );
+		}
+
+		// Fire the global callback
+		if ( s.global ) {
+			jQuery.triggerGlobal( s, "ajaxError", [xhr, s, e] );
+		}
+	},
+
+	handleSuccess: function( s, xhr, status, data ) {
+		// If a local callback was specified, fire it and pass it the data
+		if ( s.success ) {
+			s.success.call( s.context, data, status, xhr );
+		}
+
+		// Fire the global callback
+		if ( s.global ) {
+			jQuery.triggerGlobal( s, "ajaxSuccess", [xhr, s] );
+		}
+	},
+
+	handleComplete: function( s, xhr, status ) {
+		// Process result
+		if ( s.complete ) {
+			s.complete.call( s.context, xhr, status );
+		}
+
+		// The request was completed
+		if ( s.global ) {
+			jQuery.triggerGlobal( s, "ajaxComplete", [xhr, s] );
+		}
+
+		// Handle the global AJAX counter
+		if ( s.global && jQuery.active-- === 1 ) {
+			jQuery.event.trigger( "ajaxStop" );
+		}
+	},
+		
+	triggerGlobal: function( s, type, args ) {
+		(s.context && s.context.url == null ? jQuery(s.context) : jQuery.event).trigger(type, args);
+	},
+
+	// Determines if an XMLHttpRequest was successful or not
+	httpSuccess: function( xhr ) {
+		try {
+			// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
+			return !xhr.status && location.protocol === "file:" ||
+				xhr.status >= 200 && xhr.status < 300 ||
+				xhr.status === 304 || xhr.status === 1223;
+		} catch(e) {}
+
+		return false;
+	},
+
+	// Determines if an XMLHttpRequest returns NotModified
+	httpNotModified: function( xhr, url ) {
+		var lastModified = xhr.getResponseHeader("Last-Modified"),
+			etag = xhr.getResponseHeader("Etag");
+
+		if ( lastModified ) {
+			jQuery.lastModified[url] = lastModified;
+		}
+
+		if ( etag ) {
+			jQuery.etag[url] = etag;
+		}
+
+		return xhr.status === 304;
+	},
+
+	httpData: function( xhr, type, s ) {
+		var ct = xhr.getResponseHeader("content-type") || "",
+			xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
+			data = xml ? xhr.responseXML : xhr.responseText;
+
+		if ( xml && data.documentElement.nodeName === "parsererror" ) {
+			jQuery.error( "parsererror" );
+		}
+
+		// Allow a pre-filtering function to sanitize the response
+		// s is checked to keep backwards compatibility
+		if ( s && s.dataFilter ) {
+			data = s.dataFilter( data, type );
+		}
+
+		// The filter can actually parse the response
+		if ( typeof data === "string" ) {
+			// Get the JavaScript object, if JSON is used.
+			if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
+				data = jQuery.parseJSON( data );
+
+			// If the type is "script", eval it in global context
+			} else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
+				jQuery.globalEval( data );
+			}
+		}
+
+		return data;
+	}
+
+});
+
+/*
+ * Create the request object; Microsoft failed to properly
+ * implement the XMLHttpRequest in IE7 (can't request local files),
+ * so we use the ActiveXObject when it is available
+ * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+ * we need a fallback.
+ */
+if ( window.ActiveXObject ) {
+	jQuery.ajaxSettings.xhr = function() {
+		if ( window.location.protocol !== "file:" ) {
+			try {
+				return new window.XMLHttpRequest();
+			} catch(xhrError) {}
+		}
+
+		try {
+			return new window.ActiveXObject("Microsoft.XMLHTTP");
+		} catch(activeError) {}
+	};
+}
+
+// Does this browser support XHR requests?
+jQuery.support.ajax = !!jQuery.ajaxSettings.xhr();
+
+
+
+
+var elemdisplay = {},
+	rfxtypes = /^(?:toggle|show|hide)$/,
+	rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/,
+	timerId,
+	fxAttrs = [
+		// height animations
+		[ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+		// width animations
+		[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+		// opacity animations
+		[ "opacity" ]
+	];
+
+jQuery.fn.extend({
+	show: function( speed, easing, callback ) {
+		if ( speed || speed === 0 ) {
+			return this.animate( genFx("show", 3), speed, easing, callback);
+		} else {
+			for ( var i = 0, j = this.length; i < j; i++ ) {
+				// Reset the inline display of this element to learn if it is
+				// being hidden by cascaded rules or not
+				if ( !jQuery.data(this[i], "olddisplay") && this[i].style.display === "none" ) {
+					this[i].style.display = "";
+				}
+
+				// Set elements which have been overridden with display: none
+				// in a stylesheet to whatever the default browser style is
+				// for such an element
+				if ( this[i].style.display === "" && jQuery.css( this[i], "display" ) === "none" ) {
+					jQuery.data(this[i], "olddisplay", defaultDisplay(this[i].nodeName));
+				}
+			}
+
+			// Set the display of most of the elements in a second loop
+			// to avoid the constant reflow
+			for ( i = 0; i < j; i++ ) {
+				this[i].style.display = jQuery.data(this[i], "olddisplay") || "";
+			}
+
+			return this;
+		}
+	},
+
+	hide: function( speed, easing, callback ) {
+		if ( speed || speed === 0 ) {
+			return this.animate( genFx("hide", 3), speed, easing, callback);
+
+		} else {
+			for ( var i = 0, j = this.length; i < j; i++ ) {
+				var display = jQuery.css( this[i], "display" );
+
+				if ( display !== "none" ) {
+					jQuery.data( this[i], "olddisplay", display );
+				}
+			}
+
+			// Set the display of the elements in a second loop
+			// to avoid the constant reflow
+			for ( i = 0; i < j; i++ ) {
+				this[i].style.display = "none";
+			}
+
+			return this;
+		}
+	},
+
+	// Save the old toggle function
+	_toggle: jQuery.fn.toggle,
+
+	toggle: function( fn, fn2, callback ) {
+		var bool = typeof fn === "boolean";
+
+		if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
+			this._toggle.apply( this, arguments );
+
+		} else if ( fn == null || bool ) {
+			this.each(function() {
+				var state = bool ? fn : jQuery(this).is(":hidden");
+				jQuery(this)[ state ? "show" : "hide" ]();
+			});
+
+		} else {
+			this.animate(genFx("toggle", 3), fn, fn2, callback);
+		}
+
+		return this;
+	},
+
+	fadeTo: function( speed, to, easing, callback ) {
+		return this.filter(":hidden").css("opacity", 0).show().end()
+					.animate({opacity: to}, speed, easing, callback);
+	},
+
+	animate: function( prop, speed, easing, callback ) {
+		var optall = jQuery.speed(speed, easing, callback);
+
+		if ( jQuery.isEmptyObject( prop ) ) {
+			return this.each( optall.complete );
+		}
+
+		return this[ optall.queue === false ? "each" : "queue" ](function() {
+			// XXX ‘this’ does not always have a nodeName when running the
+			// test suite
+
+			var opt = jQuery.extend({}, optall), p,
+				isElement = this.nodeType === 1,
+				hidden = isElement && jQuery(this).is(":hidden"),
+				self = this;
+
+			for ( p in prop ) {
+				var name = jQuery.camelCase( p );
+
+				if ( p !== name ) {
+					prop[ name ] = prop[ p ];
+					delete prop[ p ];
+					p = name;
+				}
+
+				if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
+					return opt.complete.call(this);
+				}
+
+				if ( isElement && ( p === "height" || p === "width" ) ) {
+					// Make sure that nothing sneaks out
+					// Record all 3 overflow attributes because IE does not
+					// change the overflow attribute when overflowX and
+					// overflowY are set to the same value
+					opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
+
+					// Set display property to inline-block for height/width
+					// animations on inline elements that are having width/height
+					// animated
+					if ( jQuery.css( this, "display" ) === "inline" &&
+							jQuery.css( this, "float" ) === "none" ) {
+						if ( !jQuery.support.inlineBlockNeedsLayout ) {
+							this.style.display = "inline-block";
+
+						} else {
+							var display = defaultDisplay(this.nodeName);
+
+							// inline-level elements accept inline-block;
+							// block-level elements need to be inline with layout
+							if ( display === "inline" ) {
+								this.style.display = "inline-block";
+
+							} else {
+								this.style.display = "inline";
+								this.style.zoom = 1;
+							}
+						}
+					}
+				}
+
+				if ( jQuery.isArray( prop[p] ) ) {
+					// Create (if needed) and add to specialEasing
+					(opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
+					prop[p] = prop[p][0];
+				}
+			}
+
+			if ( opt.overflow != null ) {
+				this.style.overflow = "hidden";
+			}
+
+			opt.curAnim = jQuery.extend({}, prop);
+
+			jQuery.each( prop, function( name, val ) {
+				var e = new jQuery.fx( self, opt, name );
+
+				if ( rfxtypes.test(val) ) {
+					e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+
+				} else {
+					var parts = rfxnum.exec(val),
+						start = e.cur(true) || 0;
+
+					if ( parts ) {
+						var end = parseFloat( parts[2] ),
+							unit = parts[3] || "px";
+
+						// We need to compute starting value
+						if ( unit !== "px" ) {
+							jQuery.style( self, name, (end || 1) + unit);
+							start = ((end || 1) / e.cur(true)) * start;
+							jQuery.style( self, name, start + unit);
+						}
+
+						// If a +=/-= token was provided, we're doing a relative animation
+						if ( parts[1] ) {
+							end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
+						}
+
+						e.custom( start, end, unit );
+
+					} else {
+						e.custom( start, val, "" );
+					}
+				}
+			});
+
+			// For JS strict compliance
+			return true;
+		});
+	},
+
+	stop: function( clearQueue, gotoEnd ) {
+		var timers = jQuery.timers;
+
+		if ( clearQueue ) {
+			this.queue([]);
+		}
+
+		this.each(function() {
+			// go in reverse order so anything added to the queue during the loop is ignored
+			for ( var i = timers.length - 1; i >= 0; i-- ) {
+				if ( timers[i].elem === this ) {
+					if (gotoEnd) {
+						// force the next step to be the last
+						timers[i](true);
+					}
+
+					timers.splice(i, 1);
+				}
+			}
+		});
+
+		// start the next in the queue if the last step wasn't forced
+		if ( !gotoEnd ) {
+			this.dequeue();
+		}
+
+		return this;
+	}
+
+});
+
+function genFx( type, num ) {
+	var obj = {};
+
+	jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
+		obj[ this ] = type;
+	});
+
+	return obj;
+}
+
+// Generate shortcuts for custom animations
+jQuery.each({
+	slideDown: genFx("show", 1),
+	slideUp: genFx("hide", 1),
+	slideToggle: genFx("toggle", 1),
+	fadeIn: { opacity: "show" },
+	fadeOut: { opacity: "hide" }
+}, function( name, props ) {
+	jQuery.fn[ name ] = function( speed, easing, callback ) {
+		return this.animate( props, speed, easing, callback );
+	};
+});
+
+jQuery.extend({
+	speed: function( speed, easing, fn ) {
+		var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
+			complete: fn || !fn && easing ||
+				jQuery.isFunction( speed ) && speed,
+			duration: speed,
+			easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+		};
+
+		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+			opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
+
+		// Queueing
+		opt.old = opt.complete;
+		opt.complete = function() {
+			if ( opt.queue !== false ) {
+				jQuery(this).dequeue();
+			}
+			if ( jQuery.isFunction( opt.old ) ) {
+				opt.old.call( this );
+			}
+		};
+
+		return opt;
+	},
+
+	easing: {
+		linear: function( p, n, firstNum, diff ) {
+			return firstNum + diff * p;
+		},
+		swing: function( p, n, firstNum, diff ) {
+			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+		}
+	},
+
+	timers: [],
+
+	fx: function( elem, options, prop ) {
+		this.options = options;
+		this.elem = elem;
+		this.prop = prop;
+
+		if ( !options.orig ) {
+			options.orig = {};
+		}
+	}
+
+});
+
+jQuery.fx.prototype = {
+	// Simple function for setting a style value
+	update: function() {
+		if ( this.options.step ) {
+			this.options.step.call( this.elem, this.now, this );
+		}
+
+		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+	},
+
+	// Get the current size
+	cur: function() {
+		if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
+			return this.elem[ this.prop ];
+		}
+
+		var r = parseFloat( jQuery.css( this.elem, this.prop ) );
+		return r && r > -10000 ? r : 0;
+	},
+
+	// Start an animation from one number to another
+	custom: function( from, to, unit ) {
+		this.startTime = jQuery.now();
+		this.start = from;
+		this.end = to;
+		this.unit = unit || this.unit || "px";
+		this.now = this.start;
+		this.pos = this.state = 0;
+
+		var self = this, fx = jQuery.fx;
+		function t( gotoEnd ) {
+			return self.step(gotoEnd);
+		}
+
+		t.elem = this.elem;
+
+		if ( t() && jQuery.timers.push(t) && !timerId ) {
+			timerId = setInterval(fx.tick, fx.interval);
+		}
+	},
+
+	// Simple 'show' function
+	show: function() {
+		// Remember where we started, so that we can go back to it later
+		this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+		this.options.show = true;
+
+		// Begin the animation
+		// Make sure that we start at a small width/height to avoid any
+		// flash of content
+		this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
+
+		// Start by showing the element
+		jQuery( this.elem ).show();
+	},
+
+	// Simple 'hide' function
+	hide: function() {
+		// Remember where we started, so that we can go back to it later
+		this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+		this.options.hide = true;
+
+		// Begin the animation
+		this.custom(this.cur(), 0);
+	},
+
+	// Each step of an animation
+	step: function( gotoEnd ) {
+		var t = jQuery.now(), done = true;
+
+		if ( gotoEnd || t >= this.options.duration + this.startTime ) {
+			this.now = this.end;
+			this.pos = this.state = 1;
+			this.update();
+
+			this.options.curAnim[ this.prop ] = true;
+
+			for ( var i in this.options.curAnim ) {
+				if ( this.options.curAnim[i] !== true ) {
+					done = false;
+				}
+			}
+
+			if ( done ) {
+				// Reset the overflow
+				if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
+					var elem = this.elem, options = this.options;
+					jQuery.each( [ "", "X", "Y" ], function (index, value) {
+						elem.style[ "overflow" + value ] = options.overflow[index];
+					} );
+				}
+
+				// Hide the element if the "hide" operation was done
+				if ( this.options.hide ) {
+					jQuery(this.elem).hide();
+				}
+
+				// Reset the properties, if the item has been hidden or shown
+				if ( this.options.hide || this.options.show ) {
+					for ( var p in this.options.curAnim ) {
+						jQuery.style( this.elem, p, this.options.orig[p] );
+					}
+				}
+
+				// Execute the complete function
+				this.options.complete.call( this.elem );
+			}
+
+			return false;
+
+		} else {
+			var n = t - this.startTime;
+			this.state = n / this.options.duration;
+
+			// Perform the easing function, defaults to swing
+			var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
+			var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
+			this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
+			this.now = this.start + ((this.end - this.start) * this.pos);
+
+			// Perform the next step of the animation
+			this.update();
+		}
+
+		return true;
+	}
+};
+
+jQuery.extend( jQuery.fx, {
+	tick: function() {
+		var timers = jQuery.timers;
+
+		for ( var i = 0; i < timers.length; i++ ) {
+			if ( !timers[i]() ) {
+				timers.splice(i--, 1);
+			}
+		}
+
+		if ( !timers.length ) {
+			jQuery.fx.stop();
+		}
+	},
+
+	interval: 13,
+
+	stop: function() {
+		clearInterval( timerId );
+		timerId = null;
+	},
+
+	speeds: {
+		slow: 600,
+		fast: 200,
+		// Default speed
+		_default: 400
+	},
+
+	step: {
+		opacity: function( fx ) {
+			jQuery.style( fx.elem, "opacity", fx.now );
+		},
+
+		_default: function( fx ) {
+			if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
+				fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
+			} else {
+				fx.elem[ fx.prop ] = fx.now;
+			}
+		}
+	}
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+	jQuery.expr.filters.animated = function( elem ) {
+		return jQuery.grep(jQuery.timers, function( fn ) {
+			return elem === fn.elem;
+		}).length;
+	};
+}
+
+function defaultDisplay( nodeName ) {
+	if ( !elemdisplay[ nodeName ] ) {
+		var elem = jQuery("<" + nodeName + ">").appendTo("body"),
+			display = elem.css("display");
+
+		elem.remove();
+
+		if ( display === "none" || display === "" ) {
+			display = "block";
+		}
+
+		elemdisplay[ nodeName ] = display;
+	}
+
+	return elemdisplay[ nodeName ];
+}
+
+
+
+
+var rtable = /^t(?:able|d|h)$/i,
+	rroot = /^(?:body|html)$/i;
+
+if ( "getBoundingClientRect" in document.documentElement ) {
+	jQuery.fn.offset = function( options ) {
+		var elem = this[0], box;
+
+		if ( options ) { 
+			return this.each(function( i ) {
+				jQuery.offset.setOffset( this, options, i );
+			});
+		}
+
+		if ( !elem || !elem.ownerDocument ) {
+			return null;
+		}
+
+		if ( elem === elem.ownerDocument.body ) {
+			return jQuery.offset.bodyOffset( elem );
+		}
+
+		try {
+			box = elem.getBoundingClientRect();
+		} catch(e) {}
+
+		var doc = elem.ownerDocument,
+			docElem = doc.documentElement;
+
+		// Make sure we're not dealing with a disconnected DOM node
+		if ( !box || !jQuery.contains( docElem, elem ) ) {
+			return box || { top: 0, left: 0 };
+		}
+
+		var body = doc.body,
+			win = getWindow(doc),
+			clientTop  = docElem.clientTop  || body.clientTop  || 0,
+			clientLeft = docElem.clientLeft || body.clientLeft || 0,
+			scrollTop  = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop ),
+			scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft),
+			top  = box.top  + scrollTop  - clientTop,
+			left = box.left + scrollLeft - clientLeft;
+
+		return { top: top, left: left };
+	};
+
+} else {
+	jQuery.fn.offset = function( options ) {
+		var elem = this[0];
+
+		if ( options ) { 
+			return this.each(function( i ) {
+				jQuery.offset.setOffset( this, options, i );
+			});
+		}
+
+		if ( !elem || !elem.ownerDocument ) {
+			return null;
+		}
+
+		if ( elem === elem.ownerDocument.body ) {
+			return jQuery.offset.bodyOffset( elem );
+		}
+
+		jQuery.offset.initialize();
+
+		var offsetParent = elem.offsetParent, prevOffsetParent = elem,
+			doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
+			body = doc.body, defaultView = doc.defaultView,
+			prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
+			top = elem.offsetTop, left = elem.offsetLeft;
+
+		while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+			if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+				break;
+			}
+
+			computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
+			top  -= elem.scrollTop;
+			left -= elem.scrollLeft;
+
+			if ( elem === offsetParent ) {
+				top  += elem.offsetTop;
+				left += elem.offsetLeft;
+
+				if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
+					top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
+					left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+				}
+
+				prevOffsetParent = offsetParent;
+				offsetParent = elem.offsetParent;
+			}
+
+			if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
+				top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
+				left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+			}
+
+			prevComputedStyle = computedStyle;
+		}
+
+		if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
+			top  += body.offsetTop;
+			left += body.offsetLeft;
+		}
+
+		if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+			top  += Math.max( docElem.scrollTop, body.scrollTop );
+			left += Math.max( docElem.scrollLeft, body.scrollLeft );
+		}
+
+		return { top: top, left: left };
+	};
+}
+
+jQuery.offset = {
+	initialize: function() {
+		var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
+			html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+
+		jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
+
+		container.innerHTML = html;
+		body.insertBefore( container, body.firstChild );
+		innerDiv = container.firstChild;
+		checkDiv = innerDiv.firstChild;
+		td = innerDiv.nextSibling.firstChild.firstChild;
+
+		this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
+		this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
+
+		checkDiv.style.position = "fixed";
+		checkDiv.style.top = "20px";
+
+		// safari subtracts parent border width here which is 5px
+		this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
+		checkDiv.style.position = checkDiv.style.top = "";
+
+		innerDiv.style.overflow = "hidden";
+		innerDiv.style.position = "relative";
+
+		this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
+
+		this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
+
+		body.removeChild( container );
+		body = container = innerDiv = checkDiv = table = td = null;
+		jQuery.offset.initialize = jQuery.noop;
+	},
+
+	bodyOffset: function( body ) {
+		var top = body.offsetTop, left = body.offsetLeft;
+
+		jQuery.offset.initialize();
+
+		if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
+			top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
+			left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
+		}
+
+		return { top: top, left: left };
+	},
+	
+	setOffset: function( elem, options, i ) {
+		var position = jQuery.css( elem, "position" );
+
+		// set position first, in-case top/left are set even on static elem
+		if ( position === "static" ) {
+			elem.style.position = "relative";
+		}
+
+		var curElem = jQuery( elem ),
+			curOffset = curElem.offset(),
+			curCSSTop = jQuery.css( elem, "top" ),
+			curCSSLeft = jQuery.css( elem, "left" ),
+			calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1),
+			props = {}, curPosition = {}, curTop, curLeft;
+
+		// need to be able to calculate position if either top or left is auto and position is absolute
+		if ( calculatePosition ) {
+			curPosition = curElem.position();
+		}
+
+		curTop  = calculatePosition ? curPosition.top  : parseInt( curCSSTop,  10 ) || 0;
+		curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0;
+
+		if ( jQuery.isFunction( options ) ) {
+			options = options.call( elem, i, curOffset );
+		}
+
+		if (options.top != null) {
+			props.top = (options.top - curOffset.top) + curTop;
+		}
+		if (options.left != null) {
+			props.left = (options.left - curOffset.left) + curLeft;
+		}
+		
+		if ( "using" in options ) {
+			options.using.call( elem, props );
+		} else {
+			curElem.css( props );
+		}
+	}
+};
+
+
+jQuery.fn.extend({
+	position: function() {
+		if ( !this[0] ) {
+			return null;
+		}
+
+		var elem = this[0],
+
+		// Get *real* offsetParent
+		offsetParent = this.offsetParent(),
+
+		// Get correct offsets
+		offset       = this.offset(),
+		parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+		// Subtract element margins
+		// note: when an element has margin: auto the offsetLeft and marginLeft
+		// are the same in Safari causing offset.left to incorrectly be 0
+		offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
+		offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
+
+		// Add offsetParent borders
+		parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
+		parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
+
+		// Subtract the two offsets
+		return {
+			top:  offset.top  - parentOffset.top,
+			left: offset.left - parentOffset.left
+		};
+	},
+
+	offsetParent: function() {
+		return this.map(function() {
+			var offsetParent = this.offsetParent || document.body;
+			while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
+				offsetParent = offsetParent.offsetParent;
+			}
+			return offsetParent;
+		});
+	}
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ["Left", "Top"], function( i, name ) {
+	var method = "scroll" + name;
+
+	jQuery.fn[ method ] = function(val) {
+		var elem = this[0], win;
+		
+		if ( !elem ) {
+			return null;
+		}
+
+		if ( val !== undefined ) {
+			// Set the scroll offset
+			return this.each(function() {
+				win = getWindow( this );
+
+				if ( win ) {
+					win.scrollTo(
+						!i ? val : jQuery(win).scrollLeft(),
+						 i ? val : jQuery(win).scrollTop()
+					);
+
+				} else {
+					this[ method ] = val;
+				}
+			});
+		} else {
+			win = getWindow( elem );
+
+			// Return the scroll offset
+			return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
+				jQuery.support.boxModel && win.document.documentElement[ method ] ||
+					win.document.body[ method ] :
+				elem[ method ];
+		}
+	};
+});
+
+function getWindow( elem ) {
+	return jQuery.isWindow( elem ) ?
+		elem :
+		elem.nodeType === 9 ?
+			elem.defaultView || elem.parentWindow :
+			false;
+}
+
+
+
+
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function( i, name ) {
+
+	var type = name.toLowerCase();
+
+	// innerHeight and innerWidth
+	jQuery.fn["inner" + name] = function() {
+		return this[0] ?
+			parseFloat( jQuery.css( this[0], type, "padding" ) ) :
+			null;
+	};
+
+	// outerHeight and outerWidth
+	jQuery.fn["outer" + name] = function( margin ) {
+		return this[0] ?
+			parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
+			null;
+	};
+
+	jQuery.fn[ type ] = function( size ) {
+		// Get window width or height
+		var elem = this[0];
+		if ( !elem ) {
+			return size == null ? null : this;
+		}
+		
+		if ( jQuery.isFunction( size ) ) {
+			return this.each(function( i ) {
+				var self = jQuery( this );
+				self[ type ]( size.call( this, i, self[ type ]() ) );
+			});
+		}
+
+		return jQuery.isWindow( elem ) ?
+			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+			elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
+			elem.document.body[ "client" + name ] :
+
+			// Get document width or height
+			(elem.nodeType === 9) ? // is it a document
+				// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+				Math.max(
+					elem.documentElement["client" + name],
+					elem.body["scroll" + name], elem.documentElement["scroll" + name],
+					elem.body["offset" + name], elem.documentElement["offset" + name]
+				) :
+
+				// Get or set width or height on the element
+				size === undefined ?
+					// Get width or height on the element
+					parseFloat( jQuery.css( elem, type ) ) :
+
+					// Set the width or height on the element (default to pixels if value is unitless)
+					this.css( type, typeof size === "string" ? size : size + "px" );
+	};
+
+});
+
+
+})(window);
diff --git a/browserid/static/dialog/jquery/download/test/run.js b/browserid/static/dialog/jquery/download/test/run.js
new file mode 100644
index 0000000000000000000000000000000000000000..5bb69abb11586fc1907b707688474a3238c82d77
--- /dev/null
+++ b/browserid/static/dialog/jquery/download/test/run.js
@@ -0,0 +1,16 @@
+// load('steal/compress/test/run.js')
+/**
+ * Tests compressing a very basic page and one that is using steal
+ */
+load('steal/rhino/steal.js')
+steal('//steal/test/test', function( s ) {
+	STEALPRINT = false;
+	s.test.module("jquery/download")
+	
+	s.test.test("controller", function(){
+		load('steal/rhino/steal.js')
+		s.test.open('jquery/download/test/controllerpage.html')
+		s.test.ok(MyController, "Controller was loaded")
+		s.test.clear();
+	});
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/default/default.html b/browserid/static/dialog/jquery/event/default/default.html
new file mode 100644
index 0000000000000000000000000000000000000000..ff645fe6f6f1d21437b9fbba34056f4ba5ce2310
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/default/default.html
@@ -0,0 +1,85 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>default</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .error {border: solid 1px red;}
+            .error_text { color: red; font-size: 10px;}
+            td {padding: 3px;}
+			.clickme {
+				padding: 5px; margin: 5px;
+				border: dashed 1px red;
+				width: 100px;
+			}
+			ul li {
+				float: left;
+				border: solid 1px red;
+				padding: 5px;
+				list-style: none;
+			}
+			ul { margin: 0px; padding: 0px;}
+			.tab {
+				clear: both;
+				border: solid 1px black;
+				padding: 10px;
+			}
+        </style>
+	</head>
+	<body>
+		
+		    <h1>Default Events</h1>
+			<p>A tabs widget that doesn't let you continue until the first part is complete.</p>
+<div id="demo-html">
+<div id='tabs'>
+  <ul>
+    <li><a href='#first'>Part 1</a></li>
+    <li><a href='#second'>Part 2</a></li>
+  </ul>
+  <div id='first' class='tab'>
+    <input type='checkbox' id='complete'/> Check to complete this part.
+  </div>
+  <div id='second' class='tab'>
+    You completed part 1
+  </div>
+</div>
+</div>
+	
+			
+		<script type='text/javascript' 
+                src='../../../steal/steal.js'>   
+        </script>
+<script id="demo-source" type='text/javascript'>
+steal.plugins("jquery/controller",'jquery/event/default').then(function($){
+$.Controller.extend("Tabs",{
+	init : function(){
+		this.find("li:first").addClass('active')
+		this.find(".tab:gt(0)").hide();
+	},
+	"li click" : function(el, ev){
+		ev.preventDefault();
+		if(!el.hasClass('active') && this.sub(el).triggerDefaults("show")){
+			this.sub(this.find(".active").removeClass("active")).hide();
+			el.addClass("active")	
+		}
+	},
+	sub : function(el){
+		return $(el.find("a").attr("href"))
+	},
+	".tab default.show" : function(el){
+		el.show();
+	}
+})
+
+$("#tabs").tabs();
+$("#second").bind("show",function(ev){
+	if(! $("#complete")[0].checked ){
+		ev.preventDefault();
+	}
+})
+
+}).start();
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/default/default.js b/browserid/static/dialog/jquery/event/default/default.js
new file mode 100644
index 0000000000000000000000000000000000000000..2e6a62055700337873d7fa96ac546542dc02c1de
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/default/default.js
@@ -0,0 +1,193 @@
+/**
+ * @add jQuery.event.special
+ */
+steal.plugins('jquery/event').then(function($){
+
+//cache default types for performance
+var types = {}, rnamespaces= /\.(.*)$/;
+/**
+ * @attribute default
+ * @parent specialevents
+ * @plugin jquery/event/default
+ * @download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/event/default/default.js
+ * @test jquery/event/default/qunit.html
+ * Allows you to perform default actions as a result of an event.
+ * <p>
+ * Event based APIs are a powerful way of exposing functionality of your widgets.  It also fits in 
+ * quite nicely with how the DOM works.
+ * </p>
+ * <p>
+ * Like default events in normal functions (e.g. submitting a form), synthetic default events run after
+ * all event handlers have been triggered and no event handler has called
+ * preventDefault or returned false.
+ * </p>
+ * <p>To listen for a default event, just prefix the event with default.</p>
+ * @codestart
+ * $("div").bind("default.show", function(ev){ ... });
+ * $("ul").delegate("li","default.activate", function(ev){ ... });
+ * @codeend
+ * <p>
+ * The default plugin also adds the [jQuery.fn.triggerDefault triggerDefault] and [jQuery.fn.triggerDefaults triggerDefaults] methods.  These are used to trigger 
+ * an event and report back whether preventDefault was called on the event.  The only difference is [jQuery.fn.triggerDefault triggerDefault] 
+ * doesn't bubble.
+ * </p>
+ * <h2>Example</h2>
+ * <p>Lets look at how you could build a simple tabs widget with default events.
+ * First with just jQuery:</p>
+ * <p>
+ * Default events are useful in cases where you want to provide an event based 
+ * API for users of your widgets.  Users can simply listen to your synthetic events and 
+ * prevent your default functionality by calling preventDefault.  
+ * </p>
+ * <p>
+ * In the example below, the tabs widget provides a show event.  Users of the 
+ * tabs widget simply listen for show, and if they wish for some reason, call preventDefault 
+ * to avoid showing the tab.
+ * </p>
+ * <p>
+ * In this case, the application developer doesn't want to show the second 
+ * tab until the checkbox is checked. 
+ * </p>
+ * @demo jquery/event/default/defaultjquery.html
+ * <p>Lets see how we would build this with JavaScriptMVC:</p>
+ * @demo jquery/event/default/default.html
+ */
+$.event.special["default"] = {
+	add: function( handleObj ) {
+		//save the type
+		types[handleObj.namespace.replace(rnamespaces,"")] = true;
+		
+		//move the handler ...
+		var origHandler = handleObj.handler;
+		
+		handleObj.origHandler = origHandler;
+		handleObj.handler = function(ev, data){
+			if(!ev._defaultActions) ev._defaultActions = [];
+			ev._defaultActions.push({element: this, handler: origHandler, event: ev, data: data, currentTarget: ev.currentTarget})
+		}
+	},
+	setup: function() {return true}
+}
+
+// overwrite trigger to allow default types
+var oldTrigger = $.event.trigger;
+$.event.trigger =  function defaultTriggerer( event, data, elem, bubbling){
+    //always need to convert here so we know if we have default actions
+    var type = event.type || event
+
+    if ( !bubbling ) {
+		event = typeof event === "object" ?
+			// jQuery.Event object
+			event[$.expando] ? event :
+			// Object literal
+			jQuery.extend( jQuery.Event(type), event ) :
+			// Just the event type (string)
+			jQuery.Event(type);
+
+		if ( type.indexOf("!") >= 0 ) {
+			event.type = type = type.slice(0, -1);
+			event.exclusive = true;
+		}
+        event._defaultActions = []; //set depth for possibly reused events
+    }
+	
+	var defaultGetter = jQuery.Event("default."+event.type), 
+		res;
+		
+	$.extend(defaultGetter,{
+		target: elem,
+		_defaultActions: event._defaultActions,
+		exclusive : true
+	});
+	
+	defaultGetter.stopPropagation();
+	
+	//default events only work on elements
+	if(elem){
+		oldTrigger.call($.event, defaultGetter, [defaultGetter, data], elem, true);
+	}
+	
+	//fire old trigger, this will call back here	
+    res = oldTrigger.call($.event, event, data, elem, bubbling); 
+    
+	//fire if there are default actions to run && 
+    //        we have not prevented default &&
+    //        propagation has been stopped or we are at the document element
+    //        we have reached the document
+	if (!event.isDefaultPrevented() &&
+         event._defaultActions  &&
+        ( ( event.isPropagationStopped() ) ||
+          ( !elem.parentNode && !elem.ownerDocument ) )
+          
+        ) {			
+		
+		// put event back
+		event.namespace= event.type;
+		event.type = "default";
+		event.liveFired = null;
+		
+		// call each event handler
+		for(var i = 0 ; i < event._defaultActions.length; i++){
+			var a  = event._defaultActions[i],
+				oldHandle = event.handled;
+			event.currentTarget = a.currentTarget;
+			a.handler.call(a.element, event, a.data);
+			event.handled = event.handled === null ? oldHandle : true;
+        }
+        event._defaultActions = null; //set to null so everyone else on this element ignores it
+    }
+}
+/**
+ * @add jQuery.fn
+ */
+$.fn.
+/**
+ * Triggers the event, stops the event from propagating through the DOM, and 
+ * returns whether or not the event's default action was prevented.  
+ * If true, the default action was not prevented.  If false, the 
+ * default action was prevented.  This is the same as triggerDefaults, but 
+ * the event doesn't bubble.  Use these methods to easily determine if default was 
+ * prevented, and proceed accordingly.
+ * 
+ * <p>Widget developers might use this method to perform additional logic if an event 
+ * handler doesn't prevent the default action.  For example, a tabs widget might 
+ * hide the currently shown tab if the application developer doesn't prevent default.</p>
+ * @param {Object} type The type of event to trigger.
+ * @param {Object} data Some data to pass to callbacks listening to this 
+ * event.
+ */
+triggerDefault = function(type, data){
+	if ( this[0] ) {
+		var event = $.Event( type );
+		event.stopPropagation();
+		jQuery.event.trigger( event, data, this[0] );
+		return !event.isDefaultPrevented();
+	}
+	return true;
+}
+$.fn.
+/**
+ * Triggers the event and returns whether or not the event's 
+ * default action was prevented.  If true, the default action was not 
+ * prevented.  If false, the default action was prevented.  This is the same 
+ * as triggerDefault, but the event bubbles.  Use these methods to easily determine if default was 
+ * prevented, and proceed accordingly.
+ * @param {Object} type The type of event to trigger.
+ * @param {Object} data Some data to pass to callbacks listening to this 
+ * event.
+ */
+triggerDefaults = function(type, data){
+	if ( this[0] ) {
+		var event = $.Event( type );
+		jQuery.event.trigger( event, data, this[0] );
+		return !event.isDefaultPrevented();
+	}
+	return true;
+}
+	
+	
+	
+	
+	
+	
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/default/defaultjquery.html b/browserid/static/dialog/jquery/event/default/defaultjquery.html
new file mode 100644
index 0000000000000000000000000000000000000000..c102d2ad9ea7a478a7825569cae8e3ef3a34b100
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/default/defaultjquery.html
@@ -0,0 +1,117 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+    <head>
+        <title>Default</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .error {border: solid 1px red;}
+            .error_text { color: red; font-size: 10px;}
+            td {padding: 3px;}
+            .clickme {
+                padding: 5px; margin: 5px;
+                border: dashed 1px red;
+                width: 100px;
+            }
+            ul li {
+                float: left;
+                border: solid 1px red;
+                padding: 5px;
+                list-style: none;
+            }
+            ul { margin: 0px; padding: 0px;}
+            .tab {
+                clear: both;
+                border: solid 1px black;
+                padding: 10px;
+            }
+        </style>
+    </head>
+    <body>
+        
+            <h1>Default Events</h1>
+            <p>A tabs widget that doesn't let you continue until the first part is complete.</p>
+<div id="demo-html">
+<div id='tabs'>
+  <ul>
+    <li><a href='#first'>Part 1</a></li>
+    <li><a href='#second'>Part 2</a></li>
+  </ul>
+  <div id='first' class='tab'>
+    <input type='checkbox' id='complete'/> Check to complete this part.
+  </div>
+  <div id='second' class='tab'>
+    You completed part 1
+  </div>
+</div>
+</div>
+    
+            
+        <script type='text/javascript' 
+                src='../../../steal/steal.js?jquery/event/default'>   
+        </script>
+<script id="demo-source" type='text/javascript'>
+// create a tabs plugin
+// this is code written by a widget developer, and provides an event based 
+// tabs API
+$.fn.tabs = function(){
+
+  // finds the tab from the tab button
+  var sub = function(el){
+    return $(el.find("a").attr("href"))
+  }
+  
+  this.each(function(){
+    var tab = $(this);
+    
+  //set the first tab button as active
+  tab.find("li:first").addClass('active')
+    
+  //hide all the other tabs
+  tab.find(".tab:gt(0)").hide();
+    
+  //listen for a click on a tab button
+  tab.delegate("li","click", function(ev){
+    ev.preventDefault();
+    var el = $(this);
+        
+
+    if( // not active button
+	    !el.hasClass('active') && 
+		// default wasn't prevented
+        sub(el).triggerDefaults("show")){
+			
+	  // remove active and hide old active	
+      sub(tab.find(".active").removeClass("active")).hide();
+	  
+	  //mark as active
+      el.addClass("active");
+    }
+  })
+    
+  // show a tab if default isn't prevented
+  .delegate(".tab","default.show", function(ev){
+    $(this).show();
+  })
+})
+};
+
+// create tabs widget
+// this is code written by an application developer using the tabs API
+// this code is usually in a separate file from the tabs widget code
+$("#tabs").tabs();
+
+// listen on the second tab for show
+$("#second").bind("show",function(ev){
+  
+  //if complete isn't checked
+  if(! $("#complete")[0].checked ){
+  	
+	//prevent the default action!
+    ev.preventDefault();
+  }
+});
+</script>
+
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/default/qunit.html b/browserid/static/dialog/jquery/event/default/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..207b0e31c2d000c7db0b3f27b849ff3d4fbc13cc
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/default/qunit.html
@@ -0,0 +1,22 @@
+<html>
+    <head>
+        <title>Default Test Suite</title>
+		<link rel="stylesheet" type="text/css" href="../../../funcunit/qunit/qunit.css" />
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+		<script type='text/javascript' src='../../../steal/steal.js?steal[app]=jquery/event/default/test/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">Default Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/default/test/qunit/default_test.js b/browserid/static/dialog/jquery/event/default/test/qunit/default_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..269af1c21f6081d52bbb945bf67647edeef89168
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/default/test/qunit/default_test.js
@@ -0,0 +1,104 @@
+module("jquery/event/default")
+test("namespaced with same function", function(){
+
+	var count = 0 ,  func = function(){
+		count++;
+	}
+	$("#qunit-test-area").html("<div id='one'>hey</div>")
+	$("#one").bind("foo.bar", func).bind("foo.zar", func)
+	$("#one").trigger("foo.bar")
+	equals(1, count,"jquery seems ok")
+})
+
+
+test("triggering defaults", function(){
+
+	$("#qunit-test-area").html("//jquery/event/default/test/qunit/html.micro",{})
+	
+	
+	
+	
+	var count1 = 0, defaultNum, touchNum, num = 0;;
+	$("#wrap1").bind("default.touch", function(){
+		count1++;
+		defaultNum = (++num)
+	})
+	$("#wrap1").bind("touch", function(){
+		touchNum = (++num)
+	})
+	$("#touchme1").trigger("touch")
+	equals(1, count1, "trigger default event")
+	equals(1, touchNum, "default called second")
+	equals(2, defaultNum, "default called second")
+	
+	
+	
+	//now prevent
+	
+	$("#bigwrapper").bind("touch", function(e){ e.preventDefault()})
+	$("#touchme1").trigger("touch")
+	equals(1, count1, "default event not called")
+	equals(3, touchNum, "touch called again")
+	
+	var count2 = 0;
+	$("#wrap2").bind("default.hide.me.a", function(){
+		count2++;               
+	})
+	$(document.body).bind("hide", function(ev){
+		if(ev.target.id == "clickme1"){
+			console.log("stopping and preventing")
+			ev.stopPropagation()
+			ev.preventDefault()
+		}
+			
+	})
+	$(".clickme").click(function(){
+		$(this).trigger("hide")
+	})
+	
+	
+	$("#qunit-test-area").html("")
+})
+
+
+
+test("live on default events", function(){
+	
+	$("#qunit-test-area").html("//jquery/event/default/test/qunit/html.micro",{})
+	var bw = $("#bigwrapper"), 
+		count1 = 0, 
+		count2 = 0, 
+		count3 = 0;
+	var jq = $();
+	jq.context = bw[0];
+	jq.selector = "#wrap1"
+	jq.live("default.touch", function(){
+		count1++;
+	});
+	
+	//2nd selector
+	var jq2 = $();
+	jq2.context = bw[0];
+	jq2.selector = "#wrap2"
+	jq2.live("default.touching", function(){
+		count2++;
+	});
+	
+
+	bw.delegate("#wrap2","default.somethingElse",function(){
+		count3++;
+	})
+	
+	
+	$("#touchme1").trigger("touch")
+	equals(count1,1,  "doing touch")
+	
+	$("#touchme2").trigger("touching")
+	equals(count2,1,  "doing touching")
+	
+	$("#touchme2").trigger("somethingElse")
+	equals(count3,1,  "delegated live somethingElse")
+	
+	
+	$("#qunit-test-area").html("")
+})
diff --git a/browserid/static/dialog/jquery/event/default/test/qunit/html.micro b/browserid/static/dialog/jquery/event/default/test/qunit/html.micro
new file mode 100644
index 0000000000000000000000000000000000000000..e10f1199b92640452b8160dc401c61b57a813588
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/default/test/qunit/html.micro
@@ -0,0 +1,8 @@
+<div id="bigwrapper">
+	<div id='wrap1'>
+	    <div id="touchme1">ClickMe</div>
+	</div>
+	<div id='wrap2'>
+	    <div id='touchme2'>ClickMe</a>
+	</div>
+</div>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/default/test/qunit/qunit.js b/browserid/static/dialog/jquery/event/default/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..cf8ac90b5dff931a1565e5028fac435df8d56bb7
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/default/test/qunit/qunit.js
@@ -0,0 +1,6 @@
+//we probably have to have this only describing where the tests are
+steal
+ .plugins("jquery/event/default")  //load your app
+ .plugins('funcunit/qunit','jquery/view/micro')  //load qunit
+ .then("default_test")
+ 
diff --git a/browserid/static/dialog/jquery/event/destroyed/destroyed.html b/browserid/static/dialog/jquery/event/destroyed/destroyed.html
new file mode 100644
index 0000000000000000000000000000000000000000..e486480cbf3e9a12fdff3a5230570b9474ab783c
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/destroyed/destroyed.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>destroyed demo</title>
+        <style type='text/css'>#clickToDestroy { padding: 5px; border: solid 1px;width: 200px;}</style>
+	</head>
+	<body>
+<div id='demo-html'>
+<div id='clickToDestroy'>Click Below to destroy me</div>
+<a id='change' href="javascript://">Click here!</div>
+</div>
+	    
+		<script type='text/javascript' src='../../../steal/steal.js?jquery/event/destroyed/destroyed.js'></script>
+		<script type='text/javascript' id='demo-source'>
+$("#clickToDestroy").bind("destroyed", function(){
+	$("#change").html("destroyed with "+$(this).data("testData"))
+}).data("testData","joy :)")
+$("#change").bind("click", function(){
+	$("#clickToDestroy").remove()
+})
+
+		</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/destroyed/destroyed.js b/browserid/static/dialog/jquery/event/destroyed/destroyed.js
new file mode 100644
index 0000000000000000000000000000000000000000..afd851b0c9a2ab21142ee816fede0fe5efe5e797
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/destroyed/destroyed.js
@@ -0,0 +1,40 @@
+/**
+ * @add jQuery.event.special
+ */
+steal.plugins('jquery/event').then(function( $ ) {
+	/**
+	 * @attribute destroyed
+	 * @parent specialevents
+	 * @download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/dom/destroyed/destroyed.js
+	 * @test jquery/event/destroyed/qunit.html
+	 * Provides a destroyed event on an element.
+	 * <p>
+	 * The destroyed event is called when the element
+	 * is removed as a result of jQuery DOM manipulators like remove, html,
+	 * replaceWith, etc. Destroyed events do not bubble, so make sure you don't use live or delegate with destroyed
+	 * events.
+	 * </p>
+	 * <h2>Quick Example</h2>
+	 * @codestart
+	 * $(".foo").bind("destroyed", function(){
+	 *    //clean up code
+	 * })
+	 * @codeend
+	 * <h2>Quick Demo</h2>
+	 * @demo jquery/event/destroyed/destroyed.html 
+	 * <h2>More Involved Demo</h2>
+	 * @demo jquery/event/destroyed/destroyed_menu.html 
+	 */
+
+	var oldClean = jQuery.cleanData;
+
+	$.cleanData = function( elems ) {
+		for ( var i = 0, elem;
+		(elem = elems[i]) !== undefined; i++ ) {
+			$(elem).triggerHandler("destroyed");
+			//$.event.remove( elem, 'destroyed' );
+		}
+		oldClean(elems);
+	};
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/destroyed/destroyed_menu.html b/browserid/static/dialog/jquery/event/destroyed/destroyed_menu.html
new file mode 100644
index 0000000000000000000000000000000000000000..8d6d7056cf23c0e9450a4d2a8bbab41d2b4f4bfc
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/destroyed/destroyed_menu.html
@@ -0,0 +1,96 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>destroyed demo</title>
+        <style type='text/css'>
+        	ul.menu {
+        		padding: 0px; margin: 0px;
+				border: solid 1px black;
+				width: 100px;
+				position: absolute;
+				list-style: none;
+				background-color: white;
+        	}
+			.menu li{
+				padding: 1px; margin: 0px;
+				font-size: 1px;
+			}
+			#remove {
+				color: red;
+			}
+		</style>
+	</head>
+	<body>
+<p>This demo creates a single, reusable menu for multiple elements.
+	Click each "Show Menu" button to see the menu expand.  By clicking 
+	the "Remove" button, it removes a "Show Menu".  When
+	all "Show Menu" buttons are gone, the elment is removed.
+	  After removing all the "Show Me" elements,
+	the menu will be removed completely.  This is done with the help of the
+	destroyed special event.
+</p>
+<div id='demo-html'>
+<a href='javascript://' class='context'>Show Menu 1</a>
+<a href='javascript://' class='context'>Show Menu 2</a>
+<a href='javascript://' class='context'>Show Menu 3</a>
+<br/>
+<a id='remove' href="javascript://">Remove a "Show Menu"</div>
+</div>
+	    
+		<script type='text/javascript' src='../../../steal/steal.js?jquery/event/destroyed/destroyed.js'></script>
+<script type='text/javascript' id='demo-source'>
+//create a contextmenu plugin
+jQuery.fn.reusemenu = function(options){
+  //create menu and put in dom
+  var ul = $("<ul/>")
+              .addClass("menu")
+              .html(options.length ? "<li>"+options.join("</li><li>")+"</li>" :""  )
+              .appendTo(document.body),
+      //save a reference to our handler so we can remove it
+	  hideHandler = function(){ 
+        ul.find("li").animate({fontSize: 1, padding: 1});
+      },
+	  //the number of elements that remain
+	  count = this.length; 
+  
+  //take out the hide handler when we
+  //no longer have the ul
+  ul.bind("destroyed", function(){
+    $(document).unbind("click",hideHandler )	 
+  })
+
+  $(document).click(hideHandler)	  
+  
+  //for each menu 
+  this.each(function(){
+    
+	var me = $(this);
+	
+    //position menu on click
+	me.click( function(ev) {
+		
+      ul.offset({
+        top: ev.pageY+20,
+        left: ev.pageX+20
+      }).find("li").animate({fontSize: 12, padding: 10});
+      ev.stopPropagation();
+    })
+	
+	//if last element, remove menu
+	.bind("destroyed", function() {
+      count--;
+      if(!count){
+        ul.remove();
+        ul = null;
+      }
+    })
+  })
+};
+
+$(".context").reusemenu(["reuse","able","menu"])
+$("#remove").click(function(){
+  $(".context:first").remove()
+})
+		</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/destroyed/qunit.html b/browserid/static/dialog/jquery/event/destroyed/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..f16857d89c95b006f333d291393ce626e11f47da
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/destroyed/qunit.html
@@ -0,0 +1,21 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../../funcunit/qunit/qunit.css" />
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+		<script type='text/javascript' src='../../../steal/steal.js?steal[app]=jquery/event/destroyed/test/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">destroyed Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/destroyed/test/qunit/destroyed_test.js b/browserid/static/dialog/jquery/event/destroyed/test/qunit/destroyed_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..17228983e321977425cf174926232d5c47308eb0
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/destroyed/test/qunit/destroyed_test.js
@@ -0,0 +1,12 @@
+module("jquery/event/destroyed")
+test("removing an element", function(){
+	var div = $("<div/>").data("testData",5)
+	div.appendTo($("#qunit-test-area"))
+	var destroyed = false;
+	div.bind("destroyed",function(){
+		destroyed = true;
+		equals($(this).data("testData"),5, "other data still exists")
+	})
+	div.remove();
+	ok(destroyed, "destroyed called")
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/destroyed/test/qunit/qunit.js b/browserid/static/dialog/jquery/event/destroyed/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..22bc1506de92e06b97a2128d7d489b1d0386e35b
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/destroyed/test/qunit/qunit.js
@@ -0,0 +1,6 @@
+//we probably have to have this only describing where the tests are
+steal
+ .plugins("jquery/event/destroyed")  //load your app
+ .plugins('funcunit/qunit')  //load qunit
+ .then("destroyed_test")
+ 
diff --git a/browserid/static/dialog/jquery/event/drag/drag.html b/browserid/static/dialog/jquery/event/drag/drag.html
new file mode 100644
index 0000000000000000000000000000000000000000..f9437d58b4a1cee7227b0d9078a25ff20cc45f8b
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/drag/drag.html
@@ -0,0 +1,122 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>drag</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+			.handle {
+				width: 300px;
+				height: 25px;
+				border: dashed 1px red;
+				cursor : pointer;
+			}
+			.big {
+				height: 100px;
+			}
+			#container {
+				padding: 20px;
+				border: dashed 2px green;
+			}
+			#representative {
+				width: 100px;
+				height: 60px;
+				border: solid 1px blue;
+				cursor: pointer;
+			}
+			#scrollarea ul li {height: 40px; border: solid 1px gray; font-size: 25px;list-style: none}
+			#scrollarea ul {margin: 0px;padding: 0px;}
+			#scrollarea {
+				width: 200px; height: 100px; overflow: auto;
+				border: solid 2px black;
+			}
+        </style>
+	</head>
+	<body>
+<div  id='demo-html'>
+<h2>Drag with bind</h2>
+<div id="drag" class='handle'>Drag Me</div>
+
+<h2>Delegated Drags</h2>
+<div id="delegate">
+	<div class='handle'>handle</div>
+	<div class='handle'>handle</div>
+</div>
+
+<h2>Drag Ghost</h2>
+<div id="ghost" class='handle'>Drag and I get cloned</div>
+
+<h2>Drag Revert</h2>
+<div id="revert" class='handle'>Drag and let me go</div>
+
+<h2>Limit Drag</h2>
+<div id='container'>
+	<div class='handle'>drag me out of bounds</div>
+</div>
+
+<h2>Drag Representative</h2>
+<div id='repdrag' class='handle'>Drag a Representative</div>
+<div id='representative' style='display: none'>I represent You</div>
+
+<h2>Drag Horizontal</h2>
+<div id='horizontal' class='handle'>I only move horizontal</div>
+
+<h2>Drag Scrolls</h2>
+<div id='scroll-drag' class='handle'>I move scrollbars</div>
+<div id='scrollarea'>
+	<ul><li>1</li><li>2</li><li>3</li>
+	    <li>4</li><li>5</li><li>6</li>
+		<li>7</li><li>8</li><li>9</li></ul>
+</div>
+</div>
+<h2>Allow Text Selection</h2>
+<div id='form-drag' class='handle big'>
+	<p>I should be able to drag on this</p>
+	<input type='text' value='I can be clicked on'/>
+</div>
+		<script type='text/javascript' src='../../../steal/steal.js'>   
+        </script>
+		<script type='text/javascript'>
+steal.plugins("jquery/event/drag",
+	"jquery/event/drag/scroll",
+	"jquery/event/drag/limit").then(function($){
+	
+		
+}).start()
+		</script>
+	<script type='text/javascript' id='demo-source'>
+//drag with bind
+$("#drag").bind("draginit",function(){})
+
+//delegated drags
+$("#delegate").delegate(".handle","draginit",function(){})
+
+//ghost
+$("#ghost").bind("draginit",function(ev, drag){drag.ghost()})
+
+//revert
+$("#revert").bind("draginit",function(ev, drag){drag.revert()})
+
+//limit
+$("#container").delegate(".handle","draginit",function(ev, drag){drag.limit( $("#container") )})
+
+//representative
+$("#repdrag").bind("draginit",function(ev, drag){drag.representative($("#representative"),50,30)})
+
+//horizontal
+$("#horizontal").bind("draginit",function(ev, drag){drag.horizontal()})
+
+//scrolls
+$("#scroll-drag").bind("draginit",function(ev, drag){drag.scrolls( $("#scrollarea") )})
+
+// allow form elements to be selected
+$("#form-drag").bind("dragdown",function(ev, drag){
+	if(ev.target.nodeName.toLowerCase() == 'input'){
+		drag.cancel();
+	}else{
+		ev.preventDefault();
+	}
+})
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/drag/drag.js b/browserid/static/dialog/jquery/event/drag/drag.js
new file mode 100644
index 0000000000000000000000000000000000000000..5c6b6f844781174c87fb84fa08edff3bbb0fb4e0
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/drag/drag.js
@@ -0,0 +1,500 @@
+steal.plugins('jquery/event', 'jquery/lang/vector', 'jquery/event/livehack').then(function( $ ) {
+	//modify live
+	//steal the live handler ....
+	var bind = function( object, method ) {
+		var args = Array.prototype.slice.call(arguments, 2);
+		return function() {
+			var args2 = [this].concat(args, $.makeArray(arguments));
+			return method.apply(object, args2);
+		};
+	},
+		event = $.event;
+	// var handle = event.handle; //unused
+	/**
+	 * @class jQuery.Drag
+	 * @parent specialevents
+	 * @plugin jquery/event/drag
+	 * @download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/event/drag/drag.js
+	 * @test jquery/event/drag/qunit.html
+	 * Provides drag events as a special events to jQuery.  
+	 * A jQuery.Drag instance is created on a drag and passed
+	 * as a parameter to the drag event callbacks.  By calling
+	 * methods on the drag event, you can alter the drag's
+	 * behavior.
+	 * <h2>Drag Events</h2>
+	 * The drag plugin allows you to listen to the following events:
+	 * <ul>
+	 *  <li><code>dragdown</code> - the mouse cursor is pressed down</li>
+	 *  <li><code>draginit</code> - the drag motion is started</li>
+	 *  <li><code>dragmove</code> - the drag is moved</li>
+	 *  <li><code>dragend</code> - the drag has ended</li>
+	 *  <li><code>dragover</code> - the drag is over a drop point</li>
+	 *  <li><code>dragout</code> - the drag moved out of a drop point</li>
+	 * </ul>
+	 * <p>Just by binding or delegating on one of these events, you make
+	 * the element dragable.  You can change the behavior of the drag
+	 * by calling methods on the drag object passed to the callback.
+	 * <h3>Example</h3>
+	 * Here's a quick example:
+	 * @codestart
+	 * //makes the drag vertical
+	 * $(".drags").live("draginit", function(event, drag){
+	 *   drag.vertical();
+	 * })
+	 * //gets the position of the drag and uses that to set the width
+	 * //of an element
+	 * $(".resize").live("dragmove",function(event, drag){
+	 *   $(this).width(drag.position.left() - $(this).offset().left   )
+	 * })
+	 * @codeend
+	 * <h2>Drag Object</h2>
+	 * <p>The drag object is passed after the event to drag 
+	 * event callback functions.  By calling methods
+	 * and changing the properties of the drag object,
+	 * you can alter how the drag behaves.
+	 * </p>
+	 * <p>The drag properties and methods:</p>
+	 * <ul>
+	 *  <li><code>[jQuery.Drag.prototype.cancel cancel]</code> - stops the drag motion from happening</li>
+	 *  <li><code>[jQuery.Drag.prototype.ghost ghost]</code> - copys the draggable and drags the cloned element</li>
+	 *  <li><code>[jQuery.Drag.prototype.horizontal horizontal]</code> - limits the scroll to horizontal movement</li>
+	 *  <li><code>[jQuery.Drag.prototype.location location]</code> - where the drag should be on the screen</li>
+	 *  <li><code>[jQuery.Drag.prototype.mouseElementPosition mouseElementPosition]</code> - where the mouse should be on the drag</li>
+	 *  <li><code>[jQuery.Drag.prototype.only only]</code> - only have drags, no drops</li>
+	 *  <li><code>[jQuery.Drag.prototype.representative representative]</code> - move another element in place of this element</li>
+	 *  <li><code>[jQuery.Drag.prototype.revert revert]</code> - animate the drag back to its position</li>
+	 *  <li><code>[jQuery.Drag.prototype.vertical vertical]</code> - limit the drag to vertical movement</li>
+	 *  <li><code>[jQuery.Drag.prototype.limit limit]</code> - limit the drag within an element (*limit plugin)</li>
+	 *  <li><code>[jQuery.Drag.prototype.scrolls scrolls]</code> - scroll scrollable areas when dragging near their boundries (*scroll plugin)</li>
+	 * </ul>
+	 * <h2>Demo</h2>
+	 * Now lets see some examples:
+	 * @demo jquery/event/drag/drag.html 1000
+	 * @constructor
+	 * The constructor is never called directly.
+	 */
+	$.Drag = function() {};
+
+	/**
+	 * @Static
+	 */
+	$.extend($.Drag, {
+		lowerName: "drag",
+		current: null,
+		/**
+		 * Called when someone mouses down on a draggable object.
+		 * Gathers all callback functions and creates a new Draggable.
+		 * @hide
+		 */
+		mousedown: function( ev, element ) {
+			var isLeftButton = ev.button === 0 || ev.button == 1;
+			if (!isLeftButton || this.current ) {
+				return;
+			} //only allows 1 drag at a time, but in future could allow more
+			//ev.preventDefault();
+			//create Drag
+			var drag = new $.Drag(),
+				delegate = ev.liveFired || element,
+				selector = ev.handleObj.selector,
+				self = this;
+			this.current = drag;
+
+			drag.setup({
+				element: element,
+				delegate: ev.liveFired || element,
+				selector: ev.handleObj.selector,
+				moved: false,
+				callbacks: {
+					dragdown: event.find(delegate, ["dragdown"], selector),
+					draginit: event.find(delegate, ["draginit"], selector),
+					dragover: event.find(delegate, ["dragover"], selector),
+					dragmove: event.find(delegate, ["dragmove"], selector),
+					dragout: event.find(delegate, ["dragout"], selector),
+					dragend: event.find(delegate, ["dragend"], selector)
+				},
+				destroyed: function() {
+					self.current = null;
+				}
+			}, ev);
+		}
+	});
+
+
+
+
+
+	/**
+	 * @Prototype
+	 */
+	$.extend($.Drag.prototype, {
+		setup: function( options, ev ) {
+			//this.noSelection();
+			$.extend(this, options);
+			this.element = $(this.element);
+			this.event = ev;
+			this.moved = false;
+			this.allowOtherDrags = false;
+			var mousemove = bind(this, this.mousemove),
+				mouseup = bind(this, this.mouseup);
+			this._mousemove = mousemove;
+			this._mouseup = mouseup;
+			$(document).bind('mousemove', mousemove);
+			$(document).bind('mouseup', mouseup);
+
+			if (!this.callEvents('down', this.element, ev) ) {
+				ev.preventDefault();
+			}
+		},
+		/**
+		 * Unbinds listeners and allows other drags ...
+		 * @hide
+		 */
+		destroy: function() {
+			$(document).unbind('mousemove', this._mousemove);
+			$(document).unbind('mouseup', this._mouseup);
+			if (!this.moved ) {
+				this.event = this.element = null;
+			}
+			//this.selection();
+			this.destroyed();
+		},
+		mousemove: function( docEl, ev ) {
+			if (!this.moved ) {
+				this.init(this.element, ev);
+				this.moved = true;
+			}
+
+			var pointer = ev.vector();
+			if ( this._start_position && this._start_position.equals(pointer) ) {
+				return;
+			}
+			//e.preventDefault();
+			this.draw(pointer, ev);
+		},
+		mouseup: function( docEl, event ) {
+			//if there is a current, we should call its dragstop
+			if ( this.moved ) {
+				this.end(event);
+			}
+			this.destroy();
+		},
+		noSelection: function() {
+			document.documentElement.onselectstart = function() {
+				return false;
+			};
+			document.documentElement.unselectable = "on";
+			$(document.documentElement).css('-moz-user-select', 'none');
+		},
+		selection: function() {
+			document.documentElement.onselectstart = function() {};
+			document.documentElement.unselectable = "off";
+			$(document.documentElement).css('-moz-user-select', '');
+		},
+		init: function( element, event ) {
+			element = $(element);
+			var startElement = (this.movingElement = (this.element = $(element))); //the element that has been clicked on
+			//if a mousemove has come after the click
+			this._cancelled = false; //if the drag has been cancelled
+			this.event = event;
+			this.mouseStartPosition = event.vector(); //where the mouse is located
+			/**
+			 * @attribute mouseElementPosition
+			 * The position of start of the cursor on the element
+			 */
+			this.mouseElementPosition = this.mouseStartPosition.minus(this.element.offsetv()); //where the mouse is on the Element
+			//this.callStart(element, event);
+			this.callEvents('init', element, event);
+
+			//Check what they have set and respond accordingly
+			//  if they canceled
+			if ( this._cancelled === true ) {
+				return;
+			}
+			//if they set something else as the element
+			this.startPosition = startElement != this.movingElement ? this.movingElement.offsetv() : this.currentDelta();
+
+			this.makePositioned(this.movingElement);
+			this.oldZIndex = this.movingElement.css('zIndex');
+			this.movingElement.css('zIndex', 1000);
+			if (!this._only && this.constructor.responder ) {
+				this.constructor.responder.compile(event, this);
+			}
+		},
+		makePositioned: function( that ) {
+			var style, pos = that.css('position');
+
+			if (!pos || pos == 'static' ) {
+				style = {
+					position: 'relative'
+				};
+
+				if ( window.opera ) {
+					style.top = '0px';
+					style.left = '0px';
+				}
+				that.css(style);
+			}
+		},
+		callEvents: function( type, element, event, drop ) {
+			var i, cbs = this.callbacks[this.constructor.lowerName + type];
+			for ( i = 0; i < cbs.length; i++ ) {
+				cbs[i].call(element, event, this, drop);
+			}
+			return cbs.length;
+		},
+		/**
+		 * Returns the position of the movingElement by taking its top and left.
+		 * @hide
+		 * @return {Vector}
+		 */
+		currentDelta: function() {
+			return new $.Vector(parseInt(this.movingElement.css('left'), 10) || 0, parseInt(this.movingElement.css('top'), 10) || 0);
+		},
+		//draws the position of the dragmove object
+		draw: function( pointer, event ) {
+			// only drag if we haven't been cancelled;
+			if ( this._cancelled ) {
+				return;
+			}
+			/**
+			 * @attribute location
+			 * The location of where the element should be in the page.  This 
+			 * takes into account the start position of the cursor on the element.
+			 */
+			this.location = pointer.minus(this.mouseElementPosition); // the offset between the mouse pointer and the representative that the user asked for
+			// position = mouse - (dragOffset - dragTopLeft) - mousePosition
+			this.move(event);
+			if ( this._cancelled ) {
+				return;
+			}
+			if (!event.isDefaultPrevented() ) {
+				this.position(this.location);
+			}
+
+			//fill in
+			if (!this._only && this.constructor.responder ) {
+				this.constructor.responder.show(pointer, this, event);
+			}
+		},
+		/**
+		 * Sets the position of this drag.  
+		 * 
+		 * The limit and scroll plugins
+		 * overwrite this to make sure the drag follows a particular path.
+		 * 
+		 * @param {jQuery.Vector} newOffsetv the position of the element (not the mouse)
+		 */
+		position: function( newOffsetv ) { //should draw it on the page
+			var style, dragged_element_css_offset = this.currentDelta(),
+				//  the drag element's current left + top css attributes
+				dragged_element_position_vector = // the vector between the movingElement's page and css positions
+				this.movingElement.offsetv().minus(dragged_element_css_offset); // this can be thought of as the original offset
+			this.required_css_position = newOffsetv.minus(dragged_element_position_vector);
+
+			this.offsetv = newOffsetv;
+			//dragged_element vector can probably be cached.
+			style = this.movingElement[0].style;
+			if (!this._cancelled && !this._horizontal ) {
+				style.top = this.required_css_position.top() + "px";
+			}
+			if (!this._cancelled && !this._vertical ) {
+				style.left = this.required_css_position.left() + "px";
+			}
+		},
+		move: function( event ) {
+			this.callEvents('move', this.element, event);
+		},
+		over: function( event, drop ) {
+			this.callEvents('over', this.element, event, drop);
+		},
+		out: function( event, drop ) {
+			this.callEvents('out', this.element, event, drop);
+		},
+		/**
+		 * Called on drag up
+		 * @hide
+		 * @param {Event} event a mouseup event signalling drag/drop has completed
+		 */
+		end: function( event ) {
+			if ( this._cancelled ) {
+				return;
+			}
+			if (!this._only && this.constructor.responder ) {
+				this.constructor.responder.end(event, this);
+			}
+
+			this.callEvents('end', this.element, event);
+
+			if ( this._revert ) {
+				var self = this;
+				this.movingElement.animate({
+					top: this.startPosition.top() + "px",
+					left: this.startPosition.left() + "px"
+				}, function() {
+					self.cleanup.apply(self, arguments);
+				});
+			}
+			else {
+				this.cleanup();
+			}
+			this.event = null;
+		},
+		/**
+		 * Cleans up drag element after drag drop.
+		 * @hide
+		 */
+		cleanup: function() {
+			this.movingElement.css({
+				zIndex: this.oldZIndex
+			});
+			if ( this.movingElement[0] !== this.element[0] ) {
+				this.movingElement.css({
+					display: 'none'
+				});
+			}
+			if ( this._removeMovingElement ) {
+				this.movingElement.remove();
+			}
+
+			this.movingElement = this.element = this.event = null;
+		},
+		/**
+		 * Stops drag drop from running.
+		 */
+		cancel: function() {
+			this._cancelled = true;
+			//this.end(this.event);
+			if (!this._only && this.constructor.responder ) {
+				this.constructor.responder.clear(this.event.vector(), this, this.event);
+			}
+			this.destroy();
+
+		},
+		/**
+		 * Clones the element and uses it as the moving element.
+		 * @return {jQuery.fn} the ghost
+		 */
+		ghost: function( loc ) {
+			// create a ghost by cloning the source element and attach the clone to the dom after the source element
+			var ghost = this.movingElement.clone().css('position', 'absolute');
+			(loc ? $(loc) : this.movingElement).after(ghost);
+			ghost.width(this.movingElement.width()).height(this.movingElement.height());
+
+			// store the original element and make the ghost the dragged element
+			this.movingElement = ghost;
+			this._removeMovingElement = true;
+			return ghost;
+		},
+		/**
+		 * Use a representative element, instead of the movingElement.
+		 * @param {HTMLElement} element the element you want to actually drag
+		 * @param {Number} offsetX the x position where you want your mouse on the object
+		 * @param {Number} offsetY the y position where you want your mouse on the object
+		 */
+		representative: function( element, offsetX, offsetY ) {
+			this._offsetX = offsetX || 0;
+			this._offsetY = offsetY || 0;
+
+			var p = this.mouseStartPosition;
+
+			this.movingElement = $(element);
+			this.movingElement.css({
+				top: (p.y() - this._offsetY) + "px",
+				left: (p.x() - this._offsetX) + "px",
+				display: 'block',
+				position: 'absolute'
+			}).show();
+
+			this.mouseElementPosition = new $.Vector(this._offsetX, this._offsetY);
+		},
+		/**
+		 * Makes the movingElement go back to its original position after drop.
+		 * @codestart
+		 * ".handle dragend" : function( el, ev, drag ) {
+		 *    drag.revert()
+		 * }
+		 * @codeend
+		 * @param {Boolean} [val] optional, set to false if you don't want to revert.
+		 */
+		revert: function( val ) {
+			this._revert = val === null ? true : val;
+		},
+		/**
+		 * Isolates the drag to vertical movement.
+		 */
+		vertical: function() {
+			this._vertical = true;
+		},
+		/**
+		 * Isolates the drag to horizontal movement.
+		 */
+		horizontal: function() {
+			this._horizontal = true;
+		},
+
+
+		/**
+		 * Respondables will not be alerted to this drag.
+		 */
+		only: function( only ) {
+			return (this._only = (only === undefined ? true : only));
+		}
+	});
+
+	/**
+	 * @add jQuery.event.special
+	 */
+	event.setupHelper([
+	/**
+	 * @attribute dragdown
+	 * <p>Listens for when a drag movement has started on a mousedown.
+	 * If you listen to this, the mousedown's default event (preventing
+	 * text selection) is not prevented.  You are responsible for calling it
+	 * if you want it (you probably do).  </p>
+	 * <p><b>Why might you not want it?</b></p>
+	 * <p>You might want it if you want to allow text selection on element
+	 * within the drag element.  Typically these are input elements.</p>
+	 * <p>Drag events are covered in more detail in [jQuery.Drag].</p>
+	 * @codestart
+	 * $(".handles").live("dragdown", function(ev, drag){})
+	 * @codeend
+	 */
+	'dragdown',
+	/**
+	 * @attribute draginit
+	 * Called when the drag starts.
+	 * <p>Drag events are covered in more detail in [jQuery.Drag].</p>
+	 */
+	'draginit',
+	/**
+	 * @attribute dragover
+	 * Called when the drag is over a drop.
+	 * <p>Drag events are covered in more detail in [jQuery.Drag].</p>
+	 */
+	'dragover',
+	/**
+	 * @attribute dragmove
+	 * Called when the drag is moved.
+	 * <p>Drag events are covered in more detail in [jQuery.Drag].</p>
+	 */
+	'dragmove',
+	/**
+	 * @attribute dragout
+	 * When the drag leaves a drop point.
+	 * <p>Drag events are covered in more detail in [jQuery.Drag].</p>
+	 */
+	'dragout',
+	/**
+	 * @attribute dragend
+	 * Called when the drag is done.
+	 * <p>Drag events are covered in more detail in [jQuery.Drag].</p>
+	 */
+	'dragend'], "mousedown", function( e ) {
+		$.Drag.mousedown.call($.Drag, e, this);
+
+	});
+
+
+
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/drag/limit/limit.html b/browserid/static/dialog/jquery/event/drag/limit/limit.html
new file mode 100644
index 0000000000000000000000000000000000000000..604dbf74e7a91a18e9a4b5a8f287500d0d31e270
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/drag/limit/limit.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>drag</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .error {border: solid 1px red;}
+            .error_text { color: red; font-size: 10px;}
+            td {padding: 3px;}
+			.handle {
+				width: 300px;
+				height: 25px;
+				border: dashed 1px red;
+				cursor : pointer;
+			}
+			#internal .handle {
+				border-color: green;
+			}
+			#internal {
+				border: solid 3px green;
+				padding: 5px;
+				margin-top: 50px;
+			}
+			#ondoc {
+				border: solid 3px red;
+				padding: 5px;
+			}
+        </style>
+	</head>
+	<body>
+	    <div id="internal">
+	    	<div class='handle'>handle</div>
+			<div class='handle'>handle</div>
+	    </div>
+		
+		<div id="ondoc">
+	    	<div class='handle'>handle</div>
+			<div class='handle'>handle</div>
+	    </div>
+		<script type='text/javascript' 
+                src='../../../../steal/steal.js?steal[app]=jquery/event/drag/limit&steal[env]=development'
+                package='main.js'
+                compress='false'>   
+        </script>
+		<script type='text/javascript'>
+			$("#ondoc .handle").live("draginit", function(ev, drag){
+				drag.limit($("#ondoc"))
+			})
+			$("#ondoc .handle").live("dragmove", function(ev, drag){
+				//console.log("dragmove",this, ev, drag)
+			})
+			$("#ondoc .handle").live("dragend", function(ev, drag){
+				//console.log("dragend",this, ev, drag)
+			})
+			$("#ondoc .handle").live("mouesdown", function(){
+				//console.log("mousedowned")
+			})
+			
+			//do internal
+			
+			var jq = $()
+			jq.context = document.getElementById("internal")
+			jq.selector = ".handle"
+			
+			jq.live("dragstart",function(ev, drag){
+				console.log("internal works")
+			})
+			
+		</script>
+		
+		
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/drag/limit/limit.js b/browserid/static/dialog/jquery/event/drag/limit/limit.js
new file mode 100644
index 0000000000000000000000000000000000000000..9398e83f6b104eb161063bb70e959e9945b90855
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/drag/limit/limit.js
@@ -0,0 +1,62 @@
+/**
+ * @add jQuery.Drag.prototype
+ */
+
+steal.plugins('jquery/event/drag', 'jquery/dom/cur_styles').then(function( $ ) {
+
+
+	$.Drag.prototype
+	/**
+	 * @function limit
+	 * @plugin jquery/event/drag/limit
+	 * @download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/event/event/drag/limit/limit.js
+	 * limits the drag to a containing element
+	 * @param {jQuery} container
+	 * @return {$.Drag}
+	 */
+	.limit = function( container ) {
+		//on draws ... make sure this happens
+		var styles = container.curStyles('borderTopWidth', 'paddingTop', 'borderLeftWidth', 'paddingLeft'),
+			paddingBorder = new $.Vector(
+			parseInt(styles.borderLeftWidth, 10) + parseInt(styles.paddingLeft, 10) || 0, parseInt(styles.borderTopWidth, 10) + parseInt(styles.paddingTop, 10) || 0);
+
+		this._limit = {
+			offset: container.offsetv().plus(paddingBorder),
+			size: container.dimensionsv()
+		};
+		return this;
+	};
+
+	var oldPosition = $.Drag.prototype.position;
+	$.Drag.prototype.position = function( offsetPositionv ) {
+		//adjust required_css_position accordingly
+		if ( this._limit ) {
+			var movingSize = this.movingElement.dimensionsv('outer'),
+				lot = this._limit.offset.top(),
+				lof = this._limit.offset.left(),
+				height = this._limit.size.height(),
+				width = this._limit.size.width();
+
+			//check if we are out of bounds ...
+			//above
+			if ( offsetPositionv.top() < lot ) {
+				offsetPositionv.top(lot);
+			}
+			//below
+			if ( offsetPositionv.top() + movingSize.height() > lot + height ) {
+				offsetPositionv.top(lot + height - movingSize.height());
+			}
+			//left
+			if ( offsetPositionv.left() < lof ) {
+				offsetPositionv.left(lof);
+			}
+			//right
+			if ( offsetPositionv.left() + movingSize.width() > lof + width ) {
+				offsetPositionv.left(lof + width - movingSize.left());
+			}
+		}
+
+		oldPosition.call(this, offsetPositionv);
+	};
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/drag/qunit.html b/browserid/static/dialog/jquery/event/drag/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..4ffe9031c8b346ffd041502b1e7510ed652bf1f2
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/drag/qunit.html
@@ -0,0 +1,16 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../../funcunit/qunit/qunit.css" />
+    </head>
+    <body>
+
+        <h1 id="qunit-header">Drag/Drop Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+
+    <script type='text/javascript' src='../../../steal/steal.js?steal[app]=jquery/event/drag/test/qunit'></script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/drag/scroll/scroll.js b/browserid/static/dialog/jquery/event/drag/scroll/scroll.js
new file mode 100644
index 0000000000000000000000000000000000000000..75a427eac83017d6034158347970d8c415daf667
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/drag/scroll/scroll.js
@@ -0,0 +1,120 @@
+steal.plugins("jquery/event/drop").then(function($){ //needs drop to determine if respondable
+
+/**
+ * @add jQuery.Drag.prototype
+ */
+$.Drag.prototype.
+	/**
+	 * Will scroll elements with a scroll bar as the drag moves to borders.
+	 * @plugin jquery/event/drag/scroll
+	 * @download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/event/drag/scroll/scroll.js
+	 * @param {jQuery} elements to scroll.  The window can be in this array.
+	 */
+	scrolls = function(elements){
+		for(var i = 0 ; i < elements.length; i++){
+			this.constructor.responder._responders.push( new $.Scrollable(elements[i]) )
+		}
+	},
+	
+$.Scrollable = function(element){
+	this.element = jQuery(element);
+}
+$.extend($.Scrollable.prototype,{
+	init: function( element ) {
+		this.element = jQuery(element);
+	},
+	callHandlers: function( method, el, ev, drag ) {
+		this[method](el || this.element[0], ev, this, drag)
+	},
+	dropover: function() {
+		
+	},
+	dropon: function() {
+		this.clear_timeout();
+	}, 
+	dropout: function() {
+		this.clear_timeout();
+	},
+	dropinit: function() {
+		
+	},
+	dropend: function() {},
+	clear_timeout: function() {
+		if(this.interval){
+			clearTimeout(this.interval)
+			this.interval = null;
+		}
+	},
+	distance: function( diff ) {
+		return (30 - diff) / 2;
+	},
+	dropmove: function( el, ev, drop, drag ) {
+		
+		//if we were about to call a move, clear it.
+		this.clear_timeout();
+		
+		//position of the mouse
+		var mouse = ev.vector(),
+		
+		//get the object we are going to get the boundries of
+			location_object = $(el == document.documentElement ? window : el),
+		
+		//get the dimension and location of that object
+			dimensions = location_object.dimensionsv('outer'),
+			position = location_object.offsetv(),
+		
+		//how close our mouse is to the boundries
+			bottom = position.y()+dimensions.y() - mouse.y(),
+			top = mouse.y() - position.y(),
+			right = position.x()+dimensions.x() - mouse.x(),
+			left = mouse.x() - position.x(),
+		
+		//how far we should scroll
+			dx =0, dy =0;
+
+		
+		//check if we should scroll
+		if(bottom < 30)
+			dy = this.distance(bottom);
+		else if(top < 30)
+			dy = -this.distance(top)
+		if(right < 30)
+			dx = this.distance(right);
+		else if(left < 30)
+			dx = -this.distance(left);
+		
+		//if we should scroll
+		if(dx || dy){
+			//set a timeout that will create a mousemove on that object
+			var self = this;
+			this.interval =  setTimeout( function(){
+				self.move($(el), drag.movingElement, dx, dy, ev, ev.clientX, ev.clientY, ev.screenX, ev.screenY)
+			},15)
+		}
+	},
+	/**
+	 * Scrolls an element then calls mouse a mousemove in the same location.
+	 * @param {HTMLElement} scroll_element the element to be scrolled
+	 * @param {HTMLElement} drag_element
+	 * @param {Number} dx how far to scroll
+	 * @param {Number} dy how far to scroll
+	 * @param {Number} x the mouse position
+	 * @param {Number} y the mouse position
+	 */
+	move: function( scroll_element, drag_element, dx, dy, ev/*, x,y,sx, sy*/ ) {
+		scroll_element.scrollTop( scroll_element.scrollTop() + dy);
+		scroll_element.scrollLeft(scroll_element.scrollLeft() + dx);
+		
+		drag_element.trigger(
+			$.event.fix({type: "mousemove", 
+					 clientX: ev.clientX, 
+					 clientY: ev.clientY, 
+					 screenX: ev.screenX, 
+					 screenY: ev.screenY,
+					 pageX:   ev.pageX,
+					 pageY:   ev.pageY}))
+		//drag_element.synthetic('mousemove',{clientX: x, clientY: y, screenX: sx, screenY: sy})
+	}
+})
+
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/drag/step/step.html b/browserid/static/dialog/jquery/event/drag/step/step.html
new file mode 100644
index 0000000000000000000000000000000000000000..43b6991bbe8a1c6ebb5b1e9484f78cea30f56eaa
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/drag/step/step.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>drag</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .error {border: solid 1px red;}
+            .error_text { color: red; font-size: 10px;}
+            td {padding: 3px;}
+			.handle {
+				width: 300px;
+				height: 40px;
+				border: dashed 1px red;
+				cursor : pointer;
+			}
+			#internal .handle {
+				border-color: green;
+			}
+			#internal {
+				border: solid 3px green;
+				padding: 5px;
+				margin-top: 50px;
+			}
+			#ondoc {
+				border: solid 5px red;
+				padding: 20px;
+				height: 300px;
+				width: 600px;
+				margin: 10px;
+			}
+        </style>
+	</head>
+	<body>
+
+		
+		<div id="ondoc">
+	    	<div class='handle'>handle</div>
+			<div class='handle'>handle</div>
+	    </div>
+		<script type='text/javascript' 
+                src='../../../../steal/steal.js?steal[app]=jquery/event/drag/step&steal[env]=development'
+                package='main.js'
+                compress='false'>   
+        </script>
+		<script type='text/javascript'>
+			$("#ondoc .handle").live("draginit", function(ev, drag){
+				drag.step(40,$("#ondoc"))
+			})
+			
+			
+		</script>
+		
+		
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/drag/step/step.js b/browserid/static/dialog/jquery/event/drag/step/step.js
new file mode 100644
index 0000000000000000000000000000000000000000..855e13b8886e40fbeb807c85ad31541b5408f9a6
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/drag/step/step.js
@@ -0,0 +1,62 @@
+/**
+ * @add jQuery.Drag.prototype
+ */
+
+steal.plugins('jquery/event/drag', 'jquery/dom/cur_styles').then(function( $ ) {
+	var round = function( x, m ) {
+		return Math.round(x / m) * m;
+	}
+
+	$.Drag.prototype.
+	/**
+	 * @function step
+	 * @plugin jquery/event/drag/step
+	 * @download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/event/drag/step/step.js
+	 * makes the drag move in steps of amount pixels.
+	 * @codestart
+	 * drag.step({x: 5}, $('foo'))
+	 * @codeend
+	 * @param {number} amount
+	 * @param {jQuery} container
+	 * @return {jQuery.Drag} the drag
+	 */
+	step = function( amount, container ) {
+		//on draws ... make sure this happens
+		if ( typeof amount == 'number' ) {
+			amount = {
+				x: amount,
+				y: amount
+			}
+		}
+		container = container || $(document.body);
+		this._step = amount;
+
+		var styles = container.curStyles("borderTopWidth", "paddingTop", "borderLeftWidth", "paddingLeft");
+		var left = parseInt(styles.borderTopWidth) + parseInt(styles.paddingTop),
+			top = parseInt(styles.borderLeftWidth) + parseInt(styles.paddingLeft);
+
+		this._step.offset = container.offsetv().plus(left, top);
+		return this;
+	};
+
+
+	var oldPosition = $.Drag.prototype.position;
+	$.Drag.prototype.position = function( offsetPositionv ) {
+		//adjust required_css_position accordingly
+		if ( this._step ) {
+			var movingSize = this.movingElement.dimensionsv('outer'),
+				lot = this._step.offset.top(),
+				lof = this._step.offset.left();
+
+			if ( this._step.x ) {
+				offsetPositionv.left(Math.round(lof + round(offsetPositionv.left() - lof, this._step.x)))
+			}
+			if ( this._step.y ) {
+				offsetPositionv.top(Math.round(lot + round(offsetPositionv.top() - lot, this._step.y)))
+			}
+		}
+
+		oldPosition.call(this, offsetPositionv)
+	}
+
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/drag/test/qunit/drag_test.js b/browserid/static/dialog/jquery/event/drag/test/qunit/drag_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..4e8b8524ef61cba67069722519f438954fc13151
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/drag/test/qunit/drag_test.js
@@ -0,0 +1,189 @@
+module("jquery/event/drag",{
+	makePoints : function(){
+		var div = $("<div>"+
+			"<div id='drag'></div>"+
+			"<div id='midpoint'></div>"+
+			"<div id='drop'></div>"+
+			"</div>");
+	
+		div.appendTo($("#qunit-test-area"));
+		var basicCss = {
+			width: "20px",
+			height: "20px",
+			position: "absolute",
+			border: "solid 1px black"
+		}
+		$("#drag").css(basicCss).css({top: "0px", left: "0px", zIndex: 1000, backgroundColor: "red"})
+		$("#midpoint").css(basicCss).css({top: "0px", left: "30px"})
+		$("#drop").css(basicCss).css({top: "30px", left: "30px"});
+	}
+})
+test("dragging an element", function(){
+	var div = $("<div>"+
+			"<div id='drag'></div>"+
+			"<div id='midpoint'></div>"+
+			"<div id='drop'></div>"+
+			"</div>");
+	
+	div.appendTo($("#qunit-test-area"));
+	var basicCss = {
+		width: "20px",
+		height: "20px",
+		position: "absolute",
+		border: "solid 1px black"
+	}
+	$("#drag").css(basicCss).css({top: "0px", left: "0px", zIndex: 1000, backgroundColor: "red"})
+	$("#midpoint").css(basicCss).css({top: "0px", left: "30px"})
+	$("#drop").css(basicCss).css({top: "30px", left: "30px"});
+	
+	
+	var drags = {}, drops ={};
+	
+	$('#drag')
+		.live("dragdown", function(){
+			drags.dragdown = true;
+		})
+		.live("draginit", function(){
+			drags.draginit = true;
+		})
+		.live("dragmove", function(){
+			drags.dragmove = true;
+		})
+		.live("dragend", function(){
+			drags.dragend = true;
+		})
+		.live("dragover", function(){
+			drags.dragover = true;
+		})
+		.live("dragout", function(){
+			drags.dragout = true;
+		})
+	$('#drop')
+		.live("dropinit", function(){ 
+			drops.dropinit = true;
+		})
+		.live("dropover", function(){ 
+			drops.dropover = true;
+		})
+		.live("dropout", function(){ 
+			drops.dropout = true;
+		})
+		.live("dropmove", function(){ 
+			drops.dropmove = true;
+		})
+		.live("dropon", function(){ 
+			drops.dropon = true;
+		})
+		.live("dropend", function(){ 
+			drops.dropend = true;
+		})
+
+	stop();
+	
+	Syn.drag({to: "#midpoint"},"drag", function(){
+		ok(drags.dragdown, "dragdown fired correctly")
+		ok(drags.draginit, "draginit fired correctly")
+		ok(drags.dragmove, "dragmove fired correctly")
+		ok(drags.dragend, 	"dragend fired correctly")
+		ok(!drags.dragover,"dragover not fired yet")
+		ok(!drags.dragout, "dragout not fired yet")
+		//console.log(drags, drags.dragout)
+		ok(drops.dropinit, "dropinit fired correctly")
+		ok(!drops.dropover,"dropover fired correctly")
+		ok(!drops.dropout, "dropout not fired")
+		ok(!drops.dropmove,"dropmove not fired")
+		ok(!drops.dropon,	"dropon not fired yet")
+		ok(drops.dropend, 	"dropend fired")
+	}).drag({to: "#drop"}, function(){
+		ok(drags.dragover,"dragover fired correctly")
+		ok(drops.dropover, "dropmover fired correctly")
+		ok(drops.dropmove, "dropmove fired correctly")
+		ok(drops.dropon,	"dropon fired correctly")
+	}).drag({to: "#midpoint"}, function(){
+		ok(drags.dragout, 	"dragout fired correctly")
+	
+		ok(drops.dropout, 	"dropout fired correctly")
+		//div.remove();
+		start();
+	})
+	
+
+
+	
+})
+
+test("drag position", function(){
+	this.makePoints();
+	
+	
+	var drags = {}, drops ={};
+	
+	$('#drag').live("draginit", function(){
+		drags.draginit = true;
+	})
+	var offset = $('#drag').offset();
+
+	stop();
+	
+	Syn.drag("+20 +20","drag", function(){
+		var offset2 = $('#drag').offset();
+		equals(offset.top+20, offset2.top, "top")
+		equals(offset.left+20, offset2.left, "left")
+		start();
+	})
+});
+
+test("dragdown" , function(){
+	var div = $("<div>"+
+			"<div id='dragger'>"+
+				"<p>Place to drag</p>"+
+				"<input type='text' id='draginp' />"+
+				"<input type='text' id='dragnoprevent' />"+
+			"</div>"+
+			"</div>");
+	
+	$("#qunit-test-area").html(div);
+	$("#dragger").css({
+		position: "absolute",
+		backgroundColor : "blue",
+		border: "solid 1px black",
+		top: "0px",
+		left: "0px",
+		width: "200px",
+		height: "200px"
+	})
+	var draginpfocused = false,
+		dragnopreventfocused = false;
+	
+	$('#draginp').focus(function(){
+		draginpfocused = true;
+	})
+	$('#dragnoprevent').focus(function(){
+		dragnopreventfocused = true;
+	})
+	
+	$('#dragger').bind("dragdown", function(ev, drag){
+		if(ev.target.id == 'draginp'){
+			drag.cancel();
+		}else{
+			ev.preventDefault();
+		}
+	})
+	var offset = $('#dragger').offset();
+
+	stop();
+	Syn.drag("+20 +20","draginp", function(){
+		var offset2 = $('#dragger').offset();
+		equals(offset.top, offset2.top, "top")
+		equals(offset.left, offset2.left, "left")
+		
+	}).drag("+20 +20","dragnoprevent", function(){
+		var offset2 = $('#dragger').offset();
+		equals(offset.top+20, offset2.top, "top")
+		equals(offset.left+20, offset2.left, "left")
+		ok(draginpfocused, "First input was allowed to be focused correctly");
+		//ok(!dragnopreventfocused, "Second input was not allowed to focus");
+		start();
+	})
+
+})
diff --git a/browserid/static/dialog/jquery/event/drag/test/qunit/qunit.js b/browserid/static/dialog/jquery/event/drag/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..2fa324dd5d42cc4d02e5f3d462a007039b113d72
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/drag/test/qunit/qunit.js
@@ -0,0 +1,4 @@
+steal
+ .plugins("jquery/event/drop",'funcunit/syn')  //load your app
+ .plugins('funcunit/qunit' )  //load qunit
+ .then("drag_test")
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/drop/drop.html b/browserid/static/dialog/jquery/event/drop/drop.html
new file mode 100644
index 0000000000000000000000000000000000000000..9a807aa93ba7d611ac5d5d9425a65a6369ba63ce
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/drop/drop.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>drop</title>
+        <style type='text/css'>
+            .handle {
+				width: 100px;
+				height: 25px;
+				border: dashed 1px red;
+				cursor : pointer;
+			}
+            .dropout, .dropmove, .cancel {
+                width: 200px;
+				height: 50px;
+				border: dashed 1px green;
+				cursor : pointer;
+                background-color: white;
+            }
+            #dropout {
+                padding: 20px;
+                border: solid 1px blue;
+            }
+            .over {
+                background-color: yellow;
+            }
+        </style>
+	</head>
+	<body>
+<div  id='demo-html'>
+<h2>Drop Demo</h2>
+<div class='handle'>Drag Me</div>
+<h2>Dropout/Dropover</h2>
+<div id='dropout'>
+  <div class='dropout'></div>
+  <div class='dropout'></div>
+</div>
+<a href="javascript://" id='undelegate'>undelegate</a>
+<h2>Dropmove/Dropon</h2>
+<div class='dropmove'></div>
+<span>Drop Count <span class='count'>0</span></span>
+</div>
+		<script type='text/javascript' 
+                src='../../../steal/steal.js?steal[app]=jquery/event/drop'>   
+        </script>
+		<script type='text/javascript' id='demo-source'>
+//make drags
+$('.handle').live("draginit", function(){})
+			
+//add dropout/dropover
+$('#dropout')
+  .delegate(".dropout","dropover", function(){ $(this).addClass('over') })
+  .delegate(".dropout","dropout", function(){ $(this).removeClass('over') })
+  .bind("dropover", function(){ $(this).addClass('over') })
+  .bind("dropout", function(){ $(this).removeClass('over') });
+	
+//turn off dropout/dropover
+$("#undelegate").click(function(){
+    $('#dropout').undelegate(".dropout","dropover");
+    $('#dropout').undelegate(".dropout","dropout");
+})
+	
+//add dropmove/dropon
+var count = 0
+$('.dropmove')
+  .bind('dropmove', function(){
+    $('.count').text(count++)
+  })
+  .bind('dropon', function(){
+    $(this).text("Dropped on!")
+  })
+        </script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/drop/drop.js b/browserid/static/dialog/jquery/event/drop/drop.js
new file mode 100644
index 0000000000000000000000000000000000000000..632f9211263a799e5e2707a48773d9842777cf11
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/drop/drop.js
@@ -0,0 +1,301 @@
+steal.plugins('jquery/event/drag','jquery/dom/within','jquery/dom/compare').then(function($){
+	var event = $.event, 
+		callHanders = function(){
+			
+		};
+	//somehow need to keep track of elements with selectors on them.  When element is removed, somehow we need to know that
+	//
+	/**
+	 * @add jQuery.event.special
+	 */
+	var eventNames = [
+	/**
+	 * @attribute dropover
+	 * Called when a drag is first moved over this drop element.
+	 * <p>Drop events are covered in more detail in [jQuery.Drop].</p>
+	 */
+	"dropover",
+	/**
+	 * @attribute dropon
+	 * Called when a drag is dropped on a drop element.
+	 * <p>Drop events are covered in more detail in [jQuery.Drop].</p>
+	 */
+	"dropon",
+	/**
+	 * @attribute dropout
+	 * Called when a drag is moved out of this drop.
+	 * <p>Drop events are covered in more detail in [jQuery.Drop].</p>
+	 */
+	"dropout",
+	/**
+	 * @attribute dropinit
+	 * Called when a drag motion starts and the drop elements are initialized.
+	 * <p>Drop events are covered in more detail in [jQuery.Drop].</p>
+	 */
+	"dropinit",
+	/**
+	 * @attribute dropmove
+	 * Called repeatedly when a drag is moved over a drop.
+	 * <p>Drop events are covered in more detail in [jQuery.Drop].</p>
+	 */
+	"dropmove",
+	/**
+	 * @attribute dropend
+	 * Called when the drag is done for this drop.
+	 * <p>Drop events are covered in more detail in [jQuery.Drop].</p>
+	 */
+	"dropend"];
+	
+	
+	
+	/**
+	 * @class jQuery.Drop
+	 * @parent specialevents
+	 * @plugin jquery/event/drop
+	 * @download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/event/drop/drop.js
+	 * @test jquery/event/drag/qunit.html
+	 * 
+	 * Provides drop events as a special event to jQuery.  
+	 * By binding to a drop event, the your callback functions will be 
+	 * called during the corresponding phase of drag.
+	 * <h2>Drop Events</h2>
+	 * All drop events are called with the native event, an instance of drop, and the drag.  Here are the available drop 
+	 * events:
+	 * <ul>
+	 * 	<li><code>dropinit</code> - the drag motion is started, drop positions are calculated.</li>
+	 *  <li><code>dropover</code> - a drag moves over a drop element, called once as the drop is dragged over the element.</li>
+	 *  <li><code>dropout</code> - a drag moves out of the drop element.</li>
+	 *  <li><code>dropmove</code> - a drag is moved over a drop element, called repeatedly as the element is moved.</li>
+	 *  <li><code>dropon</code> - a drag is released over a drop element.</li>
+	 *  <li><code>dropend</code> - the drag motion has completed.</li>
+	 * </ul>
+	 * <h2>Examples</h2>
+	 * Here's how to listen for when a drag moves over a drop:
+	 * @codestart
+	 * $('.drop').live("dropover", function(ev, drop, drag){
+	 *   $(this).addClass("drop-over")
+	 * })
+	 * @codeend
+	 * A bit more complex example:
+	 * @demo jquery/event/drop/drop.html 1000
+	 * @constructor
+	 * The constructor is never called directly.
+	 */
+	$.Drop = function(callbacks, element){
+		jQuery.extend(this,callbacks);
+		this.element = element;
+	}
+	$.each(eventNames, function(){
+			event.special[this] = {
+				add: function( handleObj ) {
+					//add this element to the compiles list
+					var el = $(this), current = (el.data("dropEventCount") || 0);
+					el.data("dropEventCount",  current+1   )
+					if(current==0){
+						$.Drop.addElement(this);
+					}
+				},
+				remove: function() {
+					var el = $(this), current = (el.data("dropEventCount") || 0);
+					el.data("dropEventCount",  current-1   )
+					if(current<=1){
+						$.Drop.removeElement(this);
+					}
+				}
+			}
+	})
+	$.extend($.Drop,{
+		lowerName: "drop",
+		_elements: [], //elements that are listening for drops
+		_responders: [], //potential drop points
+		last_active: [],
+		endName: "dropon",
+		addElement: function( el ) {
+			//check other elements
+			for(var i =0; i < this._elements.length ; i++  ){
+				if(el ==this._elements[i]) return;
+			}
+			this._elements.push(el);
+		},
+		removeElement: function( el ) {
+			 for(var i =0; i < this._elements.length ; i++  ){
+				if(el == this._elements[i]){
+					this._elements.splice(i,1)
+					return;
+				}
+			}
+		},
+		/**
+		* @hide
+		* For a list of affected drops, sorts them by which is deepest in the DOM first.
+		*/ 
+		sortByDeepestChild: function( a, b ) {
+			var compare = a.element.compare(b.element);
+			if(compare & 16 || compare & 4) return 1;
+			if(compare & 8 || compare & 2) return -1;
+			return 0;
+		},
+		/**
+		 * @hide
+		 * Tests if a drop is within the point.
+		 */
+		isAffected: function( point, moveable, responder ) {
+			return ((responder.element != moveable.element) && (responder.element.within(point[0], point[1], responder).length == 1));
+		},
+		/**
+		 * @hide
+		 * Calls dropout and sets last active to null
+		 * @param {Object} drop
+		 * @param {Object} drag
+		 * @param {Object} event
+		 */
+		deactivate: function( responder, mover, event ) {
+			mover.out(event, responder)
+			responder.callHandlers(this.lowerName+'out',responder.element[0], event, mover)
+		}, 
+		/**
+		 * @hide
+		 * Calls dropover
+		 * @param {Object} drop
+		 * @param {Object} drag
+		 * @param {Object} event
+		 */
+		activate: function( responder, mover, event ) { //this is where we should call over
+			mover.over(event, responder)
+			//this.last_active = responder;
+			responder.callHandlers(this.lowerName+'over',responder.element[0], event, mover);
+		},
+		move: function( responder, mover, event ) {
+			responder.callHandlers(this.lowerName+'move',responder.element[0], event, mover)
+		},
+		/**
+		 * Gets all elements that are droppable, adds them
+		 */
+		compile: function( event, drag ) {
+			var el, drops, selector, sels;
+			this.last_active = [];
+			for(var i=0; i < this._elements.length; i++){ //for each element
+				el = this._elements[i]
+				var drops = $.event.findBySelector(el, eventNames)
+
+				for(selector in drops){ //find the selectors
+					sels = selector ? jQuery(selector, el) : [el];
+					for(var e= 0; e < sels.length; e++){ //for each found element, create a drop point
+						jQuery.removeData(sels[e],"offset");
+						this.add(sels[e], new this(drops[selector]), event, drag);
+					}
+				}
+			}
+			
+		},
+		add: function( element, callbacks, event, drag ) {
+			element = jQuery(element);
+			var responder = new $.Drop(callbacks, element);
+			responder.callHandlers(this.lowerName+'init', element[0], event, drag)
+			if(!responder._canceled){
+				this._responders.push(responder);
+			}
+		},
+		show: function( point, moveable, event ) {
+			var element = moveable.element;
+			if(!this._responders.length) return;
+			
+			var respondable, 
+				affected = [], 
+				propagate = true, 
+				i,j, la, toBeActivated, aff, 
+				oldLastActive = this.last_active;
+				
+			for(var d =0 ; d < this._responders.length; d++ ){
+				
+				if(this.isAffected(point, moveable, this._responders[d])){
+					affected.push(this._responders[d]);  
+				}
+					 
+			}
+			
+			affected.sort(this.sortByDeepestChild); //we should only trigger on lowest children
+			event.stopRespondPropagate = function(){
+				propagate = false;
+			}
+			//deactivate everything in last_active that isn't active
+			toBeActivated = affected.slice();
+			this.last_active = affected;
+			for (j = 0; j < oldLastActive.length; j++) {
+				la = oldLastActive[j]
+				i = 0;
+				while((aff = toBeActivated[i])){
+					if(la == aff){
+						toBeActivated.splice(i,1);break;
+					}else{
+						i++;
+					}
+				}
+				if(!aff){
+					this.deactivate(la, moveable, event);
+				}
+				if(!propagate) return;
+			}
+			for(var i =0; i < toBeActivated.length; i++){
+				this.activate(toBeActivated[i], moveable, event);
+				if(!propagate) return;
+			}
+			//activate everything in affected that isn't in last_active
+			
+			for (i = 0; i < affected.length; i++) {
+				this.move(affected[i], moveable, event);
+				
+				if(!propagate) return;
+			}
+		},
+		end: function( event, moveable ) {
+			var responder, la;
+			for(var r =0; r<this._responders.length; r++){
+				this._responders[r].callHandlers(this.lowerName+'end', null, event, moveable);
+			}
+			//go through the actives ... if you are over one, call dropped on it
+			for(var i = 0; i < this.last_active.length; i++){
+				la = this.last_active[i]
+				if( this.isAffected(event.vector(), moveable, la)  && la[this.endName]){
+					la.callHandlers(this.endName, null, event, moveable);
+				}
+			}
+			
+			
+			this.clear();
+		},
+		/**
+		 * Called after dragging has stopped.
+		 * @hide
+		 */
+		clear: function() {
+		  
+		  this._responders = [];
+		}
+	})
+	$.Drag.responder = $.Drop;
+	
+	$.extend($.Drop.prototype,{
+		callHandlers: function( method, el, ev, drag ) {
+			var length = this[method] ? this[method].length : 0
+			for(var i =0; i < length; i++){
+				this[method][i].call(el || this.element[0], ev, this, drag)
+			}
+		},
+		/**
+		 * Caches positions of draggable elements.  This should be called in dropinit.  For example:
+		 * @codestart
+		 * dropinit: function( el, ev, drop ) { drop.cache_position() }
+		 * @codeend
+		 */
+		cache: function( value ) {
+			this._cache = value != null ? value : true;
+		},
+		/**
+		 * Prevents this drop from being dropped on.
+		 */
+		cancel: function() {
+			this._canceled = true;
+		}
+	} )
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/event.js b/browserid/static/dialog/jquery/event/event.js
new file mode 100644
index 0000000000000000000000000000000000000000..42422936b05fd13d2304068e33aff0a1e0c31344
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/event.js
@@ -0,0 +1,6 @@
+/**
+ * @page specialevents Special Events
+ * @tag core
+ * JavaScriptMVC adds a bunch of useful jQuery extensions for the dom.  Check them out on the left.
+ */
+steal.plugins('jquery');
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/hashchange/hashchange.js b/browserid/static/dialog/jquery/event/hashchange/hashchange.js
new file mode 100644
index 0000000000000000000000000000000000000000..fc01306cb292ef1d2655371e78db361f23ed8d1e
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/hashchange/hashchange.js
@@ -0,0 +1,245 @@
+/*!
+ * jQuery hashchange event - v1.2 - 2/11/2010
+ * http://benalman.com/projects/jquery-hashchange-plugin/
+ * 
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+
+// Script: jQuery hashchange event
+//
+// *Version: 1.2, Last updated: 2/11/2010*
+// 
+// Project Home - http://benalman.com/projects/jquery-hashchange-plugin/
+// GitHub       - http://github.com/cowboy/jquery-hashchange/
+// Source       - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js
+// (Minified)   - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (1.1kb)
+// 
+// About: License
+// 
+// Copyright (c) 2010 "Cowboy" Ben Alman,
+// Dual licensed under the MIT and GPL licenses.
+// http://benalman.com/about/license/
+// 
+// About: Examples
+// 
+// This working example, complete with fully commented code, illustrate one way
+// in which this plugin can be used.
+// 
+// hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/
+// 
+// About: Support and Testing
+// 
+// Information about what version or versions of jQuery this plugin has been
+// tested with, what browsers it has been tested in, and where the unit tests
+// reside (so you can test it yourself).
+// 
+// jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2
+// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.7, Safari 3-4, Chrome, Opera 9.6-10.1.
+// Unit Tests      - http://benalman.com/code/projects/jquery-hashchange/unit/
+// 
+// About: Known issues
+// 
+// While this jQuery hashchange event implementation is quite stable and robust,
+// there are a few unfortunate browser bugs surrounding expected hashchange
+// event-based behaviors, independent of any JavaScript window.onhashchange
+// abstraction. See the following examples for more information:
+// 
+// Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/
+// Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/
+// WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/
+// Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/
+// 
+// About: Release History
+// 
+// 1.2   - (2/11/2010) Fixed a bug where coming back to a page using this plugin
+//         from a page on another domain would cause an error in Safari 4. Also,
+//         IE6/7 Iframe is now inserted after the body (this actually works),
+//         which prevents the page from scrolling when the event is first bound.
+//         Event can also now be bound before DOM ready, but it won't be usable
+//         before then in IE6/7.
+// 1.1   - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug
+//         where browser version is incorrectly reported as 8.0, despite
+//         inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag.
+// 1.0   - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special
+//         window.onhashchange functionality into a separate plugin for users
+//         who want just the basic event & back button support, without all the
+//         extra awesomeness that BBQ provides. This plugin will be included as
+//         part of jQuery BBQ, but also be available separately.
+
+(function($,window,undefined){
+  '$:nomunge'; // Used by YUI compressor.
+  
+  // Method / object references.
+  var fake_onhashchange,
+    jq_event_special = $.event.special,
+    
+    // Reused strings.
+    str_location = 'location',
+    str_hashchange = 'hashchange',
+    str_href = 'href',
+    
+    // IE6/7 specifically need some special love when it comes to back-button
+    // support, so let's do a little browser sniffing..
+    browser = $.browser,
+    mode = document.documentMode,
+    is_old_ie = browser.msie && ( mode === undefined || mode < 8 ),
+    
+    // Does the browser support window.onhashchange? Test for IE version, since
+    // IE8 incorrectly reports this when in "IE7" or "IE8 Compatibility View"!
+    supports_onhashchange = 'on' + str_hashchange in window && !is_old_ie;
+  
+  // Get location.hash (or what you'd expect location.hash to be) sans any
+  // leading #. Thanks for making this necessary, Firefox!
+  function get_fragment( url ) {
+    url = url || window[ str_location ][ str_href ];
+    return url.replace( /^[^#]*#?(.*)$/, '$1' );
+  };
+  
+  // Property: jQuery.hashchangeDelay
+  // 
+  // The numeric interval (in milliseconds) at which the <hashchange event>
+  // polling loop executes. Defaults to 100.
+  
+  $[ str_hashchange + 'Delay' ] = 100;
+  
+  // Event: hashchange event
+  // 
+  // Fired when location.hash changes. In browsers that support it, the native
+  // window.onhashchange event is used (IE8, FF3.6), otherwise a polling loop is
+  // initialized, running every <jQuery.hashchangeDelay> milliseconds to see if
+  // the hash has changed. In IE 6 and 7, a hidden Iframe is created to allow
+  // the back button and hash-based history to work.
+  // 
+  // Usage:
+  // 
+  // > $(window).bind( 'hashchange', function(e) {
+  // >   var hash = location.hash;
+  // >   ...
+  // > });
+  // 
+  // Additional Notes:
+  // 
+  // * The polling loop and Iframe are not created until at least one callback
+  //   is actually bound to 'hashchange'.
+  // * If you need the bound callback(s) to execute immediately, in cases where
+  //   the page 'state' exists on page load (via bookmark or page refresh, for
+  //   example) use $(window).trigger( 'hashchange' );
+  // * The event can be bound before DOM ready, but since it won't be usable
+  //   before then in IE6/7 (due to the necessary Iframe), recommended usage is
+  //   to bind it inside a $(document).ready() callback.
+  
+  jq_event_special[ str_hashchange ] = $.extend( jq_event_special[ str_hashchange ], {
+    
+    // Called only when the first 'hashchange' event is bound to window.
+    setup: function() {
+      // If window.onhashchange is supported natively, there's nothing to do..
+      if ( supports_onhashchange ) { return false; }
+      
+      // Otherwise, we need to create our own. And we don't want to call this
+      // until the user binds to the event, just in case they never do, since it
+      // will create a polling loop and possibly even a hidden Iframe.
+      $( fake_onhashchange.start );
+    },
+    
+    // Called only when the last 'hashchange' event is unbound from window.
+    teardown: function() {
+      // If window.onhashchange is supported natively, there's nothing to do..
+      if ( supports_onhashchange ) { return false; }
+      
+      // Otherwise, we need to stop ours (if possible).
+      $( fake_onhashchange.stop );
+    }
+    
+  });
+  
+  // fake_onhashchange does all the work of triggering the window.onhashchange
+  // event for browsers that don't natively support it, including creating a
+  // polling loop to watch for hash changes and in IE 6/7 creating a hidden
+  // Iframe to enable back and forward.
+  fake_onhashchange = (function(){
+    var self = {},
+      timeout_id,
+      iframe,
+      set_history,
+      get_history;
+    
+    // Initialize. In IE 6/7, creates a hidden Iframe for history handling.
+    function init(){
+      // Most browsers don't need special methods here..
+      set_history = get_history = function(val){ return val; };
+      
+      // But IE6/7 do!
+      if ( is_old_ie ) {
+        
+        // Create hidden Iframe after the end of the body to prevent initial
+        // page load from scrolling unnecessarily.
+        iframe = $('<iframe src="javascript:0"/>').hide().insertAfter( 'body' )[0].contentWindow;
+        
+        // Get history by looking at the hidden Iframe's location.hash.
+        get_history = function() {
+          return get_fragment( iframe.document[ str_location ][ str_href ] );
+        };
+        
+        // Set a new history item by opening and then closing the Iframe
+        // document, *then* setting its location.hash.
+        set_history = function( hash, history_hash ) {
+          if ( hash !== history_hash ) {
+            var doc = iframe.document;
+            doc.open().close();
+            doc[ str_location ].hash = '#' + hash;
+          }
+        };
+        
+        // Set initial history.
+        set_history( get_fragment() );
+      }
+    };
+    
+    // Start the polling loop.
+    self.start = function() {
+      // Polling loop is already running!
+      if ( timeout_id ) { return; }
+      
+      // Remember the initial hash so it doesn't get triggered immediately.
+      var last_hash = get_fragment();
+      
+      // Initialize if not yet initialized.
+      set_history || init();
+      
+      // This polling loop checks every $.hashchangeDelay milliseconds to see if
+      // location.hash has changed, and triggers the 'hashchange' event on
+      // window when necessary.
+      if(!navigator.userAgent.match(/Rhino/))
+	      (function loopy(){
+	        var hash = get_fragment(),
+	          history_hash = get_history( last_hash );
+	        
+	        if ( hash !== last_hash ) {
+	          set_history( last_hash = hash, history_hash );
+	          
+	          $(window).trigger( str_hashchange );
+	          
+	        } else if ( history_hash !== last_hash ) {
+	          window[ str_location ][ str_href ] = window[ str_location ][ str_href ].replace( /#.*/, '' ) + '#' + history_hash;
+	        }
+	        
+	        timeout_id = setTimeout( loopy, $[ str_hashchange + 'Delay' ] );
+	      })();
+    };
+    
+    // Stop the polling loop, but only if an IE6/7 Iframe wasn't created. In
+    // that case, even if there are no longer any bound event handlers, the
+    // polling loop is still necessary for back/next to work at all!
+    self.stop = function() {
+      if ( !iframe ) {
+        timeout_id && clearTimeout( timeout_id );
+        timeout_id = 0;
+      }
+    };
+    
+    return self;
+  })();
+  
+})(jQuery,this);
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/hover/hover.html b/browserid/static/dialog/jquery/event/hover/hover.html
new file mode 100644
index 0000000000000000000000000000000000000000..a128aa4523cbf96829b4e3013b483aa30dfce6f8
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/hover/hover.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>hover</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .error {border: solid 1px red;}
+            .error_text { color: red; font-size: 10px;}
+            td {padding: 3px;}
+			.hover, .hovers {
+				border: solid 1px green;
+			}
+			.hoverstate {
+				background-color: yellow;
+			}
+			.myhover {
+				border: solid 1px red;
+			}
+        </style>
+	</head>
+	<body>
+<div id='demo-html'>
+<h4>Delegating</h4>
+<div class='hover'>hover me</div>
+<div class='hover'>hover me</div>
+<h4>Bound Directly</h4>
+<div class='hovers'>hover me for a second</div>
+<div class='hovers'>hover me for a second</div>
+</div>
+		<script type='text/javascript' 
+                src='../../../steal/steal.js?steal[app]=jquery/event/hover&steal[env]=development'>   
+        </script>
+<script type='text/javascript' id='demo-source'>
+// adds a hover class
+var add = function(ev){
+  $(this).addClass("hoverstate")	
+},
+
+// removes a hover class
+remove = function(ev){
+  $(this).removeClass("hoverstate")
+}
+
+// delegate on hover
+$('.hover').live('hoverenter',add)
+$('.hover').live('hoverleave', remove)
+
+$('.hovers').bind('hoverinit',function(ev, hovered){
+  hovered.delay(1000)
+})
+$('.hovers').bind('hoverenter',add)
+$('.hovers').bind('hoverleave', remove)
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/hover/hover.js b/browserid/static/dialog/jquery/event/hover/hover.js
new file mode 100644
index 0000000000000000000000000000000000000000..948a6d41d36b85bc18117787da449148d1bc0f5b
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/hover/hover.js
@@ -0,0 +1,219 @@
+steal.plugins('jquery/event','jquery/event/livehack').then(function($){
+/**
+ * @class jQuery.Hover
+ * @plugin jquery/event/hover
+ * @download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/event/hover/hover.js
+ * Provides delegate-able hover events.
+ * <p>
+ * 	A hover happens when the mouse stops moving 
+ * over an element for a period of time.  You can listen
+ * and configure hover with the following events:
+ * </p>
+ * <ul>
+ * 	<li><code>[jQuery.event.special.hoverinit hoverinit]</code> - called on mouseenter, use this event to customize 
+ *      [jQuery.Hover.prototype.delay] and [jQuery.Hover.prototype.distance]</li>
+ *  <li><code>[jQuery.event.special.hoverenter hoverenter]</code> - an element is being hovered</li>
+ *  <li><code>[jQuery.event.special.hovermove hovermove]</code> - the mouse moves on an element that has been hovered</li>
+ *  <li><code>[jQuery.event.special.hoverleave hoverleave]</code> - the mouse leaves the element that has been hovered</li>
+ * </ul>
+ * <h3>Quick Example</h3>
+ * The following listens for hoverenter and adds a class to style
+ * the element, and removes the class on hoverleave.
+ * @codestart
+ * $('#menu').delegate(".option","hoverenter",function(){
+ *   $(this).addClass("hovering");
+ * }).delegate(".option","hoverleave",function(){
+ *   $(this).removeClass("hovering");
+ * })
+ * @codeend
+ * <h2>Configuring Distance and Delay</h2>
+ * <p>An element is hovered when the mouse
+ *   moves less than a certain distance in 
+ *   specific time over the element.
+ * </p>
+ * <p>
+ *   You can configure that distance and time by
+ *   adjusting the <code>distance</code> and 
+ *   <code>delay</code> values.  
+ * </p>
+ * <p>You can set delay and distance globally
+ * by adjusting the static properties:</p>
+ * </p>
+ * @codestart
+ * $.Hover.delay = 10
+ * $.Hover.distance = 1
+ * @codeend
+ * <p>Or you can adjust delay and distance for
+ * an individual element in hoverenter:</p>
+ * @codestart
+ * $(".option").live("hoverinit", function(ev, hover){
+ * //set the distance to 10px
+ * hover.distance(10)
+ * //set the delay to 200ms
+ * hover.delay(10)
+ * })
+ * @codeend
+ * <h2>Demo</h2>
+ * @demo jquery/event/hover/hover.html
+ * @parent specialevents
+ * @constructor Creates a new hover.  This is never
+ * called directly.
+ */
+jQuery.Hover = function(){
+	this._delay =  jQuery.Hover.delay;
+	this._distance = jQuery.Hover.distance;
+};
+/**
+ * @Static
+ */
+$.extend(jQuery.Hover,{
+	/**
+	 * @attribute delay
+	 * A hover is  activated if it moves less than distance in this time.
+	 * Set this value as a global default.
+	 */
+	delay: 100,
+	/**
+	 * @attribute distance
+	 * A hover is activated if it moves less than this distance in delay time.
+	 * Set this value as a global default.
+	 */
+	distance: 10
+})
+
+/**
+ * @Prototype
+ */
+$.extend(jQuery.Hover.prototype,{
+	/**
+	 * Sets the delay for this hover.  This method should
+	 * only be used in hoverinit.
+	 * @param {Number} delay the number of milliseconds used to determine a hover
+	 * 
+	 */
+	delay: function( delay ) {
+		this._delay = delay;
+	},
+	/**
+	 * Sets the distance for this hover.  This method should
+	 * only be used in hoverinit.
+	 * @param {Number} distance the max distance in pixels a mouse can move to be considered a hover
+	 */
+	distance: function( distance ) {
+		this._distance = distance;
+	}
+})
+var $ = jQuery,
+	event = jQuery.event, 
+	handle  = event.handle,
+	onmouseenter = function(ev){
+		//now start checking mousemoves to update location
+		var delegate = ev.liveFired || ev.currentTarget;
+		var selector = ev.handleObj.selector;
+		var loc = {
+				pageX : ev.pageX,
+				pageY : ev.pageY
+			}, 
+			dist = 0, 
+			timer, 
+			entered = this, 
+			called = false,
+			lastEv = ev, 
+			hover = new jQuery.Hover();
+
+		$(entered).bind("mousemove.specialMouseEnter", {}, function(ev){
+			dist += Math.pow( ev.pageX-loc.pageX, 2 ) + Math.pow( ev.pageY-loc.pageY, 2 ); 
+			loc = {
+				pageX : ev.pageX,
+				pageY : ev.pageY
+			}
+			lastEv = ev
+		}).bind("mouseleave.specialMouseLeave",{}, function(ev){
+			clearTimeout(timer);
+			if(called){
+				$.each(event.find(delegate, ["hoverleave"], selector), function(){
+					this.call(entered, ev)
+				})
+			}
+			$(entered).unbind("mouseleave.specialMouseLeave")
+		})
+		$.each(event.find(delegate, ["hoverinit"], selector), function(){
+			this.call(entered, ev, hover)
+		})
+		timer = setTimeout(function(){
+			//check that we aren't moveing around
+			if(dist < hover._distance && $(entered).queue().length == 0){
+				$.each(event.find(delegate, ["hoverenter"], selector), function(){
+					this.call(entered, lastEv, hover)
+				})
+				called = true;
+				$(entered).unbind("mousemove.specialMouseEnter")
+				
+			}else{
+				dist = 0;
+				timer = setTimeout(arguments.callee, hover._delay)
+			}
+			
+			
+		}, hover._delay)
+		
+	};
+		
+/**
+ * @add jQuery.event.special
+ */
+event.setupHelper( [
+/**
+ * @attribute hoverinit
+ * Listen for hoverinit events to configure
+ * [jQuery.Hover.prototype.delay] and [jQuery.Hover.prototype.distance]
+ * for the current element.  Hoverinit is called on mouseenter.
+ * @codestart
+ * $(".option").live("hoverinit", function(ev, hover){
+ *    //set the distance to 10px
+ *    hover.distance(10)
+ *    //set the delay to 200ms
+ *    hover.delay(10)
+ * })
+ * @codeend
+ */
+"hoverinit", 
+/**
+ * @attribute hoverenter
+ * Hoverenter events are called when the mouses less 
+ * than [jQuery.Hover.prototype.distance] pixels in 
+ * [jQuery.Hover.prototype.delay] milliseconds.
+ * @codestart
+ * $(".option").live("hoverenter", function(ev, hover){
+ *    $(this).addClass("hovering");
+ * })
+ * @codeend
+ */
+"hoverenter",
+/**
+ * @attribute hoverleave
+ * Called when the mouse leaves an element that has been
+ * hovered.
+ * @codestart
+ * $(".option").live("hoverleave", function(ev, hover){
+ *    $(this).removeClass("hovering");
+ * })
+ * @codeend
+ */
+"hoverleave",
+/**
+ * @attribute hovermove
+ * Called when the mouse moves on an element that 
+ * has been hovered.
+ * @codestart
+ * $(".option").live("hovermove", function(ev, hover){
+ *    //not sure why you would want to listen for this
+ *    //but we provide it just in case
+ * })
+ * @codeend
+ */
+"hovermove"], "mouseenter", onmouseenter )
+		
+
+	
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/hover/qunit.html b/browserid/static/dialog/jquery/event/hover/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..14b67eaa90c9945ac10585c115c7b133d4a3c858
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/hover/qunit.html
@@ -0,0 +1,16 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../../funcunit/qunit/qunit.css" />
+		<script type='text/javascript' src='../../../steal/steal.js?steal[app]=jquery/event/hover/test/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">Hover Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/hover/test/qunit/hover_test.js b/browserid/static/dialog/jquery/event/hover/test/qunit/hover_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..5b0a2b25a47db0bf46e6362668fbd1f7026df591
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/hover/test/qunit/hover_test.js
@@ -0,0 +1,55 @@
+module("jquery/dom/hover")
+
+test("hovering", function(){
+	$("#qunit-test-area").append("<div id='hover'>Content<div>")
+	var hoverenters = 0, 
+		hoverinits = 0, 
+		hoverleaves = 0,
+		delay = 15;
+	$("#hover").bind("hoverinit", function(ev, hover){
+		hover.delay(delay);
+		hoverinits++;
+	})
+	.bind('hoverenter', function(){
+		hoverenters++;
+	})
+	.bind('hoverleave',function(){
+		hoverleaves++;
+	})
+	var hover = $("#hover")
+	var off = hover.offset();
+	
+	//add a mouseenter, and 2 mouse moves
+	Syn("mouseover",{pageX: off.top, pageY: off.left}, hover[0])
+	ok(hoverinits, 'hoverinit');
+	ok(hoverenters === 0,"hoverinit hasn't been called");
+	stop(1000);
+	
+	setTimeout(function(){
+		ok(hoverenters === 1,"hoverenter has been called");
+		
+		ok(hoverleaves === 0,"hoverleave hasn't been called");
+		Syn("mouseout",{pageX: off.top, pageY: off.left},hover[0]);
+		
+		ok(hoverleaves === 1,"hoverleave has been called");
+		
+		delay = 30;
+		
+		Syn("mouseover",{pageX: off.top, pageY: off.left},hover[0]);
+		ok(hoverinits === 2, 'hoverinit');
+		
+		setTimeout(function(){
+			
+			Syn("mouseout",{pageX: off.top, pageY: off.left},hover[0]);
+			
+			
+			setTimeout(function(){
+				ok(hoverenters === 1,"hoverenter was not called");
+				ok(hoverleaves === 1,"hoverleave was not called");
+				start();
+			},30)
+			
+		},10)
+		
+	},30)
+})
diff --git a/browserid/static/dialog/jquery/event/hover/test/qunit/qunit.js b/browserid/static/dialog/jquery/event/hover/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..9db1d755edcb12871da3d4fb738ecd8d5675a4b1
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/hover/test/qunit/qunit.js
@@ -0,0 +1,4 @@
+steal
+ .plugins("jquery/event/hover",'funcunit/syn')  //load your app
+ .plugins('funcunit/qunit')  //load qunit
+ .then("hover_test")
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/livehack/livehack.js b/browserid/static/dialog/jquery/event/livehack/livehack.js
new file mode 100644
index 0000000000000000000000000000000000000000..19de3c6656f4ec8661e6daf666bbab5d7b397ec0
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/livehack/livehack.js
@@ -0,0 +1,165 @@
+steal.plugins('jquery/event').then(function() {
+
+	var event = jQuery.event,
+
+		//helper that finds handlers by type and calls back a function, this is basically handle
+		findHelper = function( events, types, callback ) {
+			var t, type, typeHandlers, all, h, handle, namespaces, namespace;
+			for ( t = 0; t < types.length; t++ ) {
+				type = types[t];
+				all = type.indexOf(".") < 0;
+				if (!all ) {
+					namespaces = type.split(".");
+					type = namespaces.shift();
+					namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
+				}
+				typeHandlers = (events[type] || []).slice(0);
+
+				for ( h = 0; h < typeHandlers.length; h++ ) {
+					handle = typeHandlers[h];
+					if (!handle.selector && (all || namespace.test(handle.namespace)) ) {
+						callback(type, handle.origHandler || handle.handler);
+					}
+				}
+			}
+		};
+
+	/**
+	 * Finds event handlers of a given type on an element.
+	 * @param {HTMLElement} el
+	 * @param {Array} types an array of event names
+	 * @param {String} [selector] optional selector
+	 * @return {Array} an array of event handlers
+	 */
+	event.find = function( el, types, selector ) {
+		var events = $.data(el, "events"),
+			handlers = [],
+			t, liver, live;
+
+		if (!events ) {
+			return handlers;
+		}
+
+		if ( selector ) {
+			if (!events.live ) {
+				return [];
+			}
+			live = events.live;
+
+			for ( t = 0; t < live.length; t++ ) {
+				liver = live[t];
+				if ( liver.selector === selector && $.inArray(liver.origType, types) !== -1 ) {
+					handlers.push(liver.origHandler || liver.handler);
+				}
+			}
+		} else {
+			// basically re-create handler's logic
+			findHelper(events, types, function( type, handler ) {
+				handlers.push(handler);
+			});
+		}
+		return handlers;
+	};
+	/**
+	 * Finds 
+	 * @param {HTMLElement} el
+	 * @param {Array} types
+	 */
+	event.findBySelector = function( el, types ) {
+		var events = $.data(el, "events"),
+			selectors = {},
+			//adds a handler for a given selector and event
+			add = function( selector, event, handler ) {
+				var select = selectors[selector] || (selectors[selector] = {}),
+					events = select[event] || (select[event] = []);
+				events.push(handler);
+			};
+
+		if (!events ) {
+			return selectors;
+		}
+		//first check live:
+		$.each(events.live || [], function( i, live ) {
+			if ( $.inArray(live.origType, types) !== -1 ) {
+				add(live.selector, live.origType, live.origHandler || live.handler);
+			}
+		});
+		//then check straight binds
+		findHelper(events, types, function( type, handler ) {
+			add("", type, handler);
+		});
+
+		return selectors;
+	};
+	$.fn.respondsTo = function( events ) {
+		if (!this.length ) {
+			return false;
+		} else {
+			//add default ?
+			return event.find(this[0], $.isArray(events) ? events : [events]).length > 0;
+		}
+	};
+	$.fn.triggerHandled = function( event, data ) {
+		event = (typeof event == "string" ? $.Event(event) : event);
+		this.trigger(event, data);
+		return event.handled;
+	};
+	/**
+	 * Only attaches one event handler for all types ...
+	 * @param {Array} types llist of types that will delegate here
+	 * @param {Object} startingEvent the first event to start listening to
+	 * @param {Object} onFirst a function to call 
+	 */
+	event.setupHelper = function( types, startingEvent, onFirst ) {
+		if (!onFirst ) {
+			onFirst = startingEvent;
+			startingEvent = null;
+		}
+		var add = function( handleObj ) {
+
+			var bySelector, selector = handleObj.selector || "";
+			if ( selector ) {
+				bySelector = event.find(this, types, selector);
+				if (!bySelector.length ) {
+					$(this).delegate(selector, startingEvent, onFirst);
+				}
+			}
+			else {
+				//var bySelector = event.find(this, types, selector);
+				if (!event.find(this, types, selector).length ) {
+					event.add(this, startingEvent, onFirst, {
+						selector: selector,
+						delegate: this
+					});
+				}
+
+			}
+
+		},
+			remove = function( handleObj ) {
+				var bySelector, selector = handleObj.selector || "";
+				if ( selector ) {
+					bySelector = event.find(this, types, selector);
+					if (!bySelector.length ) {
+						$(this).undelegate(selector, startingEvent, onFirst);
+					}
+				}
+				else {
+					if (!event.find(this, types, selector).length ) {
+						event.remove(this, startingEvent, onFirst, {
+							selector: selector,
+							delegate: this
+						});
+					}
+				}
+			};
+		$.each(types, function() {
+			event.special[this] = {
+				add: add,
+				remove: remove,
+				setup: function() {},
+				teardown: function() {}
+			};
+		});
+	};
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/offline/offline.html b/browserid/static/dialog/jquery/event/offline/offline.html
new file mode 100644
index 0000000000000000000000000000000000000000..280d91ce436df711b10f7df13134cf045251c88a
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/offline/offline.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>offline</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .error {border: solid 1px red;}
+            .error_text { color: red; font-size: 10px;}
+            td {padding: 3px;}
+        </style>
+	</head>
+	<body>
+	    <div id='log'></div>
+		<script type='text/javascript' 
+                src='../../../steal/steal.js?steal[app]=jquery/event/offline&steal[env]=development'>   
+        </script>
+		<script type='text/javascript'>
+			var logger = function(ev){
+				$('#log').append("<p>"+ev.type+":"+(this == window ? "window" : this.nodeName)+"</p>")
+			}
+			$(document.body).bind("offline", logger)
+			$(document.body).bind("online", logger)
+		</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/offline/offline.js b/browserid/static/dialog/jquery/event/offline/offline.js
new file mode 100644
index 0000000000000000000000000000000000000000..43452276983fe74dd9ea00a9025b92bf8ac10baa
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/offline/offline.js
@@ -0,0 +1,36 @@
+steal.plugins('jquery/event').then(function($){
+	
+	
+	
+	
+	var support = $.support;
+	support.online = ("onLine" in window.navigator)
+	
+	
+	
+	
+	//support.offlineEvents = eventSupported("online",document.documentElement)
+	$(function(){
+		support.onlineEvents = ("ononline" in document.body)
+		if(!support.onlineEvents){
+			document.body.setAttribute("ononline","")
+			support.onlineEvents = ("ononline" in window)
+		}
+		if(support.onlineEvents){
+			return;
+		}
+		var lastStatus = navigator.onLine;
+		setInterval(function(){
+			if(lastStatus !== navigator.onLine){
+				lastStatus = navigator.onLine
+				$(document.body).trigger(lastStatus ? "online" : "offline")
+				$(window).triggerHandle(lastStatus ? "online" : "offline")
+			}
+		},100)
+
+	})
+	
+	
+	
+	
+})
diff --git a/browserid/static/dialog/jquery/event/resize/resize.js b/browserid/static/dialog/jquery/event/resize/resize.js
new file mode 100644
index 0000000000000000000000000000000000000000..7c874ba9d3cd105632f0f01a2f95e289849dc127
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/resize/resize.js
@@ -0,0 +1,50 @@
+steal.plugins('jquery/event').then(function($){
+	/**
+	 * @add jQuery.event.special
+	 */
+	var resizeCount = 0, 
+		win = $(window),
+		windowWidth = win.width(), 
+		windowHeight = win.height(), 
+		timer;
+	/**
+	 * @attribute resize
+	 * @parent specialevents
+	 * Normalizes resize events cross browser.
+	 * <p>This only allows native resize events on the window and prevents them from being called 
+	 * indefinitely.
+	 * </p>
+	 */
+	$.event.special.resize = {
+		add: function( handleObj ) {
+			//jQuery.event.add( this, handleObj.origType, jQuery.extend({}, handleObj, {handler: liveHandler}) );
+			
+			var origHandler = handleObj.handler;
+			handleObj.origHandler = origHandler;
+			
+			handleObj.handler = function(ev, data){							
+			    if((this !== window) || (resizeCount === 0 && !ev.originalEvent)){
+				     resizeCount++;
+			         handleObj.origHandler.call(this, ev, data);
+					 resizeCount--;
+			    }
+			    var width = win.width();
+				var height = win.height();
+				if(resizeCount ===  0 && (width != windowWidth ||height != windowHeight)){
+					windowWidth = width;
+					windowHeight = height;
+					clearTimeout(timer)
+					timer = setTimeout(function(){
+						win.triggerHandler("resize");
+					},1)
+			        
+			    }					
+			}
+		},
+		
+		setup: function() {
+			return this !== window;
+		}
+	}
+})
+
diff --git a/browserid/static/dialog/jquery/event/select/select.html b/browserid/static/dialog/jquery/event/select/select.html
new file mode 100644
index 0000000000000000000000000000000000000000..3cfc3d12adda714b2ba6b733d94690812448043c
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/select/select.html
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>select</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .error {border: solid 1px red;}
+            .error_text { color: red; font-size: 10px;}
+            td {padding: 3px;}
+			.selected {
+				background-color: blue;
+			}
+        </style>
+	</head>
+	<body>
+	    <div class='select'>
+	    	this is selectable
+	    </div>
+		<div class='select'>
+	    	this is selectable
+	    </div>
+		<p>
+			This is not selectable
+		</p>
+		<div id='container'>
+			<div class='selectme' tabindex='0'>
+				Select me
+			</div>
+			<div class='selectme' tabindex='0'>
+				Select me
+			</div>
+		</div>
+		<a href='#' id='remove'>Remove</a>
+		<script type='text/javascript' 
+                src='../../../steal/steal.js?steal[app]=jquery/event/select&steal[env]=development'>   
+        </script>
+		<script type='text/javascript'>
+			var s = {
+				'selectin' : function(ev, previous){
+					console.log('selectin',ev, previous)
+					$(this).addClass('selected')
+				},
+				'selectout' : function(ev, to){
+					console.log('selectout',ev, to)
+					$(this).removeClass('selected')
+				}
+			}
+			$(".select").bind(s)
+			$("#container").delegate('.selectme','selectin',function(ev, previous){
+				console.log('selectin',ev, previous)
+				$(this).addClass('selected')
+			});
+			$("#container").delegate('.selectme','selectout',function(ev, previous){
+				console.log('selectout',ev, previous)
+				$(this).removeClass('selected')
+			});
+			$("#remove").click(function(){
+				$("#container").remove();
+			})
+		</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/event/select/select.js b/browserid/static/dialog/jquery/event/select/select.js
new file mode 100644
index 0000000000000000000000000000000000000000..00506172e53ca16ff8dece122af705a3f8b808f8
--- /dev/null
+++ b/browserid/static/dialog/jquery/event/select/select.js
@@ -0,0 +1,65 @@
+steal.plugins('jquery/event').then(function($){
+	var currentSelected = null, 
+		currentTimer, 
+		pieces,
+		focusin = function(ev){
+			clearTimeout(currentTimer);
+			ev.stopPropagation(); //prevent others from handling focusin
+			var so = $.Event('selectout');
+			so.relatedTarget = this;
+
+			$(currentSelected).trigger(so);
+			
+			var si = $.Event('selectin');
+			si.relatedTarget = currentSelected;
+			si.byFocus = true;
+			$(ev.target).trigger(si );
+			currentSelected = null;
+
+		},
+		focusout = function(ev){
+			ev.stopPropagation();
+			currentSelected = ev.currentTarget;
+			clearTimeout(currentTimer);
+			currentTimer = setTimeout(function(){
+				$(currentSelected).trigger('selectout');
+				currentSelected = null;
+			}, 100)
+		}, 
+		focusBubble = 'focusin',
+		blurBubble = 'focusout';
+		
+		
+	if(document.addEventListener){
+		document.addEventListener('focus', function(ev){
+			jQuery.event.trigger( 'focusbubble', null, ev.target )
+		},true);
+		document.addEventListener('blur', function(ev){
+			jQuery.event.trigger( 'blurbubble', null, ev.target )
+		},true);
+		focusBubble = 'focusbubble',
+		blurBubble = 'blurbubble';
+	}
+		
+	$.event.special.selectin = {
+		add: function( handleObj ) {
+			if(handleObj.selector){
+				$(this).delegate(handleObj.selector,focusBubble, focusin)
+				$(this).delegate(handleObj.selector,blurBubble, focusout)
+			}else{
+				$(this).bind(focusBubble, focusin).
+						bind(blurBubble, focusout)
+			}
+		},
+		remove: function( handleObj ) {
+			if(handleObj.selector){
+				$(this).undelegate(handleObj.selector,focusBubble, focusin)
+				$(this).undelegate(handleObj.selector,blurBubble, focusout)
+			}else{
+				$(this).unbind(focusBubble, focusin).
+						unbind(blurBubble, focusout)
+			}
+		}
+	}
+	
+})
diff --git a/browserid/static/dialog/jquery/generate/app b/browserid/static/dialog/jquery/generate/app
new file mode 100644
index 0000000000000000000000000000000000000000..e30d21835b5c8cc780563968f6aab5f1a4857bd1
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/app
@@ -0,0 +1,21 @@
+// _args = ['cookbook']; load('steal/generate/app')
+
+if (!_args[0]) {
+	print("Usage: steal/js steal/generate/app path");
+	quit();
+}
+
+load('steal/rhino/steal.js');
+
+steal('//steal/generate/generate','//steal/generate/system',function(steal){
+	var path =  _args[0].toLowerCase().replace('.',"/"),
+		data = steal.extend({
+			path: path, 
+			application_name: path.match(/[^\/]*$/)[0],
+			current_path: steal.File.cwdURL(),
+			path_to_steal : new steal.File(path).pathToRoot()
+		}, steal.system)
+	
+	steal.generate("jquery/generate/templates/app",path,data);
+});
+
diff --git a/browserid/static/dialog/jquery/generate/controller b/browserid/static/dialog/jquery/generate/controller
new file mode 100644
index 0000000000000000000000000000000000000000..b48b7f16df80e797128edfd8efb2ef0192ede6f7
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/controller
@@ -0,0 +1,21 @@
+if (_args.length < 1) {
+	print("USAGE : steal/js steal/generate/controller YourController")
+	print("EX    : steal/js steal/generate/model Cookbook.Controllers.Recipe");
+	print("      > cookbook/controller/recipe.js")
+	print();
+	quit();
+}
+
+load('steal/rhino/steal.js');
+
+steal(	'//steal/generate/generate',
+		'//steal/generate/system',	
+function(steal){
+	var md = steal.generate.convert(_args[0]);
+	
+	md.appPath =  md.path.replace(/\/controllers$/,"");
+
+	steal.generate("jquery/generate/templates/controller",md.appPath,md)
+	
+});
+
diff --git a/browserid/static/dialog/jquery/generate/model b/browserid/static/dialog/jquery/generate/model
new file mode 100644
index 0000000000000000000000000000000000000000..b9267e8ebbec6d8935170b826429c0005b3dd486
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/model
@@ -0,0 +1,26 @@
+if (_args.length < 1) {
+	print("USAGE : steal/js jquery/generate/model ClassName Type")
+	print("TYPES : JsonRest\n")
+	print("EX    : steal/js jquery/generate/model Cashnet.Models.Customer");
+	print("      > cashnet/models/customer.js")
+	print();
+	quit();
+}
+
+
+
+load('steal/rhino/steal.js');
+
+steal(	'//steal/generate/generate',
+		'//steal/generate/system',
+		'//steal/generate/inflector'	,	
+function(steal){
+	var md = steal.generate.convert(_args[0]);
+	
+	md.type = _args[1]
+	
+	md.appPath =  md.path.replace(/\/models$/,"");
+
+	steal.generate("jquery/generate/templates/model",md.appPath,md)
+	
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/page b/browserid/static/dialog/jquery/generate/page
new file mode 100644
index 0000000000000000000000000000000000000000..d1b81e19cf81e0d6d73571f8cef01ddedcc8b6cf
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/page
@@ -0,0 +1,21 @@
+if (_args.length < 2) {
+	print("Creates an html page that loads one of your applications.\n")
+	print("USAGE: js steal/generate/test app_name page_location\n")
+	print();
+	quit();
+}
+
+load('steal/rhino/steal.js');
+
+steal('//steal/generate/generate','//steal/generate/system',function(steal){
+	var path =  _args[0].toLowerCase().replace('.',"/")
+	var	data = steal.extend({
+		path: path, 
+		application_name: path.match(/[^\/]*$/)[0],
+		current_path: steal.File.cwdURL(),
+			path_to_steal : new steal.File(path).pathToRoot()
+	}, steal.system)
+	
+	var to = path+"/"+_args[1];
+	steal.generate.render("jquery/generate/templates/page.ejs", to, data)
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/plugin b/browserid/static/dialog/jquery/generate/plugin
new file mode 100644
index 0000000000000000000000000000000000000000..e62fdf5e02335be68c2d417b4c4db57a790498b8
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/plugin
@@ -0,0 +1,20 @@
+// _args = ['thing']; load('steal/generate/app')
+
+if (!_args[0]) {
+	print("Usage: steal/js steal/generate/plugin path");
+	quit();
+}
+load('steal/rhino/steal.js');
+
+steal('//steal/generate/generate',function(steal){
+	var	data = steal.extend({
+		path: _args[0], 
+		application_name: _args[0].match(/[^\/]*$/)[0],
+		current_path: steal.File.cwdURL(),
+		path_to_steal : new steal.File(_args[0]).pathToRoot()
+	}, steal.system)
+	
+	steal.generate("jquery/generate/templates/plugin",_args[0],data)
+	
+})();
+
diff --git a/browserid/static/dialog/jquery/generate/scaffold b/browserid/static/dialog/jquery/generate/scaffold
new file mode 100644
index 0000000000000000000000000000000000000000..82d1c49ef31b76c2c2cff610c4cb1a98539c5130
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/scaffold
@@ -0,0 +1,50 @@
+if (_args.length < 1) {
+	print("USAGE : steal/js steal/generate/scaffold FullName Type")
+	print("TYPES : JsonRest\n")
+	print("EX    : js steal/generate/scaffold Cashnet.Models.Customer");
+	print("      > cashnet/models/customer.js ....")
+	print();
+	quit();
+}
+
+load('steal/rhino/steal.js');
+
+steal(	'//steal/generate/generate',
+		'//steal/generate/system',	
+function(steal){
+	//check capitalization
+	
+	var parts = _args[0].split("."), part;
+	
+	for(var i=0; i< parts.length;i++){
+		part = parts[i];
+		if( part[0] !== part[0].toUpperCase() ){
+			print("! Warning: "+part+" should probably be capitalized.  JavaScriptMVC likes capital namespaces and class names.")
+		}
+		parts[i] = steal.generate.underscore(part);
+	}
+	// check folders
+	var folder = parts.slice(0, parts.length-1).join("/");
+	if(!folder){
+		print("! Error: Scaffolding needs to be part of an app");
+		quit();
+	}
+	if(!steal.File(folder).exists()){
+		print("! Error: folder "+folder+" does not exist!");
+		quit();
+	}
+	//check pluralization of last part
+	if(steal.Inflector.singularize(part) !== part){
+		print("! Warning: Model names should be singular.  I don't think "+part+
+		" is singular!")	
+	}
+
+	var md = steal.generate.convert(_args[0]);
+	
+	md.type = _args[1]
+	
+	md.appPath =  md.path.replace(/\/models$/,"");
+
+	steal.generate("jquery/generate/templates/scaffold",md.appPath,md)
+	
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/app/(application_name).css.ejs b/browserid/static/dialog/jquery/generate/templates/app/(application_name).css.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..62aab7ebd574bdd24850cfc4aa2b768e01726b2a
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/app/(application_name).css.ejs
@@ -0,0 +1,2 @@
+body {font-family: verdana}
+td {padding: 3px;}
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/app/(application_name).html.ejs b/browserid/static/dialog/jquery/generate/templates/app/(application_name).html.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..365011942c57baf21bcd7b79cbe4e0b7a731c7c5
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/app/(application_name).html.ejs
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title><%= application_name %></title>
+	</head>
+	<body>
+	    <h1>Welcome to JavaScriptMVC 3.0!</h1>
+        <ul>
+			<li>Include plugins and files in <i><%= path %>/<%= application_name %>.js</i>.</li>
+			<li>Change to production mode by changing <i>development</i> to <i>production</i> in this file.</li>
+        </ul>
+		<script type='text/javascript' 
+	    src='<%= path_to_steal %>/steal/steal.js?<%= path %>,development'>	 
+        </script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/app/(application_name).js.ejs b/browserid/static/dialog/jquery/generate/templates/app/(application_name).js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..124c38eb646dbb46a6eb3b2f2fec23b312924546
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/app/(application_name).js.ejs
@@ -0,0 +1,18 @@
+steal.plugins(	
+	'jquery/controller',			// a widget factory
+	'jquery/controller/subscribe',	// subscribe to OpenAjax.hub
+	'jquery/view/ejs',				// client side templates
+	'jquery/controller/view',		// lookup views with the controller's name
+	'jquery/model',					// Ajax wrappers
+	'jquery/dom/fixture',			// simulated Ajax requests
+	'jquery/dom/form_params')		// form data helper
+	
+	.css('<%= application_name %>')	// loads styles
+
+	.resources()					// 3rd party script's (like jQueryUI), in resources folder
+
+	.models()						// loads files in models folder 
+
+	.controllers()					// loads files in controllers folder
+
+	.views();						// adds views to be added to build
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/app/controllers/.ignore b/browserid/static/dialog/jquery/generate/templates/app/controllers/.ignore
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/browserid/static/dialog/jquery/generate/templates/app/docs/.ignore b/browserid/static/dialog/jquery/generate/templates/app/docs/.ignore
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/browserid/static/dialog/jquery/generate/templates/app/fixtures/.ignore b/browserid/static/dialog/jquery/generate/templates/app/fixtures/.ignore
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/browserid/static/dialog/jquery/generate/templates/app/funcunit.html.ejs b/browserid/static/dialog/jquery/generate/templates/app/funcunit.html.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..8b261254adc36c899aca2f857575c4a79773ca96
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/app/funcunit.html.ejs
@@ -0,0 +1,14 @@
+<html>
+	<head>
+		<link rel="stylesheet" type="text/css" href="<%= path_to_steal %>/funcunit/qunit/qunit.css" />
+		<title><%= application_name%> FuncUnit Test</title>
+		<script type='text/javascript' src='<%= path_to_steal %>/steal/steal.js?<%=path%>/test/funcunit'></script>
+	</head>
+	<body>
+		<h1 id="qunit-header"><%= application_name%> Test Suite</h1>
+		<h2 id="qunit-banner"></h2>
+		<div id="qunit-testrunner-toolbar"></div>
+		<h2 id="qunit-userAgent"></h2>
+		<ol id="qunit-tests"></ol>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/app/models/.ignore b/browserid/static/dialog/jquery/generate/templates/app/models/.ignore
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/browserid/static/dialog/jquery/generate/templates/app/qunit.html.ejs b/browserid/static/dialog/jquery/generate/templates/app/qunit.html.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..9a2e275b2d4f4d2765fc10ab498ea82f58b82579
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/app/qunit.html.ejs
@@ -0,0 +1,20 @@
+<html>
+	<head>
+		<link rel="stylesheet" type="text/css" href="<%= path_to_steal %>/funcunit/qunit/qunit.css" />
+		<title><%= application_name%> QUnit Test</title>
+		<script type='text/javascript'>
+			steal = {ignoreControllers: true}
+		</script>
+		<script type='text/javascript' src='<%= path_to_steal %>/steal/steal.js?<%=path%>/test/qunit'></script>
+	</head>
+	<body>
+
+		<h1 id="qunit-header"><%= application_name%> Test Suite</h1>
+		<h2 id="qunit-banner"></h2>
+		<div id="qunit-testrunner-toolbar"></div>
+		<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+		<ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/app/resources/.ignore b/browserid/static/dialog/jquery/generate/templates/app/resources/.ignore
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/browserid/static/dialog/jquery/generate/templates/app/scripts/build.html.ejs b/browserid/static/dialog/jquery/generate/templates/app/scripts/build.html.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..35b326e7503eb2c13e6e41a6bba78303a66bee68
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/app/scripts/build.html.ejs
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title><%= application_name %> Build Page</title>
+	</head>
+	<body>
+	    <h1><%= application_name %> Build Page</h1>
+		<p>This is a dummy page that loads your app so steal can
+		   get all the files.  
+		</p>
+		<p>If you built your app
+		   to depend on HTML in the page before DOMContent loaded or 
+		   onload, you can add the HTML here, or you can change the
+		   build.js script to point to a better html file.
+		</p>
+		<script type='text/javascript' 
+	    src='../<%= path_to_steal %>/steal/steal.js?<%= path %>'>	 
+        </script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/app/scripts/build.js.ejs b/browserid/static/dialog/jquery/generate/templates/app/scripts/build.js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..cb5672ac9ac9c121aa63bfefd02138c4a8883a11
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/app/scripts/build.js.ejs
@@ -0,0 +1,6 @@
+//steal/js <%= path %>/scripts/compress.js
+
+load("steal/rhino/steal.js");
+steal.plugins('steal/build','steal/build/scripts','steal/build/styles',function(){
+	steal.build('<%= path %>/scripts/build.html',{to: '<%= path %>'});
+});
diff --git a/browserid/static/dialog/jquery/generate/templates/app/scripts/clean.js.ejs b/browserid/static/dialog/jquery/generate/templates/app/scripts/clean.js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..a90472c0313276d361b8f6b2896f667d851512df
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/app/scripts/clean.js.ejs
@@ -0,0 +1,17 @@
+//steal/js <%= path %>/scripts/compress.js
+
+load("steal/rhino/steal.js");
+steal.plugins('steal/clean',function(){
+	steal.clean('<%= path %>/<%= application_name %>.html',{
+		indent_size: 1, 
+		indent_char: '\t', 
+		jslint : false,
+		ignore: /jquery\/jquery.js/,
+		predefined: {
+			steal: true, 
+			jQuery: true, 
+			$ : true,
+			window : true
+			}
+	});
+});
diff --git a/browserid/static/dialog/jquery/generate/templates/app/scripts/docs.js.ejs b/browserid/static/dialog/jquery/generate/templates/app/scripts/docs.js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..44635db84968c971760e603cd0da6da777388a72
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/app/scripts/docs.js.ejs
@@ -0,0 +1,6 @@
+//js <%= path %>/scripts/doc.js
+
+load('steal/rhino/steal.js');
+steal.plugins("documentjs").then(function(){
+	DocumentJS('<%= path %>/<%= application_name %>.html');
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/app/test/funcunit/(application_name)_test.js.ejs b/browserid/static/dialog/jquery/generate/templates/app/test/funcunit/(application_name)_test.js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..afb29a4599295345e5403297e9fa926c0d486c80
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/app/test/funcunit/(application_name)_test.js.ejs
@@ -0,0 +1,9 @@
+module("<%=application_name%> test", { 
+	setup: function(){
+		S.open("//<%= path %>/<%=application_name%>.html");
+	}
+});
+
+test("Copy Test", function(){
+	equals(S("h1").text(), "Welcome to JavaScriptMVC 3.0!","welcome text");
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/app/test/funcunit/funcunit.js.ejs b/browserid/static/dialog/jquery/generate/templates/app/test/funcunit/funcunit.js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..760df6b34c7a766bc965f25b7ae177aa0bd6566a
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/app/test/funcunit/funcunit.js.ejs
@@ -0,0 +1,3 @@
+steal
+ .plugins("funcunit")
+ .then("<%= application_name %>_test");
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/app/test/qunit/(application_name)_test.js.ejs b/browserid/static/dialog/jquery/generate/templates/app/test/qunit/(application_name)_test.js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..c00d40d7cdcde66546fde0e1871770a6cfb90429
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/app/test/qunit/(application_name)_test.js.ejs
@@ -0,0 +1,5 @@
+module("<%= application_name %>");
+
+test("<%= application_name %> testing works", function(){
+	ok(true,"an assert is run");
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/app/test/qunit/qunit.js.ejs b/browserid/static/dialog/jquery/generate/templates/app/test/qunit/qunit.js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..c901b815430bd9bcba9a86e963d730666670e25c
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/app/test/qunit/qunit.js.ejs
@@ -0,0 +1,3 @@
+steal
+  .plugins("funcunit/qunit", "<%= path %>")
+  .then("<%= application_name %>_test");
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/app/views/.ignore b/browserid/static/dialog/jquery/generate/templates/app/views/.ignore
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/browserid/static/dialog/jquery/generate/templates/controller/controllers/(underscore)_controller.js.ejs b/browserid/static/dialog/jquery/generate/templates/controller/controllers/(underscore)_controller.js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..be4e663b37d90e4cc3bcd39302948e4670c19cc8
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/controller/controllers/(underscore)_controller.js.ejs
@@ -0,0 +1,12 @@
+/**
+ * @tag controllers, home
+ */
+jQuery.Controller.extend('<%=name.replace("Models","Controllers")%>',
+/* @Static */
+{
+
+},
+/* @Prototype */
+{
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/model/fixtures.link b/browserid/static/dialog/jquery/generate/templates/model/fixtures.link
new file mode 100644
index 0000000000000000000000000000000000000000..9cb5b4ccd0549cb1a002602bea691e31b3985649
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/model/fixtures.link
@@ -0,0 +1 @@
+jquery/generate/templates/scaffold/fixtures
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/model/models.link b/browserid/static/dialog/jquery/generate/templates/model/models.link
new file mode 100644
index 0000000000000000000000000000000000000000..96e2df1257ddc21d3101cc8fa45b50872376b593
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/model/models.link
@@ -0,0 +1 @@
+jquery/generate/templates/scaffold/models
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/model/test/qunit.link b/browserid/static/dialog/jquery/generate/templates/model/test/qunit.link
new file mode 100644
index 0000000000000000000000000000000000000000..a3810cd6c95dcdd789bef437f205a6413d172e31
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/model/test/qunit.link
@@ -0,0 +1 @@
+jquery/generate/templates/scaffold/test/qunit
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/page.ejs b/browserid/static/dialog/jquery/generate/templates/page.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..932506c4ab28d4652656b2bc98995b09f2fae07d
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/page.ejs
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title><%= application_name %></title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .error {border: solid 1px red;}
+            .error_text { color: red; font-size: 10px;}
+            td {padding: 3px;}
+        </style>
+	</head>
+	<body>
+	    <h1>Welcome to JavaScriptMVC 3.0!</h1>
+        <ul>
+            <li>Steal plugins and files in <i><%= path %>/<%= application_name %>.js</i>.</li>
+            <li>Change to production mode by changing <i>development</i> to <i>production</i> in this file.</li>
+        </ul>
+		<script type='text/javascript' 
+                src='<%= path_to_steal ? path_to_steal +"/" : "" %>steal/steal.js?<%= path %>,development'>   
+        </script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/plugin/(application_name).html.ejs b/browserid/static/dialog/jquery/generate/templates/plugin/(application_name).html.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..94feff6f28d69b4affcfb924e6c71809a632d723
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/plugin/(application_name).html.ejs
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title><%= application_name %></title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .error {border: solid 1px red;}
+            .error_text { color: red; font-size: 10px;}
+            td {padding: 3px;}
+        </style>
+	</head>
+	<body>
+	    <h1>Welcome to JavaScriptMVC 3.0!</h1>
+        <ul>
+            <li>Include plugins and files in <i><%= path %>/<%= application_name %>.js</i>.</li>
+            <li>Change to production mode by changing <i>development</i> to <i>production</i> in this file.</li>
+        </ul>
+		<script type='text/javascript' 
+                src='<%= path_to_steal %>/steal/steal.js?<%= path %>,development'>   
+        </script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/plugin/(application_name).js.ejs b/browserid/static/dialog/jquery/generate/templates/plugin/(application_name).js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..f4ca1b5cba61231a01cf0f941c5d813cecb726a8
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/plugin/(application_name).js.ejs
@@ -0,0 +1,3 @@
+steal.plugins().then(function($){
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/plugin/docs/.gitignore b/browserid/static/dialog/jquery/generate/templates/plugin/docs/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/browserid/static/dialog/jquery/generate/templates/plugin/fixtures/.ignore b/browserid/static/dialog/jquery/generate/templates/plugin/fixtures/.ignore
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/browserid/static/dialog/jquery/generate/templates/plugin/funcunit.html.ejs b/browserid/static/dialog/jquery/generate/templates/plugin/funcunit.html.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..3dc825d552abae265eb7d0eadedec14f9f36e2eb
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/plugin/funcunit.html.ejs
@@ -0,0 +1,15 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="<%= path_to_steal %>/funcunit/qunit/qunit.css" />
+        <title><%= application_name%> FuncUnit Test</title>
+		<script type='text/javascript' src='<%= path_to_steal %>/steal/steal.js?<%=path%>/test/funcunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header"><%= application_name%> Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+        <ol id="qunit-tests"></ol>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/plugin/qunit.html.ejs b/browserid/static/dialog/jquery/generate/templates/plugin/qunit.html.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..9a17aeade67f0240e44b7d478724e94336f9af32
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/plugin/qunit.html.ejs
@@ -0,0 +1,20 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="<%= path_to_steal %>/funcunit/qunit/qunit.css" />
+        <title><%= application_name%> QUnit Test</title>
+		<script type='text/javascript'>
+			steal = {ignoreControllers: true}
+		</script>
+		<script type='text/javascript' src='<%= path_to_steal %>/steal/steal.js?<%=path%>/test/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header"><%= application_name%> Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/plugin/resources/.ignore b/browserid/static/dialog/jquery/generate/templates/plugin/resources/.ignore
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/browserid/static/dialog/jquery/generate/templates/plugin/scripts.link b/browserid/static/dialog/jquery/generate/templates/plugin/scripts.link
new file mode 100644
index 0000000000000000000000000000000000000000..adb8fab0d4c667d0a9a873f93d6c92b868836f72
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/plugin/scripts.link
@@ -0,0 +1 @@
+jquery/generate/templates/app/scripts
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/plugin/test.link b/browserid/static/dialog/jquery/generate/templates/plugin/test.link
new file mode 100644
index 0000000000000000000000000000000000000000..43220fc258f89082763afd21f9f464f29b12a5f5
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/plugin/test.link
@@ -0,0 +1 @@
+jquery/generate/templates/app/test
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/plugin/views/.ignore b/browserid/static/dialog/jquery/generate/templates/plugin/views/.ignore
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/browserid/static/dialog/jquery/generate/templates/scaffold/controllers/(underscore)_controller.js.ejs b/browserid/static/dialog/jquery/generate/templates/scaffold/controllers/(underscore)_controller.js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..9a1062088dc72342d542b9435bfea488e0ebcb53
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/scaffold/controllers/(underscore)_controller.js.ejs
@@ -0,0 +1,98 @@
+/**
+ * @tag controllers, home
+ * Displays a table of <%= plural %>.	 Lets the user 
+ * ["<%=name.replace("Models","Controllers")%>.prototype.form submit" create], 
+ * ["<%=name.replace("Models","Controllers")%>.prototype.&#46;edit click" edit],
+ * or ["<%=name.replace("Models","Controllers")%>.prototype.&#46;destroy click" destroy] <%= plural %>.
+ */
+$.Controller.extend('<%=name.replace("Models","Controllers")%>',
+/* @Static */
+{
+	onDocument: true
+},
+/* @Prototype */
+{
+ /**
+ * When the page loads, gets all <%= plural %> to be displayed.
+ */
+ load: function(){
+	if(!$("#<%= underscore %>").length){
+	 $(document.body).append($('<div/>').attr('id','<%= underscore %>'));
+		 <%= name %>.findAll({}, this.callback('list'));
+ 	}
+ },
+ /**
+ * Displays a list of <%= plural %> and the submit form.
+ * @param {Array} <%= plural %> An array of <%=name%> objects.
+ */
+ list: function( <%= plural %> ){
+	$('#<%= underscore %>').html(this.view('init', {<%= plural %>:<%= plural %>} ));
+ },
+ /**
+ * Responds to the create form being submitted by creating a new <%=name%>.
+ * @param {jQuery} el A jQuery wrapped element.
+ * @param {Event} ev A jQuery event whose default action is prevented.
+ */
+'form submit': function( el, ev ){
+	ev.preventDefault();
+	new <%= name %>(el.formParams()).save();
+},
+/**
+ * Listens for <%= plural %> being created.	 When a <%= underscore %> is created, displays the new <%= underscore %>.
+ * @param {String} called The open ajax event that was called.
+ * @param {Event} <%= underscore %> The new <%= underscore %>.
+ */
+'<%= underscore %>.created subscribe': function( called, <%= underscore %> ){
+	$("#<%= underscore %> tbody").append( this.view("list", {<%= plural %>:[<%= underscore %>]}) );
+	$("#<%= underscore %> form input[type!=submit]").val(""); //clear old vals
+},
+ /**
+ * Creates and places the edit interface.
+ * @param {jQuery} el The <%= underscore %>'s edit link element.
+ */
+'.edit click': function( el ){
+	var <%= underscore %> = el.closest('.<%= underscore %>').model();
+	<%= underscore %>.elements().html(this.view('edit', <%= underscore %>));
+},
+ /**
+ * Removes the edit interface.
+ * @param {jQuery} el The <%= underscore %>'s cancel link element.
+ */
+'.cancel click': function( el ){
+	this.show(el.closest('.<%= underscore %>').model());
+},
+ /**
+ * Updates the <%= underscore %> from the edit values.
+ */
+'.update click': function( el ){
+	var $<%= underscore %> = el.closest('.<%= underscore %>'); 
+	$<%= underscore %>.model().update($<%= underscore %>.formParams());
+},
+ /**
+ * Listens for updated <%= plural %>.	 When a <%= underscore %> is updated, 
+ * update's its display.
+ */
+'<%= underscore %>.updated subscribe': function( called, <%= underscore %> ){
+	this.show(<%= underscore %>);
+},
+ /**
+ * Shows a <%= underscore %>'s information.
+ */
+show: function( <%= underscore %> ){
+	<%= underscore %>.elements().html(this.view('show',<%= underscore %>));
+},
+ /**
+ *	 Handle's clicking on a <%= underscore %>'s destroy link.
+ */
+'.destroy click': function( el ){
+	if(confirm("Are you sure you want to destroy?")){
+		el.closest('.<%= underscore %>').model().destroy();
+	}
+ },
+ /**
+ *	 Listens for <%= plural %> being destroyed and removes them from being displayed.
+ */
+"<%= underscore %>.destroyed subscribe": function(called, <%= underscore %>){
+	<%= underscore %>.elements().remove();	 //removes ALL elements
+ }
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/scaffold/fixtures/(plural).json.get.ejs b/browserid/static/dialog/jquery/generate/templates/scaffold/fixtures/(plural).json.get.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..4f4bef3bf71922a1315dc65ceaaeae33d4a7671b
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/scaffold/fixtures/(plural).json.get.ejs
@@ -0,0 +1,3 @@
+[
+	{"name": "Take Out Trash", "description": "To the curb!", "id": 5}
+]
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/scaffold/models/(underscore).js.ejs b/browserid/static/dialog/jquery/generate/templates/scaffold/models/(underscore).js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..158775e1c3412e37c5eaa0886e8dd3cc7cdbfdd3
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/scaffold/models/(underscore).js.ejs
@@ -0,0 +1,82 @@
+/**
+ * @tag models, home
+ * Wraps backend <%=underscore%> services.  Enables 
+ * [<%=name%>.static.findAll retrieving],
+ * [<%=name%>.static.update updating],
+ * [<%=name%>.static.destroy destroying], and
+ * [<%=name%>.static.create creating] <%= plural %>.
+ */
+$.Model.extend('<%=name%>',
+/* @Static */
+{
+	/**
+ 	 * Retrieves <%= plural %> data from your backend services.
+ 	 * @param {Object} params params that might refine your results.
+ 	 * @param {Function} success a callback function that returns wrapped <%=underscore%> objects.
+ 	 * @param {Function} error a callback function for an error in the ajax request.
+ 	 */
+	findAll: function( params, success, error ){
+		$.ajax({
+			url: '/<%= underscore %>',
+			type: 'get',
+			dataType: 'json',
+			data: params,
+			success: this.callback(['wrapMany',success]),
+			error: error,
+			fixture: "//<%= appPath %>/fixtures/<%= plural %>.json.get" //calculates the fixture path from the url and type.
+		});
+	},
+	/**
+	 * Updates a <%= underscore %>'s data.
+	 * @param {String} id A unique id representing your <%= underscore %>.
+	 * @param {Object} attrs Data to update your <%= underscore %> with.
+	 * @param {Function} success a callback function that indicates a successful update.
+ 	 * @param {Function} error a callback that should be called with an object of errors.
+     */
+	update: function( id, attrs, success, error ){
+		$.ajax({
+			url: '/<%= plural %>/'+id,
+			type: 'put',
+			dataType: 'json',
+			data: attrs,
+			success: success,
+			error: error,
+			fixture: "-restUpdate" //uses $.fixture.restUpdate for response.
+		});
+	},
+	/**
+ 	 * Destroys a <%= underscore %>'s data.
+ 	 * @param {String} id A unique id representing your <%= underscore %>.
+	 * @param {Function} success a callback function that indicates a successful destroy.
+ 	 * @param {Function} error a callback that should be called with an object of errors.
+	 */
+	destroy: function( id, success, error ){
+		$.ajax({
+			url: '/<%= plural %>/'+id,
+			type: 'delete',
+			dataType: 'json',
+			success: success,
+			error: error,
+			fixture: "-restDestroy" // uses $.fixture.restDestroy for response.
+		});
+	},
+	/**
+	 * Creates a <%= underscore %>.
+	 * @param {Object} attrs A <%= underscore %>'s attributes.
+	 * @param {Function} success a callback function that indicates a successful create.  The data that comes back must have an ID property.
+	 * @param {Function} error a callback that should be called with an object of errors.
+	 */
+	create: function( attrs, success, error ){
+		$.ajax({
+			url: '/<%= plural %>',
+			type: 'post',
+			dataType: 'json',
+			success: success,
+			error: error,
+			data: attrs,
+			fixture: "-restCreate" //uses $.fixture.restCreate for response.
+		});
+	}
+},
+/* @Prototype */
+{});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/scaffold/test/funcunit/(underscore)_controller_test.js.ejs b/browserid/static/dialog/jquery/generate/templates/scaffold/test/funcunit/(underscore)_controller_test.js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..346f0209b4b28575f79fac7d57c2092b549e9e49
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/scaffold/test/funcunit/(underscore)_controller_test.js.ejs
@@ -0,0 +1,61 @@
+/*global module: true, ok: true, equals: true, S: true, test: true */
+module("<%= underscore %>", {
+	setup: function () {
+		// open the page
+		S.open("//<%= appPath %>/<%= appName %>.html");
+
+		//make sure there's at least one <%= underscore %> on the page before running a test
+		S('.<%= underscore %>').exists();
+	},
+	//a helper function that creates a <%= underscore %>
+	create: function () {
+		S("[name=name]").type("Ice");
+		S("[name=description]").type("Cold Water");
+		S("[type=submit]").click();
+		S('.<%= underscore %>:nth-child(2)').exists();
+	}
+});
+
+test("<%= plural %> present", function () {
+	ok(S('.<%= underscore %>').size() >= 1, "There is at least one <%= underscore %>");
+});
+
+test("create <%= plural %>", function () {
+
+	this.create();
+
+	S(function () {
+		ok(S('.<%= underscore %>:nth-child(2) td:first').text().match(/Ice/), "Typed Ice");
+	});
+});
+
+test("edit <%= plural %>", function () {
+
+	this.create();
+
+	S('.<%= underscore %>:nth-child(2) a.edit').click();
+	S(".<%= underscore %> input[name=name]").type(" Water");
+	S(".<%= underscore %> input[name=description]").type("\b\b\b\b\bTap Water");
+	S(".update").click();
+	S('.<%= underscore %>:nth-child(2) .edit').exists(function () {
+
+		ok(S('.<%= underscore %>:nth-child(2) td:first').text().match(/Ice Water/), "Typed Ice Water");
+
+		ok(S('.<%= underscore %>:nth-child(2) td:nth-child(2)').text().match(/Cold Tap Water/), "Typed Cold Tap Water");
+	});
+});
+
+test("destroy", function () {
+
+	this.create();
+
+	S(".<%= underscore %>:nth-child(2) .destroy").click();
+
+	//makes the next confirmation return true
+	S.confirm(true);
+
+	S('.<%= underscore %>:nth-child(2)').missing(function () {
+		ok("destroyed");
+	});
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/scaffold/test/qunit/(underscore)_test.js.ejs b/browserid/static/dialog/jquery/generate/templates/scaffold/test/qunit/(underscore)_test.js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..0b5640a435b962eed249e1c7d87a291b6f38e8de
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/scaffold/test/qunit/(underscore)_test.js.ejs
@@ -0,0 +1,45 @@
+module("Model: <%= name %>")
+
+test("findAll", function(){
+	stop(2000);
+	<%= name %>.findAll({}, function(<%= plural %>){
+		start()
+		ok(<%= plural %>)
+        ok(<%= plural %>.length)
+        ok(<%= plural %>[0].name)
+        ok(<%= plural %>[0].description)
+	});
+	
+})
+
+test("create", function(){
+	stop(2000);
+	new <%= name %>({name: "dry cleaning", description: "take to street corner"}).save(function(<%= underscore %>){
+		start();
+		ok(<%= underscore %>);
+        ok(<%= underscore %>.id);
+        equals(<%= underscore %>.name,"dry cleaning")
+        <%= underscore %>.destroy()
+	})
+})
+test("update" , function(){
+	stop();
+	new <%= name %>({name: "cook dinner", description: "chicken"}).
+            save(function(<%= underscore %>){
+            	equals(<%= underscore %>.description,"chicken");
+        		<%= underscore %>.update({description: "steak"},function(<%= underscore %>){
+        			start()
+        			equals(<%= underscore %>.description,"steak");
+        			<%= underscore %>.destroy();
+        		})
+            })
+
+});
+test("destroy", function(){
+	stop(2000);
+	new <%= name %>({name: "mow grass", description: "use riding mower"}).
+            destroy(function(<%= underscore %>){
+            	start();
+            	ok( true ,"Destroy called" )
+            })
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/scaffold/views/(underscore)/edit.ejs.ejs b/browserid/static/dialog/jquery/generate/templates/scaffold/views/(underscore)/edit.ejs.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..3a4acb6edf5383380d6ab4ff569a84e651067425
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/scaffold/views/(underscore)/edit.ejs.ejs
@@ -0,0 +1,10 @@
+<%%for(var attribute in <%=name%>.attributes){%>
+	<%%if(attribute == 'id') continue;%>
+	<td class='<%%= attribute %>'>
+		<input type="text" value="<%%= this[attribute]%>" name="<%%= attribute%>"/>
+	</td>
+<%%}%>
+<td>
+	<input type='submit' value='Update' class='update'/>
+	<a href='javascript://' class='cancel'>cancel</a>
+</td>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/scaffold/views/(underscore)/init.ejs.ejs b/browserid/static/dialog/jquery/generate/templates/scaffold/views/(underscore)/init.ejs.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..170339a8f0ea49510ed165c701767c849b7d9d73
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/scaffold/views/(underscore)/init.ejs.ejs
@@ -0,0 +1,26 @@
+<h2><%=plural%></h2>
+<table cellspacing='0px'>
+	<thead>
+	<tr>
+		<%% for(var attr in <%= name%>.attributes){%>
+			<%% if(attr == 'id') continue;%>
+			<th><%%= attr%> </th>	 
+		<%%}%>
+		<th>Options</th>
+	</tr>
+	</thead>
+	<tbody>
+		<%%= $.View('//<%= appPath %>/views/<%= underscore %>/list',{<%=plural%>: <%=plural%>})%>
+	</tbody>
+</table>
+<h2>New <%= underscore %></h2>
+<form>
+	<%% for(var attr in <%= name%>.attributes){ %>
+		<%% if(attr == 'id') continue;%>
+		<div>
+			<label><%%= attr %> </label><br />
+			<input type="text" value="" name="<%%= attr %>"/>
+		</div>
+	<%%}%>
+	<input type='submit' value='Create'/>
+</form>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/scaffold/views/(underscore)/list.ejs.ejs b/browserid/static/dialog/jquery/generate/templates/scaffold/views/(underscore)/list.ejs.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..b1b9db536038aea5847f7a6cc2541a0839da416a
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/scaffold/views/(underscore)/list.ejs.ejs
@@ -0,0 +1,5 @@
+<%%for(var i = 0; i < <%=plural%>.length ; i++){%>
+	<tr <%%= <%=plural%>[i]%>>
+		<%%= $.View('//<%= appPath %>/views/<%= underscore%>/show',<%=plural%>[i])%>
+	</tr>
+<%%}%>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/templates/scaffold/views/(underscore)/show.ejs.ejs b/browserid/static/dialog/jquery/generate/templates/scaffold/views/(underscore)/show.ejs.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..61a504979d1dfe8a2f89ef20844ced6a38a4a7e2
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/templates/scaffold/views/(underscore)/show.ejs.ejs
@@ -0,0 +1,10 @@
+<%%for(var attribute in this.Class.attributes){%>
+	<%%if(attribute == 'id') continue;%>
+	<td class='<%%= attribute%>'>
+		<%%=this[attribute]%>
+	</td>
+<%%}%>
+<td>
+	<a href='javascript://' class='edit'>edit</a>
+	<a href='javascript://' class='destroy'>destroy</a>
+</td>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/generate/test/app_plugin_model_controller.js b/browserid/static/dialog/jquery/generate/test/app_plugin_model_controller.js
new file mode 100644
index 0000000000000000000000000000000000000000..d9460401e111203e2abc32a7ee67f342fb4a8e8c
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/test/app_plugin_model_controller.js
@@ -0,0 +1,61 @@
+load('steal/rhino/steal.js')
+load('steal/rhino/test.js');
+
+(function(rhinoSteal){
+	_S = steal.test;
+	
+	
+	_S.module("jquery/generate")
+	STEALPRINT = false;
+	
+	_S.test("app" , function(t){
+		_args = ['cnu']; 
+		load('jquery/generate/app');
+		_S.clear();
+		_S.open('cnu/cnu.html')
+		t.ok(typeof steal !== 'undefined', "steal is fine")
+		_S.clear();
+	})
+	
+	_S.test("app 2 levels deep" , function(t){		
+		_args = ['cnu/widget']; 
+		load('jquery/generate/plugin');
+		_S.clear();
+		_S.open('cnu/widget/widget.html')
+		t.ok(typeof steal !== 'undefined', "steal is fine")
+		_S.clear();
+	})
+	
+	/**
+	 * Tests generating a very basic controller and model
+	 */
+	
+	_S.test("controller, model, and page" , function(t){		
+		_args = ['Cnu.Controllers.Todos']; 
+		load('jquery/generate/controller');
+		_S.clear();
+
+		_args = ['Cnu.Models.Todo']; 
+		load('jquery/generate/model');
+		_S.clear();
+		cnuContent = readFile('cnu/cnu.js').
+		    replace(".models()", ".models('todo')").
+		    replace(".controllers()", ".controllers('todos')");
+		load('steal/rhino/steal.js')
+		new steal.File('cnu/cnu.js').save( cnuContent );
+		
+
+		_args = ['cnu','cnugen.html']; 
+		load('jquery/generate/page');
+		_S.clear();
+		
+		_S.open('cnu/cnugen.html');
+		
+		t.ok(typeof Cnu.Controllers.Todos !== 'undefined', "Cnu.Controllers.Todos")
+		t.ok(typeof Cnu.Controllers.Todos !== 'undefined',"load Cnu.Controllers.Todos")
+		t.ok(typeof Cnu.Models.Todo !== 'undefined', "load Cnu.Models.Todo")
+		
+		rhinoSteal.File("cnu").removeDir();
+	})
+	
+})(steal);
diff --git a/browserid/static/dialog/jquery/generate/test/run.js b/browserid/static/dialog/jquery/generate/test/run.js
new file mode 100644
index 0000000000000000000000000000000000000000..1efe5c72a60ab1f1944b628aef08da163625c93a
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/test/run.js
@@ -0,0 +1,3 @@
+load("jquery/generate/test/app_plugin_model_controller.js");
+
+load("jquery/generate/test/scaffold.js");
diff --git a/browserid/static/dialog/jquery/generate/test/scaffold.js b/browserid/static/dialog/jquery/generate/test/scaffold.js
new file mode 100644
index 0000000000000000000000000000000000000000..f023c23d18947fd90cd722264129fb3826e97fce
--- /dev/null
+++ b/browserid/static/dialog/jquery/generate/test/scaffold.js
@@ -0,0 +1,87 @@
+
+
+load('steal/rhino/steal.js');
+load('steal/test/test.js');
+
+steal('//steal/test/test', function(s){
+	
+	s.test.module("jquery/generate/scaffold")
+	
+	STEALPRINT = false;
+	
+	s.test.test("make app and scaffold", function(t){
+		_args = ['cookbook']; 
+		load('jquery/generate/app');
+		_args = ['Cookbook.Models.Recipe']; 
+		load('jquery/generate/scaffold');
+		
+		
+		load('steal/rhino/steal.js');
+		var cookbookContent = readFile('cookbook/cookbook.js').
+		    replace(".models()", ".models('recipe')").
+		    replace(".controllers()", ".controllers('recipe')");
+		new steal.File('cookbook/cookbook.js').save( cookbookContent );
+		
+		var qunitContent = readFile('cookbook/test/qunit/qunit.js').
+		    replace(".then(\"cookbook_test\")", ".then(\"recipe_test\")");
+		new steal.File('cookbook/test/qunit/qunit.js').save( qunitContent );
+		
+		var funcunitContent = readFile('cookbook/test/funcunit/funcunit.js').
+		    replace(".then(\"cookbook_test\")", ".then(\"recipe_controller_test\")");
+		new steal.File('cookbook/test/funcunit/funcunit.js').save( funcunitContent );
+
+		t.clear();
+		print('trying to open ...')
+		t.open('cookbook/cookbook.html', false)
+		t.ok(Cookbook.Controllers.Recipe, "Recipe Controller")
+		t.ok(Cookbook.Models.Recipe, "Recipe Controller")
+		t.clear();
+	});
+	
+	//now see if unit and functional run
+	
+	s.test.test("scaffold unit tests", function(t){
+		
+		load('steal/rhino/steal.js');
+		load('funcunit/loader.js');
+		FuncUnit.load('cookbook/qunit.html');
+	});
+	
+	s.test.test("scaffold functional tests", function(t){
+		load('steal/rhino/steal.js');
+		load('funcunit/loader.js');
+		FuncUnit.load('cookbook/funcunit.html');
+		
+	});
+	
+	s.test.test("documentjs", function(t){
+		t.clear();
+		load('steal/rhino/steal.js');
+		_args = ['cookbook/cookbook.html']
+		load("documentjs/documentjs.js");
+		DocumentJS('cookbook/cookbook.html');
+	});
+	
+	s.test.test("compress", function(t){
+		t.clear();
+		load("cookbook/scripts/build.js")
+		
+		var cookbookPage = readFile('cookbook/cookbook.html').
+	    	replace("steal.js?cookbook,development", "steal.production.js?cookbook");
+		new steal.File('cookbook/cookbook.html').save( cookbookPage );
+		
+		t.clear();
+		t.open('cookbook/cookbook.html', false)
+		t.ok(Cookbook.Controllers.Recipe, "Recipe Controller")
+		t.ok(Cookbook.Models.Recipe, "Recipe Controller")
+		t.clear();
+	});
+	
+	
+	//print("-- cleanup --");
+	s.File("cookbook").removeDir();
+
+})
+
+
+
diff --git a/browserid/static/dialog/jquery/jquery.js b/browserid/static/dialog/jquery/jquery.js
new file mode 100644
index 0000000000000000000000000000000000000000..615f7f488b013215c2c7d53d4748dfb43af007bb
--- /dev/null
+++ b/browserid/static/dialog/jquery/jquery.js
@@ -0,0 +1,7183 @@
+/*!
+ * jQuery JavaScript Library v1.4.4
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Thu Nov 11 19:04:53 2010 -0500
+ */
+(function( window, undefined ) {
+
+// Use the correct document accordingly with window argument (sandbox)
+var document = window.document;
+var jQuery = (function() {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
+		// The jQuery object is actually just the init constructor 'enhanced'
+		return new jQuery.fn.init( selector, context );
+	},
+
+	// Map over jQuery in case of overwrite
+	_jQuery = window.jQuery,
+
+	// Map over the $ in case of overwrite
+	_$ = window.$,
+
+	// A central reference to the root jQuery(document)
+	rootjQuery,
+
+	// A simple way to check for HTML strings or ID strings
+	// (both of which we optimize for)
+	quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,
+
+	// Is it a simple selector
+	isSimple = /^.[^:#\[\.,]*$/,
+
+	// Check if a string has a non-whitespace character in it
+	rnotwhite = /\S/,
+	rwhite = /\s/,
+
+	// Used for trimming whitespace
+	trimLeft = /^\s+/,
+	trimRight = /\s+$/,
+
+	// Check for non-word characters
+	rnonword = /\W/,
+
+	// Check for digits
+	rdigit = /\d/,
+
+	// Match a standalone tag
+	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+	// JSON RegExp
+	rvalidchars = /^[\],:{}\s]*$/,
+	rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
+	rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
+	rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+
+	// Useragent RegExp
+	rwebkit = /(webkit)[ \/]([\w.]+)/,
+	ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
+	rmsie = /(msie) ([\w.]+)/,
+	rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
+
+	// Keep a UserAgent string for use with jQuery.browser
+	userAgent = navigator.userAgent,
+
+	// For matching the engine and version of the browser
+	browserMatch,
+	
+	// Has the ready events already been bound?
+	readyBound = false,
+	
+	// The functions to execute on DOM ready
+	readyList = [],
+
+	// The ready event handler
+	DOMContentLoaded,
+
+	// Save a reference to some core methods
+	toString = Object.prototype.toString,
+	hasOwn = Object.prototype.hasOwnProperty,
+	push = Array.prototype.push,
+	slice = Array.prototype.slice,
+	trim = String.prototype.trim,
+	indexOf = Array.prototype.indexOf,
+	
+	// [[Class]] -> type pairs
+	class2type = {};
+
+jQuery.fn = jQuery.prototype = {
+	init: function( selector, context ) {
+		var match, elem, ret, doc;
+
+		// Handle $(""), $(null), or $(undefined)
+		if ( !selector ) {
+			return this;
+		}
+
+		// Handle $(DOMElement)
+		if ( selector.nodeType ) {
+			this.context = this[0] = selector;
+			this.length = 1;
+			return this;
+		}
+		
+		// The body element only exists once, optimize finding it
+		if ( selector === "body" && !context && document.body ) {
+			this.context = document;
+			this[0] = document.body;
+			this.selector = "body";
+			this.length = 1;
+			return this;
+		}
+
+		// Handle HTML strings
+		if ( typeof selector === "string" ) {
+			// Are we dealing with HTML string or an ID?
+			match = quickExpr.exec( selector );
+
+			// Verify a match, and that no context was specified for #id
+			if ( match && (match[1] || !context) ) {
+
+				// HANDLE: $(html) -> $(array)
+				if ( match[1] ) {
+					doc = (context ? context.ownerDocument || context : document);
+
+					// If a single string is passed in and it's a single tag
+					// just do a createElement and skip the rest
+					ret = rsingleTag.exec( selector );
+
+					if ( ret ) {
+						if ( jQuery.isPlainObject( context ) ) {
+							selector = [ document.createElement( ret[1] ) ];
+							jQuery.fn.attr.call( selector, context, true );
+
+						} else {
+							selector = [ doc.createElement( ret[1] ) ];
+						}
+
+					} else {
+						ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
+						selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
+					}
+					
+					return jQuery.merge( this, selector );
+					
+				// HANDLE: $("#id")
+				} else {
+					elem = document.getElementById( match[2] );
+
+					// Check parentNode to catch when Blackberry 4.6 returns
+					// nodes that are no longer in the document #6963
+					if ( elem && elem.parentNode ) {
+						// Handle the case where IE and Opera return items
+						// by name instead of ID
+						if ( elem.id !== match[2] ) {
+							return rootjQuery.find( selector );
+						}
+
+						// Otherwise, we inject the element directly into the jQuery object
+						this.length = 1;
+						this[0] = elem;
+					}
+
+					this.context = document;
+					this.selector = selector;
+					return this;
+				}
+
+			// HANDLE: $("TAG")
+			} else if ( !context && !rnonword.test( selector ) ) {
+				this.selector = selector;
+				this.context = document;
+				selector = document.getElementsByTagName( selector );
+				return jQuery.merge( this, selector );
+
+			// HANDLE: $(expr, $(...))
+			} else if ( !context || context.jquery ) {
+				return (context || rootjQuery).find( selector );
+
+			// HANDLE: $(expr, context)
+			// (which is just equivalent to: $(context).find(expr)
+			} else {
+				return jQuery( context ).find( selector );
+			}
+
+		// HANDLE: $(function)
+		// Shortcut for document ready
+		} else if ( jQuery.isFunction( selector ) ) {
+			return rootjQuery.ready( selector );
+		}
+
+		if (selector.selector !== undefined) {
+			this.selector = selector.selector;
+			this.context = selector.context;
+		}
+
+		return jQuery.makeArray( selector, this );
+	},
+
+	// Start with an empty selector
+	selector: "",
+
+	// The current version of jQuery being used
+	jquery: "1.4.4",
+
+	// The default length of a jQuery object is 0
+	length: 0,
+
+	// The number of elements contained in the matched element set
+	size: function() {
+		return this.length;
+	},
+
+	toArray: function() {
+		return slice.call( this, 0 );
+	},
+
+	// Get the Nth element in the matched element set OR
+	// Get the whole matched element set as a clean array
+	get: function( num ) {
+		return num == null ?
+
+			// Return a 'clean' array
+			this.toArray() :
+
+			// Return just the object
+			( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
+	},
+
+	// Take an array of elements and push it onto the stack
+	// (returning the new matched element set)
+	pushStack: function( elems, name, selector ) {
+		// Build a new jQuery matched element set
+		var ret = jQuery();
+
+		if ( jQuery.isArray( elems ) ) {
+			push.apply( ret, elems );
+		
+		} else {
+			jQuery.merge( ret, elems );
+		}
+
+		// Add the old object onto the stack (as a reference)
+		ret.prevObject = this;
+
+		ret.context = this.context;
+
+		if ( name === "find" ) {
+			ret.selector = this.selector + (this.selector ? " " : "") + selector;
+		} else if ( name ) {
+			ret.selector = this.selector + "." + name + "(" + selector + ")";
+		}
+
+		// Return the newly-formed element set
+		return ret;
+	},
+
+	// Execute a callback for every element in the matched set.
+	// (You can seed the arguments with an array of args, but this is
+	// only used internally.)
+	each: function( callback, args ) {
+		return jQuery.each( this, callback, args );
+	},
+	
+	ready: function( fn ) {
+		// Attach the listeners
+		jQuery.bindReady();
+
+		// If the DOM is already ready
+		if ( jQuery.isReady ) {
+			// Execute the function immediately
+			fn.call( document, jQuery );
+
+		// Otherwise, remember the function for later
+		} else if ( readyList ) {
+			// Add the function to the wait list
+			readyList.push( fn );
+		}
+
+		return this;
+	},
+	
+	eq: function( i ) {
+		return i === -1 ?
+			this.slice( i ) :
+			this.slice( i, +i + 1 );
+	},
+
+	first: function() {
+		return this.eq( 0 );
+	},
+
+	last: function() {
+		return this.eq( -1 );
+	},
+
+	slice: function() {
+		return this.pushStack( slice.apply( this, arguments ),
+			"slice", slice.call(arguments).join(",") );
+	},
+
+	map: function( callback ) {
+		return this.pushStack( jQuery.map(this, function( elem, i ) {
+			return callback.call( elem, i, elem );
+		}));
+	},
+	
+	end: function() {
+		return this.prevObject || jQuery(null);
+	},
+
+	// For internal use only.
+	// Behaves like an Array's method, not like a jQuery method.
+	push: push,
+	sort: [].sort,
+	splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+	 var options, name, src, copy, copyIsArray, clone,
+		target = arguments[0] || {},
+		i = 1,
+		length = arguments.length,
+		deep = false;
+
+	// Handle a deep copy situation
+	if ( typeof target === "boolean" ) {
+		deep = target;
+		target = arguments[1] || {};
+		// skip the boolean and the target
+		i = 2;
+	}
+
+	// Handle case when target is a string or something (possible in deep copy)
+	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+		target = {};
+	}
+
+	// extend jQuery itself if only one argument is passed
+	if ( length === i ) {
+		target = this;
+		--i;
+	}
+
+	for ( ; i < length; i++ ) {
+		// Only deal with non-null/undefined values
+		if ( (options = arguments[ i ]) != null ) {
+			// Extend the base object
+			for ( name in options ) {
+				src = target[ name ];
+				copy = options[ name ];
+
+				// Prevent never-ending loop
+				if ( target === copy ) {
+					continue;
+				}
+
+				// Recurse if we're merging plain objects or arrays
+				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+					if ( copyIsArray ) {
+						copyIsArray = false;
+						clone = src && jQuery.isArray(src) ? src : [];
+
+					} else {
+						clone = src && jQuery.isPlainObject(src) ? src : {};
+					}
+
+					// Never move original objects, clone them
+					target[ name ] = jQuery.extend( deep, clone, copy );
+
+				// Don't bring in undefined values
+				} else if ( copy !== undefined ) {
+					target[ name ] = copy;
+				}
+			}
+		}
+	}
+
+	// Return the modified object
+	return target;
+};
+
+jQuery.extend({
+	noConflict: function( deep ) {
+		window.$ = _$;
+
+		if ( deep ) {
+			window.jQuery = _jQuery;
+		}
+
+		return jQuery;
+	},
+	
+	// Is the DOM ready to be used? Set to true once it occurs.
+	isReady: false,
+
+	// A counter to track how many items to wait for before
+	// the ready event fires. See #6781
+	readyWait: 1,
+	
+	// Handle when the DOM is ready
+	ready: function( wait ) {
+		// A third-party is pushing the ready event forwards
+		if ( wait === true ) {
+			jQuery.readyWait--;
+		}
+
+		// Make sure that the DOM is not already loaded
+		if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) {
+			// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+			if ( !document.body ) {
+				return setTimeout( jQuery.ready, 1 );
+			}
+
+			// Remember that the DOM is ready
+			jQuery.isReady = true;
+
+			// If a normal DOM Ready event fired, decrement, and wait if need be
+			if ( wait !== true && --jQuery.readyWait > 0 ) {
+				return;
+			}
+
+			// If there are functions bound, to execute
+			if ( readyList ) {
+				// Execute all of them
+				var fn,
+					i = 0,
+					ready = readyList;
+
+				// Reset the list of functions
+				readyList = null;
+
+				while ( (fn = ready[ i++ ]) ) {
+					fn.call( document, jQuery );
+				}
+
+				// Trigger any bound ready events
+				if ( jQuery.fn.trigger ) {
+					jQuery( document ).trigger( "ready" ).unbind( "ready" );
+				}
+			}
+		}
+	},
+	
+	bindReady: function() {
+		if ( readyBound ) {
+			return;
+		}
+
+		readyBound = true;
+
+		// Catch cases where $(document).ready() is called after the
+		// browser event has already occurred.
+		if ( document.readyState === "complete" ) {
+			// Handle it asynchronously to allow scripts the opportunity to delay ready
+			return setTimeout( jQuery.ready, 1 );
+		}
+
+		// Mozilla, Opera and webkit nightlies currently support this event
+		if ( document.addEventListener ) {
+			// Use the handy event callback
+			document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+			
+			// A fallback to window.onload, that will always work
+			window.addEventListener( "load", jQuery.ready, false );
+
+		// If IE event model is used
+		} else if ( document.attachEvent ) {
+			// ensure firing before onload,
+			// maybe late but safe also for iframes
+			document.attachEvent("onreadystatechange", DOMContentLoaded);
+			
+			// A fallback to window.onload, that will always work
+			window.attachEvent( "onload", jQuery.ready );
+
+			// If IE and not a frame
+			// continually check to see if the document is ready
+			var toplevel = false;
+
+			try {
+				toplevel = window.frameElement == null;
+			} catch(e) {}
+
+			if ( document.documentElement.doScroll && toplevel ) {
+				doScrollCheck();
+			}
+		}
+	},
+
+	// See test/unit/core.js for details concerning isFunction.
+	// Since version 1.3, DOM methods and functions like alert
+	// aren't supported. They return false on IE (#2968).
+	isFunction: function( obj ) {
+		return jQuery.type(obj) === "function";
+	},
+
+	isArray: Array.isArray || function( obj ) {
+		return jQuery.type(obj) === "array";
+	},
+
+	// A crude way of determining if an object is a window
+	isWindow: function( obj ) {
+		return obj && typeof obj === "object" && "setInterval" in obj;
+	},
+
+	isNaN: function( obj ) {
+		return obj == null || !rdigit.test( obj ) || isNaN( obj );
+	},
+
+	type: function( obj ) {
+		return obj == null ?
+			String( obj ) :
+			class2type[ toString.call(obj) ] || "object";
+	},
+
+	isPlainObject: function( obj ) {
+		// Must be an Object.
+		// Because of IE, we also have to check the presence of the constructor property.
+		// Make sure that DOM nodes and window objects don't pass through, as well
+		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+			return false;
+		}
+		
+		// Not own constructor property must be Object
+		if ( obj.constructor &&
+			!hasOwn.call(obj, "constructor") &&
+			!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+			return false;
+		}
+		
+		// Own properties are enumerated firstly, so to speed up,
+		// if last one is own, then all properties are own.
+	
+		var key;
+		for ( key in obj ) {}
+		
+		return key === undefined || hasOwn.call( obj, key );
+	},
+
+	isEmptyObject: function( obj ) {
+		for ( var name in obj ) {
+			return false;
+		}
+		return true;
+	},
+	
+	error: function( msg ) {
+		throw msg;
+	},
+	
+	parseJSON: function( data ) {
+		if ( typeof data !== "string" || !data ) {
+			return null;
+		}
+
+		// Make sure leading/trailing whitespace is removed (IE can't handle it)
+		data = jQuery.trim( data );
+		
+		// Make sure the incoming data is actual JSON
+		// Logic borrowed from http://json.org/json2.js
+		if ( rvalidchars.test(data.replace(rvalidescape, "@")
+			.replace(rvalidtokens, "]")
+			.replace(rvalidbraces, "")) ) {
+
+			// Try to use the native JSON parser first
+			return window.JSON && window.JSON.parse ?
+				window.JSON.parse( data ) :
+				(new Function("return " + data))();
+
+		} else {
+			jQuery.error( "Invalid JSON: " + data );
+		}
+	},
+
+	noop: function() {},
+
+	// Evalulates a script in a global context
+	globalEval: function( data ) {
+		if ( data && rnotwhite.test(data) ) {
+			// Inspired by code by Andrea Giammarchi
+			// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+			var head = document.getElementsByTagName("head")[0] || document.documentElement,
+				script = document.createElement("script");
+
+			script.type = "text/javascript";
+
+			if ( jQuery.support.scriptEval ) {
+				script.appendChild( document.createTextNode( data ) );
+			} else {
+				script.text = data;
+			}
+
+			// Use insertBefore instead of appendChild to circumvent an IE6 bug.
+			// This arises when a base node is used (#2709).
+			head.insertBefore( script, head.firstChild );
+			head.removeChild( script );
+		}
+	},
+
+	nodeName: function( elem, name ) {
+		return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+	},
+
+	// args is for internal usage only
+	each: function( object, callback, args ) {
+		var name, i = 0,
+			length = object.length,
+			isObj = length === undefined || jQuery.isFunction(object);
+
+		if ( args ) {
+			if ( isObj ) {
+				for ( name in object ) {
+					if ( callback.apply( object[ name ], args ) === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( ; i < length; ) {
+					if ( callback.apply( object[ i++ ], args ) === false ) {
+						break;
+					}
+				}
+			}
+
+		// A special, fast, case for the most common use of each
+		} else {
+			if ( isObj ) {
+				for ( name in object ) {
+					if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( var value = object[0];
+					i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
+			}
+		}
+
+		return object;
+	},
+
+	// Use native String.trim function wherever possible
+	trim: trim ?
+		function( text ) {
+			return text == null ?
+				"" :
+				trim.call( text );
+		} :
+
+		// Otherwise use our own trimming functionality
+		function( text ) {
+			return text == null ?
+				"" :
+				text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
+		},
+
+	// results is for internal usage only
+	makeArray: function( array, results ) {
+		var ret = results || [];
+
+		if ( array != null ) {
+			// The window, strings (and functions) also have 'length'
+			// The extra typeof function check is to prevent crashes
+			// in Safari 2 (See: #3039)
+			// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
+			var type = jQuery.type(array);
+
+			if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
+				push.call( ret, array );
+			} else {
+				jQuery.merge( ret, array );
+			}
+		}
+
+		return ret;
+	},
+
+	inArray: function( elem, array ) {
+		if ( array.indexOf ) {
+			return array.indexOf( elem );
+		}
+
+		for ( var i = 0, length = array.length; i < length; i++ ) {
+			if ( array[ i ] === elem ) {
+				return i;
+			}
+		}
+
+		return -1;
+	},
+
+	merge: function( first, second ) {
+		var i = first.length,
+			j = 0;
+
+		if ( typeof second.length === "number" ) {
+			for ( var l = second.length; j < l; j++ ) {
+				first[ i++ ] = second[ j ];
+			}
+		
+		} else {
+			while ( second[j] !== undefined ) {
+				first[ i++ ] = second[ j++ ];
+			}
+		}
+
+		first.length = i;
+
+		return first;
+	},
+
+	grep: function( elems, callback, inv ) {
+		var ret = [], retVal;
+		inv = !!inv;
+
+		// Go through the array, only saving the items
+		// that pass the validator function
+		for ( var i = 0, length = elems.length; i < length; i++ ) {
+			retVal = !!callback( elems[ i ], i );
+			if ( inv !== retVal ) {
+				ret.push( elems[ i ] );
+			}
+		}
+
+		return ret;
+	},
+
+	// arg is for internal usage only
+	map: function( elems, callback, arg ) {
+		var ret = [], value;
+
+		// Go through the array, translating each of the items to their
+		// new value (or values).
+		for ( var i = 0, length = elems.length; i < length; i++ ) {
+			value = callback( elems[ i ], i, arg );
+
+			if ( value != null ) {
+				ret[ ret.length ] = value;
+			}
+		}
+
+		return ret.concat.apply( [], ret );
+	},
+
+	// A global GUID counter for objects
+	guid: 1,
+
+	proxy: function( fn, proxy, thisObject ) {
+		if ( arguments.length === 2 ) {
+			if ( typeof proxy === "string" ) {
+				thisObject = fn;
+				fn = thisObject[ proxy ];
+				proxy = undefined;
+
+			} else if ( proxy && !jQuery.isFunction( proxy ) ) {
+				thisObject = proxy;
+				proxy = undefined;
+			}
+		}
+
+		if ( !proxy && fn ) {
+			proxy = function() {
+				return fn.apply( thisObject || this, arguments );
+			};
+		}
+
+		// Set the guid of unique handler to the same of original handler, so it can be removed
+		if ( fn ) {
+			proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+		}
+
+		// So proxy can be declared as an argument
+		return proxy;
+	},
+
+	// Mutifunctional method to get and set values to a collection
+	// The value/s can be optionally by executed if its a function
+	access: function( elems, key, value, exec, fn, pass ) {
+		var length = elems.length;
+	
+		// Setting many attributes
+		if ( typeof key === "object" ) {
+			for ( var k in key ) {
+				jQuery.access( elems, k, key[k], exec, fn, value );
+			}
+			return elems;
+		}
+	
+		// Setting one attribute
+		if ( value !== undefined ) {
+			// Optionally, function values get executed if exec is true
+			exec = !pass && exec && jQuery.isFunction(value);
+		
+			for ( var i = 0; i < length; i++ ) {
+				fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+			}
+		
+			return elems;
+		}
+	
+		// Getting an attribute
+		return length ? fn( elems[0], key ) : undefined;
+	},
+
+	now: function() {
+		return (new Date()).getTime();
+	},
+
+	// Use of jQuery.browser is frowned upon.
+	// More details: http://docs.jquery.com/Utilities/jQuery.browser
+	uaMatch: function( ua ) {
+		ua = ua.toLowerCase();
+
+		var match = rwebkit.exec( ua ) ||
+			ropera.exec( ua ) ||
+			rmsie.exec( ua ) ||
+			ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
+			[];
+
+		return { browser: match[1] || "", version: match[2] || "0" };
+	},
+
+	browser: {}
+});
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
+	class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+	jQuery.browser[ browserMatch.browser ] = true;
+	jQuery.browser.version = browserMatch.version;
+}
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+	jQuery.browser.safari = true;
+}
+
+if ( indexOf ) {
+	jQuery.inArray = function( elem, array ) {
+		return indexOf.call( array, elem );
+	};
+}
+
+// Verify that \s matches non-breaking spaces
+// (IE fails on this test)
+if ( !rwhite.test( "\xA0" ) ) {
+	trimLeft = /^[\s\xA0]+/;
+	trimRight = /[\s\xA0]+$/;
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+	DOMContentLoaded = function() {
+		document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+		jQuery.ready();
+	};
+
+} else if ( document.attachEvent ) {
+	DOMContentLoaded = function() {
+		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+		if ( document.readyState === "complete" ) {
+			document.detachEvent( "onreadystatechange", DOMContentLoaded );
+			jQuery.ready();
+		}
+	};
+}
+
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+	if ( jQuery.isReady ) {
+		return;
+	}
+
+	try {
+		// If IE is used, use the trick by Diego Perini
+		// http://javascript.nwbox.com/IEContentLoaded/
+		document.documentElement.doScroll("left");
+	} catch(e) {
+		setTimeout( doScrollCheck, 1 );
+		return;
+	}
+
+	// and execute any waiting functions
+	jQuery.ready();
+}
+
+// Expose jQuery to the global object
+return (window.jQuery = window.$ = jQuery);
+
+})();
+
+
+(function() {
+
+	jQuery.support = {};
+
+	var root = document.documentElement,
+		script = document.createElement("script"),
+		div = document.createElement("div"),
+		id = "script" + jQuery.now();
+
+	div.style.display = "none";
+	div.innerHTML = "   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
+	var all = div.getElementsByTagName("*"),
+		a = div.getElementsByTagName("a")[0],
+		select = document.createElement("select"),
+		opt = select.appendChild( document.createElement("option") );
+
+	// Can't get basic test support
+	if ( !all || !all.length || !a ) {
+		return;
+	}
+
+	jQuery.support = {
+		// IE strips leading whitespace when .innerHTML is used
+		leadingWhitespace: div.firstChild.nodeType === 3,
+
+		// Make sure that tbody elements aren't automatically inserted
+		// IE will insert them into empty tables
+		tbody: !div.getElementsByTagName("tbody").length,
+
+		// Make sure that link elements get serialized correctly by innerHTML
+		// This requires a wrapper element in IE
+		htmlSerialize: !!div.getElementsByTagName("link").length,
+
+		// Get the style information from getAttribute
+		// (IE uses .cssText insted)
+		style: /red/.test( a.getAttribute("style") ),
+
+		// Make sure that URLs aren't manipulated
+		// (IE normalizes it by default)
+		hrefNormalized: a.getAttribute("href") === "/a",
+
+		// Make sure that element opacity exists
+		// (IE uses filter instead)
+		// Use a regex to work around a WebKit issue. See #5145
+		opacity: /^0.55$/.test( a.style.opacity ),
+
+		// Verify style float existence
+		// (IE uses styleFloat instead of cssFloat)
+		cssFloat: !!a.style.cssFloat,
+
+		// Make sure that if no value is specified for a checkbox
+		// that it defaults to "on".
+		// (WebKit defaults to "" instead)
+		checkOn: div.getElementsByTagName("input")[0].value === "on",
+
+		// Make sure that a selected-by-default option has a working selected property.
+		// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+		optSelected: opt.selected,
+
+		// Will be defined later
+		deleteExpando: true,
+		optDisabled: false,
+		checkClone: false,
+		scriptEval: false,
+		noCloneEvent: true,
+		boxModel: null,
+		inlineBlockNeedsLayout: false,
+		shrinkWrapBlocks: false,
+		reliableHiddenOffsets: true
+	};
+
+	// Make sure that the options inside disabled selects aren't marked as disabled
+	// (WebKit marks them as diabled)
+	select.disabled = true;
+	jQuery.support.optDisabled = !opt.disabled;
+
+	script.type = "text/javascript";
+	try {
+		script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
+	} catch(e) {}
+
+	root.insertBefore( script, root.firstChild );
+
+	// Make sure that the execution of code works by injecting a script
+	// tag with appendChild/createTextNode
+	// (IE doesn't support this, fails, and uses .text instead)
+	if ( window[ id ] ) {
+		jQuery.support.scriptEval = true;
+		delete window[ id ];
+	}
+
+	// Test to see if it's possible to delete an expando from an element
+	// Fails in Internet Explorer
+	try {
+		delete script.test;
+
+	} catch(e) {
+		jQuery.support.deleteExpando = false;
+	}
+
+	root.removeChild( script );
+
+	if ( div.attachEvent && div.fireEvent ) {
+		div.attachEvent("onclick", function click() {
+			// Cloning a node shouldn't copy over any
+			// bound event handlers (IE does this)
+			jQuery.support.noCloneEvent = false;
+			div.detachEvent("onclick", click);
+		});
+		div.cloneNode(true).fireEvent("onclick");
+	}
+
+	div = document.createElement("div");
+	div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
+
+	var fragment = document.createDocumentFragment();
+	fragment.appendChild( div.firstChild );
+
+	// WebKit doesn't clone checked state correctly in fragments
+	jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
+
+	// Figure out if the W3C box model works as expected
+	// document.body must exist before we can do this
+	jQuery(function() {
+		var div = document.createElement("div");
+		div.style.width = div.style.paddingLeft = "1px";
+
+		document.body.appendChild( div );
+		jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
+
+		if ( "zoom" in div.style ) {
+			// Check if natively block-level elements act like inline-block
+			// elements when setting their display to 'inline' and giving
+			// them layout
+			// (IE < 8 does this)
+			div.style.display = "inline";
+			div.style.zoom = 1;
+			jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;
+
+			// Check if elements with layout shrink-wrap their children
+			// (IE 6 does this)
+			div.style.display = "";
+			div.innerHTML = "<div style='width:4px;'></div>";
+			jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
+		}
+
+		div.innerHTML = "<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";
+		var tds = div.getElementsByTagName("td");
+
+		// Check if table cells still have offsetWidth/Height when they are set
+		// to display:none and there are still other visible table cells in a
+		// table row; if so, offsetWidth/Height are not reliable for use when
+		// determining if an element has been hidden directly using
+		// display:none (it is still safe to use offsets if a parent element is
+		// hidden; don safety goggles and see bug #4512 for more information).
+		// (only IE 8 fails this test)
+		jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;
+
+		tds[0].style.display = "";
+		tds[1].style.display = "none";
+
+		// Check if empty table cells still have offsetWidth/Height
+		// (IE < 8 fail this test)
+		jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
+		div.innerHTML = "";
+
+		document.body.removeChild( div ).style.display = "none";
+		div = tds = null;
+	});
+
+	// Technique from Juriy Zaytsev
+	// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+	var eventSupported = function( eventName ) {
+		var el = document.createElement("div");
+		eventName = "on" + eventName;
+
+		var isSupported = (eventName in el);
+		if ( !isSupported ) {
+			el.setAttribute(eventName, "return;");
+			isSupported = typeof el[eventName] === "function";
+		}
+		el = null;
+
+		return isSupported;
+	};
+
+	jQuery.support.submitBubbles = eventSupported("submit");
+	jQuery.support.changeBubbles = eventSupported("change");
+
+	// release memory in IE
+	root = script = div = all = a = null;
+})();
+
+
+
+var windowData = {},
+	rbrace = /^(?:\{.*\}|\[.*\])$/;
+
+jQuery.extend({
+	cache: {},
+
+	// Please use with caution
+	uuid: 0,
+
+	// Unique for each copy of jQuery on the page	
+	expando: "jQuery" + jQuery.now(),
+
+	// The following elements throw uncatchable exceptions if you
+	// attempt to add expando properties to them.
+	noData: {
+		"embed": true,
+		// Ban all objects except for Flash (which handle expandos)
+		"object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
+		"applet": true
+	},
+
+	data: function( elem, name, data ) {
+		if ( !jQuery.acceptData( elem ) ) {
+			return;
+		}
+
+		elem = elem == window ?
+			windowData :
+			elem;
+
+		var isNode = elem.nodeType,
+			id = isNode ? elem[ jQuery.expando ] : null,
+			cache = jQuery.cache, thisCache;
+
+		if ( isNode && !id && typeof name === "string" && data === undefined ) {
+			return;
+		}
+
+		// Get the data from the object directly
+		if ( !isNode ) {
+			cache = elem;
+
+		// Compute a unique ID for the element
+		} else if ( !id ) {
+			elem[ jQuery.expando ] = id = ++jQuery.uuid;
+		}
+
+		// Avoid generating a new cache unless none exists and we
+		// want to manipulate it.
+		if ( typeof name === "object" ) {
+			if ( isNode ) {
+				cache[ id ] = jQuery.extend(cache[ id ], name);
+
+			} else {
+				jQuery.extend( cache, name );
+			}
+
+		} else if ( isNode && !cache[ id ] ) {
+			cache[ id ] = {};
+		}
+
+		thisCache = isNode ? cache[ id ] : cache;
+
+		// Prevent overriding the named cache with undefined values
+		if ( data !== undefined ) {
+			thisCache[ name ] = data;
+		}
+
+		return typeof name === "string" ? thisCache[ name ] : thisCache;
+	},
+
+	removeData: function( elem, name ) {
+		if ( !jQuery.acceptData( elem ) ) {
+			return;
+		}
+
+		elem = elem == window ?
+			windowData :
+			elem;
+
+		var isNode = elem.nodeType,
+			id = isNode ? elem[ jQuery.expando ] : elem,
+			cache = jQuery.cache,
+			thisCache = isNode ? cache[ id ] : id;
+
+		// If we want to remove a specific section of the element's data
+		if ( name ) {
+			if ( thisCache ) {
+				// Remove the section of cache data
+				delete thisCache[ name ];
+
+				// If we've removed all the data, remove the element's cache
+				if ( isNode && jQuery.isEmptyObject(thisCache) ) {
+					jQuery.removeData( elem );
+				}
+			}
+
+		// Otherwise, we want to remove all of the element's data
+		} else {
+			if ( isNode && jQuery.support.deleteExpando ) {
+				delete elem[ jQuery.expando ];
+
+			} else if ( elem.removeAttribute ) {
+				elem.removeAttribute( jQuery.expando );
+
+			// Completely remove the data cache
+			} else if ( isNode ) {
+				delete cache[ id ];
+
+			// Remove all fields from the object
+			} else {
+				for ( var n in elem ) {
+					delete elem[ n ];
+				}
+			}
+		}
+	},
+
+	// A method for determining if a DOM node can handle the data expando
+	acceptData: function( elem ) {
+		if ( elem.nodeName ) {
+			var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
+
+			if ( match ) {
+				return !(match === true || elem.getAttribute("classid") !== match);
+			}
+		}
+
+		return true;
+	}
+});
+
+jQuery.fn.extend({
+	data: function( key, value ) {
+		var data = null;
+
+		if ( typeof key === "undefined" ) {
+			if ( this.length ) {
+				var attr = this[0].attributes, name;
+				data = jQuery.data( this[0] );
+
+				for ( var i = 0, l = attr.length; i < l; i++ ) {
+					name = attr[i].name;
+
+					if ( name.indexOf( "data-" ) === 0 ) {
+						name = name.substr( 5 );
+						dataAttr( this[0], name, data[ name ] );
+					}
+				}
+			}
+
+			return data;
+
+		} else if ( typeof key === "object" ) {
+			return this.each(function() {
+				jQuery.data( this, key );
+			});
+		}
+
+		var parts = key.split(".");
+		parts[1] = parts[1] ? "." + parts[1] : "";
+
+		if ( value === undefined ) {
+			data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+			// Try to fetch any internally stored data first
+			if ( data === undefined && this.length ) {
+				data = jQuery.data( this[0], key );
+				data = dataAttr( this[0], key, data );
+			}
+
+			return data === undefined && parts[1] ?
+				this.data( parts[0] ) :
+				data;
+
+		} else {
+			return this.each(function() {
+				var $this = jQuery( this ),
+					args = [ parts[0], value ];
+
+				$this.triggerHandler( "setData" + parts[1] + "!", args );
+				jQuery.data( this, key, value );
+				$this.triggerHandler( "changeData" + parts[1] + "!", args );
+			});
+		}
+	},
+
+	removeData: function( key ) {
+		return this.each(function() {
+			jQuery.removeData( this, key );
+		});
+	}
+});
+
+function dataAttr( elem, key, data ) {
+	// If nothing was found internally, try to fetch any
+	// data from the HTML5 data-* attribute
+	if ( data === undefined && elem.nodeType === 1 ) {
+		data = elem.getAttribute( "data-" + key );
+
+		if ( typeof data === "string" ) {
+			try {
+				data = data === "true" ? true :
+				data === "false" ? false :
+				data === "null" ? null :
+				!jQuery.isNaN( data ) ? parseFloat( data ) :
+					rbrace.test( data ) ? jQuery.parseJSON( data ) :
+					data;
+			} catch( e ) {}
+
+			// Make sure we set the data so it isn't changed later
+			jQuery.data( elem, key, data );
+
+		} else {
+			data = undefined;
+		}
+	}
+
+	return data;
+}
+
+
+
+
+jQuery.extend({
+	queue: function( elem, type, data ) {
+		if ( !elem ) {
+			return;
+		}
+
+		type = (type || "fx") + "queue";
+		var q = jQuery.data( elem, type );
+
+		// Speed up dequeue by getting out quickly if this is just a lookup
+		if ( !data ) {
+			return q || [];
+		}
+
+		if ( !q || jQuery.isArray(data) ) {
+			q = jQuery.data( elem, type, jQuery.makeArray(data) );
+
+		} else {
+			q.push( data );
+		}
+
+		return q;
+	},
+
+	dequeue: function( elem, type ) {
+		type = type || "fx";
+
+		var queue = jQuery.queue( elem, type ),
+			fn = queue.shift();
+
+		// If the fx queue is dequeued, always remove the progress sentinel
+		if ( fn === "inprogress" ) {
+			fn = queue.shift();
+		}
+
+		if ( fn ) {
+			// Add a progress sentinel to prevent the fx queue from being
+			// automatically dequeued
+			if ( type === "fx" ) {
+				queue.unshift("inprogress");
+			}
+
+			fn.call(elem, function() {
+				jQuery.dequeue(elem, type);
+			});
+		}
+	}
+});
+
+jQuery.fn.extend({
+	queue: function( type, data ) {
+		if ( typeof type !== "string" ) {
+			data = type;
+			type = "fx";
+		}
+
+		if ( data === undefined ) {
+			return jQuery.queue( this[0], type );
+		}
+		return this.each(function( i ) {
+			var queue = jQuery.queue( this, type, data );
+
+			if ( type === "fx" && queue[0] !== "inprogress" ) {
+				jQuery.dequeue( this, type );
+			}
+		});
+	},
+	dequeue: function( type ) {
+		return this.each(function() {
+			jQuery.dequeue( this, type );
+		});
+	},
+
+	// Based off of the plugin by Clint Helfers, with permission.
+	// http://blindsignals.com/index.php/2009/07/jquery-delay/
+	delay: function( time, type ) {
+		time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+		type = type || "fx";
+
+		return this.queue( type, function() {
+			var elem = this;
+			setTimeout(function() {
+				jQuery.dequeue( elem, type );
+			}, time );
+		});
+	},
+
+	clearQueue: function( type ) {
+		return this.queue( type || "fx", [] );
+	}
+});
+
+
+
+
+var rclass = /[\n\t]/g,
+	rspaces = /\s+/,
+	rreturn = /\r/g,
+	rspecialurl = /^(?:href|src|style)$/,
+	rtype = /^(?:button|input)$/i,
+	rfocusable = /^(?:button|input|object|select|textarea)$/i,
+	rclickable = /^a(?:rea)?$/i,
+	rradiocheck = /^(?:radio|checkbox)$/i;
+
+jQuery.props = {
+	"for": "htmlFor",
+	"class": "className",
+	readonly: "readOnly",
+	maxlength: "maxLength",
+	cellspacing: "cellSpacing",
+	rowspan: "rowSpan",
+	colspan: "colSpan",
+	tabindex: "tabIndex",
+	usemap: "useMap",
+	frameborder: "frameBorder"
+};
+
+jQuery.fn.extend({
+	attr: function( name, value ) {
+		return jQuery.access( this, name, value, true, jQuery.attr );
+	},
+
+	removeAttr: function( name, fn ) {
+		return this.each(function(){
+			jQuery.attr( this, name, "" );
+			if ( this.nodeType === 1 ) {
+				this.removeAttribute( name );
+			}
+		});
+	},
+
+	addClass: function( value ) {
+		if ( jQuery.isFunction(value) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.addClass( value.call(this, i, self.attr("class")) );
+			});
+		}
+
+		if ( value && typeof value === "string" ) {
+			var classNames = (value || "").split( rspaces );
+
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				var elem = this[i];
+
+				if ( elem.nodeType === 1 ) {
+					if ( !elem.className ) {
+						elem.className = value;
+
+					} else {
+						var className = " " + elem.className + " ",
+							setClass = elem.className;
+
+						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+							if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
+								setClass += " " + classNames[c];
+							}
+						}
+						elem.className = jQuery.trim( setClass );
+					}
+				}
+			}
+		}
+
+		return this;
+	},
+
+	removeClass: function( value ) {
+		if ( jQuery.isFunction(value) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.removeClass( value.call(this, i, self.attr("class")) );
+			});
+		}
+
+		if ( (value && typeof value === "string") || value === undefined ) {
+			var classNames = (value || "").split( rspaces );
+
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				var elem = this[i];
+
+				if ( elem.nodeType === 1 && elem.className ) {
+					if ( value ) {
+						var className = (" " + elem.className + " ").replace(rclass, " ");
+						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+							className = className.replace(" " + classNames[c] + " ", " ");
+						}
+						elem.className = jQuery.trim( className );
+
+					} else {
+						elem.className = "";
+					}
+				}
+			}
+		}
+
+		return this;
+	},
+
+	toggleClass: function( value, stateVal ) {
+		var type = typeof value,
+			isBool = typeof stateVal === "boolean";
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
+			});
+		}
+
+		return this.each(function() {
+			if ( type === "string" ) {
+				// toggle individual class names
+				var className,
+					i = 0,
+					self = jQuery( this ),
+					state = stateVal,
+					classNames = value.split( rspaces );
+
+				while ( (className = classNames[ i++ ]) ) {
+					// check each className given, space seperated list
+					state = isBool ? state : !self.hasClass( className );
+					self[ state ? "addClass" : "removeClass" ]( className );
+				}
+
+			} else if ( type === "undefined" || type === "boolean" ) {
+				if ( this.className ) {
+					// store className if set
+					jQuery.data( this, "__className__", this.className );
+				}
+
+				// toggle whole className
+				this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
+			}
+		});
+	},
+
+	hasClass: function( selector ) {
+		var className = " " + selector + " ";
+		for ( var i = 0, l = this.length; i < l; i++ ) {
+			if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+				return true;
+			}
+		}
+
+		return false;
+	},
+
+	val: function( value ) {
+		if ( !arguments.length ) {
+			var elem = this[0];
+
+			if ( elem ) {
+				if ( jQuery.nodeName( elem, "option" ) ) {
+					// attributes.value is undefined in Blackberry 4.7 but
+					// uses .value. See #6932
+					var val = elem.attributes.value;
+					return !val || val.specified ? elem.value : elem.text;
+				}
+
+				// We need to handle select boxes special
+				if ( jQuery.nodeName( elem, "select" ) ) {
+					var index = elem.selectedIndex,
+						values = [],
+						options = elem.options,
+						one = elem.type === "select-one";
+
+					// Nothing was selected
+					if ( index < 0 ) {
+						return null;
+					}
+
+					// Loop through all the selected options
+					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+						var option = options[ i ];
+
+						// Don't return options that are disabled or in a disabled optgroup
+						if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && 
+								(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
+
+							// Get the specific value for the option
+							value = jQuery(option).val();
+
+							// We don't need an array for one selects
+							if ( one ) {
+								return value;
+							}
+
+							// Multi-Selects return an array
+							values.push( value );
+						}
+					}
+
+					return values;
+				}
+
+				// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+				if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
+					return elem.getAttribute("value") === null ? "on" : elem.value;
+				}
+				
+
+				// Everything else, we just grab the value
+				return (elem.value || "").replace(rreturn, "");
+
+			}
+
+			return undefined;
+		}
+
+		var isFunction = jQuery.isFunction(value);
+
+		return this.each(function(i) {
+			var self = jQuery(this), val = value;
+
+			if ( this.nodeType !== 1 ) {
+				return;
+			}
+
+			if ( isFunction ) {
+				val = value.call(this, i, self.val());
+			}
+
+			// Treat null/undefined as ""; convert numbers to string
+			if ( val == null ) {
+				val = "";
+			} else if ( typeof val === "number" ) {
+				val += "";
+			} else if ( jQuery.isArray(val) ) {
+				val = jQuery.map(val, function (value) {
+					return value == null ? "" : value + "";
+				});
+			}
+
+			if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
+				this.checked = jQuery.inArray( self.val(), val ) >= 0;
+
+			} else if ( jQuery.nodeName( this, "select" ) ) {
+				var values = jQuery.makeArray(val);
+
+				jQuery( "option", this ).each(function() {
+					this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+				});
+
+				if ( !values.length ) {
+					this.selectedIndex = -1;
+				}
+
+			} else {
+				this.value = val;
+			}
+		});
+	}
+});
+
+jQuery.extend({
+	attrFn: {
+		val: true,
+		css: true,
+		html: true,
+		text: true,
+		data: true,
+		width: true,
+		height: true,
+		offset: true
+	},
+		
+	attr: function( elem, name, value, pass ) {
+		// don't set attributes on text and comment nodes
+		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return undefined;
+		}
+
+		if ( pass && name in jQuery.attrFn ) {
+			return jQuery(elem)[name](value);
+		}
+
+		var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
+			// Whether we are setting (or getting)
+			set = value !== undefined;
+
+		// Try to normalize/fix the name
+		name = notxml && jQuery.props[ name ] || name;
+
+		// These attributes require special treatment
+		var special = rspecialurl.test( name );
+
+		// Safari mis-reports the default selected property of an option
+		// Accessing the parent's selectedIndex property fixes it
+		if ( name === "selected" && !jQuery.support.optSelected ) {
+			var parent = elem.parentNode;
+			if ( parent ) {
+				parent.selectedIndex;
+
+				// Make sure that it also works with optgroups, see #5701
+				if ( parent.parentNode ) {
+					parent.parentNode.selectedIndex;
+				}
+			}
+		}
+
+		// If applicable, access the attribute via the DOM 0 way
+		// 'in' checks fail in Blackberry 4.7 #6931
+		if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
+			if ( set ) {
+				// We can't allow the type property to be changed (since it causes problems in IE)
+				if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
+					jQuery.error( "type property can't be changed" );
+				}
+
+				if ( value === null ) {
+					if ( elem.nodeType === 1 ) {
+						elem.removeAttribute( name );
+					}
+
+				} else {
+					elem[ name ] = value;
+				}
+			}
+
+			// browsers index elements by id/name on forms, give priority to attributes.
+			if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
+				return elem.getAttributeNode( name ).nodeValue;
+			}
+
+			// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+			// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+			if ( name === "tabIndex" ) {
+				var attributeNode = elem.getAttributeNode( "tabIndex" );
+
+				return attributeNode && attributeNode.specified ?
+					attributeNode.value :
+					rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+						0 :
+						undefined;
+			}
+
+			return elem[ name ];
+		}
+
+		if ( !jQuery.support.style && notxml && name === "style" ) {
+			if ( set ) {
+				elem.style.cssText = "" + value;
+			}
+
+			return elem.style.cssText;
+		}
+
+		if ( set ) {
+			// convert the value to a string (all browsers do this but IE) see #1070
+			elem.setAttribute( name, "" + value );
+		}
+
+		// Ensure that missing attributes return undefined
+		// Blackberry 4.7 returns "" from getAttribute #6938
+		if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
+			return undefined;
+		}
+
+		var attr = !jQuery.support.hrefNormalized && notxml && special ?
+				// Some attributes require a special call on IE
+				elem.getAttribute( name, 2 ) :
+				elem.getAttribute( name );
+
+		// Non-existent attributes return null, we normalize to undefined
+		return attr === null ? undefined : attr;
+	}
+});
+
+
+
+
+var rnamespaces = /\.(.*)$/,
+	rformElems = /^(?:textarea|input|select)$/i,
+	rperiod = /\./g,
+	rspace = / /g,
+	rescape = /[^\w\s.|`]/g,
+	fcleanup = function( nm ) {
+		return nm.replace(rescape, "\\$&");
+	},
+	focusCounts = { focusin: 0, focusout: 0 };
+
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+	// Bind an event to an element
+	// Original by Dean Edwards
+	add: function( elem, types, handler, data ) {
+		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return;
+		}
+
+		// For whatever reason, IE has trouble passing the window object
+		// around, causing it to be cloned in the process
+		if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) {
+			elem = window;
+		}
+
+		if ( handler === false ) {
+			handler = returnFalse;
+		} else if ( !handler ) {
+			// Fixes bug #7229. Fix recommended by jdalton
+		  return;
+		}
+
+		var handleObjIn, handleObj;
+
+		if ( handler.handler ) {
+			handleObjIn = handler;
+			handler = handleObjIn.handler;
+		}
+
+		// Make sure that the function being executed has a unique ID
+		if ( !handler.guid ) {
+			handler.guid = jQuery.guid++;
+		}
+
+		// Init the element's event structure
+		var elemData = jQuery.data( elem );
+
+		// If no elemData is found then we must be trying to bind to one of the
+		// banned noData elements
+		if ( !elemData ) {
+			return;
+		}
+
+		// Use a key less likely to result in collisions for plain JS objects.
+		// Fixes bug #7150.
+		var eventKey = elem.nodeType ? "events" : "__events__",
+			events = elemData[ eventKey ],
+			eventHandle = elemData.handle;
+			
+		if ( typeof events === "function" ) {
+			// On plain objects events is a fn that holds the the data
+			// which prevents this data from being JSON serialized
+			// the function does not need to be called, it just contains the data
+			eventHandle = events.handle;
+			events = events.events;
+
+		} else if ( !events ) {
+			if ( !elem.nodeType ) {
+				// On plain objects, create a fn that acts as the holder
+				// of the values to avoid JSON serialization of event data
+				elemData[ eventKey ] = elemData = function(){};
+			}
+
+			elemData.events = events = {};
+		}
+
+		if ( !eventHandle ) {
+			elemData.handle = eventHandle = function() {
+				// Handle the second event of a trigger and when
+				// an event is called after a page has unloaded
+				return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+					jQuery.event.handle.apply( eventHandle.elem, arguments ) :
+					undefined;
+			};
+		}
+
+		// Add elem as a property of the handle function
+		// This is to prevent a memory leak with non-native events in IE.
+		eventHandle.elem = elem;
+
+		// Handle multiple events separated by a space
+		// jQuery(...).bind("mouseover mouseout", fn);
+		types = types.split(" ");
+
+		var type, i = 0, namespaces;
+
+		while ( (type = types[ i++ ]) ) {
+			handleObj = handleObjIn ?
+				jQuery.extend({}, handleObjIn) :
+				{ handler: handler, data: data };
+
+			// Namespaced event handlers
+			if ( type.indexOf(".") > -1 ) {
+				namespaces = type.split(".");
+				type = namespaces.shift();
+				handleObj.namespace = namespaces.slice(0).sort().join(".");
+
+			} else {
+				namespaces = [];
+				handleObj.namespace = "";
+			}
+
+			handleObj.type = type;
+			if ( !handleObj.guid ) {
+				handleObj.guid = handler.guid;
+			}
+
+			// Get the current list of functions bound to this event
+			var handlers = events[ type ],
+				special = jQuery.event.special[ type ] || {};
+
+			// Init the event handler queue
+			if ( !handlers ) {
+				handlers = events[ type ] = [];
+
+				// Check for a special event handler
+				// Only use addEventListener/attachEvent if the special
+				// events handler returns false
+				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+					// Bind the global event handler to the element
+					if ( elem.addEventListener ) {
+						elem.addEventListener( type, eventHandle, false );
+
+					} else if ( elem.attachEvent ) {
+						elem.attachEvent( "on" + type, eventHandle );
+					}
+				}
+			}
+			
+			if ( special.add ) { 
+				special.add.call( elem, handleObj ); 
+
+				if ( !handleObj.handler.guid ) {
+					handleObj.handler.guid = handler.guid;
+				}
+			}
+
+			// Add the function to the element's handler list
+			handlers.push( handleObj );
+
+			// Keep track of which events have been used, for global triggering
+			jQuery.event.global[ type ] = true;
+		}
+
+		// Nullify elem to prevent memory leaks in IE
+		elem = null;
+	},
+
+	global: {},
+
+	// Detach an event or set of events from an element
+	remove: function( elem, types, handler, pos ) {
+		// don't do events on text and comment nodes
+		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return;
+		}
+
+		if ( handler === false ) {
+			handler = returnFalse;
+		}
+
+		var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
+			eventKey = elem.nodeType ? "events" : "__events__",
+			elemData = jQuery.data( elem ),
+			events = elemData && elemData[ eventKey ];
+
+		if ( !elemData || !events ) {
+			return;
+		}
+		
+		if ( typeof events === "function" ) {
+			elemData = events;
+			events = events.events;
+		}
+
+		// types is actually an event object here
+		if ( types && types.type ) {
+			handler = types.handler;
+			types = types.type;
+		}
+
+		// Unbind all events for the element
+		if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
+			types = types || "";
+
+			for ( type in events ) {
+				jQuery.event.remove( elem, type + types );
+			}
+
+			return;
+		}
+
+		// Handle multiple events separated by a space
+		// jQuery(...).unbind("mouseover mouseout", fn);
+		types = types.split(" ");
+
+		while ( (type = types[ i++ ]) ) {
+			origType = type;
+			handleObj = null;
+			all = type.indexOf(".") < 0;
+			namespaces = [];
+
+			if ( !all ) {
+				// Namespaced event handlers
+				namespaces = type.split(".");
+				type = namespaces.shift();
+
+				namespace = new RegExp("(^|\\.)" + 
+					jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
+			}
+
+			eventType = events[ type ];
+
+			if ( !eventType ) {
+				continue;
+			}
+
+			if ( !handler ) {
+				for ( j = 0; j < eventType.length; j++ ) {
+					handleObj = eventType[ j ];
+
+					if ( all || namespace.test( handleObj.namespace ) ) {
+						jQuery.event.remove( elem, origType, handleObj.handler, j );
+						eventType.splice( j--, 1 );
+					}
+				}
+
+				continue;
+			}
+
+			special = jQuery.event.special[ type ] || {};
+
+			for ( j = pos || 0; j < eventType.length; j++ ) {
+				handleObj = eventType[ j ];
+
+				if ( handler.guid === handleObj.guid ) {
+					// remove the given handler for the given type
+					if ( all || namespace.test( handleObj.namespace ) ) {
+						if ( pos == null ) {
+							eventType.splice( j--, 1 );
+						}
+
+						if ( special.remove ) {
+							special.remove.call( elem, handleObj );
+						}
+					}
+
+					if ( pos != null ) {
+						break;
+					}
+				}
+			}
+
+			// remove generic event handler if no more handlers exist
+			if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
+				if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
+					jQuery.removeEvent( elem, type, elemData.handle );
+				}
+
+				ret = null;
+				delete events[ type ];
+			}
+		}
+
+		// Remove the expando if it's no longer used
+		if ( jQuery.isEmptyObject( events ) ) {
+			var handle = elemData.handle;
+			if ( handle ) {
+				handle.elem = null;
+			}
+
+			delete elemData.events;
+			delete elemData.handle;
+
+			if ( typeof elemData === "function" ) {
+				jQuery.removeData( elem, eventKey );
+
+			} else if ( jQuery.isEmptyObject( elemData ) ) {
+				jQuery.removeData( elem );
+			}
+		}
+	},
+
+	// bubbling is internal
+	trigger: function( event, data, elem /*, bubbling */ ) {
+		// Event object or event type
+		var type = event.type || event,
+			bubbling = arguments[3];
+
+		if ( !bubbling ) {
+			event = typeof event === "object" ?
+				// jQuery.Event object
+				event[ jQuery.expando ] ? event :
+				// Object literal
+				jQuery.extend( jQuery.Event(type), event ) :
+				// Just the event type (string)
+				jQuery.Event(type);
+
+			if ( type.indexOf("!") >= 0 ) {
+				event.type = type = type.slice(0, -1);
+				event.exclusive = true;
+			}
+
+			// Handle a global trigger
+			if ( !elem ) {
+				// Don't bubble custom events when global (to avoid too much overhead)
+				event.stopPropagation();
+
+				// Only trigger if we've ever bound an event for it
+				if ( jQuery.event.global[ type ] ) {
+					jQuery.each( jQuery.cache, function() {
+						if ( this.events && this.events[type] ) {
+							jQuery.event.trigger( event, data, this.handle.elem );
+						}
+					});
+				}
+			}
+
+			// Handle triggering a single element
+
+			// don't do events on text and comment nodes
+			if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+				return undefined;
+			}
+
+			// Clean up in case it is reused
+			event.result = undefined;
+			event.target = elem;
+
+			// Clone the incoming data, if any
+			data = jQuery.makeArray( data );
+			data.unshift( event );
+		}
+
+		event.currentTarget = elem;
+
+		// Trigger the event, it is assumed that "handle" is a function
+		var handle = elem.nodeType ?
+			jQuery.data( elem, "handle" ) :
+			(jQuery.data( elem, "__events__" ) || {}).handle;
+
+		if ( handle ) {
+			handle.apply( elem, data );
+		}
+
+		var parent = elem.parentNode || elem.ownerDocument;
+
+		// Trigger an inline bound script
+		try {
+			if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
+				if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
+					event.result = false;
+					event.preventDefault();
+				}
+			}
+
+		// prevent IE from throwing an error for some elements with some event types, see #3533
+		} catch (inlineError) {}
+
+		if ( !event.isPropagationStopped() && parent ) {
+			jQuery.event.trigger( event, data, parent, true );
+
+		} else if ( !event.isDefaultPrevented() ) {
+			var old,
+				target = event.target,
+				targetType = type.replace( rnamespaces, "" ),
+				isClick = jQuery.nodeName( target, "a" ) && targetType === "click",
+				special = jQuery.event.special[ targetType ] || {};
+
+			if ( (!special._default || special._default.call( elem, event ) === false) && 
+				!isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
+
+				try {
+					if ( target[ targetType ] ) {
+						// Make sure that we don't accidentally re-trigger the onFOO events
+						old = target[ "on" + targetType ];
+
+						if ( old ) {
+							target[ "on" + targetType ] = null;
+						}
+
+						jQuery.event.triggered = true;
+						target[ targetType ]();
+					}
+
+				// prevent IE from throwing an error for some elements with some event types, see #3533
+				} catch (triggerError) {}
+
+				if ( old ) {
+					target[ "on" + targetType ] = old;
+				}
+
+				jQuery.event.triggered = false;
+			}
+		}
+	},
+
+	handle: function( event ) {
+		var all, handlers, namespaces, namespace_re, events,
+			namespace_sort = [],
+			args = jQuery.makeArray( arguments );
+
+		event = args[0] = jQuery.event.fix( event || window.event );
+		event.currentTarget = this;
+
+		// Namespaced event handlers
+		all = event.type.indexOf(".") < 0 && !event.exclusive;
+
+		if ( !all ) {
+			namespaces = event.type.split(".");
+			event.type = namespaces.shift();
+			namespace_sort = namespaces.slice(0).sort();
+			namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
+		}
+
+		event.namespace = event.namespace || namespace_sort.join(".");
+
+		events = jQuery.data(this, this.nodeType ? "events" : "__events__");
+
+		if ( typeof events === "function" ) {
+			events = events.events;
+		}
+
+		handlers = (events || {})[ event.type ];
+
+		if ( events && handlers ) {
+			// Clone the handlers to prevent manipulation
+			handlers = handlers.slice(0);
+
+			for ( var j = 0, l = handlers.length; j < l; j++ ) {
+				var handleObj = handlers[ j ];
+
+				// Filter the functions by class
+				if ( all || namespace_re.test( handleObj.namespace ) ) {
+					// Pass in a reference to the handler function itself
+					// So that we can later remove it
+					event.handler = handleObj.handler;
+					event.data = handleObj.data;
+					event.handleObj = handleObj;
+	
+					var oldHandle = event.handled,
+						ret = handleObj.handler.apply( this, args );
+					event.handled = event.handled ===null || handleObj.handler === liveHandler  ? oldHandle : true
+
+					if ( ret !== undefined ) {
+						event.result = ret;
+						if ( ret === false ) {
+							event.preventDefault();
+							event.stopPropagation();
+						}
+					}
+
+					if ( event.isImmediatePropagationStopped() ) {
+						break;
+					}
+				}
+			}
+		}
+
+		return event.result;
+	},
+
+	props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+	fix: function( event ) {
+		if ( event[ jQuery.expando ] ) {
+			return event;
+		}
+
+		// store a copy of the original event object
+		// and "clone" to set read-only properties
+		var originalEvent = event;
+		event = jQuery.Event( originalEvent );
+
+		for ( var i = this.props.length, prop; i; ) {
+			prop = this.props[ --i ];
+			event[ prop ] = originalEvent[ prop ];
+		}
+
+		// Fix target property, if necessary
+		if ( !event.target ) {
+			// Fixes #1925 where srcElement might not be defined either
+			event.target = event.srcElement || document;
+		}
+
+		// check if target is a textnode (safari)
+		if ( event.target.nodeType === 3 ) {
+			event.target = event.target.parentNode;
+		}
+
+		// Add relatedTarget, if necessary
+		if ( !event.relatedTarget && event.fromElement ) {
+			event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
+		}
+
+		// Calculate pageX/Y if missing and clientX/Y available
+		if ( event.pageX == null && event.clientX != null ) {
+			var doc = document.documentElement,
+				body = document.body;
+
+			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
+			event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
+		}
+
+		// Add which for key events
+		if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
+			event.which = event.charCode != null ? event.charCode : event.keyCode;
+		}
+
+		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+		if ( !event.metaKey && event.ctrlKey ) {
+			event.metaKey = event.ctrlKey;
+		}
+
+		// Add which for click: 1 === left; 2 === middle; 3 === right
+		// Note: button is not normalized, so don't use it
+		if ( !event.which && event.button !== undefined ) {
+			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+		}
+
+		return event;
+	},
+
+	// Deprecated, use jQuery.guid instead
+	guid: 1E8,
+
+	// Deprecated, use jQuery.proxy instead
+	proxy: jQuery.proxy,
+
+	special: {
+		ready: {
+			// Make sure the ready event is setup
+			setup: jQuery.bindReady,
+			teardown: jQuery.noop
+		},
+
+		live: {
+			add: function( handleObj ) {
+				jQuery.event.add( this,
+					liveConvert( handleObj.origType, handleObj.selector ),
+					jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) ); 
+			},
+
+			remove: function( handleObj ) {
+				jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
+			}
+		},
+
+		beforeunload: {
+			setup: function( data, namespaces, eventHandle ) {
+				// We only want to do this special case on windows
+				if ( jQuery.isWindow( this ) ) {
+					this.onbeforeunload = eventHandle;
+				}
+			},
+
+			teardown: function( namespaces, eventHandle ) {
+				if ( this.onbeforeunload === eventHandle ) {
+					this.onbeforeunload = null;
+				}
+			}
+		}
+	}
+};
+
+jQuery.removeEvent = document.removeEventListener ?
+	function( elem, type, handle ) {
+		if ( elem.removeEventListener ) {
+			elem.removeEventListener( type, handle, false );
+		}
+	} : 
+	function( elem, type, handle ) {
+		if ( elem.detachEvent ) {
+			elem.detachEvent( "on" + type, handle );
+		}
+	};
+
+jQuery.Event = function( src ) {
+	// Allow instantiation without the 'new' keyword
+	if ( !this.preventDefault ) {
+		return new jQuery.Event( src );
+	}
+
+	// Event object
+	if ( src && src.type ) {
+		this.originalEvent = src;
+		this.type = src.type;
+	// Event type
+	} else {
+		this.type = src;
+	}
+
+	// timeStamp is buggy for some events on Firefox(#3843)
+	// So we won't rely on the native value
+	this.timeStamp = jQuery.now();
+
+	// Mark it as fixed
+	this[ jQuery.expando ] = true;
+};
+
+function returnFalse() {
+	return false;
+}
+function returnTrue() {
+	return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+	preventDefault: function() {
+		this.isDefaultPrevented = returnTrue;
+
+		var e = this.originalEvent;
+		if ( !e ) {
+			return;
+		}
+		
+		// if preventDefault exists run it on the original event
+		if ( e.preventDefault ) {
+			e.preventDefault();
+
+		// otherwise set the returnValue property of the original event to false (IE)
+		} else {
+			e.returnValue = false;
+		}
+	},
+	stopPropagation: function() {
+		this.isPropagationStopped = returnTrue;
+
+		var e = this.originalEvent;
+		if ( !e ) {
+			return;
+		}
+		// if stopPropagation exists run it on the original event
+		if ( e.stopPropagation ) {
+			e.stopPropagation();
+		}
+		// otherwise set the cancelBubble property of the original event to true (IE)
+		e.cancelBubble = true;
+	},
+	stopImmediatePropagation: function() {
+		this.isImmediatePropagationStopped = returnTrue;
+		this.stopPropagation();
+	},
+	isDefaultPrevented: returnFalse,
+	isPropagationStopped: returnFalse,
+	isImmediatePropagationStopped: returnFalse
+};
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function( event ) {
+	// Check if mouse(over|out) are still within the same parent element
+	var parent = event.relatedTarget;
+
+	// Firefox sometimes assigns relatedTarget a XUL element
+	// which we cannot access the parentNode property of
+	try {
+		// Traverse up the tree
+		while ( parent && parent !== this ) {
+			parent = parent.parentNode;
+		}
+
+		if ( parent !== this ) {
+			// set the correct event type
+			event.type = event.data;
+
+			// handle event if we actually just moused on to a non sub-element
+			jQuery.event.handle.apply( this, arguments );
+		}
+
+	// assuming we've left the element since we most likely mousedover a xul element
+	} catch(e) { }
+},
+
+// In case of event delegation, we only need to rename the event.type,
+// liveHandler will take care of the rest.
+delegate = function( event ) {
+	event.type = event.data;
+	jQuery.event.handle.apply( this, arguments );
+};
+
+// Create mouseenter and mouseleave events
+jQuery.each({
+	mouseenter: "mouseover",
+	mouseleave: "mouseout"
+}, function( orig, fix ) {
+	jQuery.event.special[ orig ] = {
+		setup: function( data ) {
+			jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
+		},
+		teardown: function( data ) {
+			jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
+		}
+	};
+});
+
+// submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+	jQuery.event.special.submit = {
+		setup: function( data, namespaces ) {
+			if ( this.nodeName.toLowerCase() !== "form" ) {
+				jQuery.event.add(this, "click.specialSubmit", function( e ) {
+					var elem = e.target,
+						type = elem.type;
+
+					if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
+						e.liveFired = undefined;
+						return trigger( "submit", this, arguments );
+					}
+				});
+	 
+				jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
+					var elem = e.target,
+						type = elem.type;
+
+					if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
+						e.liveFired = undefined;
+						return trigger( "submit", this, arguments );
+					}
+				});
+
+			} else {
+				return false;
+			}
+		},
+
+		teardown: function( namespaces ) {
+			jQuery.event.remove( this, ".specialSubmit" );
+		}
+	};
+
+}
+
+// change delegation, happens here so we have bind.
+if ( !jQuery.support.changeBubbles ) {
+
+	var changeFilters,
+
+	getVal = function( elem ) {
+		var type = elem.type, val = elem.value;
+
+		if ( type === "radio" || type === "checkbox" ) {
+			val = elem.checked;
+
+		} else if ( type === "select-multiple" ) {
+			val = elem.selectedIndex > -1 ?
+				jQuery.map( elem.options, function( elem ) {
+					return elem.selected;
+				}).join("-") :
+				"";
+
+		} else if ( elem.nodeName.toLowerCase() === "select" ) {
+			val = elem.selectedIndex;
+		}
+
+		return val;
+	},
+
+	testChange = function testChange( e ) {
+		var elem = e.target, data, val;
+
+		if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
+			return;
+		}
+
+		data = jQuery.data( elem, "_change_data" );
+		val = getVal(elem);
+
+		// the current data will be also retrieved by beforeactivate
+		if ( e.type !== "focusout" || elem.type !== "radio" ) {
+			jQuery.data( elem, "_change_data", val );
+		}
+		
+		if ( data === undefined || val === data ) {
+			return;
+		}
+
+		if ( data != null || val ) {
+			e.type = "change";
+			e.liveFired = undefined;
+			return jQuery.event.trigger( e, arguments[1], elem );
+		}
+	};
+
+	jQuery.event.special.change = {
+		filters: {
+			focusout: testChange, 
+
+			beforedeactivate: testChange,
+
+			click: function( e ) {
+				var elem = e.target, type = elem.type;
+
+				if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
+					return testChange.call( this, e );
+				}
+			},
+
+			// Change has to be called before submit
+			// Keydown will be called before keypress, which is used in submit-event delegation
+			keydown: function( e ) {
+				var elem = e.target, type = elem.type;
+
+				if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
+					(e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
+					type === "select-multiple" ) {
+					return testChange.call( this, e );
+				}
+			},
+
+			// Beforeactivate happens also before the previous element is blurred
+			// with this event you can't trigger a change event, but you can store
+			// information
+			beforeactivate: function( e ) {
+				var elem = e.target;
+				jQuery.data( elem, "_change_data", getVal(elem) );
+			}
+		},
+
+		setup: function( data, namespaces ) {
+			if ( this.type === "file" ) {
+				return false;
+			}
+
+			for ( var type in changeFilters ) {
+				jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
+			}
+
+			return rformElems.test( this.nodeName );
+		},
+
+		teardown: function( namespaces ) {
+			jQuery.event.remove( this, ".specialChange" );
+
+			return rformElems.test( this.nodeName );
+		}
+	};
+
+	changeFilters = jQuery.event.special.change.filters;
+
+	// Handle when the input is .focus()'d
+	changeFilters.focus = changeFilters.beforeactivate;
+}
+
+function trigger( type, elem, args ) {
+	args[0].type = type;
+	return jQuery.event.handle.apply( elem, args );
+}
+
+// Create "bubbling" focus and blur events
+if ( document.addEventListener ) {
+	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+		jQuery.event.special[ fix ] = {
+			setup: function() {
+				if ( focusCounts[fix]++ === 0 ) {
+					document.addEventListener( orig, handler, true );
+				}
+			}, 
+			teardown: function() { 
+				if ( --focusCounts[fix] === 0 ) {
+					document.removeEventListener( orig, handler, true );
+				}
+			}
+		};
+
+		function handler( e ) { 
+			e = jQuery.event.fix( e );
+			e.type = fix;
+			return jQuery.event.trigger( e, null, e.target );
+		}
+	});
+}
+
+jQuery.each(["bind", "one"], function( i, name ) {
+	jQuery.fn[ name ] = function( type, data, fn ) {
+		// Handle object literals
+		if ( typeof type === "object" ) {
+			for ( var key in type ) {
+				this[ name ](key, data, type[key], fn);
+			}
+			return this;
+		}
+		
+		if ( jQuery.isFunction( data ) || data === false ) {
+			fn = data;
+			data = undefined;
+		}
+
+		var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
+			jQuery( this ).unbind( event, handler );
+			return fn.apply( this, arguments );
+		}) : fn;
+
+		if ( type === "unload" && name !== "one" ) {
+			this.one( type, data, fn );
+
+		} else {
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				jQuery.event.add( this[i], type, handler, data );
+			}
+		}
+
+		return this;
+	};
+});
+
+jQuery.fn.extend({
+	unbind: function( type, fn ) {
+		// Handle object literals
+		if ( typeof type === "object" && !type.preventDefault ) {
+			for ( var key in type ) {
+				this.unbind(key, type[key]);
+			}
+
+		} else {
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				jQuery.event.remove( this[i], type, fn );
+			}
+		}
+
+		return this;
+	},
+	
+	delegate: function( selector, types, data, fn ) {
+		return this.live( types, data, fn, selector );
+	},
+	
+	undelegate: function( selector, types, fn ) {
+		if ( arguments.length === 0 ) {
+				return this.unbind( "live" );
+		
+		} else {
+			return this.die( types, null, fn, selector );
+		}
+	},
+	
+	trigger: function( type, data ) {
+		return this.each(function() {
+			jQuery.event.trigger( type, data, this );
+		});
+	},
+
+	triggerHandler: function( type, data ) {
+		if ( this[0] ) {
+			var event = jQuery.Event( type );
+			event.preventDefault();
+			event.stopPropagation();
+			jQuery.event.trigger( event, data, this[0] );
+			return event.result;
+		}
+	},
+
+	toggle: function( fn ) {
+		// Save reference to arguments for access in closure
+		var args = arguments,
+			i = 1;
+
+		// link all the functions, so any of them can unbind this click handler
+		while ( i < args.length ) {
+			jQuery.proxy( fn, args[ i++ ] );
+		}
+
+		return this.click( jQuery.proxy( fn, function( event ) {
+			// Figure out which function to execute
+			var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+			jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+			// Make sure that clicks stop
+			event.preventDefault();
+
+			// and execute the function
+			return args[ lastToggle ].apply( this, arguments ) || false;
+		}));
+	},
+
+	hover: function( fnOver, fnOut ) {
+		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+	}
+});
+
+var liveMap = {
+	focus: "focusin",
+	blur: "focusout",
+	mouseenter: "mouseover",
+	mouseleave: "mouseout"
+};
+
+jQuery.each(["live", "die"], function( i, name ) {
+	jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
+		var type, i = 0, match, namespaces, preType,
+			selector = origSelector || this.selector,
+			context = origSelector ? this : jQuery( this.context );
+		
+		if ( typeof types === "object" && !types.preventDefault ) {
+			for ( var key in types ) {
+				context[ name ]( key, data, types[key], selector );
+			}
+			
+			return this;
+		}
+
+		if ( jQuery.isFunction( data ) ) {
+			fn = data;
+			data = undefined;
+		}
+
+		types = (types || "").split(" ");
+
+		while ( (type = types[ i++ ]) != null ) {
+			match = rnamespaces.exec( type );
+			namespaces = "";
+
+			if ( match )  {
+				namespaces = match[0];
+				type = type.replace( rnamespaces, "" );
+			}
+
+			if ( type === "hover" ) {
+				types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
+				continue;
+			}
+
+			preType = type;
+
+			if ( type === "focus" || type === "blur" ) {
+				types.push( liveMap[ type ] + namespaces );
+				type = type + namespaces;
+
+			} else {
+				type = (liveMap[ type ] || type) + namespaces;
+			}
+
+			if ( name === "live" ) {
+				// bind live handler
+				for ( var j = 0, l = context.length; j < l; j++ ) {
+					jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
+						{ data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
+				}
+
+			} else {
+				// unbind live handler
+				context.unbind( "live." + liveConvert( type, selector ), fn );
+			}
+		}
+		
+		return this;
+	};
+});
+
+function liveHandler( event ) {
+	var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
+		elems = [],
+		selectors = [],
+		events = jQuery.data( this, this.nodeType ? "events" : "__events__" );
+
+	if ( typeof events === "function" ) {
+		events = events.events;
+	}
+
+	// Make sure we avoid non-left-click bubbling in Firefox (#3861)
+	if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
+		return;
+	}
+	
+	if ( event.namespace ) {
+		namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
+	}
+
+	event.liveFired = this;
+
+	var live = events.live.slice(0);
+
+	for ( j = 0; j < live.length; j++ ) {
+		handleObj = live[j];
+
+		if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
+			selectors.push( handleObj.selector );
+
+		} else {
+			live.splice( j--, 1 );
+		}
+	}
+
+	match = jQuery( event.target ).closest( selectors, event.currentTarget );
+
+	for ( i = 0, l = match.length; i < l; i++ ) {
+		close = match[i];
+
+		for ( j = 0; j < live.length; j++ ) {
+			handleObj = live[j];
+
+			if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) {
+				elem = close.elem;
+				related = null;
+
+				// Those two events require additional checking
+				if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
+					event.type = handleObj.preType;
+					related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
+				}
+
+				if ( !related || related !== elem ) {
+					elems.push({ elem: elem, handleObj: handleObj, level: close.level });
+				}
+			}
+		}
+	}
+
+	for ( i = 0, l = elems.length; i < l; i++ ) {
+		match = elems[i];
+
+		if ( maxLevel && match.level > maxLevel ) {
+			break;
+		}
+
+		event.currentTarget = match.elem;
+		event.data = match.handleObj.data;
+		event.handleObj = match.handleObj;
+
+		var oldHandle = event.handled;
+		ret = match.handleObj.origHandler.apply( match.elem, arguments );
+		event.handled = event.handled === null ? oldHandle : true;
+
+		if ( ret === false || event.isPropagationStopped() ) {
+			maxLevel = match.level;
+
+			if ( ret === false ) {
+				stop = false;
+			}
+			if ( event.isImmediatePropagationStopped() ) {
+				break;
+			}
+		}
+	}
+
+	return stop;
+}
+
+function liveConvert( type, selector ) {
+	return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&");
+}
+
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+	"change select submit keydown keypress keyup error").split(" "), function( i, name ) {
+
+	// Handle event binding
+	jQuery.fn[ name ] = function( data, fn ) {
+		if ( fn == null ) {
+			fn = data;
+			data = null;
+		}
+
+		return arguments.length > 0 ?
+			this.bind( name, data, fn ) :
+			this.trigger( name );
+	};
+
+	if ( jQuery.attrFn ) {
+		jQuery.attrFn[ name ] = true;
+	}
+});
+
+// Prevent memory leaks in IE
+// Window isn't included so as not to unbind existing unload events
+// More info:
+//  - http://isaacschlueter.com/2006/10/msie-memory-leaks/
+if ( window.attachEvent && !window.addEventListener ) {
+	jQuery(window).bind("unload", function() {
+		for ( var id in jQuery.cache ) {
+			if ( jQuery.cache[ id ].handle ) {
+				// Try/Catch is to handle iframes being unloaded, see #4280
+				try {
+					jQuery.event.remove( jQuery.cache[ id ].handle.elem );
+				} catch(e) {}
+			}
+		}
+	});
+}
+
+
+/*!
+ * Sizzle CSS Selector Engine - v1.0
+ *  Copyright 2009, The Dojo Foundation
+ *  Released under the MIT, BSD, and GPL Licenses.
+ *  More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+	done = 0,
+	toString = Object.prototype.toString,
+	hasDuplicate = false,
+	baseHasDuplicate = true;
+
+// Here we check if the JavaScript engine is using some sort of
+// optimization where it does not always call our comparision
+// function. If that is the case, discard the hasDuplicate value.
+//   Thus far that includes Google Chrome.
+[0, 0].sort(function() {
+	baseHasDuplicate = false;
+	return 0;
+});
+
+var Sizzle = function( selector, context, results, seed ) {
+	results = results || [];
+	context = context || document;
+
+	var origContext = context;
+
+	if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+		return [];
+	}
+	
+	if ( !selector || typeof selector !== "string" ) {
+		return results;
+	}
+
+	var m, set, checkSet, extra, ret, cur, pop, i,
+		prune = true,
+		contextXML = Sizzle.isXML( context ),
+		parts = [],
+		soFar = selector;
+	
+	// Reset the position of the chunker regexp (start from head)
+	do {
+		chunker.exec( "" );
+		m = chunker.exec( soFar );
+
+		if ( m ) {
+			soFar = m[3];
+		
+			parts.push( m[1] );
+		
+			if ( m[2] ) {
+				extra = m[3];
+				break;
+			}
+		}
+	} while ( m );
+
+	if ( parts.length > 1 && origPOS.exec( selector ) ) {
+
+		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+			set = posProcess( parts[0] + parts[1], context );
+
+		} else {
+			set = Expr.relative[ parts[0] ] ?
+				[ context ] :
+				Sizzle( parts.shift(), context );
+
+			while ( parts.length ) {
+				selector = parts.shift();
+
+				if ( Expr.relative[ selector ] ) {
+					selector += parts.shift();
+				}
+				
+				set = posProcess( selector, set );
+			}
+		}
+
+	} else {
+		// Take a shortcut and set the context if the root selector is an ID
+		// (but not if it'll be faster if the inner selector is an ID)
+		if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+				Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+
+			ret = Sizzle.find( parts.shift(), context, contextXML );
+			context = ret.expr ?
+				Sizzle.filter( ret.expr, ret.set )[0] :
+				ret.set[0];
+		}
+
+		if ( context ) {
+			ret = seed ?
+				{ expr: parts.pop(), set: makeArray(seed) } :
+				Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+
+			set = ret.expr ?
+				Sizzle.filter( ret.expr, ret.set ) :
+				ret.set;
+
+			if ( parts.length > 0 ) {
+				checkSet = makeArray( set );
+
+			} else {
+				prune = false;
+			}
+
+			while ( parts.length ) {
+				cur = parts.pop();
+				pop = cur;
+
+				if ( !Expr.relative[ cur ] ) {
+					cur = "";
+				} else {
+					pop = parts.pop();
+				}
+
+				if ( pop == null ) {
+					pop = context;
+				}
+
+				Expr.relative[ cur ]( checkSet, pop, contextXML );
+			}
+
+		} else {
+			checkSet = parts = [];
+		}
+	}
+
+	if ( !checkSet ) {
+		checkSet = set;
+	}
+
+	if ( !checkSet ) {
+		Sizzle.error( cur || selector );
+	}
+
+	if ( toString.call(checkSet) === "[object Array]" ) {
+		if ( !prune ) {
+			results.push.apply( results, checkSet );
+
+		} else if ( context && context.nodeType === 1 ) {
+			for ( i = 0; checkSet[i] != null; i++ ) {
+				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
+					results.push( set[i] );
+				}
+			}
+
+		} else {
+			for ( i = 0; checkSet[i] != null; i++ ) {
+				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+					results.push( set[i] );
+				}
+			}
+		}
+
+	} else {
+		makeArray( checkSet, results );
+	}
+
+	if ( extra ) {
+		Sizzle( extra, origContext, results, seed );
+		Sizzle.uniqueSort( results );
+	}
+
+	return results;
+};
+
+Sizzle.uniqueSort = function( results ) {
+	if ( sortOrder ) {
+		hasDuplicate = baseHasDuplicate;
+		results.sort( sortOrder );
+
+		if ( hasDuplicate ) {
+			for ( var i = 1; i < results.length; i++ ) {
+				if ( results[i] === results[ i - 1 ] ) {
+					results.splice( i--, 1 );
+				}
+			}
+		}
+	}
+
+	return results;
+};
+
+Sizzle.matches = function( expr, set ) {
+	return Sizzle( expr, null, null, set );
+};
+
+Sizzle.matchesSelector = function( node, expr ) {
+	return Sizzle( expr, null, null, [node] ).length > 0;
+};
+
+Sizzle.find = function( expr, context, isXML ) {
+	var set;
+
+	if ( !expr ) {
+		return [];
+	}
+
+	for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+		var match,
+			type = Expr.order[i];
+		
+		if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+			var left = match[1];
+			match.splice( 1, 1 );
+
+			if ( left.substr( left.length - 1 ) !== "\\" ) {
+				match[1] = (match[1] || "").replace(/\\/g, "");
+				set = Expr.find[ type ]( match, context, isXML );
+
+				if ( set != null ) {
+					expr = expr.replace( Expr.match[ type ], "" );
+					break;
+				}
+			}
+		}
+	}
+
+	if ( !set ) {
+		set = context.getElementsByTagName( "*" );
+	}
+
+	return { set: set, expr: expr };
+};
+
+Sizzle.filter = function( expr, set, inplace, not ) {
+	var match, anyFound,
+		old = expr,
+		result = [],
+		curLoop = set,
+		isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
+
+	while ( expr && set.length ) {
+		for ( var type in Expr.filter ) {
+			if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
+				var found, item,
+					filter = Expr.filter[ type ],
+					left = match[1];
+
+				anyFound = false;
+
+				match.splice(1,1);
+
+				if ( left.substr( left.length - 1 ) === "\\" ) {
+					continue;
+				}
+
+				if ( curLoop === result ) {
+					result = [];
+				}
+
+				if ( Expr.preFilter[ type ] ) {
+					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+					if ( !match ) {
+						anyFound = found = true;
+
+					} else if ( match === true ) {
+						continue;
+					}
+				}
+
+				if ( match ) {
+					for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+						if ( item ) {
+							found = filter( item, match, i, curLoop );
+							var pass = not ^ !!found;
+
+							if ( inplace && found != null ) {
+								if ( pass ) {
+									anyFound = true;
+
+								} else {
+									curLoop[i] = false;
+								}
+
+							} else if ( pass ) {
+								result.push( item );
+								anyFound = true;
+							}
+						}
+					}
+				}
+
+				if ( found !== undefined ) {
+					if ( !inplace ) {
+						curLoop = result;
+					}
+
+					expr = expr.replace( Expr.match[ type ], "" );
+
+					if ( !anyFound ) {
+						return [];
+					}
+
+					break;
+				}
+			}
+		}
+
+		// Improper expression
+		if ( expr === old ) {
+			if ( anyFound == null ) {
+				Sizzle.error( expr );
+
+			} else {
+				break;
+			}
+		}
+
+		old = expr;
+	}
+
+	return curLoop;
+};
+
+Sizzle.error = function( msg ) {
+	throw "Syntax error, unrecognized expression: " + msg;
+};
+
+var Expr = Sizzle.selectors = {
+	order: [ "ID", "NAME", "TAG" ],
+
+	match: {
+		ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+		CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
+		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+		TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
+		CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
+		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
+		PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
+	},
+
+	leftMatch: {},
+
+	attrMap: {
+		"class": "className",
+		"for": "htmlFor"
+	},
+
+	attrHandle: {
+		href: function( elem ) {
+			return elem.getAttribute( "href" );
+		}
+	},
+
+	relative: {
+		"+": function(checkSet, part){
+			var isPartStr = typeof part === "string",
+				isTag = isPartStr && !/\W/.test( part ),
+				isPartStrNotTag = isPartStr && !isTag;
+
+			if ( isTag ) {
+				part = part.toLowerCase();
+			}
+
+			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+				if ( (elem = checkSet[i]) ) {
+					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+					checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
+						elem || false :
+						elem === part;
+				}
+			}
+
+			if ( isPartStrNotTag ) {
+				Sizzle.filter( part, checkSet, true );
+			}
+		},
+
+		">": function( checkSet, part ) {
+			var elem,
+				isPartStr = typeof part === "string",
+				i = 0,
+				l = checkSet.length;
+
+			if ( isPartStr && !/\W/.test( part ) ) {
+				part = part.toLowerCase();
+
+				for ( ; i < l; i++ ) {
+					elem = checkSet[i];
+
+					if ( elem ) {
+						var parent = elem.parentNode;
+						checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
+					}
+				}
+
+			} else {
+				for ( ; i < l; i++ ) {
+					elem = checkSet[i];
+
+					if ( elem ) {
+						checkSet[i] = isPartStr ?
+							elem.parentNode :
+							elem.parentNode === part;
+					}
+				}
+
+				if ( isPartStr ) {
+					Sizzle.filter( part, checkSet, true );
+				}
+			}
+		},
+
+		"": function(checkSet, part, isXML){
+			var nodeCheck,
+				doneName = done++,
+				checkFn = dirCheck;
+
+			if ( typeof part === "string" && !/\W/.test(part) ) {
+				part = part.toLowerCase();
+				nodeCheck = part;
+				checkFn = dirNodeCheck;
+			}
+
+			checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
+		},
+
+		"~": function( checkSet, part, isXML ) {
+			var nodeCheck,
+				doneName = done++,
+				checkFn = dirCheck;
+
+			if ( typeof part === "string" && !/\W/.test( part ) ) {
+				part = part.toLowerCase();
+				nodeCheck = part;
+				checkFn = dirNodeCheck;
+			}
+
+			checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
+		}
+	},
+
+	find: {
+		ID: function( match, context, isXML ) {
+			if ( typeof context.getElementById !== "undefined" && !isXML ) {
+				var m = context.getElementById(match[1]);
+				// Check parentNode to catch when Blackberry 4.6 returns
+				// nodes that are no longer in the document #6963
+				return m && m.parentNode ? [m] : [];
+			}
+		},
+
+		NAME: function( match, context ) {
+			if ( typeof context.getElementsByName !== "undefined" ) {
+				var ret = [],
+					results = context.getElementsByName( match[1] );
+
+				for ( var i = 0, l = results.length; i < l; i++ ) {
+					if ( results[i].getAttribute("name") === match[1] ) {
+						ret.push( results[i] );
+					}
+				}
+
+				return ret.length === 0 ? null : ret;
+			}
+		},
+
+		TAG: function( match, context ) {
+			return context.getElementsByTagName( match[1] );
+		}
+	},
+	preFilter: {
+		CLASS: function( match, curLoop, inplace, result, not, isXML ) {
+			match = " " + match[1].replace(/\\/g, "") + " ";
+
+			if ( isXML ) {
+				return match;
+			}
+
+			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+				if ( elem ) {
+					if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
+						if ( !inplace ) {
+							result.push( elem );
+						}
+
+					} else if ( inplace ) {
+						curLoop[i] = false;
+					}
+				}
+			}
+
+			return false;
+		},
+
+		ID: function( match ) {
+			return match[1].replace(/\\/g, "");
+		},
+
+		TAG: function( match, curLoop ) {
+			return match[1].toLowerCase();
+		},
+
+		CHILD: function( match ) {
+			if ( match[1] === "nth" ) {
+				// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+				var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+					match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
+					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+				// calculate the numbers (first)n+(last) including if they are negative
+				match[2] = (test[1] + (test[2] || 1)) - 0;
+				match[3] = test[3] - 0;
+			}
+
+			// TODO: Move to normal caching system
+			match[0] = done++;
+
+			return match;
+		},
+
+		ATTR: function( match, curLoop, inplace, result, not, isXML ) {
+			var name = match[1].replace(/\\/g, "");
+			
+			if ( !isXML && Expr.attrMap[name] ) {
+				match[1] = Expr.attrMap[name];
+			}
+
+			if ( match[2] === "~=" ) {
+				match[4] = " " + match[4] + " ";
+			}
+
+			return match;
+		},
+
+		PSEUDO: function( match, curLoop, inplace, result, not ) {
+			if ( match[1] === "not" ) {
+				// If we're dealing with a complex expression, or a simple one
+				if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+					match[3] = Sizzle(match[3], null, null, curLoop);
+
+				} else {
+					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+
+					if ( !inplace ) {
+						result.push.apply( result, ret );
+					}
+
+					return false;
+				}
+
+			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+				return true;
+			}
+			
+			return match;
+		},
+
+		POS: function( match ) {
+			match.unshift( true );
+
+			return match;
+		}
+	},
+	
+	filters: {
+		enabled: function( elem ) {
+			return elem.disabled === false && elem.type !== "hidden";
+		},
+
+		disabled: function( elem ) {
+			return elem.disabled === true;
+		},
+
+		checked: function( elem ) {
+			return elem.checked === true;
+		},
+		
+		selected: function( elem ) {
+			// Accessing this property makes selected-by-default
+			// options in Safari work properly
+			elem.parentNode.selectedIndex;
+			
+			return elem.selected === true;
+		},
+
+		parent: function( elem ) {
+			return !!elem.firstChild;
+		},
+
+		empty: function( elem ) {
+			return !elem.firstChild;
+		},
+
+		has: function( elem, i, match ) {
+			return !!Sizzle( match[3], elem ).length;
+		},
+
+		header: function( elem ) {
+			return (/h\d/i).test( elem.nodeName );
+		},
+
+		text: function( elem ) {
+			return "text" === elem.type;
+		},
+		radio: function( elem ) {
+			return "radio" === elem.type;
+		},
+
+		checkbox: function( elem ) {
+			return "checkbox" === elem.type;
+		},
+
+		file: function( elem ) {
+			return "file" === elem.type;
+		},
+		password: function( elem ) {
+			return "password" === elem.type;
+		},
+
+		submit: function( elem ) {
+			return "submit" === elem.type;
+		},
+
+		image: function( elem ) {
+			return "image" === elem.type;
+		},
+
+		reset: function( elem ) {
+			return "reset" === elem.type;
+		},
+
+		button: function( elem ) {
+			return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
+		},
+
+		input: function( elem ) {
+			return (/input|select|textarea|button/i).test( elem.nodeName );
+		}
+	},
+	setFilters: {
+		first: function( elem, i ) {
+			return i === 0;
+		},
+
+		last: function( elem, i, match, array ) {
+			return i === array.length - 1;
+		},
+
+		even: function( elem, i ) {
+			return i % 2 === 0;
+		},
+
+		odd: function( elem, i ) {
+			return i % 2 === 1;
+		},
+
+		lt: function( elem, i, match ) {
+			return i < match[3] - 0;
+		},
+
+		gt: function( elem, i, match ) {
+			return i > match[3] - 0;
+		},
+
+		nth: function( elem, i, match ) {
+			return match[3] - 0 === i;
+		},
+
+		eq: function( elem, i, match ) {
+			return match[3] - 0 === i;
+		}
+	},
+	filter: {
+		PSEUDO: function( elem, match, i, array ) {
+			var name = match[1],
+				filter = Expr.filters[ name ];
+
+			if ( filter ) {
+				return filter( elem, i, match, array );
+
+			} else if ( name === "contains" ) {
+				return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
+
+			} else if ( name === "not" ) {
+				var not = match[3];
+
+				for ( var j = 0, l = not.length; j < l; j++ ) {
+					if ( not[j] === elem ) {
+						return false;
+					}
+				}
+
+				return true;
+
+			} else {
+				Sizzle.error( "Syntax error, unrecognized expression: " + name );
+			}
+		},
+
+		CHILD: function( elem, match ) {
+			var type = match[1],
+				node = elem;
+
+			switch ( type ) {
+				case "only":
+				case "first":
+					while ( (node = node.previousSibling) )	 {
+						if ( node.nodeType === 1 ) { 
+							return false; 
+						}
+					}
+
+					if ( type === "first" ) { 
+						return true; 
+					}
+
+					node = elem;
+
+				case "last":
+					while ( (node = node.nextSibling) )	 {
+						if ( node.nodeType === 1 ) { 
+							return false; 
+						}
+					}
+
+					return true;
+
+				case "nth":
+					var first = match[2],
+						last = match[3];
+
+					if ( first === 1 && last === 0 ) {
+						return true;
+					}
+					
+					var doneName = match[0],
+						parent = elem.parentNode;
+	
+					if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+						var count = 0;
+						
+						for ( node = parent.firstChild; node; node = node.nextSibling ) {
+							if ( node.nodeType === 1 ) {
+								node.nodeIndex = ++count;
+							}
+						} 
+
+						parent.sizcache = doneName;
+					}
+					
+					var diff = elem.nodeIndex - last;
+
+					if ( first === 0 ) {
+						return diff === 0;
+
+					} else {
+						return ( diff % first === 0 && diff / first >= 0 );
+					}
+			}
+		},
+
+		ID: function( elem, match ) {
+			return elem.nodeType === 1 && elem.getAttribute("id") === match;
+		},
+
+		TAG: function( elem, match ) {
+			return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
+		},
+		
+		CLASS: function( elem, match ) {
+			return (" " + (elem.className || elem.getAttribute("class")) + " ")
+				.indexOf( match ) > -1;
+		},
+
+		ATTR: function( elem, match ) {
+			var name = match[1],
+				result = Expr.attrHandle[ name ] ?
+					Expr.attrHandle[ name ]( elem ) :
+					elem[ name ] != null ?
+						elem[ name ] :
+						elem.getAttribute( name ),
+				value = result + "",
+				type = match[2],
+				check = match[4];
+
+			return result == null ?
+				type === "!=" :
+				type === "=" ?
+				value === check :
+				type === "*=" ?
+				value.indexOf(check) >= 0 :
+				type === "~=" ?
+				(" " + value + " ").indexOf(check) >= 0 :
+				!check ?
+				value && result !== false :
+				type === "!=" ?
+				value !== check :
+				type === "^=" ?
+				value.indexOf(check) === 0 :
+				type === "$=" ?
+				value.substr(value.length - check.length) === check :
+				type === "|=" ?
+				value === check || value.substr(0, check.length + 1) === check + "-" :
+				false;
+		},
+
+		POS: function( elem, match, i, array ) {
+			var name = match[2],
+				filter = Expr.setFilters[ name ];
+
+			if ( filter ) {
+				return filter( elem, i, match, array );
+			}
+		}
+	}
+};
+
+var origPOS = Expr.match.POS,
+	fescape = function(all, num){
+		return "\\" + (num - 0 + 1);
+	};
+
+for ( var type in Expr.match ) {
+	Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
+	Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
+}
+
+var makeArray = function( array, results ) {
+	array = Array.prototype.slice.call( array, 0 );
+
+	if ( results ) {
+		results.push.apply( results, array );
+		return results;
+	}
+	
+	return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+// Also verifies that the returned array holds DOM nodes
+// (which is not the case in the Blackberry browser)
+try {
+	Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
+
+// Provide a fallback method if it does not work
+} catch( e ) {
+	makeArray = function( array, results ) {
+		var i = 0,
+			ret = results || [];
+
+		if ( toString.call(array) === "[object Array]" ) {
+			Array.prototype.push.apply( ret, array );
+
+		} else {
+			if ( typeof array.length === "number" ) {
+				for ( var l = array.length; i < l; i++ ) {
+					ret.push( array[i] );
+				}
+
+			} else {
+				for ( ; array[i]; i++ ) {
+					ret.push( array[i] );
+				}
+			}
+		}
+
+		return ret;
+	};
+}
+
+var sortOrder, siblingCheck;
+
+if ( document.documentElement.compareDocumentPosition ) {
+	sortOrder = function( a, b ) {
+		if ( a === b ) {
+			hasDuplicate = true;
+			return 0;
+		}
+
+		if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+			return a.compareDocumentPosition ? -1 : 1;
+		}
+
+		return a.compareDocumentPosition(b) & 4 ? -1 : 1;
+	};
+
+} else {
+	sortOrder = function( a, b ) {
+		var al, bl,
+			ap = [],
+			bp = [],
+			aup = a.parentNode,
+			bup = b.parentNode,
+			cur = aup;
+
+		// The nodes are identical, we can exit early
+		if ( a === b ) {
+			hasDuplicate = true;
+			return 0;
+
+		// If the nodes are siblings (or identical) we can do a quick check
+		} else if ( aup === bup ) {
+			return siblingCheck( a, b );
+
+		// If no parents were found then the nodes are disconnected
+		} else if ( !aup ) {
+			return -1;
+
+		} else if ( !bup ) {
+			return 1;
+		}
+
+		// Otherwise they're somewhere else in the tree so we need
+		// to build up a full list of the parentNodes for comparison
+		while ( cur ) {
+			ap.unshift( cur );
+			cur = cur.parentNode;
+		}
+
+		cur = bup;
+
+		while ( cur ) {
+			bp.unshift( cur );
+			cur = cur.parentNode;
+		}
+
+		al = ap.length;
+		bl = bp.length;
+
+		// Start walking down the tree looking for a discrepancy
+		for ( var i = 0; i < al && i < bl; i++ ) {
+			if ( ap[i] !== bp[i] ) {
+				return siblingCheck( ap[i], bp[i] );
+			}
+		}
+
+		// We ended someplace up the tree so do a sibling check
+		return i === al ?
+			siblingCheck( a, bp[i], -1 ) :
+			siblingCheck( ap[i], b, 1 );
+	};
+
+	siblingCheck = function( a, b, ret ) {
+		if ( a === b ) {
+			return ret;
+		}
+
+		var cur = a.nextSibling;
+
+		while ( cur ) {
+			if ( cur === b ) {
+				return -1;
+			}
+
+			cur = cur.nextSibling;
+		}
+
+		return 1;
+	};
+}
+
+// Utility function for retreiving the text value of an array of DOM nodes
+Sizzle.getText = function( elems ) {
+	var ret = "", elem;
+
+	for ( var i = 0; elems[i]; i++ ) {
+		elem = elems[i];
+
+		// Get the text from text nodes and CDATA nodes
+		if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
+			ret += elem.nodeValue;
+
+		// Traverse everything else, except comment nodes
+		} else if ( elem.nodeType !== 8 ) {
+			ret += Sizzle.getText( elem.childNodes );
+		}
+	}
+
+	return ret;
+};
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+	// We're going to inject a fake input element with a specified name
+	var form = document.createElement("div"),
+		id = "script" + (new Date()).getTime(),
+		root = document.documentElement;
+
+	form.innerHTML = "<a name='" + id + "'/>";
+
+	// Inject it into the root element, check its status, and remove it quickly
+	root.insertBefore( form, root.firstChild );
+
+	// The workaround has to do additional checks after a getElementById
+	// Which slows things down for other browsers (hence the branching)
+	if ( document.getElementById( id ) ) {
+		Expr.find.ID = function( match, context, isXML ) {
+			if ( typeof context.getElementById !== "undefined" && !isXML ) {
+				var m = context.getElementById(match[1]);
+
+				return m ?
+					m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
+						[m] :
+						undefined :
+					[];
+			}
+		};
+
+		Expr.filter.ID = function( elem, match ) {
+			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+
+			return elem.nodeType === 1 && node && node.nodeValue === match;
+		};
+	}
+
+	root.removeChild( form );
+
+	// release memory in IE
+	root = form = null;
+})();
+
+(function(){
+	// Check to see if the browser returns only elements
+	// when doing getElementsByTagName("*")
+
+	// Create a fake element
+	var div = document.createElement("div");
+	div.appendChild( document.createComment("") );
+
+	// Make sure no comments are found
+	if ( div.getElementsByTagName("*").length > 0 ) {
+		Expr.find.TAG = function( match, context ) {
+			var results = context.getElementsByTagName( match[1] );
+
+			// Filter out possible comments
+			if ( match[1] === "*" ) {
+				var tmp = [];
+
+				for ( var i = 0; results[i]; i++ ) {
+					if ( results[i].nodeType === 1 ) {
+						tmp.push( results[i] );
+					}
+				}
+
+				results = tmp;
+			}
+
+			return results;
+		};
+	}
+
+	// Check to see if an attribute returns normalized href attributes
+	div.innerHTML = "<a href='#'></a>";
+
+	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+			div.firstChild.getAttribute("href") !== "#" ) {
+
+		Expr.attrHandle.href = function( elem ) {
+			return elem.getAttribute( "href", 2 );
+		};
+	}
+
+	// release memory in IE
+	div = null;
+})();
+
+if ( document.querySelectorAll ) {
+	(function(){
+		var oldSizzle = Sizzle,
+			div = document.createElement("div"),
+			id = "__sizzle__";
+
+		div.innerHTML = "<p class='TEST'></p>";
+
+		// Safari can't handle uppercase or unicode characters when
+		// in quirks mode.
+		if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+			return;
+		}
+	
+		Sizzle = function( query, context, extra, seed ) {
+			context = context || document;
+
+			// Make sure that attribute selectors are quoted
+			query = query.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
+
+			// Only use querySelectorAll on non-XML documents
+			// (ID selectors don't work in non-HTML documents)
+			if ( !seed && !Sizzle.isXML(context) ) {
+				if ( context.nodeType === 9 ) {
+					try {
+						return makeArray( context.querySelectorAll(query), extra );
+					} catch(qsaError) {}
+
+				// qSA works strangely on Element-rooted queries
+				// We can work around this by specifying an extra ID on the root
+				// and working up from there (Thanks to Andrew Dupont for the technique)
+				// IE 8 doesn't work on object elements
+				} else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+					var old = context.getAttribute( "id" ),
+						nid = old || id;
+
+					if ( !old ) {
+						context.setAttribute( "id", nid );
+					}
+
+					try {
+						return makeArray( context.querySelectorAll( "#" + nid + " " + query ), extra );
+
+					} catch(pseudoError) {
+					} finally {
+						if ( !old ) {
+							context.removeAttribute( "id" );
+						}
+					}
+				}
+			}
+		
+			return oldSizzle(query, context, extra, seed);
+		};
+
+		for ( var prop in oldSizzle ) {
+			Sizzle[ prop ] = oldSizzle[ prop ];
+		}
+
+		// release memory in IE
+		div = null;
+	})();
+}
+
+(function(){
+	var html = document.documentElement,
+		matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector,
+		pseudoWorks = false;
+
+	try {
+		// This should fail with an exception
+		// Gecko does not error, returns false instead
+		matches.call( document.documentElement, "[test!='']:sizzle" );
+	
+	} catch( pseudoError ) {
+		pseudoWorks = true;
+	}
+
+	if ( matches ) {
+		Sizzle.matchesSelector = function( node, expr ) {
+			// Make sure that attribute selectors are quoted
+			expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
+
+			if ( !Sizzle.isXML( node ) ) {
+				try { 
+					if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
+						return matches.call( node, expr );
+					}
+				} catch(e) {}
+			}
+
+			return Sizzle(expr, null, null, [node]).length > 0;
+		};
+	}
+})();
+
+(function(){
+	var div = document.createElement("div");
+
+	div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+	// Opera can't find a second classname (in 9.6)
+	// Also, make sure that getElementsByClassName actually exists
+	if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
+		return;
+	}
+
+	// Safari caches class attributes, doesn't catch changes (in 3.2)
+	div.lastChild.className = "e";
+
+	if ( div.getElementsByClassName("e").length === 1 ) {
+		return;
+	}
+	
+	Expr.order.splice(1, 0, "CLASS");
+	Expr.find.CLASS = function( match, context, isXML ) {
+		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+			return context.getElementsByClassName(match[1]);
+		}
+	};
+
+	// release memory in IE
+	div = null;
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+		var elem = checkSet[i];
+
+		if ( elem ) {
+			var match = false;
+
+			elem = elem[dir];
+
+			while ( elem ) {
+				if ( elem.sizcache === doneName ) {
+					match = checkSet[elem.sizset];
+					break;
+				}
+
+				if ( elem.nodeType === 1 && !isXML ){
+					elem.sizcache = doneName;
+					elem.sizset = i;
+				}
+
+				if ( elem.nodeName.toLowerCase() === cur ) {
+					match = elem;
+					break;
+				}
+
+				elem = elem[dir];
+			}
+
+			checkSet[i] = match;
+		}
+	}
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+		var elem = checkSet[i];
+
+		if ( elem ) {
+			var match = false;
+			
+			elem = elem[dir];
+
+			while ( elem ) {
+				if ( elem.sizcache === doneName ) {
+					match = checkSet[elem.sizset];
+					break;
+				}
+
+				if ( elem.nodeType === 1 ) {
+					if ( !isXML ) {
+						elem.sizcache = doneName;
+						elem.sizset = i;
+					}
+
+					if ( typeof cur !== "string" ) {
+						if ( elem === cur ) {
+							match = true;
+							break;
+						}
+
+					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+						match = elem;
+						break;
+					}
+				}
+
+				elem = elem[dir];
+			}
+
+			checkSet[i] = match;
+		}
+	}
+}
+
+if ( document.documentElement.contains ) {
+	Sizzle.contains = function( a, b ) {
+		return a !== b && (a.contains ? a.contains(b) : true);
+	};
+
+} else if ( document.documentElement.compareDocumentPosition ) {
+	Sizzle.contains = function( a, b ) {
+		return !!(a.compareDocumentPosition(b) & 16);
+	};
+
+} else {
+	Sizzle.contains = function() {
+		return false;
+	};
+}
+
+Sizzle.isXML = function( elem ) {
+	// documentElement is verified for cases where it doesn't yet exist
+	// (such as loading iframes in IE - #4833) 
+	var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
+
+	return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+var posProcess = function( selector, context ) {
+	var match,
+		tmpSet = [],
+		later = "",
+		root = context.nodeType ? [context] : context;
+
+	// Position selectors must be done after the filter
+	// And so must :not(positional) so we move all PSEUDOs to the end
+	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+		later += match[0];
+		selector = selector.replace( Expr.match.PSEUDO, "" );
+	}
+
+	selector = Expr.relative[selector] ? selector + "*" : selector;
+
+	for ( var i = 0, l = root.length; i < l; i++ ) {
+		Sizzle( selector, root[i], tmpSet );
+	}
+
+	return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+})();
+
+
+var runtil = /Until$/,
+	rparentsprev = /^(?:parents|prevUntil|prevAll)/,
+	// Note: This RegExp should be improved, or likely pulled from Sizzle
+	rmultiselector = /,/,
+	isSimple = /^.[^:#\[\.,]*$/,
+	slice = Array.prototype.slice,
+	POS = jQuery.expr.match.POS;
+
+jQuery.fn.extend({
+	find: function( selector ) {
+		var ret = this.pushStack( "", "find", selector ),
+			length = 0;
+
+		for ( var i = 0, l = this.length; i < l; i++ ) {
+			length = ret.length;
+			jQuery.find( selector, this[i], ret );
+
+			if ( i > 0 ) {
+				// Make sure that the results are unique
+				for ( var n = length; n < ret.length; n++ ) {
+					for ( var r = 0; r < length; r++ ) {
+						if ( ret[r] === ret[n] ) {
+							ret.splice(n--, 1);
+							break;
+						}
+					}
+				}
+			}
+		}
+
+		return ret;
+	},
+
+	has: function( target ) {
+		var targets = jQuery( target );
+		return this.filter(function() {
+			for ( var i = 0, l = targets.length; i < l; i++ ) {
+				if ( jQuery.contains( this, targets[i] ) ) {
+					return true;
+				}
+			}
+		});
+	},
+
+	not: function( selector ) {
+		return this.pushStack( winnow(this, selector, false), "not", selector);
+	},
+
+	filter: function( selector ) {
+		return this.pushStack( winnow(this, selector, true), "filter", selector );
+	},
+	
+	is: function( selector ) {
+		return !!selector && jQuery.filter( selector, this ).length > 0;
+	},
+
+	closest: function( selectors, context ) {
+		var ret = [], i, l, cur = this[0];
+
+		if ( jQuery.isArray( selectors ) ) {
+			var match, selector,
+				matches = {},
+				level = 1;
+
+			if ( cur && selectors.length ) {
+				for ( i = 0, l = selectors.length; i < l; i++ ) {
+					selector = selectors[i];
+
+					if ( !matches[selector] ) {
+						matches[selector] = jQuery.expr.match.POS.test( selector ) ? 
+							jQuery( selector, context || this.context ) :
+							selector;
+					}
+				}
+
+				while ( cur && cur.ownerDocument && cur !== context ) {
+					for ( selector in matches ) {
+						match = matches[selector];
+
+						if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
+							ret.push({ selector: selector, elem: cur, level: level });
+						}
+					}
+
+					cur = cur.parentNode;
+					level++;
+				}
+			}
+
+			return ret;
+		}
+
+		var pos = POS.test( selectors ) ? 
+			jQuery( selectors, context || this.context ) : null;
+
+		for ( i = 0, l = this.length; i < l; i++ ) {
+			cur = this[i];
+
+			while ( cur ) {
+				if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
+					ret.push( cur );
+					break;
+
+				} else {
+					cur = cur.parentNode;
+					if ( !cur || !cur.ownerDocument || cur === context ) {
+						break;
+					}
+				}
+			}
+		}
+
+		ret = ret.length > 1 ? jQuery.unique(ret) : ret;
+		
+		return this.pushStack( ret, "closest", selectors );
+	},
+	
+	// Determine the position of an element within
+	// the matched set of elements
+	index: function( elem ) {
+		if ( !elem || typeof elem === "string" ) {
+			return jQuery.inArray( this[0],
+				// If it receives a string, the selector is used
+				// If it receives nothing, the siblings are used
+				elem ? jQuery( elem ) : this.parent().children() );
+		}
+		// Locate the position of the desired element
+		return jQuery.inArray(
+			// If it receives a jQuery object, the first element is used
+			elem.jquery ? elem[0] : elem, this );
+	},
+
+	add: function( selector, context ) {
+		var set = typeof selector === "string" ?
+				jQuery( selector, context || this.context ) :
+				jQuery.makeArray( selector ),
+			all = jQuery.merge( this.get(), set );
+
+		return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
+			all :
+			jQuery.unique( all ) );
+	},
+
+	andSelf: function() {
+		return this.add( this.prevObject );
+	}
+});
+
+// A painfully simple check to see if an element is disconnected
+// from a document (should be improved, where feasible).
+function isDisconnected( node ) {
+	return !node || !node.parentNode || node.parentNode.nodeType === 11;
+}
+
+jQuery.each({
+	parent: function( elem ) {
+		var parent = elem.parentNode;
+		return parent && parent.nodeType !== 11 ? parent : null;
+	},
+	parents: function( elem ) {
+		return jQuery.dir( elem, "parentNode" );
+	},
+	parentsUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "parentNode", until );
+	},
+	next: function( elem ) {
+		return jQuery.nth( elem, 2, "nextSibling" );
+	},
+	prev: function( elem ) {
+		return jQuery.nth( elem, 2, "previousSibling" );
+	},
+	nextAll: function( elem ) {
+		return jQuery.dir( elem, "nextSibling" );
+	},
+	prevAll: function( elem ) {
+		return jQuery.dir( elem, "previousSibling" );
+	},
+	nextUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "nextSibling", until );
+	},
+	prevUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "previousSibling", until );
+	},
+	siblings: function( elem ) {
+		return jQuery.sibling( elem.parentNode.firstChild, elem );
+	},
+	children: function( elem ) {
+		return jQuery.sibling( elem.firstChild );
+	},
+	contents: function( elem ) {
+		return jQuery.nodeName( elem, "iframe" ) ?
+			elem.contentDocument || elem.contentWindow.document :
+			jQuery.makeArray( elem.childNodes );
+	}
+}, function( name, fn ) {
+	jQuery.fn[ name ] = function( until, selector ) {
+		var ret = jQuery.map( this, fn, until );
+		
+		if ( !runtil.test( name ) ) {
+			selector = until;
+		}
+
+		if ( selector && typeof selector === "string" ) {
+			ret = jQuery.filter( selector, ret );
+		}
+
+		ret = this.length > 1 ? jQuery.unique( ret ) : ret;
+
+		if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
+			ret = ret.reverse();
+		}
+
+		return this.pushStack( ret, name, slice.call(arguments).join(",") );
+	};
+});
+
+jQuery.extend({
+	filter: function( expr, elems, not ) {
+		if ( not ) {
+			expr = ":not(" + expr + ")";
+		}
+
+		return elems.length === 1 ?
+			jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
+			jQuery.find.matches(expr, elems);
+	},
+	
+	dir: function( elem, dir, until ) {
+		var matched = [],
+			cur = elem[ dir ];
+
+		while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+			if ( cur.nodeType === 1 ) {
+				matched.push( cur );
+			}
+			cur = cur[dir];
+		}
+		return matched;
+	},
+
+	nth: function( cur, result, dir, elem ) {
+		result = result || 1;
+		var num = 0;
+
+		for ( ; cur; cur = cur[dir] ) {
+			if ( cur.nodeType === 1 && ++num === result ) {
+				break;
+			}
+		}
+
+		return cur;
+	},
+
+	sibling: function( n, elem ) {
+		var r = [];
+
+		for ( ; n; n = n.nextSibling ) {
+			if ( n.nodeType === 1 && n !== elem ) {
+				r.push( n );
+			}
+		}
+
+		return r;
+	}
+});
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, keep ) {
+	if ( jQuery.isFunction( qualifier ) ) {
+		return jQuery.grep(elements, function( elem, i ) {
+			var retVal = !!qualifier.call( elem, i, elem );
+			return retVal === keep;
+		});
+
+	} else if ( qualifier.nodeType ) {
+		return jQuery.grep(elements, function( elem, i ) {
+			return (elem === qualifier) === keep;
+		});
+
+	} else if ( typeof qualifier === "string" ) {
+		var filtered = jQuery.grep(elements, function( elem ) {
+			return elem.nodeType === 1;
+		});
+
+		if ( isSimple.test( qualifier ) ) {
+			return jQuery.filter(qualifier, filtered, !keep);
+		} else {
+			qualifier = jQuery.filter( qualifier, filtered );
+		}
+	}
+
+	return jQuery.grep(elements, function( elem, i ) {
+		return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
+	});
+}
+
+
+
+
+var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
+	rleadingWhitespace = /^\s+/,
+	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
+	rtagName = /<([\w:]+)/,
+	rtbody = /<tbody/i,
+	rhtml = /<|&#?\w+;/,
+	rnocache = /<(?:script|object|embed|option|style)/i,
+	// checked="checked" or checked (html5)
+	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+	raction = /\=([^="'>\s]+\/)>/g,
+	wrapMap = {
+		option: [ 1, "<select multiple='multiple'>", "</select>" ],
+		legend: [ 1, "<fieldset>", "</fieldset>" ],
+		thead: [ 1, "<table>", "</table>" ],
+		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+		area: [ 1, "<map>", "</map>" ],
+		_default: [ 0, "", "" ]
+	};
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// IE can't serialize <link> and <script> tags normally
+if ( !jQuery.support.htmlSerialize ) {
+	wrapMap._default = [ 1, "div<div>", "</div>" ];
+}
+
+jQuery.fn.extend({
+	text: function( text ) {
+		if ( jQuery.isFunction(text) ) {
+			return this.each(function(i) {
+				var self = jQuery( this );
+
+				self.text( text.call(this, i, self.text()) );
+			});
+		}
+
+		if ( typeof text !== "object" && text !== undefined ) {
+			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+		}
+
+		return jQuery.text( this );
+	},
+
+	wrapAll: function( html ) {
+		if ( jQuery.isFunction( html ) ) {
+			return this.each(function(i) {
+				jQuery(this).wrapAll( html.call(this, i) );
+			});
+		}
+
+		if ( this[0] ) {
+			// The elements to wrap the target around
+			var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+			if ( this[0].parentNode ) {
+				wrap.insertBefore( this[0] );
+			}
+
+			wrap.map(function() {
+				var elem = this;
+
+				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+					elem = elem.firstChild;
+				}
+
+				return elem;
+			}).append(this);
+		}
+
+		return this;
+	},
+
+	wrapInner: function( html ) {
+		if ( jQuery.isFunction( html ) ) {
+			return this.each(function(i) {
+				jQuery(this).wrapInner( html.call(this, i) );
+			});
+		}
+
+		return this.each(function() {
+			var self = jQuery( this ),
+				contents = self.contents();
+
+			if ( contents.length ) {
+				contents.wrapAll( html );
+
+			} else {
+				self.append( html );
+			}
+		});
+	},
+
+	wrap: function( html ) {
+		return this.each(function() {
+			jQuery( this ).wrapAll( html );
+		});
+	},
+
+	unwrap: function() {
+		return this.parent().each(function() {
+			if ( !jQuery.nodeName( this, "body" ) ) {
+				jQuery( this ).replaceWith( this.childNodes );
+			}
+		}).end();
+	},
+
+	append: function() {
+		return this.domManip(arguments, true, function( elem ) {
+			if ( this.nodeType === 1 ) {
+				this.appendChild( elem );
+			}
+		});
+	},
+
+	prepend: function() {
+		return this.domManip(arguments, true, function( elem ) {
+			if ( this.nodeType === 1 ) {
+				this.insertBefore( elem, this.firstChild );
+			}
+		});
+	},
+
+	before: function() {
+		if ( this[0] && this[0].parentNode ) {
+			return this.domManip(arguments, false, function( elem ) {
+				this.parentNode.insertBefore( elem, this );
+			});
+		} else if ( arguments.length ) {
+			var set = jQuery(arguments[0]);
+			set.push.apply( set, this.toArray() );
+			return this.pushStack( set, "before", arguments );
+		}
+	},
+
+	after: function() {
+		if ( this[0] && this[0].parentNode ) {
+			return this.domManip(arguments, false, function( elem ) {
+				this.parentNode.insertBefore( elem, this.nextSibling );
+			});
+		} else if ( arguments.length ) {
+			var set = this.pushStack( this, "after", arguments );
+			set.push.apply( set, jQuery(arguments[0]).toArray() );
+			return set;
+		}
+	},
+	
+	// keepData is for internal use only--do not document
+	remove: function( selector, keepData ) {
+		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+			if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
+				if ( !keepData && elem.nodeType === 1 ) {
+					jQuery.cleanData( elem.getElementsByTagName("*") );
+					jQuery.cleanData( [ elem ] );
+				}
+
+				if ( elem.parentNode ) {
+					 elem.parentNode.removeChild( elem );
+				}
+			}
+		}
+		
+		return this;
+	},
+
+	empty: function() {
+		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+			// Remove element nodes and prevent memory leaks
+			if ( elem.nodeType === 1 ) {
+				jQuery.cleanData( elem.getElementsByTagName("*") );
+			}
+
+			// Remove any remaining nodes
+			while ( elem.firstChild ) {
+				elem.removeChild( elem.firstChild );
+			}
+		}
+		
+		return this;
+	},
+
+	clone: function( events ) {
+		// Do the clone
+		var ret = this.map(function() {
+			if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
+				// IE copies events bound via attachEvent when
+				// using cloneNode. Calling detachEvent on the
+				// clone will also remove the events from the orignal
+				// In order to get around this, we use innerHTML.
+				// Unfortunately, this means some modifications to
+				// attributes in IE that are actually only stored
+				// as properties will not be copied (such as the
+				// the name attribute on an input).
+				var html = this.outerHTML,
+					ownerDocument = this.ownerDocument;
+
+				if ( !html ) {
+					var div = ownerDocument.createElement("div");
+					div.appendChild( this.cloneNode(true) );
+					html = div.innerHTML;
+				}
+
+				return jQuery.clean([html.replace(rinlinejQuery, "")
+					// Handle the case in IE 8 where action=/test/> self-closes a tag
+					.replace(raction, '="$1">')
+					.replace(rleadingWhitespace, "")], ownerDocument)[0];
+			} else {
+				return this.cloneNode(true);
+			}
+		});
+
+		// Copy the events from the original to the clone
+		if ( events === true ) {
+			cloneCopyEvent( this, ret );
+			cloneCopyEvent( this.find("*"), ret.find("*") );
+		}
+
+		// Return the cloned set
+		return ret;
+	},
+
+	html: function( value ) {
+		if ( value === undefined ) {
+			return this[0] && this[0].nodeType === 1 ?
+				this[0].innerHTML.replace(rinlinejQuery, "") :
+				null;
+
+		// See if we can take a shortcut and just use innerHTML
+		} else if ( typeof value === "string" && !rnocache.test( value ) &&
+			(jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
+			!wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
+
+			value = value.replace(rxhtmlTag, "<$1></$2>");
+
+			try {
+				for ( var i = 0, l = this.length; i < l; i++ ) {
+					// Remove element nodes and prevent memory leaks
+					if ( this[i].nodeType === 1 ) {
+						jQuery.cleanData( this[i].getElementsByTagName("*") );
+						this[i].innerHTML = value;
+					}
+				}
+
+			// If using innerHTML throws an exception, use the fallback method
+			} catch(e) {
+				this.empty().append( value );
+			}
+
+		} else if ( jQuery.isFunction( value ) ) {
+			this.each(function(i){
+				var self = jQuery( this );
+
+				self.html( value.call(this, i, self.html()) );
+			});
+
+		} else {
+			this.empty().append( value );
+		}
+
+		return this;
+	},
+
+	replaceWith: function( value ) {
+		if ( this[0] && this[0].parentNode ) {
+			// Make sure that the elements are removed from the DOM before they are inserted
+			// this can help fix replacing a parent with child elements
+			if ( jQuery.isFunction( value ) ) {
+				return this.each(function(i) {
+					var self = jQuery(this), old = self.html();
+					self.replaceWith( value.call( this, i, old ) );
+				});
+			}
+
+			if ( typeof value !== "string" ) {
+				value = jQuery( value ).detach();
+			}
+
+			return this.each(function() {
+				var next = this.nextSibling,
+					parent = this.parentNode;
+
+				jQuery( this ).remove();
+
+				if ( next ) {
+					jQuery(next).before( value );
+				} else {
+					jQuery(parent).append( value );
+				}
+			});
+		} else {
+			return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
+		}
+	},
+
+	detach: function( selector ) {
+		return this.remove( selector, true );
+	},
+
+	domManip: function( args, table, callback ) {
+		var results, first, fragment, parent,
+			value = args[0],
+			scripts = [];
+
+		// We can't cloneNode fragments that contain checked, in WebKit
+		if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
+			return this.each(function() {
+				jQuery(this).domManip( args, table, callback, true );
+			});
+		}
+
+		if ( jQuery.isFunction(value) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				args[0] = value.call(this, i, table ? self.html() : undefined);
+				self.domManip( args, table, callback );
+			});
+		}
+
+		if ( this[0] ) {
+			parent = value && value.parentNode;
+
+			// If we're in a fragment, just use that instead of building a new one
+			if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
+				results = { fragment: parent };
+
+			} else {
+				results = jQuery.buildFragment( args, this, scripts );
+			}
+			
+			fragment = results.fragment;
+			
+			if ( fragment.childNodes.length === 1 ) {
+				first = fragment = fragment.firstChild;
+			} else {
+				first = fragment.firstChild;
+			}
+
+			if ( first ) {
+				table = table && jQuery.nodeName( first, "tr" );
+
+				for ( var i = 0, l = this.length; i < l; i++ ) {
+					callback.call(
+						table ?
+							root(this[i], first) :
+							this[i],
+						i > 0 || results.cacheable || this.length > 1  ?
+							fragment.cloneNode(true) :
+							fragment
+					);
+				}
+			}
+
+			if ( scripts.length ) {
+				jQuery.each( scripts, evalScript );
+			}
+		}
+
+		return this;
+	}
+});
+
+function root( elem, cur ) {
+	return jQuery.nodeName(elem, "table") ?
+		(elem.getElementsByTagName("tbody")[0] ||
+		elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+		elem;
+}
+
+function cloneCopyEvent(orig, ret) {
+	var i = 0;
+
+	ret.each(function() {
+		if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
+			return;
+		}
+
+		var oldData = jQuery.data( orig[i++] ),
+			curData = jQuery.data( this, oldData ),
+			events = oldData && oldData.events;
+
+		if ( events ) {
+			delete curData.handle;
+			curData.events = {};
+
+			for ( var type in events ) {
+				for ( var handler in events[ type ] ) {
+					jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
+				}
+			}
+		}
+	});
+}
+
+jQuery.buildFragment = function( args, nodes, scripts ) {
+	var fragment, cacheable, cacheresults,
+		doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
+
+	// Only cache "small" (1/2 KB) strings that are associated with the main document
+	// Cloning options loses the selected state, so don't cache them
+	// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
+	// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
+	if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
+		!rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
+
+		cacheable = true;
+		cacheresults = jQuery.fragments[ args[0] ];
+		if ( cacheresults ) {
+			if ( cacheresults !== 1 ) {
+				fragment = cacheresults;
+			}
+		}
+	}
+
+	if ( !fragment ) {
+		fragment = doc.createDocumentFragment();
+		jQuery.clean( args, doc, fragment, scripts );
+	}
+
+	if ( cacheable ) {
+		jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
+	}
+
+	return { fragment: fragment, cacheable: cacheable };
+};
+
+jQuery.fragments = {};
+
+jQuery.each({
+	appendTo: "append",
+	prependTo: "prepend",
+	insertBefore: "before",
+	insertAfter: "after",
+	replaceAll: "replaceWith"
+}, function( name, original ) {
+	jQuery.fn[ name ] = function( selector ) {
+		var ret = [],
+			insert = jQuery( selector ),
+			parent = this.length === 1 && this[0].parentNode;
+		
+		if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
+			insert[ original ]( this[0] );
+			return this;
+			
+		} else {
+			for ( var i = 0, l = insert.length; i < l; i++ ) {
+				var elems = (i > 0 ? this.clone(true) : this).get();
+				jQuery( insert[i] )[ original ]( elems );
+				ret = ret.concat( elems );
+			}
+		
+			return this.pushStack( ret, name, insert.selector );
+		}
+	};
+});
+
+jQuery.extend({
+	clean: function( elems, context, fragment, scripts ) {
+		context = context || document;
+
+		// !context.createElement fails in IE with an error but returns typeof 'object'
+		if ( typeof context.createElement === "undefined" ) {
+			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+		}
+
+		var ret = [];
+
+		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+			if ( typeof elem === "number" ) {
+				elem += "";
+			}
+
+			if ( !elem ) {
+				continue;
+			}
+
+			// Convert html string into DOM nodes
+			if ( typeof elem === "string" && !rhtml.test( elem ) ) {
+				elem = context.createTextNode( elem );
+
+			} else if ( typeof elem === "string" ) {
+				// Fix "XHTML"-style tags in all browsers
+				elem = elem.replace(rxhtmlTag, "<$1></$2>");
+
+				// Trim whitespace, otherwise indexOf won't work as expected
+				var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
+					wrap = wrapMap[ tag ] || wrapMap._default,
+					depth = wrap[0],
+					div = context.createElement("div");
+
+				// Go to html and back, then peel off extra wrappers
+				div.innerHTML = wrap[1] + elem + wrap[2];
+
+				// Move to the right depth
+				while ( depth-- ) {
+					div = div.lastChild;
+				}
+
+				// Remove IE's autoinserted <tbody> from table fragments
+				if ( !jQuery.support.tbody ) {
+
+					// String was a <table>, *may* have spurious <tbody>
+					var hasBody = rtbody.test(elem),
+						tbody = tag === "table" && !hasBody ?
+							div.firstChild && div.firstChild.childNodes :
+
+							// String was a bare <thead> or <tfoot>
+							wrap[1] === "<table>" && !hasBody ?
+								div.childNodes :
+								[];
+
+					for ( var j = tbody.length - 1; j >= 0 ; --j ) {
+						if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
+							tbody[ j ].parentNode.removeChild( tbody[ j ] );
+						}
+					}
+
+				}
+
+				// IE completely kills leading whitespace when innerHTML is used
+				if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+					div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
+				}
+
+				elem = div.childNodes;
+			}
+
+			if ( elem.nodeType ) {
+				ret.push( elem );
+			} else {
+				ret = jQuery.merge( ret, elem );
+			}
+		}
+
+		if ( fragment ) {
+			for ( i = 0; ret[i]; i++ ) {
+				if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+					scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+				
+				} else {
+					if ( ret[i].nodeType === 1 ) {
+						ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
+					}
+					fragment.appendChild( ret[i] );
+				}
+			}
+		}
+
+		return ret;
+	},
+	
+	cleanData: function( elems ) {
+		var data, id, cache = jQuery.cache,
+			special = jQuery.event.special,
+			deleteExpando = jQuery.support.deleteExpando;
+		
+		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+			if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+				continue;
+			}
+
+			id = elem[ jQuery.expando ];
+			
+			if ( id ) {
+				data = cache[ id ];
+				
+				if ( data && data.events ) {
+					for ( var type in data.events ) {
+						if ( special[ type ] ) {
+							jQuery.event.remove( elem, type );
+
+						} else {
+							jQuery.removeEvent( elem, type, data.handle );
+						}
+					}
+				}
+				
+				if ( deleteExpando ) {
+					delete elem[ jQuery.expando ];
+
+				} else if ( elem.removeAttribute ) {
+					elem.removeAttribute( jQuery.expando );
+				}
+				
+				delete cache[ id ];
+			}
+		}
+	}
+});
+
+function evalScript( i, elem ) {
+	if ( elem.src ) {
+		jQuery.ajax({
+			url: elem.src,
+			async: false,
+			dataType: "script"
+		});
+	} else {
+		jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+	}
+
+	if ( elem.parentNode ) {
+		elem.parentNode.removeChild( elem );
+	}
+}
+
+
+
+
+var ralpha = /alpha\([^)]*\)/i,
+	ropacity = /opacity=([^)]*)/,
+	rdashAlpha = /-([a-z])/ig,
+	rupper = /([A-Z])/g,
+	rnumpx = /^-?\d+(?:px)?$/i,
+	rnum = /^-?\d/,
+
+	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+	cssWidth = [ "Left", "Right" ],
+	cssHeight = [ "Top", "Bottom" ],
+	curCSS,
+
+	getComputedStyle,
+	currentStyle,
+
+	fcamelCase = function( all, letter ) {
+		return letter.toUpperCase();
+	};
+
+jQuery.fn.css = function( name, value ) {
+	// Setting 'undefined' is a no-op
+	if ( arguments.length === 2 && value === undefined ) {
+		return this;
+	}
+
+	return jQuery.access( this, name, value, true, function( elem, name, value ) {
+		return value !== undefined ?
+			jQuery.style( elem, name, value ) :
+			jQuery.css( elem, name );
+	});
+};
+
+jQuery.extend({
+	// Add in style property hooks for overriding the default
+	// behavior of getting and setting a style property
+	cssHooks: {
+		opacity: {
+			get: function( elem, computed ) {
+				if ( computed ) {
+					// We should always get a number back from opacity
+					var ret = curCSS( elem, "opacity", "opacity" );
+					return ret === "" ? "1" : ret;
+
+				} else {
+					return elem.style.opacity;
+				}
+			}
+		}
+	},
+
+	// Exclude the following css properties to add px
+	cssNumber: {
+		"zIndex": true,
+		"fontWeight": true,
+		"opacity": true,
+		"zoom": true,
+		"lineHeight": true
+	},
+
+	// Add in properties whose names you wish to fix before
+	// setting or getting the value
+	cssProps: {
+		// normalize float css property
+		"float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
+	},
+
+	// Get and set the style property on a DOM Node
+	style: function( elem, name, value, extra ) {
+		// Don't set styles on text and comment nodes
+		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+			return;
+		}
+
+		// Make sure that we're working with the right name
+		var ret, origName = jQuery.camelCase( name ),
+			style = elem.style, hooks = jQuery.cssHooks[ origName ];
+
+		name = jQuery.cssProps[ origName ] || origName;
+
+		// Check if we're setting a value
+		if ( value !== undefined ) {
+			// Make sure that NaN and null values aren't set. See: #7116
+			if ( typeof value === "number" && isNaN( value ) || value == null ) {
+				return;
+			}
+
+			// If a number was passed in, add 'px' to the (except for certain CSS properties)
+			if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) {
+				value += "px";
+			}
+
+			// If a hook was provided, use that value, otherwise just set the specified value
+			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
+				// Wrapped to prevent IE from throwing errors when 'invalid' values are provided
+				// Fixes bug #5509
+				try {
+					style[ name ] = value;
+				} catch(e) {}
+			}
+
+		} else {
+			// If a hook was provided get the non-computed value from there
+			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
+				return ret;
+			}
+
+			// Otherwise just get the value from the style object
+			return style[ name ];
+		}
+	},
+
+	css: function( elem, name, extra ) {
+		// Make sure that we're working with the right name
+		var ret, origName = jQuery.camelCase( name ),
+			hooks = jQuery.cssHooks[ origName ];
+
+		name = jQuery.cssProps[ origName ] || origName;
+
+		// If a hook was provided get the computed value from there
+		if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
+			return ret;
+
+		// Otherwise, if a way to get the computed value exists, use that
+		} else if ( curCSS ) {
+			return curCSS( elem, name, origName );
+		}
+	},
+
+	// A method for quickly swapping in/out CSS properties to get correct calculations
+	swap: function( elem, options, callback ) {
+		var old = {};
+
+		// Remember the old values, and insert the new ones
+		for ( var name in options ) {
+			old[ name ] = elem.style[ name ];
+			elem.style[ name ] = options[ name ];
+		}
+
+		callback.call( elem );
+
+		// Revert the old values
+		for ( name in options ) {
+			elem.style[ name ] = old[ name ];
+		}
+	},
+
+	camelCase: function( string ) {
+		return string.replace( rdashAlpha, fcamelCase );
+	}
+});
+
+// DEPRECATED, Use jQuery.css() instead
+jQuery.curCSS = jQuery.css;
+
+jQuery.each(["height", "width"], function( i, name ) {
+	jQuery.cssHooks[ name ] = {
+		get: function( elem, computed, extra ) {
+			var val;
+
+			if ( computed ) {
+				if ( elem.offsetWidth !== 0 ) {
+					val = getWH( elem, name, extra );
+
+				} else {
+					jQuery.swap( elem, cssShow, function() {
+						val = getWH( elem, name, extra );
+					});
+				}
+
+				if ( val <= 0 ) {
+					val = curCSS( elem, name, name );
+
+					if ( val === "0px" && currentStyle ) {
+						val = currentStyle( elem, name, name );
+					}
+
+					if ( val != null ) {
+						// Should return "auto" instead of 0, use 0 for
+						// temporary backwards-compat
+						return val === "" || val === "auto" ? "0px" : val;
+					}
+				}
+
+				if ( val < 0 || val == null ) {
+					val = elem.style[ name ];
+
+					// Should return "auto" instead of 0, use 0 for
+					// temporary backwards-compat
+					return val === "" || val === "auto" ? "0px" : val;
+				}
+
+				return typeof val === "string" ? val : val + "px";
+			}
+		},
+
+		set: function( elem, value ) {
+			if ( rnumpx.test( value ) ) {
+				// ignore negative width and height values #1599
+				value = parseFloat(value);
+
+				if ( value >= 0 ) {
+					return value + "px";
+				}
+
+			} else {
+				return value;
+			}
+		}
+	};
+});
+
+if ( !jQuery.support.opacity ) {
+	jQuery.cssHooks.opacity = {
+		get: function( elem, computed ) {
+			// IE uses filters for opacity
+			return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ?
+				(parseFloat(RegExp.$1) / 100) + "" :
+				computed ? "1" : "";
+		},
+
+		set: function( elem, value ) {
+			var style = elem.style;
+
+			// IE has trouble with opacity if it does not have layout
+			// Force it by setting the zoom level
+			style.zoom = 1;
+
+			// Set the alpha filter to set the opacity
+			var opacity = jQuery.isNaN(value) ?
+				"" :
+				"alpha(opacity=" + value * 100 + ")",
+				filter = style.filter || "";
+
+			style.filter = ralpha.test(filter) ?
+				filter.replace(ralpha, opacity) :
+				style.filter + ' ' + opacity;
+		}
+	};
+}
+
+if ( document.defaultView && document.defaultView.getComputedStyle ) {
+	getComputedStyle = function( elem, newName, name ) {
+		var ret, defaultView, computedStyle;
+
+		name = name.replace( rupper, "-$1" ).toLowerCase();
+
+		if ( !(defaultView = elem.ownerDocument.defaultView) ) {
+			return undefined;
+		}
+
+		if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
+			ret = computedStyle.getPropertyValue( name );
+			if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
+				ret = jQuery.style( elem, name );
+			}
+		}
+
+		return ret;
+	};
+}
+
+if ( document.documentElement.currentStyle ) {
+	currentStyle = function( elem, name ) {
+		var left, rsLeft,
+			ret = elem.currentStyle && elem.currentStyle[ name ],
+			style = elem.style;
+
+		// From the awesome hack by Dean Edwards
+		// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+		// If we're not dealing with a regular pixel number
+		// but a number that has a weird ending, we need to convert it to pixels
+		if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
+			// Remember the original values
+			left = style.left;
+			rsLeft = elem.runtimeStyle.left;
+
+			// Put in the new values to get a computed value out
+			elem.runtimeStyle.left = elem.currentStyle.left;
+			style.left = name === "fontSize" ? "1em" : (ret || 0);
+			ret = style.pixelLeft + "px";
+
+			// Revert the changed values
+			style.left = left;
+			elem.runtimeStyle.left = rsLeft;
+		}
+
+		return ret === "" ? "auto" : ret;
+	};
+}
+
+curCSS = getComputedStyle || currentStyle;
+
+function getWH( elem, name, extra ) {
+	var which = name === "width" ? cssWidth : cssHeight,
+		val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
+
+	if ( extra === "border" ) {
+		return val;
+	}
+
+	jQuery.each( which, function() {
+		if ( !extra ) {
+			val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
+		}
+
+		if ( extra === "margin" ) {
+			val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
+
+		} else {
+			val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
+		}
+	});
+
+	return val;
+}
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+	jQuery.expr.filters.hidden = function( elem ) {
+		var width = elem.offsetWidth,
+			height = elem.offsetHeight;
+
+		return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
+	};
+
+	jQuery.expr.filters.visible = function( elem ) {
+		return !jQuery.expr.filters.hidden( elem );
+	};
+}
+
+
+
+
+var jsc = jQuery.now(),
+	rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
+	rselectTextarea = /^(?:select|textarea)/i,
+	rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
+	rnoContent = /^(?:GET|HEAD)$/,
+	rbracket = /\[\]$/,
+	jsre = /\=\?(&|$)/,
+	rquery = /\?/,
+	rts = /([?&])_=[^&]*/,
+	rurl = /^(\w+:)?\/\/([^\/?#]+)/,
+	r20 = /%20/g,
+	rhash = /#.*$/,
+
+	// Keep a copy of the old load method
+	_load = jQuery.fn.load;
+
+jQuery.fn.extend({
+	load: function( url, params, callback ) {
+		if ( typeof url !== "string" && _load ) {
+			return _load.apply( this, arguments );
+
+		// Don't do a request if no elements are being requested
+		} else if ( !this.length ) {
+			return this;
+		}
+
+		var off = url.indexOf(" ");
+		if ( off >= 0 ) {
+			var selector = url.slice(off, url.length);
+			url = url.slice(0, off);
+		}
+
+		// Default to a GET request
+		var type = "GET";
+
+		// If the second parameter was provided
+		if ( params ) {
+			// If it's a function
+			if ( jQuery.isFunction( params ) ) {
+				// We assume that it's the callback
+				callback = params;
+				params = null;
+
+			// Otherwise, build a param string
+			} else if ( typeof params === "object" ) {
+				params = jQuery.param( params, jQuery.ajaxSettings.traditional );
+				type = "POST";
+			}
+		}
+
+		var self = this;
+
+		// Request the remote document
+		jQuery.ajax({
+			url: url,
+			type: type,
+			dataType: "html",
+			data: params,
+			complete: function( res, status ) {
+				// If successful, inject the HTML into all the matched elements
+				if ( status === "success" || status === "notmodified" ) {
+					// See if a selector was specified
+					self.html( selector ?
+						// Create a dummy div to hold the results
+						jQuery("<div>")
+							// inject the contents of the document in, removing the scripts
+							// to avoid any 'Permission Denied' errors in IE
+							.append(res.responseText.replace(rscript, ""))
+
+							// Locate the specified elements
+							.find(selector) :
+
+						// If not, just inject the full result
+						res.responseText );
+				}
+
+				if ( callback ) {
+					self.each( callback, [res.responseText, status, res] );
+				}
+			}
+		});
+
+		return this;
+	},
+
+	serialize: function() {
+		return jQuery.param(this.serializeArray());
+	},
+
+	serializeArray: function() {
+		return this.map(function() {
+			return this.elements ? jQuery.makeArray(this.elements) : this;
+		})
+		.filter(function() {
+			return this.name && !this.disabled &&
+				(this.checked || rselectTextarea.test(this.nodeName) ||
+					rinput.test(this.type));
+		})
+		.map(function( i, elem ) {
+			var val = jQuery(this).val();
+
+			return val == null ?
+				null :
+				jQuery.isArray(val) ?
+					jQuery.map( val, function( val, i ) {
+						return { name: elem.name, value: val };
+					}) :
+					{ name: elem.name, value: val };
+		}).get();
+	}
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
+	jQuery.fn[o] = function( f ) {
+		return this.bind(o, f);
+	};
+});
+
+jQuery.extend({
+	get: function( url, data, callback, type ) {
+		// shift arguments if data argument was omited
+		if ( jQuery.isFunction( data ) ) {
+			type = type || callback;
+			callback = data;
+			data = null;
+		}
+
+		return jQuery.ajax({
+			type: "GET",
+			url: url,
+			data: data,
+			success: callback,
+			dataType: type
+		});
+	},
+
+	getScript: function( url, callback ) {
+		return jQuery.get(url, null, callback, "script");
+	},
+
+	getJSON: function( url, data, callback ) {
+		return jQuery.get(url, data, callback, "json");
+	},
+
+	post: function( url, data, callback, type ) {
+		// shift arguments if data argument was omited
+		if ( jQuery.isFunction( data ) ) {
+			type = type || callback;
+			callback = data;
+			data = {};
+		}
+
+		return jQuery.ajax({
+			type: "POST",
+			url: url,
+			data: data,
+			success: callback,
+			dataType: type
+		});
+	},
+
+	ajaxSetup: function( settings ) {
+		jQuery.extend( jQuery.ajaxSettings, settings );
+	},
+
+	ajaxSettings: {
+		url: location.href,
+		global: true,
+		type: "GET",
+		contentType: "application/x-www-form-urlencoded",
+		processData: true,
+		async: true,
+		/*
+		timeout: 0,
+		data: null,
+		username: null,
+		password: null,
+		traditional: false,
+		*/
+		// This function can be overriden by calling jQuery.ajaxSetup
+		xhr: function() {
+			return new window.XMLHttpRequest();
+		},
+		accepts: {
+			xml: "application/xml, text/xml",
+			html: "text/html",
+			script: "text/javascript, application/javascript",
+			json: "application/json, text/javascript",
+			text: "text/plain",
+			_default: "*/*"
+		}
+	},
+
+	ajax: function( origSettings ) {
+		var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings),
+			jsonp, status, data, type = s.type.toUpperCase(), noContent = rnoContent.test(type);
+
+		s.url = s.url.replace( rhash, "" );
+
+		// Use original (not extended) context object if it was provided
+		s.context = origSettings && origSettings.context != null ? origSettings.context : s;
+
+		// convert data if not already a string
+		if ( s.data && s.processData && typeof s.data !== "string" ) {
+			s.data = jQuery.param( s.data, s.traditional );
+		}
+
+		// Handle JSONP Parameter Callbacks
+		if ( s.dataType === "jsonp" ) {
+			if ( type === "GET" ) {
+				if ( !jsre.test( s.url ) ) {
+					s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+				}
+			} else if ( !s.data || !jsre.test(s.data) ) {
+				s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+			}
+			s.dataType = "json";
+		}
+
+		// Build temporary JSONP function
+		if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
+			jsonp = s.jsonpCallback || ("jsonp" + jsc++);
+
+			// Replace the =? sequence both in the query string and the data
+			if ( s.data ) {
+				s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+			}
+
+			s.url = s.url.replace(jsre, "=" + jsonp + "$1");
+
+			// We need to make sure
+			// that a JSONP style response is executed properly
+			s.dataType = "script";
+
+			// Handle JSONP-style loading
+			var customJsonp = window[ jsonp ];
+
+			window[ jsonp ] = function( tmp ) {
+				if ( jQuery.isFunction( customJsonp ) ) {
+					customJsonp( tmp );
+
+				} else {
+					// Garbage collect
+					window[ jsonp ] = undefined;
+
+					try {
+						delete window[ jsonp ];
+					} catch( jsonpError ) {}
+				}
+
+				data = tmp;
+				jQuery.handleSuccess( s, xhr, status, data );
+				jQuery.handleComplete( s, xhr, status, data );
+				
+				if ( head ) {
+					head.removeChild( script );
+				}
+			};
+		}
+
+		if ( s.dataType === "script" && s.cache === null ) {
+			s.cache = false;
+		}
+
+		if ( s.cache === false && noContent ) {
+			var ts = jQuery.now();
+
+			// try replacing _= if it is there
+			var ret = s.url.replace(rts, "$1_=" + ts);
+
+			// if nothing was replaced, add timestamp to the end
+			s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
+		}
+
+		// If data is available, append data to url for GET/HEAD requests
+		if ( s.data && noContent ) {
+			s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
+		}
+
+		// Watch for a new set of requests
+		if ( s.global && jQuery.active++ === 0 ) {
+			jQuery.event.trigger( "ajaxStart" );
+		}
+
+		// Matches an absolute URL, and saves the domain
+		var parts = rurl.exec( s.url ),
+			remote = parts && (parts[1] && parts[1].toLowerCase() !== location.protocol || parts[2].toLowerCase() !== location.host);
+
+		// If we're requesting a remote document
+		// and trying to load JSON or Script with a GET
+		if ( s.dataType === "script" && type === "GET" && remote ) {
+			var head = document.getElementsByTagName("head")[0] || document.documentElement;
+			var script = document.createElement("script");
+			if ( s.scriptCharset ) {
+				script.charset = s.scriptCharset;
+			}
+			script.src = s.url;
+
+			// Handle Script loading
+			if ( !jsonp ) {
+				var done = false;
+
+				// Attach handlers for all browsers
+				script.onload = script.onreadystatechange = function() {
+					if ( !done && (!this.readyState ||
+							this.readyState === "loaded" || this.readyState === "complete") ) {
+						done = true;
+						jQuery.handleSuccess( s, xhr, status, data );
+						jQuery.handleComplete( s, xhr, status, data );
+
+						// Handle memory leak in IE
+						script.onload = script.onreadystatechange = null;
+						if ( head && script.parentNode ) {
+							head.removeChild( script );
+						}
+					}
+				};
+			}
+
+			// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
+			// This arises when a base node is used (#2709 and #4378).
+			head.insertBefore( script, head.firstChild );
+
+			// We handle everything using the script element injection
+			return undefined;
+		}
+
+		var requestDone = false;
+
+		// Create the request object
+		var xhr = s.xhr();
+
+		if ( !xhr ) {
+			return;
+		}
+
+		// Open the socket
+		// Passing null username, generates a login popup on Opera (#2865)
+		if ( s.username ) {
+			xhr.open(type, s.url, s.async, s.username, s.password);
+		} else {
+			xhr.open(type, s.url, s.async);
+		}
+
+		// Need an extra try/catch for cross domain requests in Firefox 3
+		try {
+			// Set content-type if data specified and content-body is valid for this type
+			if ( (s.data != null && !noContent) || (origSettings && origSettings.contentType) ) {
+				xhr.setRequestHeader("Content-Type", s.contentType);
+			}
+
+			// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+			if ( s.ifModified ) {
+				if ( jQuery.lastModified[s.url] ) {
+					xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
+				}
+
+				if ( jQuery.etag[s.url] ) {
+					xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
+				}
+			}
+
+			// Set header so the called script knows that it's an XMLHttpRequest
+			// Only send the header if it's not a remote XHR
+			if ( !remote ) {
+				xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+			}
+
+			// Set the Accepts header for the server, depending on the dataType
+			xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+				s.accepts[ s.dataType ] + ", */*; q=0.01" :
+				s.accepts._default );
+		} catch( headerError ) {}
+
+		// Allow custom headers/mimetypes and early abort
+		if ( s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false ) {
+			// Handle the global AJAX counter
+			if ( s.global && jQuery.active-- === 1 ) {
+				jQuery.event.trigger( "ajaxStop" );
+			}
+
+			// close opended socket
+			xhr.abort();
+			return false;
+		}
+
+		if ( s.global ) {
+			jQuery.triggerGlobal( s, "ajaxSend", [xhr, s] );
+		}
+
+		// Wait for a response to come back
+		var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
+			// The request was aborted
+			if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
+				// Opera doesn't call onreadystatechange before this point
+				// so we simulate the call
+				if ( !requestDone ) {
+					jQuery.handleComplete( s, xhr, status, data );
+				}
+
+				requestDone = true;
+				if ( xhr ) {
+					xhr.onreadystatechange = jQuery.noop;
+				}
+
+			// The transfer is complete and the data is available, or the request timed out
+			} else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
+				requestDone = true;
+				xhr.onreadystatechange = jQuery.noop;
+
+				status = isTimeout === "timeout" ?
+					"timeout" :
+					!jQuery.httpSuccess( xhr ) ?
+						"error" :
+						s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
+							"notmodified" :
+							"success";
+
+				var errMsg;
+
+				if ( status === "success" ) {
+					// Watch for, and catch, XML document parse errors
+					try {
+						// process the data (runs the xml through httpData regardless of callback)
+						data = jQuery.httpData( xhr, s.dataType, s );
+					} catch( parserError ) {
+						status = "parsererror";
+						errMsg = parserError;
+					}
+				}
+
+				// Make sure that the request was successful or notmodified
+				if ( status === "success" || status === "notmodified" ) {
+					// JSONP handles its own success callback
+					if ( !jsonp ) {
+						jQuery.handleSuccess( s, xhr, status, data );
+					}
+				} else {
+					jQuery.handleError( s, xhr, status, errMsg );
+				}
+
+				// Fire the complete handlers
+				if ( !jsonp ) {
+					jQuery.handleComplete( s, xhr, status, data );
+				}
+
+				if ( isTimeout === "timeout" ) {
+					xhr.abort();
+				}
+
+				// Stop memory leaks
+				if ( s.async ) {
+					xhr = null;
+				}
+			}
+		};
+
+		// Override the abort handler, if we can (IE 6 doesn't allow it, but that's OK)
+		// Opera doesn't fire onreadystatechange at all on abort
+		try {
+			var oldAbort = xhr.abort;
+			xhr.abort = function() {
+				if ( xhr ) {
+					// oldAbort has no call property in IE7 so
+					// just do it this way, which works in all
+					// browsers
+					Function.prototype.call.call( oldAbort, xhr );
+				}
+
+				onreadystatechange( "abort" );
+			};
+		} catch( abortError ) {}
+
+		// Timeout checker
+		if ( s.async && s.timeout > 0 ) {
+			setTimeout(function() {
+				// Check to see if the request is still happening
+				if ( xhr && !requestDone ) {
+					onreadystatechange( "timeout" );
+				}
+			}, s.timeout);
+		}
+
+		// Send the data
+		try {
+			xhr.send( noContent || s.data == null ? null : s.data );
+
+		} catch( sendError ) {
+			jQuery.handleError( s, xhr, null, sendError );
+
+			// Fire the complete handlers
+			jQuery.handleComplete( s, xhr, status, data );
+		}
+
+		// firefox 1.5 doesn't fire statechange for sync requests
+		if ( !s.async ) {
+			onreadystatechange();
+		}
+
+		// return XMLHttpRequest to allow aborting the request etc.
+		return xhr;
+	},
+
+	// Serialize an array of form elements or a set of
+	// key/values into a query string
+	param: function( a, traditional ) {
+		var s = [],
+			add = function( key, value ) {
+				// If value is a function, invoke it and return its value
+				value = jQuery.isFunction(value) ? value() : value;
+				s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
+			};
+		
+		// Set traditional to true for jQuery <= 1.3.2 behavior.
+		if ( traditional === undefined ) {
+			traditional = jQuery.ajaxSettings.traditional;
+		}
+		
+		// If an array was passed in, assume that it is an array of form elements.
+		if ( jQuery.isArray(a) || a.jquery ) {
+			// Serialize the form elements
+			jQuery.each( a, function() {
+				add( this.name, this.value );
+			});
+			
+		} else {
+			// If traditional, encode the "old" way (the way 1.3.2 or older
+			// did it), otherwise encode params recursively.
+			for ( var prefix in a ) {
+				buildParams( prefix, a[prefix], traditional, add );
+			}
+		}
+
+		// Return the resulting serialization
+		return s.join("&").replace(r20, "+");
+	}
+});
+
+function buildParams( prefix, obj, traditional, add ) {
+	if ( jQuery.isArray(obj) && obj.length ) {
+		// Serialize array item.
+		jQuery.each( obj, function( i, v ) {
+			if ( traditional || rbracket.test( prefix ) ) {
+				// Treat each array item as a scalar.
+				add( prefix, v );
+
+			} else {
+				// If array item is non-scalar (array or object), encode its
+				// numeric index to resolve deserialization ambiguity issues.
+				// Note that rack (as of 1.0.0) can't currently deserialize
+				// nested arrays properly, and attempting to do so may cause
+				// a server error. Possible fixes are to modify rack's
+				// deserialization algorithm or to provide an option or flag
+				// to force array serialization to be shallow.
+				buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
+			}
+		});
+			
+	} else if ( !traditional && obj != null && typeof obj === "object" ) {
+		if ( jQuery.isEmptyObject( obj ) ) {
+			add( prefix, "" );
+
+		// Serialize object item.
+		} else {
+			jQuery.each( obj, function( k, v ) {
+				buildParams( prefix + "[" + k + "]", v, traditional, add );
+			});
+		}
+					
+	} else {
+		// Serialize scalar item.
+		add( prefix, obj );
+	}
+}
+
+// This is still on the jQuery object... for now
+// Want to move this to jQuery.ajax some day
+jQuery.extend({
+
+	// Counter for holding the number of active queries
+	active: 0,
+
+	// Last-Modified header cache for next request
+	lastModified: {},
+	etag: {},
+
+	handleError: function( s, xhr, status, e ) {
+		// If a local callback was specified, fire it
+		if ( s.error ) {
+			s.error.call( s.context, xhr, status, e );
+		}
+
+		// Fire the global callback
+		if ( s.global ) {
+			jQuery.triggerGlobal( s, "ajaxError", [xhr, s, e] );
+		}
+	},
+
+	handleSuccess: function( s, xhr, status, data ) {
+		// If a local callback was specified, fire it and pass it the data
+		if ( s.success ) {
+			s.success.call( s.context, data, status, xhr );
+		}
+
+		// Fire the global callback
+		if ( s.global ) {
+			jQuery.triggerGlobal( s, "ajaxSuccess", [xhr, s] );
+		}
+	},
+
+	handleComplete: function( s, xhr, status ) {
+		// Process result
+		if ( s.complete ) {
+			s.complete.call( s.context, xhr, status );
+		}
+
+		// The request was completed
+		if ( s.global ) {
+			jQuery.triggerGlobal( s, "ajaxComplete", [xhr, s] );
+		}
+
+		// Handle the global AJAX counter
+		if ( s.global && jQuery.active-- === 1 ) {
+			jQuery.event.trigger( "ajaxStop" );
+		}
+	},
+		
+	triggerGlobal: function( s, type, args ) {
+		(s.context && s.context.url == null ? jQuery(s.context) : jQuery.event).trigger(type, args);
+	},
+
+	// Determines if an XMLHttpRequest was successful or not
+	httpSuccess: function( xhr ) {
+		try {
+			// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
+			return !xhr.status && location.protocol === "file:" ||
+				xhr.status >= 200 && xhr.status < 300 ||
+				xhr.status === 304 || xhr.status === 1223;
+		} catch(e) {}
+
+		return false;
+	},
+
+	// Determines if an XMLHttpRequest returns NotModified
+	httpNotModified: function( xhr, url ) {
+		var lastModified = xhr.getResponseHeader("Last-Modified"),
+			etag = xhr.getResponseHeader("Etag");
+
+		if ( lastModified ) {
+			jQuery.lastModified[url] = lastModified;
+		}
+
+		if ( etag ) {
+			jQuery.etag[url] = etag;
+		}
+
+		return xhr.status === 304;
+	},
+
+	httpData: function( xhr, type, s ) {
+		var ct = xhr.getResponseHeader("content-type") || "",
+			xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
+			data = xml ? xhr.responseXML : xhr.responseText;
+
+		if ( xml && data.documentElement.nodeName === "parsererror" ) {
+			jQuery.error( "parsererror" );
+		}
+
+		// Allow a pre-filtering function to sanitize the response
+		// s is checked to keep backwards compatibility
+		if ( s && s.dataFilter ) {
+			data = s.dataFilter( data, type );
+		}
+
+		// The filter can actually parse the response
+		if ( typeof data === "string" ) {
+			// Get the JavaScript object, if JSON is used.
+			if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
+				data = jQuery.parseJSON( data );
+
+			// If the type is "script", eval it in global context
+			} else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
+				jQuery.globalEval( data );
+			}
+		}
+
+		return data;
+	}
+
+});
+
+/*
+ * Create the request object; Microsoft failed to properly
+ * implement the XMLHttpRequest in IE7 (can't request local files),
+ * so we use the ActiveXObject when it is available
+ * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+ * we need a fallback.
+ */
+if ( window.ActiveXObject ) {
+	jQuery.ajaxSettings.xhr = function() {
+		if ( window.location.protocol !== "file:" ) {
+			try {
+				return new window.XMLHttpRequest();
+			} catch(xhrError) {}
+		}
+
+		try {
+			return new window.ActiveXObject("Microsoft.XMLHTTP");
+		} catch(activeError) {}
+	};
+}
+
+// Does this browser support XHR requests?
+jQuery.support.ajax = !!jQuery.ajaxSettings.xhr();
+
+
+
+
+var elemdisplay = {},
+	rfxtypes = /^(?:toggle|show|hide)$/,
+	rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/,
+	timerId,
+	fxAttrs = [
+		// height animations
+		[ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+		// width animations
+		[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+		// opacity animations
+		[ "opacity" ]
+	];
+
+jQuery.fn.extend({
+	show: function( speed, easing, callback ) {
+		var elem, display;
+
+		if ( speed || speed === 0 ) {
+			return this.animate( genFx("show", 3), speed, easing, callback);
+
+		} else {
+			for ( var i = 0, j = this.length; i < j; i++ ) {
+				elem = this[i];
+				display = elem.style.display;
+
+				// Reset the inline display of this element to learn if it is
+				// being hidden by cascaded rules or not
+				if ( !jQuery.data(elem, "olddisplay") && display === "none" ) {
+					display = elem.style.display = "";
+				}
+
+				// Set elements which have been overridden with display: none
+				// in a stylesheet to whatever the default browser style is
+				// for such an element
+				if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
+					jQuery.data(elem, "olddisplay", defaultDisplay(elem.nodeName));
+				}
+			}
+
+			// Set the display of most of the elements in a second loop
+			// to avoid the constant reflow
+			for ( i = 0; i < j; i++ ) {
+				elem = this[i];
+				display = elem.style.display;
+
+				if ( display === "" || display === "none" ) {
+					elem.style.display = jQuery.data(elem, "olddisplay") || "";
+				}
+			}
+
+			return this;
+		}
+	},
+
+	hide: function( speed, easing, callback ) {
+		if ( speed || speed === 0 ) {
+			return this.animate( genFx("hide", 3), speed, easing, callback);
+
+		} else {
+			for ( var i = 0, j = this.length; i < j; i++ ) {
+				var display = jQuery.css( this[i], "display" );
+
+				if ( display !== "none" ) {
+					jQuery.data( this[i], "olddisplay", display );
+				}
+			}
+
+			// Set the display of the elements in a second loop
+			// to avoid the constant reflow
+			for ( i = 0; i < j; i++ ) {
+				this[i].style.display = "none";
+			}
+
+			return this;
+		}
+	},
+
+	// Save the old toggle function
+	_toggle: jQuery.fn.toggle,
+
+	toggle: function( fn, fn2, callback ) {
+		var bool = typeof fn === "boolean";
+
+		if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
+			this._toggle.apply( this, arguments );
+
+		} else if ( fn == null || bool ) {
+			this.each(function() {
+				var state = bool ? fn : jQuery(this).is(":hidden");
+				jQuery(this)[ state ? "show" : "hide" ]();
+			});
+
+		} else {
+			this.animate(genFx("toggle", 3), fn, fn2, callback);
+		}
+
+		return this;
+	},
+
+	fadeTo: function( speed, to, easing, callback ) {
+		return this.filter(":hidden").css("opacity", 0).show().end()
+					.animate({opacity: to}, speed, easing, callback);
+	},
+
+	animate: function( prop, speed, easing, callback ) {
+		var optall = jQuery.speed(speed, easing, callback);
+
+		if ( jQuery.isEmptyObject( prop ) ) {
+			return this.each( optall.complete );
+		}
+
+		return this[ optall.queue === false ? "each" : "queue" ](function() {
+			// XXX 'this' does not always have a nodeName when running the
+			// test suite
+
+			var opt = jQuery.extend({}, optall), p,
+				isElement = this.nodeType === 1,
+				hidden = isElement && jQuery(this).is(":hidden"),
+				self = this;
+
+			for ( p in prop ) {
+				var name = jQuery.camelCase( p );
+
+				if ( p !== name ) {
+					prop[ name ] = prop[ p ];
+					delete prop[ p ];
+					p = name;
+				}
+
+				if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
+					return opt.complete.call(this);
+				}
+
+				if ( isElement && ( p === "height" || p === "width" ) ) {
+					// Make sure that nothing sneaks out
+					// Record all 3 overflow attributes because IE does not
+					// change the overflow attribute when overflowX and
+					// overflowY are set to the same value
+					opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
+
+					// Set display property to inline-block for height/width
+					// animations on inline elements that are having width/height
+					// animated
+					if ( jQuery.css( this, "display" ) === "inline" &&
+							jQuery.css( this, "float" ) === "none" ) {
+						if ( !jQuery.support.inlineBlockNeedsLayout ) {
+							this.style.display = "inline-block";
+
+						} else {
+							var display = defaultDisplay(this.nodeName);
+
+							// inline-level elements accept inline-block;
+							// block-level elements need to be inline with layout
+							if ( display === "inline" ) {
+								this.style.display = "inline-block";
+
+							} else {
+								this.style.display = "inline";
+								this.style.zoom = 1;
+							}
+						}
+					}
+				}
+
+				if ( jQuery.isArray( prop[p] ) ) {
+					// Create (if needed) and add to specialEasing
+					(opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
+					prop[p] = prop[p][0];
+				}
+			}
+
+			if ( opt.overflow != null ) {
+				this.style.overflow = "hidden";
+			}
+
+			opt.curAnim = jQuery.extend({}, prop);
+
+			jQuery.each( prop, function( name, val ) {
+				var e = new jQuery.fx( self, opt, name );
+
+				if ( rfxtypes.test(val) ) {
+					e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+
+				} else {
+					var parts = rfxnum.exec(val),
+						start = e.cur() || 0;
+
+					if ( parts ) {
+						var end = parseFloat( parts[2] ),
+							unit = parts[3] || "px";
+
+						// We need to compute starting value
+						if ( unit !== "px" ) {
+							jQuery.style( self, name, (end || 1) + unit);
+							start = ((end || 1) / e.cur()) * start;
+							jQuery.style( self, name, start + unit);
+						}
+
+						// If a +=/-= token was provided, we're doing a relative animation
+						if ( parts[1] ) {
+							end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
+						}
+
+						e.custom( start, end, unit );
+
+					} else {
+						e.custom( start, val, "" );
+					}
+				}
+			});
+
+			// For JS strict compliance
+			return true;
+		});
+	},
+
+	stop: function( clearQueue, gotoEnd ) {
+		var timers = jQuery.timers;
+
+		if ( clearQueue ) {
+			this.queue([]);
+		}
+
+		this.each(function() {
+			// go in reverse order so anything added to the queue during the loop is ignored
+			for ( var i = timers.length - 1; i >= 0; i-- ) {
+				if ( timers[i].elem === this ) {
+					if (gotoEnd) {
+						// force the next step to be the last
+						timers[i](true);
+					}
+
+					timers.splice(i, 1);
+				}
+			}
+		});
+
+		// start the next in the queue if the last step wasn't forced
+		if ( !gotoEnd ) {
+			this.dequeue();
+		}
+
+		return this;
+	}
+
+});
+
+function genFx( type, num ) {
+	var obj = {};
+
+	jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
+		obj[ this ] = type;
+	});
+
+	return obj;
+}
+
+// Generate shortcuts for custom animations
+jQuery.each({
+	slideDown: genFx("show", 1),
+	slideUp: genFx("hide", 1),
+	slideToggle: genFx("toggle", 1),
+	fadeIn: { opacity: "show" },
+	fadeOut: { opacity: "hide" },
+	fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+	jQuery.fn[ name ] = function( speed, easing, callback ) {
+		return this.animate( props, speed, easing, callback );
+	};
+});
+
+jQuery.extend({
+	speed: function( speed, easing, fn ) {
+		var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
+			complete: fn || !fn && easing ||
+				jQuery.isFunction( speed ) && speed,
+			duration: speed,
+			easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+		};
+
+		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+			opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
+
+		// Queueing
+		opt.old = opt.complete;
+		opt.complete = function() {
+			if ( opt.queue !== false ) {
+				jQuery(this).dequeue();
+			}
+			if ( jQuery.isFunction( opt.old ) ) {
+				opt.old.call( this );
+			}
+		};
+
+		return opt;
+	},
+
+	easing: {
+		linear: function( p, n, firstNum, diff ) {
+			return firstNum + diff * p;
+		},
+		swing: function( p, n, firstNum, diff ) {
+			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+		}
+	},
+
+	timers: [],
+
+	fx: function( elem, options, prop ) {
+		this.options = options;
+		this.elem = elem;
+		this.prop = prop;
+
+		if ( !options.orig ) {
+			options.orig = {};
+		}
+	}
+
+});
+
+jQuery.fx.prototype = {
+	// Simple function for setting a style value
+	update: function() {
+		if ( this.options.step ) {
+			this.options.step.call( this.elem, this.now, this );
+		}
+
+		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+	},
+
+	// Get the current size
+	cur: function() {
+		if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
+			return this.elem[ this.prop ];
+		}
+
+		var r = parseFloat( jQuery.css( this.elem, this.prop ) );
+		return r && r > -10000 ? r : 0;
+	},
+
+	// Start an animation from one number to another
+	custom: function( from, to, unit ) {
+		var self = this,
+			fx = jQuery.fx;
+
+		this.startTime = jQuery.now();
+		this.start = from;
+		this.end = to;
+		this.unit = unit || this.unit || "px";
+		this.now = this.start;
+		this.pos = this.state = 0;
+
+		function t( gotoEnd ) {
+			return self.step(gotoEnd);
+		}
+
+		t.elem = this.elem;
+
+		if ( t() && jQuery.timers.push(t) && !timerId ) {
+			timerId = setInterval(fx.tick, fx.interval);
+		}
+	},
+
+	// Simple 'show' function
+	show: function() {
+		// Remember where we started, so that we can go back to it later
+		this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+		this.options.show = true;
+
+		// Begin the animation
+		// Make sure that we start at a small width/height to avoid any
+		// flash of content
+		this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
+
+		// Start by showing the element
+		jQuery( this.elem ).show();
+	},
+
+	// Simple 'hide' function
+	hide: function() {
+		// Remember where we started, so that we can go back to it later
+		this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+		this.options.hide = true;
+
+		// Begin the animation
+		this.custom(this.cur(), 0);
+	},
+
+	// Each step of an animation
+	step: function( gotoEnd ) {
+		var t = jQuery.now(), done = true;
+
+		if ( gotoEnd || t >= this.options.duration + this.startTime ) {
+			this.now = this.end;
+			this.pos = this.state = 1;
+			this.update();
+
+			this.options.curAnim[ this.prop ] = true;
+
+			for ( var i in this.options.curAnim ) {
+				if ( this.options.curAnim[i] !== true ) {
+					done = false;
+				}
+			}
+
+			if ( done ) {
+				// Reset the overflow
+				if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
+					var elem = this.elem,
+						options = this.options;
+
+					jQuery.each( [ "", "X", "Y" ], function (index, value) {
+						elem.style[ "overflow" + value ] = options.overflow[index];
+					} );
+				}
+
+				// Hide the element if the "hide" operation was done
+				if ( this.options.hide ) {
+					jQuery(this.elem).hide();
+				}
+
+				// Reset the properties, if the item has been hidden or shown
+				if ( this.options.hide || this.options.show ) {
+					for ( var p in this.options.curAnim ) {
+						jQuery.style( this.elem, p, this.options.orig[p] );
+					}
+				}
+
+				// Execute the complete function
+				this.options.complete.call( this.elem );
+			}
+
+			return false;
+
+		} else {
+			var n = t - this.startTime;
+			this.state = n / this.options.duration;
+
+			// Perform the easing function, defaults to swing
+			var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
+			var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
+			this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
+			this.now = this.start + ((this.end - this.start) * this.pos);
+
+			// Perform the next step of the animation
+			this.update();
+		}
+
+		return true;
+	}
+};
+
+jQuery.extend( jQuery.fx, {
+	tick: function() {
+		var timers = jQuery.timers;
+
+		for ( var i = 0; i < timers.length; i++ ) {
+			if ( !timers[i]() ) {
+				timers.splice(i--, 1);
+			}
+		}
+
+		if ( !timers.length ) {
+			jQuery.fx.stop();
+		}
+	},
+
+	interval: 13,
+
+	stop: function() {
+		clearInterval( timerId );
+		timerId = null;
+	},
+
+	speeds: {
+		slow: 600,
+		fast: 200,
+		// Default speed
+		_default: 400
+	},
+
+	step: {
+		opacity: function( fx ) {
+			jQuery.style( fx.elem, "opacity", fx.now );
+		},
+
+		_default: function( fx ) {
+			if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
+				fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
+			} else {
+				fx.elem[ fx.prop ] = fx.now;
+			}
+		}
+	}
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+	jQuery.expr.filters.animated = function( elem ) {
+		return jQuery.grep(jQuery.timers, function( fn ) {
+			return elem === fn.elem;
+		}).length;
+	};
+}
+
+function defaultDisplay( nodeName ) {
+	if ( !elemdisplay[ nodeName ] ) {
+		var elem = jQuery("<" + nodeName + ">").appendTo("body"),
+			display = elem.css("display");
+
+		elem.remove();
+
+		if ( display === "none" || display === "" ) {
+			display = "block";
+		}
+
+		elemdisplay[ nodeName ] = display;
+	}
+
+	return elemdisplay[ nodeName ];
+}
+
+
+
+
+var rtable = /^t(?:able|d|h)$/i,
+	rroot = /^(?:body|html)$/i;
+
+if ( "getBoundingClientRect" in document.documentElement ) {
+	jQuery.fn.offset = function( options ) {
+		var elem = this[0], box;
+
+		if ( options ) { 
+			return this.each(function( i ) {
+				jQuery.offset.setOffset( this, options, i );
+			});
+		}
+
+		if ( !elem || !elem.ownerDocument ) {
+			return null;
+		}
+
+		if ( elem === elem.ownerDocument.body ) {
+			return jQuery.offset.bodyOffset( elem );
+		}
+
+		try {
+			box = elem.getBoundingClientRect();
+		} catch(e) {}
+
+		var doc = elem.ownerDocument,
+			docElem = doc.documentElement;
+
+		// Make sure we're not dealing with a disconnected DOM node
+		if ( !box || !jQuery.contains( docElem, elem ) ) {
+			return box || { top: 0, left: 0 };
+		}
+
+		var body = doc.body,
+			win = getWindow(doc),
+			clientTop  = docElem.clientTop  || body.clientTop  || 0,
+			clientLeft = docElem.clientLeft || body.clientLeft || 0,
+			scrollTop  = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop ),
+			scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft),
+			top  = box.top  + scrollTop  - clientTop,
+			left = box.left + scrollLeft - clientLeft;
+
+		return { top: top, left: left };
+	};
+
+} else {
+	jQuery.fn.offset = function( options ) {
+		var elem = this[0];
+
+		if ( options ) { 
+			return this.each(function( i ) {
+				jQuery.offset.setOffset( this, options, i );
+			});
+		}
+
+		if ( !elem || !elem.ownerDocument ) {
+			return null;
+		}
+
+		if ( elem === elem.ownerDocument.body ) {
+			return jQuery.offset.bodyOffset( elem );
+		}
+
+		jQuery.offset.initialize();
+
+		var computedStyle,
+			offsetParent = elem.offsetParent,
+			prevOffsetParent = elem,
+			doc = elem.ownerDocument,
+			docElem = doc.documentElement,
+			body = doc.body,
+			defaultView = doc.defaultView,
+			prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
+			top = elem.offsetTop,
+			left = elem.offsetLeft;
+
+		while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+			if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+				break;
+			}
+
+			computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
+			top  -= elem.scrollTop;
+			left -= elem.scrollLeft;
+
+			if ( elem === offsetParent ) {
+				top  += elem.offsetTop;
+				left += elem.offsetLeft;
+
+				if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
+					top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
+					left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+				}
+
+				prevOffsetParent = offsetParent;
+				offsetParent = elem.offsetParent;
+			}
+
+			if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
+				top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
+				left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+			}
+
+			prevComputedStyle = computedStyle;
+		}
+
+		if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
+			top  += body.offsetTop;
+			left += body.offsetLeft;
+		}
+
+		if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+			top  += Math.max( docElem.scrollTop, body.scrollTop );
+			left += Math.max( docElem.scrollLeft, body.scrollLeft );
+		}
+
+		return { top: top, left: left };
+	};
+}
+
+jQuery.offset = {
+	initialize: function() {
+		var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
+			html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+
+		jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
+
+		container.innerHTML = html;
+		body.insertBefore( container, body.firstChild );
+		innerDiv = container.firstChild;
+		checkDiv = innerDiv.firstChild;
+		td = innerDiv.nextSibling.firstChild.firstChild;
+
+		this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
+		this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
+
+		checkDiv.style.position = "fixed";
+		checkDiv.style.top = "20px";
+
+		// safari subtracts parent border width here which is 5px
+		this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
+		checkDiv.style.position = checkDiv.style.top = "";
+
+		innerDiv.style.overflow = "hidden";
+		innerDiv.style.position = "relative";
+
+		this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
+
+		this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
+
+		body.removeChild( container );
+		body = container = innerDiv = checkDiv = table = td = null;
+		jQuery.offset.initialize = jQuery.noop;
+	},
+
+	bodyOffset: function( body ) {
+		var top = body.offsetTop,
+			left = body.offsetLeft;
+
+		jQuery.offset.initialize();
+
+		if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
+			top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
+			left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
+		}
+
+		return { top: top, left: left };
+	},
+	
+	setOffset: function( elem, options, i ) {
+		var position = jQuery.css( elem, "position" );
+
+		// set position first, in-case top/left are set even on static elem
+		if ( position === "static" ) {
+			elem.style.position = "relative";
+		}
+
+		var curElem = jQuery( elem ),
+			curOffset = curElem.offset(),
+			curCSSTop = jQuery.css( elem, "top" ),
+			curCSSLeft = jQuery.css( elem, "left" ),
+			calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1),
+			props = {}, curPosition = {}, curTop, curLeft;
+
+		// need to be able to calculate position if either top or left is auto and position is absolute
+		if ( calculatePosition ) {
+			curPosition = curElem.position();
+		}
+
+		curTop  = calculatePosition ? curPosition.top  : parseInt( curCSSTop,  10 ) || 0;
+		curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0;
+
+		if ( jQuery.isFunction( options ) ) {
+			options = options.call( elem, i, curOffset );
+		}
+
+		if (options.top != null) {
+			props.top = (options.top - curOffset.top) + curTop;
+		}
+		if (options.left != null) {
+			props.left = (options.left - curOffset.left) + curLeft;
+		}
+		
+		if ( "using" in options ) {
+			options.using.call( elem, props );
+		} else {
+			curElem.css( props );
+		}
+	}
+};
+
+
+jQuery.fn.extend({
+	position: function() {
+		if ( !this[0] ) {
+			return null;
+		}
+
+		var elem = this[0],
+
+		// Get *real* offsetParent
+		offsetParent = this.offsetParent(),
+
+		// Get correct offsets
+		offset       = this.offset(),
+		parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+		// Subtract element margins
+		// note: when an element has margin: auto the offsetLeft and marginLeft
+		// are the same in Safari causing offset.left to incorrectly be 0
+		offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
+		offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
+
+		// Add offsetParent borders
+		parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
+		parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
+
+		// Subtract the two offsets
+		return {
+			top:  offset.top  - parentOffset.top,
+			left: offset.left - parentOffset.left
+		};
+	},
+
+	offsetParent: function() {
+		return this.map(function() {
+			var offsetParent = this.offsetParent || document.body;
+			while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
+				offsetParent = offsetParent.offsetParent;
+			}
+			return offsetParent;
+		});
+	}
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ["Left", "Top"], function( i, name ) {
+	var method = "scroll" + name;
+
+	jQuery.fn[ method ] = function(val) {
+		var elem = this[0], win;
+		
+		if ( !elem ) {
+			return null;
+		}
+
+		if ( val !== undefined ) {
+			// Set the scroll offset
+			return this.each(function() {
+				win = getWindow( this );
+
+				if ( win ) {
+					win.scrollTo(
+						!i ? val : jQuery(win).scrollLeft(),
+						 i ? val : jQuery(win).scrollTop()
+					);
+
+				} else {
+					this[ method ] = val;
+				}
+			});
+		} else {
+			win = getWindow( elem );
+
+			// Return the scroll offset
+			return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
+				jQuery.support.boxModel && win.document.documentElement[ method ] ||
+					win.document.body[ method ] :
+				elem[ method ];
+		}
+	};
+});
+
+function getWindow( elem ) {
+	return jQuery.isWindow( elem ) ?
+		elem :
+		elem.nodeType === 9 ?
+			elem.defaultView || elem.parentWindow :
+			false;
+}
+
+
+
+
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function( i, name ) {
+
+	var type = name.toLowerCase();
+
+	// innerHeight and innerWidth
+	jQuery.fn["inner" + name] = function() {
+		return this[0] ?
+			parseFloat( jQuery.css( this[0], type, "padding" ) ) :
+			null;
+	};
+
+	// outerHeight and outerWidth
+	jQuery.fn["outer" + name] = function( margin ) {
+		return this[0] ?
+			parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
+			null;
+	};
+
+	jQuery.fn[ type ] = function( size ) {
+		// Get window width or height
+		var elem = this[0];
+		if ( !elem ) {
+			return size == null ? null : this;
+		}
+		
+		if ( jQuery.isFunction( size ) ) {
+			return this.each(function( i ) {
+				var self = jQuery( this );
+				self[ type ]( size.call( this, i, self[ type ]() ) );
+			});
+		}
+
+		if ( jQuery.isWindow( elem ) ) {
+			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+			return elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
+				elem.document.body[ "client" + name ];
+
+		// Get document width or height
+		} else if ( elem.nodeType === 9 ) {
+			// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+			return Math.max(
+				elem.documentElement["client" + name],
+				elem.body["scroll" + name], elem.documentElement["scroll" + name],
+				elem.body["offset" + name], elem.documentElement["offset" + name]
+			);
+
+		// Get or set width or height on the element
+		} else if ( size === undefined ) {
+			var orig = jQuery.css( elem, type ),
+				ret = parseFloat( orig );
+
+			return jQuery.isNaN( ret ) ? orig : ret;
+
+		// Set the width or height on the element (default to pixels if value is unitless)
+		} else {
+			return this.css( type, typeof size === "string" ? size : size + "px" );
+		}
+	};
+
+});
+
+
+})(window);
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/lang/json/json.js b/browserid/static/dialog/jquery/lang/json/json.js
new file mode 100644
index 0000000000000000000000000000000000000000..20803485bdd726e711956cbae711992a4b96fa50
--- /dev/null
+++ b/browserid/static/dialog/jquery/lang/json/json.js
@@ -0,0 +1,201 @@
+/*
+ * jQuery JSON Plugin
+ * version: 2.1 (2009-08-14)
+ *
+ * This document is licensed as free software under the terms of the
+ * MIT License: http://www.opensource.org/licenses/mit-license.php
+ *
+ * Brantley Harris wrote this plugin. It is based somewhat on the JSON.org 
+ * website's http://www.json.org/json2.js, which proclaims:
+ * "NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.", a sentiment that
+ * I uphold.
+ *
+ * It is also influenced heavily by MochiKit's serializeJSON, which is 
+ * copyrighted 2005 by Bob Ippolito.
+ */
+ steal.plugins('jquery').then(function(){
+(function($) {
+    /** jQuery.toJSON( json-serializble )
+        Converts the given argument into a JSON respresentation.
+
+        If an object has a "toJSON" function, that will be used to get the representation.
+        Non-integer/string keys are skipped in the object, as are keys that point to a function.
+
+        json-serializble:
+            The *thing* to be converted.
+     **/
+    $.toJSON = function(o, replacer, space, recurse)
+    {
+        if (typeof(JSON) == 'object' && JSON.stringify)
+            return JSON.stringify(o, replacer, space);
+
+        if (!recurse && $.isFunction(replacer))
+            o = replacer("", o);
+
+        if (typeof space == "number")
+            space = "          ".substring(0, space);
+        space = (typeof space == "string") ? space.substring(0, 10) : "";
+        
+        var type = typeof(o);
+    
+        if (o === null)
+            return "null";
+    
+        if (type == "undefined" || type == "function")
+            return undefined;
+        
+        if (type == "number" || type == "boolean")
+            return o + "";
+    
+        if (type == "string")
+            return $.quoteString(o);
+    
+        if (type == 'object')
+        {
+            if (typeof o.toJSON == "function") 
+                return $.toJSON( o.toJSON(), replacer, space, true );
+            
+            if (o.constructor === Date)
+            {
+                var month = o.getUTCMonth() + 1;
+                if (month < 10) month = '0' + month;
+
+                var day = o.getUTCDate();
+                if (day < 10) day = '0' + day;
+
+                var year = o.getUTCFullYear();
+                
+                var hours = o.getUTCHours();
+                if (hours < 10) hours = '0' + hours;
+                
+                var minutes = o.getUTCMinutes();
+                if (minutes < 10) minutes = '0' + minutes;
+                
+                var seconds = o.getUTCSeconds();
+                if (seconds < 10) seconds = '0' + seconds;
+                
+                var milli = o.getUTCMilliseconds();
+                if (milli < 100) milli = '0' + milli;
+                if (milli < 10) milli = '0' + milli;
+
+                return '"' + year + '-' + month + '-' + day + 'T' +
+                             hours + ':' + minutes + ':' + seconds + 
+                             '.' + milli + 'Z"'; 
+            }
+
+            var process = ($.isFunction(replacer)) ?
+                function (k, v) { return replacer(k, v); } :
+                function (k, v) { return v; },
+                nl = (space) ? "\n" : "",
+                sp = (space) ? " " : "";
+
+            if (o.constructor === Array) 
+            {
+                var ret = [];
+                for (var i = 0; i < o.length; i++)
+                    ret.push(( $.toJSON( process(i, o[i]), replacer, space, true ) || "null" ).replace(/^/gm, space));
+
+                return "[" + nl + ret.join("," + nl) + nl + "]";
+            }
+        
+            var pairs = [], proplist;
+            if ($.isArray(replacer)) {
+                proplist = $.map(replacer, function (v) {
+                    return (typeof v == "string" || typeof v == "number") ?
+                        v + "" :
+                        null;
+                });
+            }
+            for (var k in o) {
+                var name, val, type = typeof k;
+
+                if (proplist && $.inArray(k + "", proplist) == -1)
+                    continue;
+
+                if (type == "number")
+                    name = '"' + k + '"';
+                else if (type == "string")
+                    name = $.quoteString(k);
+                else
+                    continue;  //skip non-string or number keys
+            
+                val = $.toJSON( process(k, o[k]), replacer, space, true );
+            
+                if (typeof val == "undefined")
+                    continue;  //skip pairs where the value is a function.
+            
+                pairs.push((name + ":" + sp + val).replace(/^/gm, space));
+            }
+
+            return "{" + nl + pairs.join("," + nl) + nl + "}";
+        }
+    };
+
+    /** jQuery.evalJSON(src)
+        Evaluates a given piece of json source.
+     **/
+    $.evalJSON = function(src)
+    {
+        if (typeof(JSON) == 'object' && JSON.parse)
+            return JSON.parse(src);
+        return eval("(" + src + ")");
+    };
+    
+    /** jQuery.secureEvalJSON(src)
+        Evals JSON in a way that is *more* secure.
+    **/
+    $.secureEvalJSON = function(src)
+    {
+        if (typeof(JSON) == 'object' && JSON.parse)
+            return JSON.parse(src);
+        
+        var filtered = src;
+        filtered = filtered.replace(/\\["\\\/bfnrtu]/g, '@');
+        filtered = filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
+        filtered = filtered.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
+        
+        if (/^[\],:{}\s]*$/.test(filtered))
+            return eval("(" + src + ")");
+        else
+            throw new SyntaxError("Error parsing JSON, source is not valid.");
+    };
+
+    /** jQuery.quoteString(string)
+        Returns a string-repr of a string, escaping quotes intelligently.  
+        Mostly a support function for toJSON.
+    
+        Examples:
+            >>> jQuery.quoteString("apple")
+            "apple"
+        
+            >>> jQuery.quoteString('"Where are we going?", she asked.')
+            "\"Where are we going?\", she asked."
+     **/
+    $.quoteString = function(string)
+    {
+        if (string.match(_escapeable))
+        {
+            return '"' + string.replace(_escapeable, function (a) 
+            {
+                var c = _meta[a];
+                if (typeof c === 'string') return c;
+                c = a.charCodeAt();
+                return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
+            }) + '"';
+        }
+        return '"' + string + '"';
+    };
+    
+    var _escapeable = /["\\\x00-\x1f\x7f-\x9f]/g;
+    
+    var _meta = {
+        '\b': '\\b',
+        '\t': '\\t',
+        '\n': '\\n',
+        '\f': '\\f',
+        '\r': '\\r',
+        '"' : '\\"',
+        '\\': '\\\\'
+    };
+})(jQuery);
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/lang/lang.html b/browserid/static/dialog/jquery/lang/lang.html
new file mode 100644
index 0000000000000000000000000000000000000000..66ea99afd9be18a2fce45abcc4e0d788114efd67
--- /dev/null
+++ b/browserid/static/dialog/jquery/lang/lang.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>Lang Performance Test</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+        </style>
+	</head>
+	<body>
+<div id="demo-html">
+</div>
+
+<script type='text/javascript' src='../../steal/steal.js'></script>
+<script type='text/javascript' id="demo-source">
+steal.plugins("jquery/lang").then(function($){
+  
+  var now = new Date()
+  for(var i=0; i < 100000; i++){
+    $.String.classize("AbcDefGhi")	
+  }
+  console.log(new Date() - now)
+  
+}).start()
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/lang/lang.js b/browserid/static/dialog/jquery/lang/lang.js
new file mode 100644
index 0000000000000000000000000000000000000000..dcf8eb5fc6d536bbda97884e31a7934116f4c13e
--- /dev/null
+++ b/browserid/static/dialog/jquery/lang/lang.js
@@ -0,0 +1,135 @@
+steal.plugins('jquery').then(function( $ ) {
+	// Several of the methods in this plugin use code adapated from Prototype
+	//  Prototype JavaScript framework, version 1.6.0.1
+	//  (c) 2005-2007 Sam Stephenson
+	var regs = {
+		undHash: /_|-/,
+		colons: /::/,
+		words: /([A-Z]+)([A-Z][a-z])/g,
+		lowerUpper: /([a-z\d])([A-Z])/g,
+		dash: /([a-z\d])([A-Z])/g,
+		replacer: /\{([^\}]+)\}/g
+	},
+		getObject = function( objectName, currentin, remove ) {
+			var current = currentin || window,
+				parts = objectName ? objectName.split(/\./) : [],
+				ret, i = 0;
+			for (; i < parts.length - 1 && current; i++ ) {
+				current = current[parts[i]];
+			}
+			ret = current[parts[i]];
+			if ( remove ) {
+				delete current[parts[i]];
+			}
+			return ret;
+		},
+
+		/** 
+		 * @class jQuery.String
+		 */
+		str = ($.String = {
+			/**
+			 * @function strip
+			 * @param {String} s returns a string with leading and trailing whitespace removed.
+			 */
+			strip: function( string ) {
+				return string.replace(/^\s+/, '').replace(/\s+$/, '');
+			},
+			/**
+			 * Capitalizes a string
+			 * @param {String} s the string to be lowercased.
+			 * @return {String} a string with the first character capitalized, and everything else lowercased
+			 */
+			capitalize: function( s, cache ) {
+				return s.charAt(0).toUpperCase() + s.substr(1);
+			},
+
+			/**
+			 * Returns if string ends with another string
+			 * @param {String} s String that is being scanned
+			 * @param {String} pattern What the string might end with
+			 * @return {Boolean} true if the string ends wtih pattern, false if otherwise
+			 */
+			endsWith: function( s, pattern ) {
+				var d = s.length - pattern.length;
+				return d >= 0 && s.lastIndexOf(pattern) === d;
+			},
+			/**
+			 * Capitalizes a string from something undercored. Examples:
+			 * @codestart
+			 * jQuery.String.camelize("one_two") //-> "oneTwo"
+			 * "three-four".camelize() //-> threeFour
+			 * @codeend
+			 * @param {String} s
+			 * @return {String} a the camelized string
+			 */
+			camelize: function( s ) {
+				var parts = s.split(regs.undHash),
+					i = 1;
+				parts[0] = parts[0].charAt(0).toLowerCase() + parts[0].substr(1);
+				for (; i < parts.length; i++ ) {
+					parts[i] = str.capitalize(parts[i]);
+				}
+
+				return parts.join('');
+			},
+			/**
+			 * Like camelize, but the first part is also capitalized
+			 * @param {String} s
+			 * @return {String} the classized string
+			 */
+			classize: function( s ) {
+				var parts = s.split(regs.undHash),
+					i = 0;
+				for (; i < parts.length; i++ ) {
+					parts[i] = str.capitalize(parts[i]);
+				}
+
+				return parts.join('');
+			},
+			/**
+			 * Like [jQuery.String.classize|classize], but a space separates each 'word'
+			 * @codestart
+			 * jQuery.String.niceName("one_two") //-> "One Two"
+			 * @codeend
+			 * @param {String} s
+			 * @return {String} the niceName
+			 */
+			niceName: function( s ) {
+				var parts = s.split(regs.undHash),
+					i = 0;
+				for (; i < parts.length; i++ ) {
+					parts[i] = str.capitalize(parts[i]);
+				}
+
+				return parts.join(' ');
+			},
+
+			/**
+			 * Underscores a string.
+			 * @codestart
+			 * jQuery.String.underscore("OneTwo") //-> "one_two"
+			 * @codeend
+			 * @param {String} s
+			 * @return {String} the underscored string
+			 */
+			underscore: function( s ) {
+				return s.replace(regs.colons, '/').replace(regs.words, '$1_$2').replace(regs.lowerUpper, '$1_$2').replace(regs.dash, '_').toLowerCase();
+			},
+			/**
+			 * Returns a string with {param} replaced with parameters
+			 * from data.
+			 *     $.String.sub("foo {bar}",{bar: "far"})
+			 *     //-> "foo far"
+			 * @param {String} s
+			 * @param {Object} data
+			 */
+			sub: function( s, data, remove ) {
+				return s.replace(regs.replacer, function( whole, inside ) {
+					//convert inside to type
+					return getObject(inside, data, remove).toString(); //gets the value in options
+				});
+			}
+		});
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/lang/lang_test.js b/browserid/static/dialog/jquery/lang/lang_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..05f8f8839bc4bd5878296273e35a0a0a9e393165
--- /dev/null
+++ b/browserid/static/dialog/jquery/lang/lang_test.js
@@ -0,0 +1,21 @@
+steal.plugins('funcunit/qunit','jquery/lang').then(function(){
+	
+module("jquery/lang")
+
+test("$.String.sub", function(){
+	equals($.String.sub("a{b}",{b: "c"}),"ac")
+	
+	var foo = {b: "c"};
+	
+	equals($.String.sub("a{b}",foo,true),"ac");
+	
+	ok(!foo.b, "removed this b");
+	
+	
+});
+
+test("String.underscore", function(){
+	equals($.String.underscore("Foo.Bar.ZarDar"),"foo.bar.zar_dar")
+})
+	
+});
diff --git a/browserid/static/dialog/jquery/lang/openajax/openajax.html b/browserid/static/dialog/jquery/lang/openajax/openajax.html
new file mode 100644
index 0000000000000000000000000000000000000000..2f5c2b780566ce946eb9358d91181b11be124c80
--- /dev/null
+++ b/browserid/static/dialog/jquery/lang/openajax/openajax.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>Lang Performance Test</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+        </style>
+	</head>
+	<body>
+<div id="demo-html">
+</div>
+
+<script type='text/javascript' src='../../../steal/steal.js'></script>
+<script type='text/javascript' id="demo-source">
+steal.plugins("jquery/lang/openajax").then(function($){
+ 	OpenAjax.hub.subscribe('todo.*.updated', function(){
+		console.log('yes')
+	});
+OpenAjax.hub.publish('todo.5.updated',{})
+}).start()
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/lang/openajax/openajax.js b/browserid/static/dialog/jquery/lang/openajax/openajax.js
new file mode 100644
index 0000000000000000000000000000000000000000..7237035165728c09f9b61e09157bb375d242698a
--- /dev/null
+++ b/browserid/static/dialog/jquery/lang/openajax/openajax.js
@@ -0,0 +1,202 @@
+//@steal-clean
+/*******************************************************************************
+ * OpenAjax.js
+ *
+ * Reference implementation of the OpenAjax Hub, as specified by OpenAjax Alliance.
+ * Specification is under development at: 
+ *
+ *   http://www.openajax.org/member/wiki/OpenAjax_Hub_Specification
+ *
+ * Copyright 2006-2008 OpenAjax Alliance
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
+ * use this file except in compliance with the License. You may obtain a copy 
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0 . Unless 
+ * required by applicable law or agreed to in writing, software distributed 
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+ * specific language governing permissions and limitations under the License.
+ *
+ ******************************************************************************/
+steal.then(function(){
+// prevent re-definition of the OpenAjax object
+if(!window["OpenAjax"]){
+	/**
+	 * @class OpenAjax
+	 * Use OpenAjax.hub to publish and subscribe to messages.
+	 */
+    OpenAjax = new function(){
+		var t = true;
+		var f = false;
+		var g = window;
+		var ooh = "org.openajax.hub.";
+
+		var h = {};
+		this.hub = h;
+		h.implementer = "http://openajax.org";
+		h.implVersion = "1.0";
+		h.specVersion = "1.0";
+		h.implExtraData = {};
+		var libs = {};
+		h.libraries = libs;
+
+		h.registerLibrary = function(prefix, nsURL, version, extra){
+			libs[prefix] = {
+				prefix: prefix,
+				namespaceURI: nsURL,
+				version: version,
+				extraData: extra 
+			};
+			this.publish(ooh+"registerLibrary", libs[prefix]);
+		}
+		h.unregisterLibrary = function(prefix){
+			this.publish(ooh+"unregisterLibrary", libs[prefix]);
+			delete libs[prefix];
+		}
+
+		h._subscriptions = { c:{}, s:[] };
+		h._cleanup = [];
+		h._subIndex = 0;
+		h._pubDepth = 0;
+
+		h.subscribe = function(name, callback, scope, subscriberData, filter)			
+		{
+			if(!scope){
+				scope = window;
+			}
+			var handle = name + "." + this._subIndex;
+			var sub = { scope: scope, cb: callback, fcb: filter, data: subscriberData, sid: this._subIndex++, hdl: handle };
+			var path = name.split(".");
+	 		this._subscribe(this._subscriptions, path, 0, sub);
+			return handle;
+		}
+
+		h.publish = function(name, message)		
+		{
+			var path = name.split(".");
+			this._pubDepth++;
+			this._publish(this._subscriptions, path, 0, name, message);
+			this._pubDepth--;
+			if((this._cleanup.length > 0) && (this._pubDepth == 0)) {
+				for(var i = 0; i < this._cleanup.length; i++) 
+					this.unsubscribe(this._cleanup[i].hdl);
+				delete(this._cleanup);
+				this._cleanup = [];
+			}
+		}
+
+		h.unsubscribe = function(sub) 
+		{
+			var path = sub.split(".");
+			var sid = path.pop();
+			this._unsubscribe(this._subscriptions, path, 0, sid);
+		}
+		
+		h._subscribe = function(tree, path, index, sub) 
+		{
+			var token = path[index];
+			if(index == path.length) 	
+				tree.s.push(sub);
+			else { 
+				if(typeof tree.c == "undefined")
+					 tree.c = {};
+				if(typeof tree.c[token] == "undefined") {
+					tree.c[token] = { c: {}, s: [] }; 
+					this._subscribe(tree.c[token], path, index + 1, sub);
+				}
+				else 
+					this._subscribe( tree.c[token], path, index + 1, sub);
+			}
+		}
+
+		h._publish = function(tree, path, index, name, msg, pcb, pcid) {
+			if(typeof tree != "undefined") {
+				var node;
+				if(index == path.length) {
+					node = tree;
+				} else {
+					this._publish(tree.c[path[index]], path, index + 1, name, msg, pcb, pcid);
+					this._publish(tree.c["*"], path, index + 1, name, msg, pcb, pcid);			
+					node = tree.c["**"];
+				}
+				if(typeof node != "undefined") {
+					var callbacks = node.s;
+					var max = callbacks.length;
+					for(var i = 0; i < max; i++) {
+						if(callbacks[i].cb) {
+							var sc = callbacks[i].scope;
+							var cb = callbacks[i].cb;
+							var fcb = callbacks[i].fcb;
+							var d = callbacks[i].data;
+							var sid = callbacks[i].sid;
+							var scid = callbacks[i].cid;
+							if(typeof cb == "string"){
+								// get a function object
+								cb = sc[cb];
+							}
+							if(typeof fcb == "string"){
+								// get a function object
+								fcb = sc[fcb];
+							}
+							if((!fcb) || (fcb.call(sc, name, msg, d))) {
+							  if((!pcb) || (pcb(name, msg, pcid, scid))) {
+								  cb.call(sc, name, msg, d, sid);
+							  }
+							}
+						}
+					}
+				}
+			}
+		}
+			
+		h._unsubscribe = function(tree, path, index, sid) {
+			if(typeof tree != "undefined") {
+				if(index < path.length) {
+					var childNode = tree.c[path[index]];
+					this._unsubscribe(childNode, path, index + 1, sid);
+					if(childNode.s.length == 0) {
+						for(var x in childNode.c) 
+					 		return;		
+						delete tree.c[path[index]];	
+					}
+					return;
+				}
+				else {
+					var callbacks = tree.s;
+					var max = callbacks.length;
+					for(var i = 0; i < max; i++) 
+						if(sid == callbacks[i].sid) {
+							if(this._pubDepth > 0) {
+								callbacks[i].cb = null;	
+								this._cleanup.push(callbacks[i]);						
+							}
+							else
+								callbacks.splice(i, 1);
+							return; 	
+						}
+				}
+			}
+		}
+		// The following function is provided for automatic testing purposes.
+		// It is not expected to be deployed in run-time OpenAjax Hub implementations.
+		h.reinit = function()
+		{
+			for (var lib in OpenAjax.hub.libraries) {
+				delete OpenAjax.hub.libraries[lib];
+			}
+			OpenAjax.hub.registerLibrary("OpenAjax", "http://openajax.org/hub", "1.0", {});
+
+			delete OpenAjax._subscriptions;
+			OpenAjax._subscriptions = {c:{},s:[]};
+			delete OpenAjax._cleanup;
+			OpenAjax._cleanup = [];
+			OpenAjax._subIndex = 0;
+			OpenAjax._pubDepth = 0;
+		}
+	};
+	// Register the OpenAjax Hub itself as a library.
+	OpenAjax.hub.registerLibrary("OpenAjax", "http://openajax.org/hub", "1.0", {});
+
+}
+OpenAjax.hub.registerLibrary("JavaScriptMVC", "http://JavaScriptMVC.com", "1.5", {});
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/lang/qunit.html b/browserid/static/dialog/jquery/lang/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..0cec0f90913a4d951cb9e131b865ac15136e52e5
--- /dev/null
+++ b/browserid/static/dialog/jquery/lang/qunit.html
@@ -0,0 +1,17 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../funcunit/qunit/qunit.css" />
+    </head>
+    <body>
+
+    <h1 id="qunit-header">Lang Test Suite</h1>
+	<h2 id="qunit-banner"></h2>
+	<div id="qunit-testrunner-toolbar"></div>
+	<h2 id="qunit-userAgent"></h2>
+    <ol id="qunit-tests"></ol>
+	<div id="qunit-test-area"></div>
+	<a href='associations/qunit.html'>associations</a>
+	<a href='list/qunit.html'>list</a>
+    <script type='text/javascript' src='../../steal/steal.js?jquery/lang/lang_test.js'></script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/lang/rsplit/rsplit.js b/browserid/static/dialog/jquery/lang/rsplit/rsplit.js
new file mode 100644
index 0000000000000000000000000000000000000000..bd2cea35fa4de95b273600d8494bb81d1c14484f
--- /dev/null
+++ b/browserid/static/dialog/jquery/lang/rsplit/rsplit.js
@@ -0,0 +1,31 @@
+steal.plugins('jquery/lang').then(function( $ ) {
+	/**
+	 * @add jQuery.String
+	 */
+	$.String.
+	/**
+	 * Splits a string with a regex correctly cross browser
+	 * @param {Object} string
+	 * @param {Object} regex
+	 */
+	rsplit = function( string, regex ) {
+		var result = regex.exec(string),
+			retArr = [],
+			first_idx, last_idx;
+		while ( result !== null ) {
+			first_idx = result.index;
+			last_idx = regex.lastIndex;
+			if ( first_idx !== 0 ) {
+				retArr.push(string.substring(0, first_idx));
+				string = string.slice(first_idx);
+			}
+			retArr.push(result[0]);
+			string = string.slice(result[0].length);
+			result = regex.exec(string);
+		}
+		if ( string !== '' ) {
+			retArr.push(string);
+		}
+		return retArr;
+	};
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/lang/vector/vector.js b/browserid/static/dialog/jquery/lang/vector/vector.js
new file mode 100644
index 0000000000000000000000000000000000000000..eb99890862576a3d7e73e102163d0018aded3738
--- /dev/null
+++ b/browserid/static/dialog/jquery/lang/vector/vector.js
@@ -0,0 +1,158 @@
+steal.then(function( $ ) {
+	var getSetZero = function( v ) {
+		return v !== undefined ? (this.array[0] = v) : this.array[0];
+	},
+		getSetOne = function( v ) {
+			return v !== undefined ? (this.array[1] = v) : this.array[1];
+		};
+	/**
+	 * @class jQuery.Vector
+	 * A vector class
+	 * @constructor creates a new vector instance from the arguments.  Example:
+	 * @codestart
+	 * new jQuery.Vector(1,2)
+	 * @codeend
+	 * 
+	 */
+	$.Vector = function() {
+		this.update($.makeArray(arguments));
+	};
+	$.Vector.prototype =
+	/* @Prototype*/
+	{
+		/**
+		 * Applys the function to every item in the vector.  Returns the new vector.
+		 * @param {Function} f
+		 * @return {jQuery.Vector} new vector class.
+		 */
+		app: function( f ) {
+			var i, vec, newArr = [];
+
+			for ( i = 0; i < this.array.length; i++ ) {
+				newArr.push(f(this.array[i]));
+			}
+			vec = new $.Vector();
+			return vec.update(newArr);
+		},
+		/**
+		 * Adds two vectors together.  Example:
+		 * @codestart
+		 * new Vector(1,2).plus(2,3) //-> &lt;3,5>
+		 * new Vector(3,5).plus(new Vector(4,5)) //-> &lt;7,10>
+		 * @codeend
+		 * @return {$.Vector}
+		 */
+		plus: function() {
+			var i, args = arguments[0] instanceof $.Vector ? arguments[0].array : $.makeArray(arguments),
+				arr = this.array.slice(0),
+				vec = new $.Vector();
+			for ( i = 0; i < args.length; i++ ) {
+				arr[i] = (arr[i] ? arr[i] : 0) + args[i];
+			}
+			return vec.update(arr);
+		},
+		/**
+		 * Like plus but subtracts 2 vectors
+		 * @return {jQuery.Vector}
+		 */
+		minus: function() {
+			var i, args = arguments[0] instanceof $.Vector ? arguments[0].array : $.makeArray(arguments),
+				arr = this.array.slice(0),
+				vec = new $.Vector();
+			for ( i = 0; i < args.length; i++ ) {
+				arr[i] = (arr[i] ? arr[i] : 0) - args[i];
+			}
+			return vec.update(arr);
+		},
+		/**
+		 * Returns the current vector if it is equal to the vector passed in.  
+		 * False if otherwise.
+		 * @return {jQuery.Vector}
+		 */
+		equals: function() {
+			var i, args = arguments[0] instanceof $.Vector ? arguments[0].array : $.makeArray(arguments),
+				arr = this.array.slice(0),
+				vec = new $.Vector();
+			for ( i = 0; i < args.length; i++ ) {
+				if ( arr[i] != args[i] ) {
+					return null;
+				}
+			}
+			return vec.update(arr);
+		},
+/*
+	 * Returns the 2nd value of the vector
+	 * @return {Number}
+	 */
+		x: getSetZero,
+		width: getSetZero,
+		/**
+		 * Returns the first value of the vector
+		 * @return {Number}
+		 */
+		y: getSetOne,
+		height: getSetOne,
+		/**
+		 * Same as x()
+		 * @return {Number}
+		 */
+		top: getSetOne,
+		/**
+		 * same as y()
+		 * @return {Number}
+		 */
+		left: getSetZero,
+		/**
+		 * returns (x,y)
+		 * @return {String}
+		 */
+		toString: function() {
+			return "(" + this.array[0] + "," + this.array[1] + ")";
+		},
+		/**
+		 * Replaces the vectors contents
+		 * @param {Object} array
+		 */
+		update: function( array ) {
+			var i;
+			if ( this.array ) {
+				for ( i = 0; i < this.array.length; i++ ) {
+					delete this.array[i];
+				}
+			}
+			this.array = array;
+			for ( i = 0; i < array.length; i++ ) {
+				this[i] = this.array[i];
+			}
+			return this;
+		}
+	};
+
+	$.Event.prototype.vector = function() {
+		if ( this.originalEvent.synthetic ) {
+			var doc = document.documentElement,
+				body = document.body;
+			return new $.Vector(this.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0), this.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0));
+		} else {
+			return new $.Vector(this.pageX, this.pageY);
+		}
+	};
+
+	$.fn.offsetv = function() {
+		if ( this[0] == window ) {
+			return new $.Vector(window.pageXOffset ? window.pageXOffset : document.documentElement.scrollLeft, window.pageYOffset ? window.pageYOffset : document.documentElement.scrollTop);
+		} else {
+			var offset = this.offset();
+			return new $.Vector(offset.left, offset.top);
+		}
+	};
+
+	$.fn.dimensionsv = function( which ) {
+		if ( this[0] == window || !which ) {
+			return new $.Vector(this.width(), this.height());
+		}
+		else {
+			return new $.Vector(this[which + "Width"](), this[which + "Height"]());
+		}
+	};
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/associations/associations.html b/browserid/static/dialog/jquery/model/associations/associations.html
new file mode 100644
index 0000000000000000000000000000000000000000..71e72c85246a56d33efea23cdb2dc539992fbdb7
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/associations/associations.html
@@ -0,0 +1,113 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>Model Events Demo</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            li {border: solid 1px gray; padding: 5px; width: 250px;}
+			li a {color: red; font-weight: bold;}
+			li li {width: auto; border: none;}
+			p {width: 400px;}
+        </style>
+	</head>
+	<body>
+		<div id="demo-instructions">
+		<h1>Model Associations Demo</h1>
+		<p>This demo shows how you can setup associations.</p>
+		</div>
+<div id="demo-html">
+<div id='contacts'></div>
+</div>
+		
+<script type='text/javascript' 
+        src='../../../steal/steal.js'>   
+</script>
+<script type='text/javascript'>
+steal.plugins('jquery/model',
+		'jquery/dom/fixture',
+		'jquery/model/list',
+		'jquery/model/associations').start()
+</script>
+<script type='text/javascript'>
+	var convertDate =  function(raw){
+		if(typeof raw == 'string'){
+			var matches = raw.match(/(\d+)-(\d+)-(\d+)/)
+			return new Date( +matches[1], 
+			                 (+matches[2])-1, 
+			                 +matches[3] )
+		}else if(raw instanceof Date){
+			return raw;
+		}
+	};
+	CONTACT_FIXTURE = function(){
+				return [[{'id': 1,'name' : 'Justin Meyer','birthday': '1982-10-20',
+							tasks : [{id: 1, title: "write up model layer", due: "2010-10-5"}]},
+					 {'id': 2,'name' : 'Brian Moschel','birthday': '1983-11-10',
+					 		tasks : [{id: 2, title: "write up funcunit", due: "2009-5-1"}, {id: 3, title: "test funcunit", due: "2010-3-15"}]},
+					 {'id': 3,'name' : 'Alex Gomes','birthday': '1980-2-10'}]];
+			}
+</script>
+<script type='text/javascript'  id="demo-source">   
+$.Model.extend("Task",{
+	convert : {
+		date :convertDate
+	},
+	attributes : {
+		due : 'date'
+	}
+},{
+	weeksPastDue : function(){
+		return Math.round( (new Date() - this.due) /
+			(1000*60*60*24*7 ) );
+	}
+})
+
+$.Model.extend("Contact",{
+	attributes : { 
+		birthday : 'date'
+	},
+	associations : {
+		hasMany : "Task"
+	},
+	convert : {
+		date :convertDate
+	},
+	findAll : function(params, success, error){
+		$.get("/recipes.json",{},
+			this.callback(['wrapMany',success]),
+			"json",CONTACT_FIXTURE)
+	}
+},{
+	ageThisYear : function(){
+		return new Date().getFullYear() - 
+		      this.birthday.getFullYear()
+	},
+	getBirthday : function(){
+		return ""+this.birthday.getFullYear()+
+			"-"+(this.birthday.getMonth()+1)+
+			"-"+this.birthday.getDate();
+	}
+
+});
+
+
+// List 1
+Contact.findAll({},function(contacts){
+  var contactsEl = $('#contacts');
+  $.each(contacts, function(i, contact){
+    var li = $('<li>')
+              .model(contact)
+              .html(contact.name+" "+contact.ageThisYear())
+              .appendTo(contactsEl);
+	var ul =$("<ul>");
+	contact.attr('tasks').each(function(){
+		ul.append('<li>'+this.title+" "+this.weeksPastDue()+'</li>')
+	})
+	ul.appendTo(li)
+  });
+});
+
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/associations/associations.js b/browserid/static/dialog/jquery/model/associations/associations.js
new file mode 100644
index 0000000000000000000000000000000000000000..57831d9f2ff3fa9c11fd201370dfae4ef2ea800d
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/associations/associations.js
@@ -0,0 +1,191 @@
+steal.plugins('jquery/model').then(function($){
+/**
+@page jquery.model.associations Associations
+@parent jQuery.Model
+@download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/model/associations/associations.js
+@test jquery/model/associations/qunit.html
+@plugin jquery/model/associations
+
+For efficiency, you often want to get data for related 
+records at the same time. The jquery.model.assocations.js 
+plugin lets you do this.
+
+Lets say we wanted to list tasks for contacts. When we request our contacts, 
+the JSON data will come back like:
+
+@codestart
+[
+ {'id': 1,
+  'name' : 'Justin Meyer',
+  'birthday': '1982-10-20',
+  'tasks' : [
+    {'id': 1, 
+     'title': "write up model layer", 
+     'due': "2010-10-5" },
+    {'id': 1, 
+     'title': "document models", 
+     'due': "2010-10-8"}]},
+  ...
+]
+@codeend
+
+We want to be able to do something like:
+
+@codestart
+var tasks = contact.attr("tasks");
+
+tasks[0].due //-> date
+@codeend
+
+Basically, we want <code>attr("tasks")</code> to
+return a list of task instances.
+
+Associations let you do this.  Here's how:
+
+First, create a Task model:
+
+@codestart
+$.Model.extend("Task",{
+  convert : {
+    date : function(date){ ... }
+  },
+  attributes : {
+    due : 'date'
+  }
+},{
+  weeksPastDue : function(){
+    return Math.round( (new Date() - this.due) /
+          (1000*60*60*24*7 ) );
+  }
+})
+@codeend
+
+Then create a Contact model that 'hasMany' tasks:
+
+@codestart
+$.Model.extend("Contact",{
+  associations : {
+    hasMany : "Task"
+  },
+  ...
+},{
+  ...
+});
+@codeend
+
+Here's a demo of this in action:
+
+@demo jquery/model/associations/associations.html
+
+You can customize associations with
+the [jQuery.Model.static.belongsTo belongsTo]
+and [jQuery.Model.static.belongsTo hasMany] methods.
+ */
+
+
+	//overwrite model's setup to provide associations
+	
+	var oldSetup = $.Model.setup,
+		associate = function(hasMany, Class, type){
+			hasMany = hasMany || [];
+			hasMany = typeof hasMany == 'string' ? [hasMany] : hasMany;
+			for(var i=0; i < hasMany.length;i++){
+				Class[type].call(Class, hasMany[i])
+			}
+		};
+	// this provides associations on the has many
+	$.Model.setup = function(){
+		oldSetup.apply(this, arguments);
+		associate( this.associations.hasMany, this, "hasMany");
+		associate(this.associations.belongsTo, this, "belongsTo");
+		delete this.associations.hasMany;
+		delete this.associations.belongsTo;
+	}
+
+	
+	$.Model.
+	/**
+	 * @function jQuery.Model.static.belongsTo
+	 * @parent jquery.model.associations
+	 * @plugin jquery/model/associations
+	 * Use to convert values on attribute <i>name</i> to
+	 * instances of model <i>type</i>.
+	 * @codestart
+	 * $.Model.extend("Task",{
+	 *   init : function(){
+	 *     this.belongsTo("Person","assignedTo");
+	 *   }
+	 * },{})
+	 * @codeend
+	 * 
+	 * @param {String} type The string name of the model.
+	 * @param {String} [name] The name of the property.  Defaults to the shortName of the model.
+	 */
+	belongsTo = function(type, name){
+		name = name || $.String.camelize( type.match(/\w+$/)[0] );
+		var cap = $.String.capitalize(name),
+			set = function(v){
+				return ( this[name] = (v == v.Class ? v : $.Class.getObject(type).wrap(v)) )
+			},
+			get = function(){
+				return this[name];
+			}
+			
+		set.doNotInhert = true;
+		get.doNotInherit = true;
+		
+		if(!this.prototype["set"+cap]){
+			this.prototype["set"+cap] = set;
+		}
+		if(!this.prototype["get"+cap]){
+			this.prototype["get"+cap] = get
+		}
+		this.associations[name] = {
+			belongsTo: type
+		};
+		return this;
+	}
+	$.Model.
+	/**
+	 * @function jQuery.Model.static.hasMany
+	 * @parent jquery.model.associations
+	 * @plugin jquery/model/associations
+	 * Converts values on attribute <i>name</i> to
+	 * instances of model <i>type</i>.
+	*  @codestart
+	 * $.Model.extend("Task",{
+	 *   init : function(){
+	 *     this.hasMany("Person","people");
+	 *   }
+	 * },{})
+	 * @codeend
+	 * 
+	 * @param {String} type The string name of the model.
+	 * @param {String} [name] The name of the property.  
+	 * Defaults to the shortName of the model with an "s" at the end.
+	 */
+	hasMany = function(type, name){
+		name = name || $.String.camelize( type.match(/\w+$/)[0] )+"s";
+		
+		var cap = $.String.capitalize(name)
+		if(!this.prototype["set"+cap]){
+			this.prototype["set"+cap] = function(v){
+				// should probably check instanceof
+				return this[name] = (v == v.Class ? v : $.Class.getObject(type).wrapMany(v))
+			}
+		}
+		if(!this.prototype["get"+cap]){
+			this.prototype["get"+cap] = function(){
+				return this[name] || $.Class.getObject(type).wrapMany([]);
+			}
+		}
+		this.associations[name] = {
+			hasMany: type
+		};
+		return this;
+	}
+
+
+
+})
+
diff --git a/browserid/static/dialog/jquery/model/associations/qunit.html b/browserid/static/dialog/jquery/model/associations/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..605cdfd6480397a671d338e98bee74017aff2a50
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/associations/qunit.html
@@ -0,0 +1,21 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../../funcunit/qunit/qunit.css" />
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+		<script type='text/javascript' src='../../../steal/steal.js?steal[app]=jquery/model/associations/test/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">associations Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/associations/test/qunit/associations_test.js b/browserid/static/dialog/jquery/model/associations/test/qunit/associations_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..d787e87e1924424c2842411ed9701b01dd219a3c
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/associations/test/qunit/associations_test.js
@@ -0,0 +1,51 @@
+module("jquery/model/associations",{
+	setup: function() {
+		
+		$.Model.extend("MyTest.Person");
+		$.Model.extend("MyTest.Loan");
+		$.Model.extend("MyTest.Issues");
+		
+		$.Model.extend("MyTest.Customer",
+		{
+			init: function() {
+				this.belongsTo("MyTest.Person")
+				this.hasMany("MyTest.Loan")
+				this.hasMany("MyTest.Issues")
+			}
+		},
+		{});
+	}
+})
+
+
+
+
+
+test("associations work", function(){
+	var c = new MyTest.Customer({
+		id: 5,
+		person : {
+			id: 1,
+			name: "Justin"
+		},
+		issues : [],
+		loans : [
+			{
+				amount : 1000,
+				id: 2
+			},
+			{
+				amount : 19999,
+				id: 3
+			}
+		]
+	})
+	equals(c.person.name, "Justin", "association present");
+	equals(c.person.Class, MyTest.Person, "belongs to association typed");
+	
+	equals(c.issues.length, 0);
+	
+	equals(c.loans.length, 2);
+	
+	equals(c.loans[0].Class, MyTest.Loan);
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/associations/test/qunit/qunit.js b/browserid/static/dialog/jquery/model/associations/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..5dba306c4fbff62adc9a2aab8b93790b49a46890
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/associations/test/qunit/qunit.js
@@ -0,0 +1,9 @@
+//we probably have to have this only describing where the tests are
+steal
+ .plugins("jquery/model/associations")  //load your app
+ .plugins('funcunit/qunit')  //load qunit
+ .then("associations_test")
+ 
+if(steal.browser.rhino){
+  steal.plugins('funcunit/qunit/env')
+}
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/backup/backup.html b/browserid/static/dialog/jquery/model/backup/backup.html
new file mode 100644
index 0000000000000000000000000000000000000000..7a6280ff51c1d675bb19d8c95c9a354899039a80
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/backup/backup.html
@@ -0,0 +1,126 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>Model Backup Demo</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            li {border: solid 1px gray; padding: 5px; width: 250px;}
+			li a {color: red; font-weight: bold;}
+			p {width: 400px;}
+        </style>
+	</head>
+	<body>
+		<div id="demo-instructions">
+		<h1>Model Backup Demo</h1>
+			<p>This demo shows backing up and restoring model instances.
+			Click the names to change birthdays.  After changing some birthdays,
+			click RESTORE.  
+			</p>
+		</div>
+<div id="demo-html">
+<div id='contacts'></div>
+<div id='update'></div>
+<a href='javascript://' id='restore'>RESTORE</a>
+</div>
+<script type='text/javascript' 
+        src='../../../steal/steal.js'>   
+</script>
+<script type='text/javascript'>
+steal.plugins('jquery/model',
+		'jquery/dom/fixture',
+		'jquery/model/list',
+		'jquery/model/backup').start()
+</script>
+<script type='text/javascript'>  
+$.Model.extend("Contact",{
+	attributes : { 
+		birthday : 'date'
+	},
+	convert : {
+		date : function(raw){
+			if(typeof raw == 'string'){
+				var matches = raw.match(/(\d+)-(\d+)-(\d+)/)
+				return new Date( +matches[1], 
+				                 (+matches[2])-1, 
+				                 +matches[3] )
+			}else if(raw instanceof Date){
+				return raw;
+			}
+		}
+	},
+	findAll : function(params, success, error){
+		$.get("/recipes.json",
+			{},
+			this.callback(['wrapMany',success]),
+			"json",
+			function(){
+				return [[{'id': 1,'name' : 'Justin Meyer','birthday': '1982-10-20'},
+					 {'id': 2,'name' : 'Brian Moschel','birthday': '1983-11-10'},
+					 {'id': 3,'name' : 'Alex Gomes','birthday': '1980-2-10'}]];
+			})
+	},
+	update : function(id, attrs, success, error){
+		$.post("/recipes.json",{},success,'json',function(){
+			return [attrs]
+		})
+	}
+},{
+	ageThisYear : function(){
+		return new Date().getFullYear() - 
+		      this.birthday.getFullYear()
+	},
+	getBirthday : function(){
+		return ""+this.birthday.getFullYear()+
+			"-"+(this.birthday.getMonth()+1)+
+			"-"+this.birthday.getDate();
+	}
+
+});
+makeAgeUpdater = function(contact){
+	var updater = $("#update")
+	updater.html("");
+	updater.append(contact.name+"'s birthday")
+	$('<input/>').val(contact.attr("birthday")).change(function(){
+		contact.update({
+			'birthday': this.value
+		})
+	}).appendTo(updater)
+}
+$('#contacts').delegate("li","click", function(){
+	 makeAgeUpdater( $(this).closest('.contact').model() );
+  });
+</script>
+<script type='text/javascript'>   
+Contact.findAll({},function(contacts){
+  var contactsEl = $('#contacts');
+  $.each(contacts, function(i, contact){
+    
+	// add the contact to the page
+	var li = $('<li>')
+              .model(contact)
+              .html(contact.name+" "+
+			  		contact.ageThisYear()+
+                    " <a>Show</a>")
+              .appendTo(contactsEl);
+    
+	// listen for changes in birthday
+	contact.bind("birthday", function(){
+      li.html(contact.name+" "+this.ageThisYear()+
+              " <a>Show</a>");
+    })
+	
+	// backup the contact
+	contact.backup();
+  })
+  
+  // on restore, update all contacts
+  $("#restore").click(function(){
+  	contacts.each(function(){
+		this.restore()
+	})
+  })
+});
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/backup/backup.js b/browserid/static/dialog/jquery/model/backup/backup.js
new file mode 100644
index 0000000000000000000000000000000000000000..65290f3e3d0c658801038f21094d01923ae1513d
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/backup/backup.js
@@ -0,0 +1,142 @@
+//allows you to backup and restore a model instance
+steal.plugins('jquery/model').then(function(){
+
+/**
+@page jquery.model.backup Backup / Restore
+@parent jQuery.Model
+@plugin jquery/model/backup
+@test jquery/model/backup/qunit.html
+@download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/model/backup/backup.js
+
+You can backup and restore instance data with the jquery/model/backup
+plugin.
+
+To backup a model instance call [jQuery.Model.prototype.backup backup] like:
+
+@codestart
+var recipe = new Recipe({name: "cheese"});
+recipe.backup()
+@codeend
+
+You can check if the instance is dirty with [jQuery.Model.prototype.isDirty isDirty]:
+
+@codestart
+recipe.name = 'blah'
+recipe.isDirty() //-> true
+@codeend
+
+Finally, you can restore the original attributes with 
+[jQuery.Model.prototype.backup backup].
+
+@codestart
+recipe.restore();
+recipe.name //-> "cheese"
+@codeend
+
+See this in action:
+
+@demo jquery/model/backup/backup.html
+ */
+
+	// a helper to iterate through the associations
+	var associations = function(instance, func){
+		var name, 
+			res;
+			
+		for(name in instance.Class.associations){
+			association = instance.Class.associations[name];
+			if("belongsTo" in association){
+				if(instance[name] && (res = func(instance[name]) ) ){
+					return res;
+				}
+			}
+			if("hasMany" in association){
+				if(instance[name]){
+					for(var i =0 ; i < instance[name].length; i++){
+						if( (res = func(instance[name][i]) ) ){
+							return res;
+						}
+					}
+				}	
+			}
+		}
+	}
+	
+
+	$.extend($.Model.prototype,{
+		/**
+		 * @function jQuery.Model.prototype.backup
+		 * @plugin jquery/model/backup
+		 * @parent jquery.model.backup
+		 * Backs up an instance of a model, so it can be restored later.
+		 * The plugin also adds an [jQuery.Model.prototype.isDirty isDirty]
+		 * method for checking if it is dirty.
+		 */
+		backup: function() {
+			associations(this, function(associated){
+				associated.backup();
+			})
+			this._backupStore = $.extend(true, {},this.attrs());
+			return this;
+		},
+	   
+	   _backup: function() {
+		   this._backupStore = $.extend(true, {},this.attrs());
+	   },
+	   /**
+	    * @function jQuery.Model.prototype.isDirty
+	    * @plugin jquery/model/backup
+	    * @parent jquery.model.backup
+	    * Returns if the instance needs to be saved.  This will go
+	    * through associations too.
+	    * @param {Boolean} [checkAssociations=false] true if associations should be checked.  Defaults to false.
+	    * be checked, false if otherwise
+	    * @return {Boolean} true if there are changes, false if otherwise
+	    */
+	   isDirty: function(checkAssociations) {
+			if(!this._backupStore) return false;
+			//go through attrs and compare ...
+			var current = this.attrs(),
+				name,
+				association,
+				res;
+			for(name in current){
+				if(current[name] !== this._backupStore[name]){
+					return true;
+				}
+					
+			}
+			if( checkAssociations ){
+				res = associations(this, function(associated){
+					return associated.isDirty();
+				})
+				if(res === true){
+					return true;
+				}
+			}
+			
+			return false;
+		},
+		/**
+		 * @function jQuery.Model.prototype.restore
+		 * @plugin jquery/model/backup
+		 * @parent jquery.model.backup
+		 * restores this instance to its backup data.
+		 * @param {Boolean} [restoreAssociations=false] if true, restores associations.
+		 * @return {model} the instance (for chaining)
+		 */
+		restore: function(restoreAssociations) {
+			this.attrs(this._backupStore);   
+			
+			if( restoreAssociations ){
+				associations(this, function(associated){
+					associated.restore();
+				})
+			}
+			return this;
+		}
+	   
+   })
+})
+
+
diff --git a/browserid/static/dialog/jquery/model/backup/qunit.html b/browserid/static/dialog/jquery/model/backup/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..954b041b3f6b0eeb4765cfbfdd9de1152b72cc77
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/backup/qunit.html
@@ -0,0 +1,21 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../../funcunit/qunit/qunit.css" />
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+		<script type='text/javascript' src='../../../steal/steal.js?jquery/model/backup/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">Model Backup Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/backup/qunit/qunit.js b/browserid/static/dialog/jquery/model/backup/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..a30ca1a49d08cf10ec92877c89dd528f73c08885
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/backup/qunit/qunit.js
@@ -0,0 +1,100 @@
+steal.plugins('funcunit/qunit')
+ .plugins("jquery/model/backup","jquery/model/associations").then(function(){
+ 	
+	
+module("jquery/model/backup",{
+	setup : function(){
+		$.Model.extend("Recipe")
+	}
+})
+
+test("backing up", function(){
+	var recipe = new Recipe({name: "cheese"});
+	ok(!recipe.isDirty(), "not backedup, but clean")
+	
+	recipe.backup();
+	ok(!recipe.isDirty(), "backedup, but clean");
+	
+	recipe.name = 'blah'
+	
+	ok(recipe.isDirty(), "dirty");
+	
+	recipe.restore();
+	
+	ok(!recipe.isDirty(), "restored, clean");
+	
+	equals(recipe.name, "cheese" ,"name back");
+	
+});
+
+test("backup / restore with associations", function(){
+	$.Model.extend("Instruction")
+	Recipe.hasMany("Instruction")
+	
+	$.Model.extend("Cookbook")
+	Recipe.belongsTo("Cookbook")
+	
+	var recipe = new Recipe({
+		name: "cheese burger",
+		instructions : [
+			{
+				description: "heat meat"
+			},
+			{
+				description: "add cheese"
+			}
+		],
+		cookbook: {
+			title : "Justin's Grillin Times"
+		}
+	});
+	
+	//test basic is dirty
+	
+	ok(!recipe.isDirty(), "not backedup, but clean")
+	
+	recipe.backup();
+	ok(!recipe.isDirty(), "backedup, but clean");
+	
+	recipe.name = 'blah'
+	
+	ok(recipe.isDirty(), "dirty");
+	
+	recipe.restore();
+	
+	ok(!recipe.isDirty(), "restored, clean");
+	
+	equals(recipe.name, "cheese burger" ,"name back");
+	
+	// test belongs too
+	
+	ok(!recipe.cookbook.isDirty(), "cookbook not backedup, but clean");
+	
+	recipe.cookbook.backup();
+	
+	recipe.cookbook.attr("title","Brian's Burgers");
+	
+	ok(!recipe.isDirty(), "recipe itself is clean");
+	
+	ok(recipe.isDirty(true), "recipe is dirty if checking associations");
+	
+	recipe.cookbook.restore()
+	
+	ok(!recipe.isDirty(true), "recipe is now clean with checking associations");
+	
+	equals(recipe.cookbook.title, "Justin's Grillin Times" ,"cookbook title back");
+	
+	//try belongs to recursive restore
+	
+	recipe.cookbook.attr("title","Brian's Burgers");
+	recipe.restore();
+	ok(recipe.isDirty(true), "recipe is dirty if checking associations, after a restore");
+	
+	recipe.restore(true);
+	ok(!recipe.isDirty(true), "cleaned all of recipe and its associations");
+	
+	
+})
+
+})
+ 
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/demo-convert.html b/browserid/static/dialog/jquery/model/demo-convert.html
new file mode 100644
index 0000000000000000000000000000000000000000..f9ad742892e56a9bdf4680d24d75aa5ed6c138fe
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/demo-convert.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>Model Convert Demo</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            li {border: solid 1px gray; padding: 5px; width: 250px;}
+			li a {color: red; font-weight: bold;}
+			p {width: 400px;}
+        </style>
+	</head>
+	<body>
+<div id="demo-instructions">
+		<h1>Model Convert Demo</h1>
+		<p>This demo shows converting date strings sent by the
+		server to JavaScript dates with attributes and convert.</p>
+</div>
+<div id="demo-html">
+<ul id='contacts'></ul>
+</div>	
+<script type='text/javascript' 
+        src='../../steal/steal.js'>   
+</script>
+<script type='text/javascript'>
+steal.plugins('jquery/model',
+		'jquery/dom/fixture',
+		'jquery/model/list').start()
+CONTACTS = [{'id': 1,'name' : 'Justin Meyer','birthday': '1982-10-20'},
+			 {'id': 2,'name' : 'Brian Moschel','birthday': '1983-11-10'},
+			 {'id': 3,'name' : 'Alex Gomes','birthday': '1980-2-10'}]
+CONTACTS_FIXTURE =  function(){
+				return [CONTACTS];
+			};
+</script>
+<script type='text/javascript' id="demo-source">   
+// A contact model
+$.Model.extend("Contact",{
+	attributes : { 
+		birthday : 'date'
+	},
+	convert : {
+		date : function(raw){
+			if(typeof raw == 'string'){
+				var matches = raw.match(/(\d+)-(\d+)-(\d+)/)
+				return new Date( matches[1], 
+				                 (+matches[2])-1, 
+				                 matches[3] )
+			}else if(raw instanceof Date){
+				return raw;
+			}
+		}
+	},
+	findAll : function(params, success, error){
+		$.get("/recipes.json", {},
+			this.callback(['wrapMany',success]),
+			"json", CONTACTS_FIXTURE );
+			
+	}
+},{
+});
+
+// get the distance between years
+var age = function(birthday){
+   return new Date().getFullYear() - 
+          birthday.getFullYear()
+};
+
+// get all contacts and put them in the page
+Contact.findAll( {}, function( contacts ){
+  var html = [];
+  for(var i =0; i < contacts.length; i++){
+    html.push('<li>'+age(contacts[i].birthday) + '</li>')
+  }
+  $('#contacts').html( html.join('') );
+});
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/demo-dom.html b/browserid/static/dialog/jquery/model/demo-dom.html
new file mode 100644
index 0000000000000000000000000000000000000000..23e9450644142329b3d7d3880764dac80935189b
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/demo-dom.html
@@ -0,0 +1,96 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>Model Convert Demo</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            li {border: solid 1px gray; padding: 5px; width: 250px;}
+			li a {color: red; font-weight: bold;}
+			p {width: 400px;}
+        </style>
+	</head>
+	<body>
+<div id="demo-instructions">
+		<h1>Model DOM Helpers Demo</h1>
+		<p>This demo shows using models to set an instance on an element.</p>
+</div>
+<div id="demo-html">
+<ul id='contacts'></ul>
+</div>	
+<script type='text/javascript' 
+        src='../../steal/steal.js'>   
+</script>
+<script type='text/javascript'>
+steal.plugins('jquery/model',
+		'jquery/dom/fixture').start()
+</script>
+<script type='text/javascript'>
+CONTACTS = [{'id': 1,'name' : 'Justin Meyer','birthday': '1982-10-20'},
+			 {'id': 2,'name' : 'Brian Moschel','birthday': '1983-11-10'},
+			 {'id': 3,'name' : 'Alex Gomes','birthday': '1980-2-10'}]
+CONTACTS_FIXTURE =  function(){
+				return [CONTACTS];
+			};
+			
+// A contact model
+$.Model.extend("Contact",{
+	attributes : { 
+		birthday : 'date'
+	},
+	convert : {
+		date : function(raw){
+			if(typeof raw == 'string'){
+				var matches = raw.match(/(\d+)-(\d+)-(\d+)/)
+				return new Date( matches[1], 
+				                 (+matches[2])-1, 
+				                 matches[3] )
+			}else if(raw instanceof Date){
+				return raw;
+			}
+		}
+	},
+	findAll : function(params, success, error){
+		$.get("/recipes.json", {},
+			this.callback(['wrapMany',success]),
+			"json", CONTACTS_FIXTURE );
+			
+	},
+	destroy : function(id, success, error){
+		success({});
+	}
+},{
+	ageThisYear : function(){
+		return new Date().getFullYear() - 
+			this.birthday.getFullYear()
+	}
+
+});
+</script>
+<script type='text/javascript' id="demo-source">   
+Contact.findAll({},function(contacts){
+  var contactsEl = $('#contacts');
+  for(var i =0; i < contacts.length; i++){
+   $('<li>').model(contacts[i])
+            .html(contacts[i].ageThisYear()+
+                  " <a>DELETE</a>")
+            .appendTo(contactsEl)
+  }
+});
+$("#contacts a").live('click', function(){
+  //get the element for this recipe
+  var contactEl = $(this).closest('.contact')
+  
+  // get the conctact instance
+  contactEl.model()
+           // call destroy on the instance
+           .destroy(function(){
+                      // remove the element
+                      contactEl.remove();
+                    })
+		  
+})
+
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/demo-encapsulate.html b/browserid/static/dialog/jquery/model/demo-encapsulate.html
new file mode 100644
index 0000000000000000000000000000000000000000..d6a4ffa1fb32d92754d808048a1d04abde5ee3f1
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/demo-encapsulate.html
@@ -0,0 +1,159 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>Grid / Encapsulate Demo</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            
+        </style>
+	</head>
+	<body>
+<div id="demo-instructions">
+<h1>Model Encapsulate Demo</h1>
+<p>This demonstrates how encapsulating Ajax functionality in
+	models makes your code more reusable.  The same grid 
+	widget uses two different models.
+</p>
+</div>
+<div id="demo-html">
+<h2>Recipe Grid</h2>
+<div id='recipes'></div>
+<h2>Work Item Grid</h2>
+<div id='workItems'></div>
+</div>
+<script type='text/javascript' 
+        src='../../steal/steal.js'>   
+</script>
+<script type='text/javascript'>
+	steal.plugins('jquery/model',
+		'jquery/controller',
+		'jquery/dom/form_params',
+		'jquery/dom/fixture',
+		'jquery/view/ejs').start()
+</script>
+<script type='text/ejs' id='listView'>
+	<table cellspacing='0px'>
+	<thead>
+	<tr>
+	    <% for(var attr in model.attributes){%>
+	        <% if(attr == 'id') continue;%>
+	        <th><%= attr%> </th>    
+	    <%}%>
+	    <th>Options</th>
+	</tr>
+	</thead>
+	<tbody>
+		<% for(var i =0; i < items.length;i++){ %>
+			<tr <%= items[i] %>>
+				<%= view('itemView',{item: items[i], model : model})%>
+			</tr>
+		<%} %>
+	    
+	</tbody>
+</table>
+</script>
+<script type='text/ejs' id='itemView'>
+	<%for(var attribute in model.attributes){%>
+	    <%if(attribute == 'id') continue;%>
+	    <td class='<%= attribute %>'>
+	            <input type="text" value="<%= item[attribute]%>" name="<%= attribute%>"/>
+	    </td>
+	<%}%>
+	<td>
+	    <input type='submit' value='Update' class='update'/>
+	    <a href='javascript://' class='cancel'>cancel</a>
+	</td>
+</script>
+<script type='text/javascript'>
+// Use fixtures to make 4 recipes
+$.fixture.make(["recipes","recipe"],4, function(i, messages){
+	return {
+		title: "Recipe "+i,
+		instructions: "Here are some instructions"
+	}
+})
+// Use fixtures to make 4 work items
+$.fixture.make(["workitems","workitem"],4, function(i, messages){
+	return {
+		task: "item "+i,
+		instructions: "Here are some instructions",
+		assignedTo : i%2? "Brian" : "Justin"
+	}
+})
+</script>
+<script type='text/javascript' id="demo-source">   
+// A grid widget
+$.Controller.extend("Grid",{
+	// when added to an element, use the model
+	// to find items
+	init : function(){
+		this.options.model.findAll({},this.callback('list'))
+	},
+	// draw the items in this element
+	list : function(items){
+		this.element.html("listView", {model : this.options.model, items: items})
+	},
+	// on update, get values, and update model instance
+	".update click" : function(el){
+		// get the tr that has our new model data
+		var tr =  el.closest('tr'),
+			
+			// get the model isntance
+			item = tr.model();
+		
+		// make it look like we are updating
+		el.val("updating ...").attr("disabled", true)
+		
+		// update the model instance
+		item.update(tr.formParams(), this.callback('updated'));
+	},
+	updated : function(item){
+		// update the html
+		item.elements(this.element).html('itemView',
+			{model : this.options.model, item: item})
+	},
+	// on cancel, use the existing model to redraw html
+	".cancel click" : function(el){
+		var tr =  el.closest('tr')
+			item = tr.model();
+		tr.html('itemView',{model : this.options.model, item: item})
+	}
+})
+
+// A Recipe model that implements findAll and update
+$.Model.extend("Recipe",{
+	findAll : function(params, success, error){
+		$.get("/recipes.json",{},
+				this.callback(['wrapMany',success]),
+				"json","-recipes")
+	},
+	update : function(id, attrs, success, error){
+		$.post("/recipes.json",{},success,'json',function(){
+			return [attrs]
+		})
+	}
+},{});
+
+// A WorkItem model that implements findAll and update
+$.Model.extend("WorkItem",{
+	findAll : function(params, success, error){
+		$.get("/recipes.json", {},
+			  this.callback(['wrapMany',success]),
+			  "json","-workitems")
+	},
+	update : function(id, attrs, success, error){
+		$.post("/recipes.json",{},success,'json',function(){
+			return [attrs]
+		})
+	}
+},{});
+
+// Add a grid with recipes
+$("#recipes").grid({model: Recipe});
+
+// Add a grid with workitems
+$("#workItems").grid({model: WorkItem});
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/demo-events.html b/browserid/static/dialog/jquery/model/demo-events.html
new file mode 100644
index 0000000000000000000000000000000000000000..2fc7bf53aeac0d9d73cf00d4666c951fab024097
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/demo-events.html
@@ -0,0 +1,179 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>Model Events Demo</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            li {border: solid 1px gray; padding: 5px; width: 250px;}
+			li a {color: red; font-weight: bold;}
+			p {width: 400px;}
+        </style>
+	</head>
+	<body>
+<div id="demo-instructions">
+		<h1>Model Events Demo</h1>
+		<p>This demo shows listening to model update events.
+		Clicking on a person's name will show a form to update
+		their birthday.  Change the birthday and 'blur' the 
+		input to update their listed age.</p>
+</div>
+<div id="demo-html">
+<div id='update'></div>
+
+<h2>Direct Binding</h2>
+<p>
+   The following list binds 
+   directly to "birthday" events.
+</p>
+<div id='contacts1'></div>
+
+<h2>Subscribing</h2>
+<p>
+   The following list subscribes
+   to "contact.updated" events.
+</p>
+<div id='contacts2'></div>
+</div>
+<script type='text/javascript' 
+        src='../../steal/steal.js'>   
+</script>
+<script type='text/javascript'>
+steal.plugins('jquery/model',
+		'jquery/dom/fixture',
+		'jquery/model/list',
+		'jquery/lang/openajax').start()
+</script>
+
+<script type='text/javascript'>
+$.Model.extend("Contact",{
+	attributes : { 
+		birthday : 'date'
+	},
+	convert : {
+		date : function(raw){
+			if(typeof raw == 'string'){
+				var matches = raw.match(/(\d+)-(\d+)-(\d+)/)
+				return new Date( matches[1], 
+				                 (+matches[2])-1, 
+				                 matches[3] )
+			}else if(raw instanceof Date){
+				return raw;
+			}
+		}
+	},
+	findAll : function(params, success, error){
+		$.get("/recipes.json",
+			{},
+			this.callback(['wrapMany',success]),
+			"json",
+			function(){
+				return [[{'id': 1,'name' : 'Justin Meyer','birthday': '1982-10-20'},
+					 {'id': 2,'name' : 'Brian Moschel','birthday': '1983-11-10'},
+					 {'id': 3,'name' : 'Alex Gomes','birthday': '1980-2-10'}]];
+			})
+	},
+	update : function(id, attrs, success, error){
+		$.post("/recipes.json",{},success,'json',function(){
+			return [attrs]
+		})
+	}
+},{
+	ageThisYear : function(){
+		return new Date().getFullYear() - 
+		      this.birthday.getFullYear()
+	},
+	getBirthday : function(){
+		return ""+this.birthday.getFullYear()+
+			"-"+(this.birthday.getMonth()+1)+
+			"-"+this.birthday.getDate();
+	}
+});
+
+drawList1 = function(contact){
+	return  $('<li>')
+              .model(contact)
+              .html(contact.name+" "+contact.ageThisYear()+
+                    " <a>Show</a>")
+              .appendTo(contactsEl)
+};
+
+$('#contacts1').delegate("li","click", function(){
+	makeAgeUpdater( $(this).closest('.contact').model() );
+});
+
+  
+makeAgeUpdater = function(contact){
+	var updater = $("#update")
+	updater.html("");
+	updater.append(contact.name+"'s birthday")
+	$('<input/>').val(contact.attr("birthday")).change(function(){
+		contact.update({
+			'birthday': this.value
+		})
+	}).appendTo(updater)
+}
+</script>
+
+<script type='text/javascript'>   
+
+
+
+makeList1 = function(contacts){
+  var contactsEl = $('#contacts1');
+  $.each(contacts, function(i, contact){
+    var li = $('<li>')
+              .model(contact)
+              .html(contact.name+" "+contact.ageThisYear()+
+                    " <a>Show</a>")
+              .appendTo(contactsEl);
+    contact.bind("birthday", function(){
+      li.html(contact.name+" "+this.ageThisYear()+
+              " <a>Show</a>");
+    })
+  })
+  
+};
+makeList2 = function(contacts){
+  var contactsEl = $('#contacts2'),
+  	html = [], 
+	contact;
+	
+  for(var i =0; i < contacts.length;i++){
+  	contact = contacts[i]
+	html.push("<li class='contact ",
+		contact.identity(),"'>",
+		contact.name+" "+contact.ageThisYear()+
+                    " <a>Show</a>",
+		"</li>")
+  }
+  contactsEl.html(html.join(""))
+  
+  
+  $('#contacts2').delegate("li","click", function(){
+	makeAgeUpdater( contacts.get(this)[0] );
+  });
+  
+}
+
+OpenAjax.hub.subscribe("contact.updated", function(called, contact){
+	 contact.elements($('#contacts2'))
+        .html(contact.name+" "+contact.ageThisYear()+
+          " <a>Show</a>");
+})
+
+
+// List 1
+Contact.findAll({},function(contacts){
+  makeList1(contacts);
+  makeList2(contacts)
+});
+
+
+
+
+
+
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/demo-setter.html b/browserid/static/dialog/jquery/model/demo-setter.html
new file mode 100644
index 0000000000000000000000000000000000000000..18f8f3dcf94db955038d5c83fa050d282270bd53
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/demo-setter.html
@@ -0,0 +1,77 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>Model Events Demo</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            li {border: solid 1px gray; padding: 5px; width: 250px;}
+			li a {color: red; font-weight: bold;}
+			p {width: 400px;}
+        </style>
+	</head>
+	<body>
+<div id="demo-instructions">
+		<h1>Model Setter Demo</h1>
+		<p>This demo shows converting date strings sent by the
+		server to JavaScript dates with Setters.</p>
+</div>
+<div id="demo-html">
+<ul id='contacts'></ul>
+</div>	
+<script type='text/javascript' 
+        src='../../steal/steal.js'>   
+</script>
+<script type='text/javascript'>
+steal.plugins('jquery/model',
+		'jquery/dom/fixture',
+		'jquery/model/list').start()
+CONTACTS = [{'id': 1,'name' : 'Justin Meyer','birthday': '1982-10-20'},
+			 {'id': 2,'name' : 'Brian Moschel','birthday': '1983-11-10'},
+			 {'id': 3,'name' : 'Alex Gomes','birthday': '1980-2-10'}]
+CONTACTS_FIXTURE =  function(){
+				return [CONTACTS];
+			};
+</script>
+<script type='text/javascript' id="demo-source">   
+// A contact model
+$.Model.extend("Contact",{
+	findAll : function(params, success, error){
+		$.get("/recipes.json", {},
+			this.callback(['wrapMany',success]),
+			"json", CONTACTS_FIXTURE );
+			
+	}
+},{
+	// converts dates
+	setBirthday : function(raw){
+		if(typeof raw == 'string'){
+				var matches = raw.match(/(\d+)-(\d+)-(\d+)/)
+				return new Date( matches[1], 
+				                (+matches[2])-1, 
+			                     matches[3] )
+		}else if(raw instanceof Date){
+			return raw;
+		}
+	}
+
+
+});
+
+// get the distance between years
+var age = function(birthday){
+   return new Date().getFullYear() - 
+          birthday.getFullYear()
+};
+
+// get all contacts and put them in the page
+Contact.findAll( {}, function( contacts ){
+  var html = [];
+  for(var i =0; i < contacts.length; i++){
+    html.push('<li>'+age(contacts[i].birthday) + '</li>')
+  }
+  $('#contacts').html( html.join('') );
+});
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/fixtures/school.json b/browserid/static/dialog/jquery/model/fixtures/school.json
new file mode 100644
index 0000000000000000000000000000000000000000..734e4916c8f14f76a11791004c50d4cc226f68c9
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/fixtures/school.json
@@ -0,0 +1,4 @@
+{
+	"id": 4,
+	"name" : "Highland"
+}
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/fixtures/schools.json b/browserid/static/dialog/jquery/model/fixtures/schools.json
new file mode 100644
index 0000000000000000000000000000000000000000..1b596fa06c04f73cf6066fa33247114eed5ffa35
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/fixtures/schools.json
@@ -0,0 +1,4 @@
+[{
+	"id": 1,
+	"name" : "adler"
+}]
diff --git a/browserid/static/dialog/jquery/model/list/cookie/cookie.html b/browserid/static/dialog/jquery/model/list/cookie/cookie.html
new file mode 100644
index 0000000000000000000000000000000000000000..69024d3a3d0826cdd109d1256e083b04cd057595
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/list/cookie/cookie.html
@@ -0,0 +1,117 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>Model List Cookie Demo</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            li {border: solid 1px gray; padding: 5px; width: 250px;}
+			li a {color: red; font-weight: bold;}
+			p {width: 400px;}
+        </style>
+	</head>
+	<body>
+		<div id="demo-instructions">
+			<h1>Cookie List Demo</h1>
+			<p>This demo show keeping data stored in a cookie.  Create a few contacts,
+			refresh the page, and they should still be present.</p>
+		</div>
+<div id="demo-html">
+<h2>Create A Contact</h2>
+<form action='' id='contact'>
+	<label>Name</label> 
+	<input type='text' name='name'/> <br/>
+	<label>Birthday</label> 
+	<input type='text' name='birthday' value='1982-10-20'/> 
+	(must be like 1982-10-20)<br/>
+	<input type='submit' value='Create' />
+</form>
+<h2>List of Contacts</h2>
+<div id='contacts'></div>
+</div>
+		
+<script type='text/javascript' 
+        src='../../../../steal/steal.js'>   
+</script>
+<script type='text/javascript'>
+steal.plugins('jquery/model',
+		'jquery/model/list/cookie',
+		'jquery/dom/form_params').start()
+</script>
+<script type='text/javascript'>   
+
+$.Model.extend("Contact",{
+	attributes : { 
+		birthday : 'date'
+	},
+	convert : {
+		date : function(raw){
+			if(typeof raw == 'string'){
+				var matches = raw.match(/(\d+)-(\d+)-(\d+)/)
+				return new Date( +matches[1], 
+				                 (+matches[2])-1, 
+				                 +matches[3] )
+			}else if(raw instanceof Date){
+				return raw;
+			}
+		}
+	}
+},{
+	ageThisYear : function(){
+		return new Date().getFullYear() - 
+		      this.birthday.getFullYear()
+	},
+	getBirthday : function(){
+		return ""+this.birthday.getFullYear()+
+			"-"+(this.birthday.getMonth()+1)+
+			"-"+this.birthday.getDate();
+	}
+
+});
+
+// Create a contact list
+$.Model.List.Cookie.extend("Contact.List");
+
+// A helper function for adding a contact to the page
+var addContact = function(contact){
+	 var li = $('<li>')
+              .model(contact)
+              .html(contact.name+" "+contact.ageThisYear())
+              .appendTo($("#contacts"));
+}
+$(function(){
+	// pull saved contacts into this list
+	var contacts = new Contact.List([]).retrieve("contacts");
+	
+	// add each contact to the page
+	contacts.each(function(){
+		addContact(this);
+	});
+	
+	// when a new cookie is crated
+	$("#contact").submit(function(ev){
+		ev.preventDefault();
+		var data = $(this).formParams();
+		
+		// gives it a random id
+		data.id = +new Date();
+		var contact = new Contact(data);
+		
+		//add it to the list of contacts 
+		contacts.push(contact);
+		
+		//store the current list
+		contacts.store("contacts");
+		
+		//show the contact
+		addContact(contact);
+	})
+})
+
+
+
+
+
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/list/cookie/cookie.js b/browserid/static/dialog/jquery/model/list/cookie/cookie.js
new file mode 100644
index 0000000000000000000000000000000000000000..308e60d18fe025c40d8c748f283c97658f276d84
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/list/cookie/cookie.js
@@ -0,0 +1,91 @@
+steal.plugins('jquery/dom/cookie','jquery/model/list').then(function($){
+
+/**
+ * @plugin jquery/model/list/cookie
+ * @test jquery/model/list/cookie/qunit.html
+ * @download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/model/list/cookie/cookie.js
+ * @parent jQuery.Model.List
+ * 
+ * Provides a store-able list of model instances.  The following 
+ * retrieves and saves a list of contacts:
+ * 
+ * @codestart
+ * var contacts = new Contact.List([]).retrieve("contacts");
+ * 
+ * // add each contact to the page
+ * contacts.each(function(){
+	addContact(this);
+ * });
+ * 
+ * // when a new cookie is crated
+ * $("#contact").submit(function(ev){
+ * 	ev.preventDefault();
+ * 	var data = $(this).formParams();
+ * 	
+ * 	// gives it a random id
+ * 	data.id = +new Date();
+ * 	var contact = new Contact(data);
+ * 	
+ * 	//add it to the list of contacts 
+ * 	contacts.push(contact);
+ * 	
+ * 	//store the current list
+ * 	contacts.store("contacts");
+ * 	
+ * 	//show the contact
+ * 	addContact(contact);
+ * })
+ * @codeend
+ * 
+ * You can see this in action in the following demo.  Create a contact, then
+ * refresh the page.
+ * 
+ * @demo jquery/model/list/cookie/cookie.html
+ */
+$.Model.List.extend("jQuery.Model.List.Cookie",
+/**
+ * @Prototype
+ */
+{
+	days : null,
+	/**
+	 * Deserializes a list of instances in the cookie with the provided name
+	 * @param {String} name the name of the cookie to use.
+	 * @return {jQuery.Model} returns this model instance.
+	 */
+	retrieve : function(name){
+		// each also needs what they are referencd by ?
+		var props = $.cookie( name ) || {type : null, ids : []},
+			instances = [],
+			Class = props.type ? $.Class.getObject(props.type) :  null;
+		for(var i =0; i < props.ids.length;i++){
+			var identity = props.ids[i],
+				instanceData = $.cookie( identity );
+			instances.push( new Class(instanceData) )
+		}
+		this.push.apply(this,instances);
+		return this;
+	},
+	/**
+	 * Serializes and saves this list of model instances to the cookie in name.
+	 * @param {String} name the name of the cookie
+	 * @return {jQuery.Model} returns this model instance.
+	 */
+	store : function(name){
+		//  go through and listen to instance updating
+		var ids = [], days = this.days;
+		this.each(function(i, inst){
+			$.cookie(inst.identity(), $.toJSON(inst.attrs()), { expires: days });
+			ids.push(inst.identity());
+		});
+		
+		$.cookie(name, $.toJSON({
+			type: this[0] && this[0].Class.fullName,
+			ids: ids
+		}), { expires: this.days });
+		return this;
+	}
+})
+	
+})
+
diff --git a/browserid/static/dialog/jquery/model/list/cookie/qunit.html b/browserid/static/dialog/jquery/model/list/cookie/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..3cf020d043b45aa692b2d551e193d0a3793b1e1e
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/list/cookie/qunit.html
@@ -0,0 +1,21 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../../../funcunit/qunit/qunit.css" />
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+		<script type='text/javascript' src='../../../../steal/steal.js?steal[app]=jquery/model/list/cookie/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">Model List Cookie Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/list/cookie/qunit/qunit.js b/browserid/static/dialog/jquery/model/list/cookie/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..6dc4b6ae59f242b9e33478c9f5c6271644986022
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/list/cookie/qunit/qunit.js
@@ -0,0 +1,27 @@
+steal.plugins('funcunit/qunit','jquery/model/list/cookie').then(function($){
+	
+module("jquery/model/list/cookie",{
+	setup: function(){
+		// clear any existing cookie ... 
+		$.cookie("list", "", {expires: -1})
+		$.Model.extend("Search", {}, {});
+		
+		$.Model.List.Cookie.extend("Search.Store")
+	}
+})
+
+test("storing and retrieving",function(){
+	
+	var store = new Search.Store([]) //should be able to look up by namespace ....
+	
+	ok(!store.length, "empty list");
+	
+	store.push( new Search({id: 1}), new Search({id: 2})   )
+	store.store("list");
+	
+	var store2 = new Search.Store([]).retrieve("list");
+	equals(store2.length, 2, "there are 2 items")
+	
+})
+	
+})
diff --git a/browserid/static/dialog/jquery/model/list/list-insert.html b/browserid/static/dialog/jquery/model/list/list-insert.html
new file mode 100644
index 0000000000000000000000000000000000000000..5fba5ea692a0a1015a878a42f168dcf0447f7799
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/list/list-insert.html
@@ -0,0 +1,134 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>Model List Insert Demo</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            li {border: solid 1px gray; padding: 5px; width: 250px;}
+			li a {color: red; font-weight: bold;}
+			p {width: 400px;}
+        </style>
+	</head>
+	<body>
+		<div id="demo-instructions">
+			<h1>Model List Demo</h1>
+			<p>This demo shows how you might use Lists to implement deleting a list
+			of contacts.</p>
+		</div>
+<div id="demo-html">
+<div id='contacts'></div>
+<div id='update'></div>
+</div>
+		
+		
+<script type='text/javascript' 
+        src='../../../steal/steal.js'>   
+</script>
+<script type='text/javascript'>
+steal.plugins('jquery/model',
+		'jquery/dom/fixture',
+		'jquery/model/list',
+		'jquery/lang/openajax').start()
+</script>
+<script type='text/javascript'>
+$.Model.extend("Contact",{
+	attributes : { 
+		birthday : 'date'
+	},
+	convert : {
+		date : function(raw){
+			if(typeof raw == 'string'){
+				var matches = raw.match(/(\d+)-(\d+)-(\d+)/)
+				return new Date( +matches[1], 
+				                 (+matches[2])-1, 
+				                 +matches[3] )
+			}else if(raw instanceof Date){
+				return raw;
+			}
+		}
+	},
+	findAll : function(params, success, error){
+		$.get("/recipes.json",
+			{},
+			this.callback(['wrapMany',success]),
+			"json",
+			function(){
+				return [[{'id': 1,'name' : 'Justin Meyer','birthday': '1982-10-20'},
+					 {'id': 2,'name' : 'Brian Moschel','birthday': '1983-11-10'},
+					 {'id': 3,'name' : 'Alex Gomes','birthday': '1980-2-10'}]];
+			})
+	},
+	update : function(id, attrs, success, error){
+		$.post("/recipes.json",{},success,'json',function(){
+			return [attrs]
+		})
+	}
+},{
+	ageThisYear : function(){
+		return new Date().getFullYear() - 
+		      this.birthday.getFullYear()
+	},
+	getBirthday : function(){
+		return ""+this.birthday.getFullYear()+
+			"-"+(this.birthday.getMonth()+1)+
+			"-"+this.birthday.getDate();
+	}
+
+});
+DESTROYFIXTURE = function(){
+				return [true]
+			}
+makeAgeUpdater = function(contact){
+	var updater = $("#update")
+	updater.html("");
+	updater.append(contact.name+"'s birthday")
+	$('<input/>').val(contact.attr("birthday")).change(function(){
+		contact.update({
+			'birthday': this.value
+		})
+	}).appendTo(updater)
+}
+// listen for contact updated events
+  OpenAjax.hub.subscribe(
+    "contact.updated", 
+    function(called, contact){
+		
+		// use the list to get the instance from the element
+        contact.elements($('#contacts'))
+          .html(contact.name+" "+contact.ageThisYear()+
+              " <a>Show</a>");
+    })
+</script>
+<script type='text/javascript' id="demo-source">   
+Contact.findAll({},function(contacts){
+  var contactsEl = $('#contacts'),
+  	html = [], 
+	contact;
+	
+  // collect contact html
+  for(var i =0; i < contacts.length;i++){
+  	contact = contacts[i]
+	html.push("<li class='contact ",
+		contact.identity(), //add the identity to the className manually
+		"'>",
+		contact.name+" "+contact.ageThisYear()+
+                    " <a>Show</a>",
+		"</li>")
+  }
+  // insert contacts html
+  contactsEl.html(html.join(""))
+  
+  contactsEl.delegate("li","click", function(){
+	 // use the contacts list to get the
+	 // contact from the clicked element
+	 var contact = contacts.get(this)[0]
+	 makeAgeUpdater( contact );
+  });
+
+});
+
+
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/list/list.html b/browserid/static/dialog/jquery/model/list/list.html
new file mode 100644
index 0000000000000000000000000000000000000000..9bb252a8d1789098bd070b563e7ee643b578948c
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/list/list.html
@@ -0,0 +1,129 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>List Helper Demo</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            li {border: solid 1px gray; padding: 5px; width: 250px;}
+			li a {color: red; font-weight: bold;}
+			p {width: 400px;}
+        </style>
+	</head>
+	<body>
+		<div id="demo-instructions">
+			<h1>Model List Helper Demo</h1>
+			<p>This demo shows how you might use Lists to implement deleting a list
+			of contacts.</p>
+		</div>
+<div id="demo-html">
+<div id='contacts'></div>
+<a href='javascript://' id='destroyAll'>DESTROY ALL</a>
+</div>
+		
+		
+<script type='text/javascript' 
+        src='../../../steal/steal.js'>   
+</script>
+<script type='text/javascript'>
+steal.plugins('jquery/model',
+		'jquery/dom/fixture',
+		'jquery/model/list').start()
+</script>
+<script type='text/javascript'>
+	$.Model.extend("Contact",{
+	attributes : { 
+		birthday : 'date'
+	},
+	convert : {
+		date : function(raw){
+			if(typeof raw == 'string'){
+				var matches = raw.match(/(\d+)-(\d+)-(\d+)/)
+				return new Date( +matches[1], 
+				                 (+matches[2])-1, 
+				                 +matches[3] )
+			}else if(raw instanceof Date){
+				return raw;
+			}
+		}
+	},
+	findAll : function(params, success, error){
+		$.get("/recipes.json",
+			{},
+			this.callback(['wrapMany',success]),
+			"json",
+			function(){
+				return [[{'id': 1,'name' : 'Justin Meyer','birthday': '1982-10-20'},
+					 {'id': 2,'name' : 'Brian Moschel','birthday': '1983-11-10'},
+					 {'id': 3,'name' : 'Alex Gomes','birthday': '1980-2-10'}]];
+			})
+	},
+	update : function(id, attrs, success, error){
+		$.post("/recipes.json",{},success,'json',function(){
+			return [attrs]
+		})
+	}
+},{
+	ageThisYear : function(){
+		return new Date().getFullYear() - 
+		      this.birthday.getFullYear()
+	},
+	getBirthday : function(){
+		return ""+this.birthday.getFullYear()+
+			"-"+(this.birthday.getMonth()+1)+
+			"-"+this.birthday.getDate();
+	}
+
+});
+DESTROYFIXTURE = function(){
+				return [true]
+			}
+</script>
+<script type='text/javascript' id="demo-source">   
+$.Model.List.extend("Contact.List",{
+	destroyAll : function(){
+		$.post("/destroy",
+			// get a list of ids
+			this.map(function(contact){
+				return contact.id
+			}),
+			this.callback('destroyed'),
+			'json', DESTROYFIXTURE)
+	},
+	destroyed : function(){
+		// call destroyed to publish OpenAjax
+		//  and trigger events
+		this.each(function(){
+			this.destroyed();
+		})
+	}
+});
+
+// Draw a list of contacts
+Contact.findAll({},function(contacts){
+  var contactsEl = $('#contacts');
+  $.each(contacts, function(i, contact){
+    var li = $('<li>')
+              .model(contact)
+              .html("<input type='checkbox'/> "+
+			  		contact.name+" "+
+					contact.ageThisYear()+
+                    " <a>Show</a>")
+              .appendTo(contactsEl);
+    // on destroyed, remove elements
+	contact.bind("destroyed", function(){
+      li.remove();
+    })
+  });
+});
+
+$("#destroyAll").click(function(){
+	//get all checked input model instances
+	$("#contacts input:checked").closest(".contact")
+		.models()
+		// destroy them
+		.destroyAll();
+})
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/list/list.js b/browserid/static/dialog/jquery/model/list/list.js
new file mode 100644
index 0000000000000000000000000000000000000000..b17bc08c10d20a59622ea1f34ca78229f0cc67fa
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/list/list.js
@@ -0,0 +1,285 @@
+steal.plugins('jquery/model').then(function($){
+
+var add = function(data, inst){
+		var id = inst.Class.id;
+		data[inst[id]] = inst;
+	},
+	getArgs = function(args){
+		if(args[0] !== undefined && args[0].length && typeof args[0] != 'string'){
+			return args[0]
+		}else{
+			return $.makeArray(args)
+		}
+	}
+/**
+ * @parent jQuery.Model
+ * @download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/model/list/list.js
+ * @test jquery/model/list/qunit.html
+ * @plugin jquery/model/list
+ * Model lists are useful for:
+ * 
+ *  - Adding helpers for multiple model instances.
+ *  - Faster HTML inserts.
+ *  - Storing and retrieving multiple instances.
+ *  
+ * ## List Helpers
+ * 
+ * It's pretty common to deal with multiple items at a time.
+ * List helpers provide methods for multiple model instances.
+ * 
+ * For example, if we wanted to be able to destroy multiple
+ * contacts, we could add a destroyAll method to a Contact
+ * list:
+ * 
+ * @codestart
+ * $.Model.List.extend("Contact.List",{
+ *   destroyAll : function(){
+ *     $.post("/destroy",
+ *       this.map(function(contact){
+ *         return contact.id
+ *       }),
+ *       this.callback('destroyed'),
+ *       'json')
+ *   },
+ *   destroyed : function(){
+ *     this.each(function(){
+ *       this.destroyed();
+ *     })
+ *   }
+ * });
+ * @codeend
+ * 
+ * The following demo illustrates this.  Check
+ * multiple Contacts and click "DESTROY ALL"
+ * 
+ * @demo jquery/model/list/list.html
+ * 
+ * ## Faster Inserts
+ * 
+ * The 'easy' way to add a model to an element is simply inserting
+ * the model into the view like:
+ * 
+ * @codestart xml
+ * &lt;div &lt;%= task %>> A task &lt;/div>
+ * @codeend
+ * 
+ * And then you can use [jQuery.fn.models $('.task').models()].
+ * 
+ * This pattern is fast enough for 90% of all widgets.  But it
+ * does require an extra query.  Lists help you avoid this.
+ * 
+ * The [jQuery.Model.List.get get] method takes elements and
+ * uses their className to return matched instances in the list.
+ * 
+ * To use get, your elements need to have the instance's 
+ * identity in their className.  So to setup a div to reprsent
+ * a task, you would have the following in a view:
+ * 
+ * @codestart xml
+ * &lt;div class='task &lt;%= task.identity() %>'> A task &lt;/div>
+ * @codeend
+ * 
+ * Then, with your model list, you could use get to get a list of
+ * tasks:
+ * 
+ * @codestart
+ * taskList.get($('.task'))
+ * @codeend
+ * 
+ * The following demonstrates how to use this technique:
+ * 
+ * @demo jquery/model/list/list-insert.html
+ */
+$.Class.extend("jQuery.Model.List",
+/**
+ * @Prototype
+ */
+{
+    init: function( instances ) {
+        this.length = 0;
+		this._data = {};
+        this.push.apply(this, $.makeArray(instances || [] ) );
+    },
+	/**
+	 * Slice works just like an array's slice, except this
+	 * returns another instance of this model list's class.
+	 */
+    slice: function() {
+        return new this.Class( Array.prototype.slice.apply( this, arguments ) );
+    },
+	/**
+	 * Returns a list of all instances who's property matches
+	 * the given value.
+	 * @param {String} property the property to match
+	 * @param {Object} value the value the property must equal
+	 */
+    match: function( property, value ) {
+        return  this.grep(function(inst){
+            return inst[property] == value;
+        });
+    },
+	/**
+	 * Returns a model list of elements where callback returns true.
+	 * @param {Function} callback the function to call back.  This
+	 * function has the same call pattern as what jQuery.grep provides.
+	 * @param {Object} args
+	 */
+    grep: function( callback, args ) {
+        return new this.Class( $.grep( this, callback, args ) );
+    },
+	_makeData : function(){
+		var data = this._data = {};
+		this.each(function(i, inst){
+			data[inst[inst.Class.id]] = inst;
+		})
+	},
+	/**
+	 * Gets a list of elements by ID or element.
+	 */
+	get: function() {
+		if(!this.length){
+			return new this.Class([]);
+		}
+		if(this._changed){
+			this._makeData();
+		}
+		var list = [],
+			underscored = this[0].Class._fullName,
+			idName = this[0].Class.id,
+			test = new RegExp(underscored+"_([^ ]+)"),
+			matches,
+			val,
+			args = getArgs(arguments);
+		
+		for(var i =0; i < args.length; i++){
+			if(args[i].nodeName && 
+				(matches = args[i].className.match(test) )){
+				val = this._data[matches[1]]
+			}else{
+				val =  this._data[typeof args[i] == 'string' || typeof args[i] == 'number'? args[i] : args[i][idName] ]
+			}
+			val && list.push(val)
+		}
+		return new this.Class(list)
+	},
+	/**
+	 * Removes instances from this list by id or by an
+	 * element.
+	 * @param {Object} args
+	 */
+	remove: function( args ) {
+		if(!this.length){
+			return [];
+		}
+		var list = [],
+			underscored = this[0].Class._fullName,
+			idName = this[0].Class.id,
+			test = new RegExp(underscored+"_([^ ]+)"),
+			matches,
+			val;
+		args = getArgs(arguments)
+		
+		//for performance, we will go through each and splice it
+		var i =0;
+		while(i < this.length){
+			//check 
+			var inst = this[i],
+				found = false
+			for(var a =0; a< args.length; a++){
+				var id = (args[a].nodeName && 
+							(matches = args[a].className.match(test) ) &&
+							matches[1]) || 
+							( typeof args[a] == 'string' || typeof args[a] == 'number' ? 
+								args[a] :
+								args[a][idName] );
+				if(inst[idName] == id){
+					list.push.apply(list, this.splice(i, 1) );
+					args.splice(a,1);
+					found = true;
+					break;
+				}
+			}
+			if(!found){
+				i++;
+			}
+		}
+		return new this.Class(list);
+	},
+	publish: function( name, data ) {
+		OpenAjax.hub.publish(this.Class.shortName+"."+name, data)
+	},
+	/**
+	 * Gets all the elements that represent this list.
+	 * @param {Object} context
+	 */
+	elements: function( context ) {
+		// TODO : this can probably be done with 1 query.
+		var jq = $();
+		this.each(function(){
+			jq.add("."+this.identity(), context)
+		})
+		return jq;
+	}
+});
+
+var modifiers = {
+	/**
+	 * @function push
+	 * Pushs an instance onto the list
+	 */
+	push: [].push,
+	/**
+	 * @function pop
+	 * Pops the last instance off the list
+	 */
+	pop: [].pop,
+	/**
+	 * @function shift
+	 * Shifts the first instance off the list
+	 */
+	shift: [].shift,
+	/**
+	 * @function unshift
+	 * Adds an instance to the start of the list.
+	 */
+	unshift: [].unshift,
+	/**
+	 * @function splice
+	 * Splices items from the list
+	 */
+	splice: [].splice,
+	/**
+	 * @function sort
+	 * sorts the list
+	 */
+	sort : [].sort
+}
+
+$.each(modifiers, function(name, func){
+	$.Model.List.prototype[name] = function(){
+		this._changed = true;
+		return func.apply( this, arguments );
+	}
+})
+
+$.each([
+/**
+ * @function each
+ * Iterates through the list, calling callback on each item in the list.
+ * @param {Function}  callback 
+ */
+'each',
+/**
+ * @function map
+ * Iterates through the list, calling callback on each item in the list.
+ * It returns an array of the items each call to callback returned.
+ * @param {Function}  callback 
+ */
+'map'], function(i, name){
+	$.Model.List.prototype[name] = function(callback, args){
+		return $[name]( this, callback, args );
+	}
+})
+
+
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/list/local/local.js b/browserid/static/dialog/jquery/model/list/local/local.js
new file mode 100644
index 0000000000000000000000000000000000000000..97fbea10771da717aa34f96251b4715c02e56301
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/list/local/local.js
@@ -0,0 +1,41 @@
+steal.plugins('jquery/dom/cookie','jquery/model/list').then(function($){
+/**
+ * @plugin jquery/model/list/local
+ * @download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/model/list/local/local.js
+ * @parent jQuery.Model.List
+ * Works exactly the same as [jQuery.Model.List.Cookie] except uses
+ * a local store instead of cookies.
+ */
+$.Model.List.extend("jQuery.Model.List.Local",
+{
+	retrieve : function(name){
+		// each also needs what they are referencd by ?
+		var props = window.localStorage[ name ] || "[]",
+			instances = [],
+			Class = props.type ? $.Class.getObject(props.type) :  null;
+		for(var i =0; i < props.ids.length;i++){
+			var identity = props.ids[i],
+				instanceData = window.localStorage[ identity ];
+			instances.push( new Class(instanceData) )
+		}
+		this.push.apply(this,instances);
+		return this;
+	},
+	store : function(name){
+		//  go through and listen to instance updating
+		var ids = [], days = this.days;
+		this.each(function(i, inst){
+			window.localStorage[inst.identity()] = instance.attrs();
+			ids.push(inst.identity());
+		});
+		window.localStorage[name] = {
+			type: this[0] && this[0].Class.fullName,
+			ids: ids
+		};
+		return this;
+	}
+	
+});
+	
+})
+
diff --git a/browserid/static/dialog/jquery/model/list/qunit.html b/browserid/static/dialog/jquery/model/list/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..81fe09fa2be0657ad7cae8f694dbeb022a27a593
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/list/qunit.html
@@ -0,0 +1,16 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../../funcunit/qunit/qunit.css" />
+		<script type='text/javascript' src='../../../steal/steal.js?steal[app]=jquery/model/list/test/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">Model List Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/list/test/qunit/list_test.js b/browserid/static/dialog/jquery/model/list/test/qunit/list_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..7e94fd66bccd9851a059aa8305d7e95852b2c5f8
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/list/test/qunit/list_test.js
@@ -0,0 +1,64 @@
+
+module("jquery/model/list", {
+	setup: function() {
+		$.Model.extend("Person")
+	
+		$.Model.List.extend("Person.List",{
+			destroy: function() {
+				equals(this.length, 20,  "Got 20 people")
+			}
+		});
+		var people = []
+		for(var i =0; i < 20; i++){
+			people.push( new Person({id: "a"+i}) )
+		}
+		this.people = new $.Model.List(people);
+	}
+})
+
+test("hookup with list", function(){
+	
+	
+	
+	var div = $("<div>")
+	
+	for(var i =0; i < 20 ; i ++){
+		var child = $("<div>");
+		var p = new Person({foo: "bar"+i, id: i});
+		p.hookup( child[0] );
+		div.append(child)
+	}
+	var models = div.children().models();
+	ok(models.Class === Person.List, "correct type");
+	models.destroy();
+
+})
+
+test("create", function(){
+	
+	equals(this.people.length, 20)
+	
+	equals(this.people.get("a2")[0].id,"a2" , "get works")
+})
+
+
+test("splice", function(){
+	ok(this.people.get("a1").length,"something where a1 is")
+	this.people.splice(1,1)
+	equals(this.people.length, 19)
+	ok(!this.people.get("a1").length,"nothing where a1 is")
+	
+})
+
+test("remove", function(){
+	var res = this.people.remove("a1")
+	ok(!this.people.get("a1").length,"nothing where a1 is")
+	ok(res.length, "got something array like")
+	equals(res[0].id, "a1")
+})
+
+
+test("list from wrapMany", function(){
+	var people = Person.wrapMany([{id: 1}, {id: 2}]);
+	ok(people.destroy, "we can destroy a list")
+})
diff --git a/browserid/static/dialog/jquery/model/list/test/qunit/qunit.js b/browserid/static/dialog/jquery/model/list/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..43a3fb325466637540c631373961afd85a1a7609
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/list/test/qunit/qunit.js
@@ -0,0 +1,6 @@
+//we probably have to have this only describing where the tests are
+steal
+ .plugins("jquery/model/list")  //load your app
+ .plugins('funcunit/qunit')  //load qunit
+ .then("list_test")
+ 
diff --git a/browserid/static/dialog/jquery/model/model.js b/browserid/static/dialog/jquery/model/model.js
new file mode 100644
index 0000000000000000000000000000000000000000..24ef9683fa075b911ed499e2759708cef935cf80
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/model.js
@@ -0,0 +1,1185 @@
+/*global OpenAjax: true */
+
+steal.plugins('jquery/class', 'jquery/lang').then(function() {
+	
+	/**
+	 * @class jQuery.Model
+	 * @tag core
+	 * @download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/model/model.js
+	 * @test jquery/model/qunit.html
+	 * @plugin jquery/model
+	 * 
+	 * Models wrap an application's data layer.  In large applications, a model is critical for:
+	 * 
+	 *  - Encapsulating services so controllers + views don't care where data comes from.
+	 *    
+	 *  - Providing helper functions that make manipulating and abstracting raw service data easier.
+	 * 
+	 * This is done in two ways:
+	 * 
+	 *  - Requesting data from and interacting with services
+	 *  
+	 *  - Converting or wrapping raw service data into a more useful form.
+	 * 
+	 * 
+	 * ## Basic Use
+	 * 
+	 * The [jQuery.Model] class provides a basic skeleton to organize pieces of your application's data layer.
+	 * First, consider doing Ajax <b>without</b> a model.  In our imaginary app, you:
+	 * 
+	 *  - retrieve a list of tasks</li>
+	 *  - display the number of days remaining for each task
+	 *  - mark tasks as complete after users click them
+	 * 
+	 * Let's see how that might look without a model:
+	 * 
+	 * @codestart
+	 * $.Controller.extend("MyApp.Controllers.Tasks",{onDocument: true},
+	 * {
+	 *   // get tasks when the page is ready 
+	 *   ready: function() {
+	 *     $.get('/tasks.json', this.callback('gotTasks'), 'json')
+	 *   },
+	 *  |* 
+	 *   * assume json is an array like [{name: "trash", due_date: 1247111409283}, ...]
+	 *   *|
+	 *  gotTasks: function( json ) { 
+	 *     for(var i =0; i < json.length; i++){
+	 *       var taskJson = json[i];
+	 *       
+	 *       //calculate time remaining
+	 *       var remaininTime = new Date() - new Date(taskJson.due_date);
+	 *       
+	 *       //append some html
+	 *       $("#tasks").append("&lt;div class='task' taskid='"+taskJson.id+"'>"+
+	 *                           "&lt;label>"+taskJson.name+"&lt;/label>"+
+	 *                           "Due Date = "+remaininTime+"&lt;/div>")
+	 *     }
+	 *   },
+	 *   // when a task is complete, get the id, make a request, remove it
+	 *   ".task click" : function( el ) {
+	 *     $.post('/task_complete',{id: el.attr('data-taskid')}, function(){
+	 *       el.remove();
+	 *     })
+	 *   }
+	 * })
+	 * @codeend
+	 * 
+	 * This code might seem fine for right now, but what if:
+	 * 
+	 *  - The service changes?
+	 *  - Other parts of the app want to calculate <code>remaininTime</code>?
+	 *  - Other parts of the app want to get tasks?</li>
+	 *  - The same task is represented multiple palces on the page?
+	 * 
+	 * The solution is of course a strong model layer.  Lets look at what a
+	 * a good model does for a controller before we learn how to make one:
+	 * 
+	 * @codestart
+	 * $.Controller.extend("MyApp.Controllers.Tasks",{onDocument: true},
+	 * {
+	 *   load: function() {
+	 *     Task.findAll({},this.callback('list'))
+	 *   },
+	 *   list: function( tasks ) {
+	 *     $("#tasks").html(this.view(tasks))
+	 *   },
+	 *   ".task click" : function( el ) {
+	 *     el.models()[0].complete(function(){
+	 *       el.remove();
+	 *     });
+	 *   }
+	 * })
+	 * @codeend
+	 * 
+	 * In views/tasks/list.ejs
+	 * 
+	 * @codestart html
+	 * &lt;% for(var i =0; i &lt; tasks.length; i++){ %>
+	 * &lt;div class='task &lt;%= tasks[i].<b>identity</b>() %>'>
+	 *    &lt;label>&lt;%= tasks[i].name %>&lt;/label>
+	 *    &lt;%= tasks[i].<b>timeRemaining</b>() %>
+	 * &lt;/div>
+	 * &lt;% } %>
+	 * @codeend
+	 * 
+	 * Isn't that better!  Granted, some of the improvement comes because we used a view, but we've
+	 * also made our controller completely understandable.  Now lets take a look at the model:
+	 * 
+	 * @codestart
+	 * $.Model.extend("Task",
+	 * {
+	 *  findAll: function( params,success ) {
+	 *   $.get("/tasks.json", params, this.callback(["wrapMany",success]),"json");
+	 *  }
+	 * },
+	 * {
+	 *  timeRemaining: function() {
+	 *   return new Date() - new Date(this.due_date)
+	 *  },
+	 *  complete: function( success ) {
+	 *   $.get("/task_complete", {id: this.id }, success,"json");
+	 *  }
+	 * })
+	 * @codeend
+	 * 
+	 * There, much better!  Now you have a single place where you can organize Ajax functionality and
+	 * wrap the data that it returned.  Lets go through each bolded item in the controller and view.<br/>
+	 * 
+	 * ### Task.findAll
+	 * 
+	 * The findAll function requests data from "/tasks.json".  When the data is returned, it it is run through
+	 * the "wrapMany" function before being passed to the success callback.<br/>
+	 * If you don't understand how the callback works, you might want to check out 
+	 * [jQuery.Model.static.wrapMany wrapMany] and [jQuery.Class.static.callback callback].
+	 * 
+	 * ### el.models
+	 * 
+	 * [jQuery.fn.models models] is a jQuery helper that returns model instances.  It uses
+	 * the jQuery's elements' shortNames to find matching model instances.  For example:
+	 * 
+	 * @codestart html
+	 * &lt;div class='task task_5'> ... &lt;/div>
+	 * @codeend
+	 * 
+	 * It knows to return a task with id = 5.
+	 * 
+	 * ### complete
+	 * 
+	 * This should be pretty obvious.
+	 * 
+	 * ### identity
+	 * 
+	 * [jQuery.Model.prototype.identity Identity] returns a unique identifier that [jQuery.fn.models] can use
+	 * to retrieve your model instance.
+	 * 
+	 * ### timeRemaining
+	 * 
+	 * timeRemaining is a good example of wrapping your model's raw data with more useful functionality.
+	 * ## Validations
+	 * 
+	 * You can validate your model's attributes with another plugin.  See [validation].
+	 */
+	
+	//helper stuff for later.
+	var underscore = $.String.underscore,
+		classize = $.String.classize,
+		ajax = function(str, attrs, success, error, fixture, type){
+			attrs = $.extend({},attrs)
+			var url = $.String.sub(str, attrs, true)
+			$.ajax({
+				url : url,
+				data : attrs,
+				success : success,
+				error: error,
+				type : type || "post",
+				dataType : "json",
+				fixture: fixture
+			});
+		},
+		fixture = function(){
+			return "//"+$.String.underscore( this.fullName )
+						.replace(/\.models\..*/,"")
+						.replace(/\./g,"/")+"/fixtures/"+$.String.underscore( this.shortName )
+		},
+		addId = function(attrs, id){
+			attrs = attrs || {};
+			if(attrs[this.id]){
+				attrs["new"+$.String.capitalize(this.id)] = attrs[this.id];
+				delete attrs[this.id];
+			}
+			attrs[this.id] = id;
+			return attrs;
+		},
+		// methods that we'll weave into model if provided
+		ajaxMethods = 
+		/** 
+	     * @Static
+	     */
+		{
+
+		/**
+		 * Create is used to create a model instance on the server.  By implementing 
+		 * create along with the rest of the [jquery.model.services service api], your models provide an abstract
+		 * API for services.  
+		 * 
+		 * Create is called by save to create a new instance.  If you want to be able to call save on an instance
+		 * you have to implement create.
+		 * 
+		 * The easist way to implement create is to just give it the url to post data to:
+		 * 
+		 *     $.Model("Recipe",{
+		 *       create: "/recipes"
+		 *     },{})
+		 *     
+		 * This lets you create a recipe like:
+		 *  
+		 *     new Recipe({name: "hot dog"}).save(function(){
+		 *       this.name //this is the new recipe
+		 *     }).save(callback)
+		 *  
+		 * You can also implement create by yourself.  You just need to call success back with
+		 * an object that contains the id of the new instance and any other properties that should be
+		 * set on the instance.
+		 *  
+		 * For example, the following code makes a request 
+		 * to '/recipes.json?name=hot+dog' and gets back
+		 * something that looks like:
+		 *  
+		 *     { 
+		 *       id: 5,
+		 *       createdAt: 2234234329
+		 *     }
+		 * 
+		 * The code looks like:
+		 * 
+		 *     $.Model("Recipe", {
+		 *       create : function(attrs, success, error){
+		 *         $.post("/recipes.json",attrs, success,"json");
+		 *       }
+		 *     },{})
+		 * 
+		 * ## API
+		 * 
+		 * @param {Object} attrs Attributes on the model instance
+		 * @param {Function} success the callback function, it must be called with an object 
+		 * that has the id of the new instance and any other attributes the service needs to add.
+		 * @param {Function} error a function to callback if something goes wrong.  
+		 */
+		create: function(str  ) {
+			return function(attrs, success, error){
+				ajax(str, attrs, success, error, "-restCreate")
+			};
+		},
+		/**
+		 * Implement this function!
+		 * Update is called by save to update an instance.  If you want to be able to call save on an instance
+		 * you have to implement update.
+		 */
+		update: function( str ) {
+			return function(id, attrs, success, error){
+				ajax(str, addId.call(this,attrs, id), success, error, "-restUpdate")
+			}
+		},
+		/**
+		 * Implement this function!
+		 * Destroy is called by destroy to remove an instance.  If you want to be able to call destroy on an instance
+		 * you have to implement update.
+		 * @param {String|Number} id the id of the instance you want destroyed
+		 */
+		destroy: function( str ) {
+			return function( id, success, error ) {
+				var attrs = {};
+				attrs[this.id] = id;
+				ajax(str, attrs, success, error, "-restDestroy")
+			}
+		},
+		/**
+		 * Implement this function!
+		 * @param {Object} params
+		 * @param {Function} success
+		 * @param {Function} error
+		 */
+		findAll: function( str ) {
+			return function(params, success, error){
+				ajax(str, 
+					params, 
+					this.callback(['wrapMany',success]), 
+					error, 
+					fixture.call(this)+"s.json",
+					"get");
+			};
+		},
+		/**
+		 * Implement this function!
+		 * @param {Object} params
+		 * @param {Function} success
+		 * @param {Function} error
+		 */
+		findOne: function( str ) {
+			return function(params, success, error){
+				ajax(str, 
+					params, 
+					this.callback(['wrap',success]), 
+					error, 
+					fixture.call(this)+".json",
+					"get");
+			};
+		}
+	};
+
+
+
+
+
+	jQuery.Class.extend("jQuery.Model",	{
+		setup: function( superClass , stat, proto) {
+			//we do not inherit attributes (or associations)
+			if (!this.attributes || superClass.attributes === this.attributes ) {
+				this.attributes = {};
+			}
+
+			if (!this.associations || superClass.associations === this.associations ) {
+				this.associations = {};
+			}
+			if (!this.validations || superClass.validations === this.validations ) {
+				this.validations = {};
+			}
+
+			//add missing converters
+			if ( superClass.convert != this.convert ) {
+				this.convert = $.extend(superClass.convert, this.convert);
+			}
+
+
+			this._fullName = underscore(this.fullName.replace(/\./g, "_"));
+
+			if ( this.fullName.substr(0, 7) == "jQuery." ) {
+				return;
+			}
+
+			//add this to the collection of models
+			jQuery.Model.models[this._fullName] = this;
+
+			if ( this.listType ) {
+				this.list = new this.listType([]);
+			}
+			//@steal-remove-start
+			if (! proto ) {
+				steal.dev.warn("model.js "+this.fullName+" has no static properties.  You probably need  ,{} ")
+			}
+			//@steal-remove-end
+			for(var name in ajaxMethods){
+				if(typeof this[name] === 'string'){
+					this[name] = ajaxMethods[name](this[name]);
+				}
+			}
+		},
+		/**
+		 * @attribute attributes
+		 * Attributes contains a list of properties and their types
+		 * for this model.  You can use this in conjunction with 
+		 * [jQuery.Model.static.convert] to provide automatic 
+		 * [jquery.model.typeconversion type conversion].  
+		 * 
+		 * The following converts dueDates to JavaScript dates:
+		 * 
+		 * @codestart
+		 * $.Model.extend("Contact",{
+		 *   attributes : { 
+		 *     birthday : 'date'
+		 *   },
+		 *   convert : {
+		 *     date : function(raw){
+		 *       if(typeof raw == 'string'){
+		 *         var matches = raw.match(/(\d+)-(\d+)-(\d+)/)
+		 *         return new Date( matches[1], 
+		 *                  (+matches[2])-1, 
+		 *                 matches[3] )
+		 *       }else if(raw instanceof Date){
+		 *           return raw;
+		 *       }
+		 *     }
+		 *   }
+		 * },{})
+		 * @codeend
+		 */
+		attributes: {},
+		/**
+		 * @attribute defaults
+		 * An object of default values to be set on all instances.  This 
+		 * is useful if you want some value to be present when new instances are created.
+		 * 
+		 * @codestart
+		 * $.Model.extend("Recipe",{
+		 *   defaults : {
+		 *     createdAt : new Date();
+		 *   }
+		 * },{})
+		 * 
+		 * var recipe = new Recipe();
+		 * 
+		 * recipe.createdAt //-> date
+		 * 
+		 * @codeend
+		 */
+		defaults: {},
+		/**
+		 * Wrap is used to create a new instance from data returned from the server.
+		 * It is very similar to doing <code> new Model(attributes) </code> 
+		 * except that wrap will check if the data passed has an
+		 * 
+		 * - attributes,
+		 * - data, or
+		 * - <i>singularName</i>
+		 * 
+		 * property.  If it does, it will use that objects attributes.
+		 * 
+		 * Wrap is really a convience method for servers that don't return just attributes.
+		 * 
+		 * @param {Object} attributes
+		 * @return {Model} an instance of the model
+		 */
+		wrap: function( attributes ) {
+			if (!attributes ) {
+				return null;
+			}
+			return new this(
+			// checks for properties in an object (like rails 2.0 gives);
+			attributes[this.singularName] || attributes.data || attributes.attributes || attributes);
+		},
+		/**
+		 * Takes raw data from the server, and returns an array of model instances.
+		 * Each item in the raw array becomes an instance of a model class.
+		 * 
+		 * @codestart
+		 * $.Model.extend("Recipe",{
+		 *   helper : function(){
+		 *     return i*i;
+		 *   }
+		 * })
+		 * 
+		 * var recipes = Recipe.wrapMany([{id: 1},{id: 2}])
+		 * recipes[0].helper() //-> 1
+		 * @codeend
+		 * 
+		 * If an array is not passed to wrapMany, it will look in the object's .data
+		 * property.  
+		 * 
+		 * For example:
+		 * 
+		 * @codestart
+		 * var recipes = Recipe.wrapMany({data: [{id: 1},{id: 2}]})
+		 * recipes[0].helper() //-> 1
+		 * @codeend
+		 * 
+		 * Often wrapMany is used with this.callback inside a model's [jQuery.Model.static.findAll findAll]
+		 * method like:
+		 * 
+		 *     findAll : function(params, success, error){
+		 *       $.get('/url',
+		 *             params,
+		 *             this.callback(['wrapMany',success]) )
+		 *     }
+		 * 
+		 * If you are having problems getting your model to callback success correctly,
+		 * make sure a request is being made (with firebug's net tab).  Also, you 
+		 * might not use this.callback and instead do:
+		 * 
+		 *     findAll : function(params, success, error){
+		 *       self = this;
+		 *       $.get('/url',
+		 *             params,
+		 *             function(data){
+		 *               var wrapped = self.wrapMany(data);
+		 *               success(data)
+		 *             })
+		 *     }
+		 * 
+		 * ## API
+		 * 
+		 * @param {Array} instancesRawData an array of raw name - value pairs.
+		 * @return {Array} a JavaScript array of instances or a [jQuery.Model.List list] of instances
+		 *  if the model list plugin has been included.
+		 */
+		wrapMany: function( instancesRawData ) {
+			if (!instancesRawData ) {
+				return null;
+			}
+			var listType = this.List || $.Model.List || Array,
+				res = new listType(),
+				arr = $.isArray(instancesRawData),
+				raw = arr ? instancesRawData : instancesRawData.data,
+				length = raw.length,
+				i = 0;
+			//@steal-remove-start
+			if (! length ) {
+				steal.dev.warn("model.js wrapMany has no data.  If you're trying to wrap 1 item, use wrap. ")
+			}
+			//@steal-remove-end
+			res._use_call = true; //so we don't call next function with all of these
+			for (; i < length; i++ ) {
+				res.push(this.wrap(raw[i]));
+			}
+			if (!arr ) { //push other stuff onto array
+				for ( var prop in instancesRawData ) {
+					if ( prop !== 'data' ) {
+						res[prop] = instancesRawData[prop];
+					}
+
+				}
+			}
+			return res;
+		},
+		/**
+		 * The name of the id field.  Defaults to 'id'. Change this if it is something different.
+		 * 
+		 * For example, it's common in .NET to use Id.  Your model might look like:
+		 * 
+		 * @codestart
+		 * $.Model.extend("Friends",{
+		 *   id: "Id"
+		 * },{});
+		 * @codeend
+		 */
+		id: 'id',
+		//if null, maybe treat as an array?
+		/**
+		 * Adds an attribute to the list of attributes for this class.
+		 * @hide
+		 * @param {String} property
+		 * @param {String} type
+		 */
+		addAttr: function( property, type ) {
+			var stub;
+
+			if ( this.associations[property] ) {
+				return;
+			}
+			stub = this.attributes[property] || (this.attributes[property] = type);
+			return type;
+		},
+		// a collection of all models
+		models: {},
+		/**
+		 * If OpenAjax is available,
+		 * publishes to OpenAjax.hub.  Always adds the shortName.event.
+		 * 
+		 * @codestart
+		 * // publishes contact.completed
+		 * Namespace.Contact.publish("completed",contact);
+		 * @codeend
+		 * 
+		 * @param {String} event The event name to publish
+		 * @param {Object} data The data to publish
+		 */
+		publish: function( event, data ) {
+			//@steal-remove-start
+			steal.dev.log("Model.js - publishing " + underscore(this.shortName) + "." + event);
+			//@steal-remove-end
+			if ( window.OpenAjax ) {
+				OpenAjax.hub.publish(underscore(this.shortName) + "." + event, data);
+			}
+
+		},
+		/**
+		 * @hide
+		 * Guesses the type of an object.  This is what sets the type if not provided in 
+		 * [jQuery.Model.static.attributes].
+		 * @param {Object} object the object you want to test.
+		 * @return {String} one of string, object, date, array, boolean, number, function
+		 */
+		guessType: function( object ) {
+			if ( typeof object != 'string' ) {
+				if ( object === null ) {
+					return typeof object;
+				}
+				if ( object.constructor == Date ) {
+					return 'date';
+				}
+				if ( $.isArray(object) ) {
+					return 'array';
+				}
+				return typeof object;
+			}
+			if ( object === "" ) {
+				return 'string';
+			}
+			//check if true or false
+			if ( object == 'true' || object == 'false' ) {
+				return 'boolean';
+			}
+			if (!isNaN(object) && isFinite(+object) ) {
+				return 'number';
+			}
+			return typeof object;
+		},
+		/**
+		 * @attribute convert
+		 * @type Object
+		 * An object of name-function pairs that are used to convert attributes.
+		 * Check out [jQuery.Model.static.attributes] or 
+		 * [jquery.model.typeconversion type conversion]
+		 * for examples.
+		 */
+		convert: {
+			"date": function( str ) {
+				return typeof str === "string" ? (isNaN(Date.parse(str)) ? null : Date.parse(str)) : str;
+			},
+			"number": function( val ) {
+				return parseFloat(val);
+			},
+			"boolean": function( val ) {
+				return Boolean(val);
+			}
+		}
+	},
+	/**
+	 * @Prototype
+	 */
+	{
+		/**
+		 * Setup is called when a new model instance is created.
+		 * It adds default attributes, then whatever attributes
+		 * are passed to the class.
+		 * Setup should never be called directly.
+		 * 
+		 * @codestart
+		 * $.Model.extend("Recipe")
+		 * var recipe = new Recipe({foo: "bar"});
+		 * recipe.foo //-> "bar"
+		 * recipe.attr("foo") //-> "bar"
+		 * @codeend
+		 * 
+		 * @param {Object} attributes a hash of attributes
+		 */
+		setup: function( attributes ) {
+			var stub;
+
+			// so we know not to fire events
+			this._initializing = true;
+
+			stub = this.Class.defaults && this.attrs(this.Class.defaults);
+
+			this.attrs(attributes);
+			delete this._initializing;
+		},
+		/**
+		 * Sets the attributes on this instance and calls save.
+		 * The instance needs to have an id.  It will use
+		 * the instance class's [jQuery.Model.static.update update]
+		 * method.
+		 * 
+		 * @codestart
+		 * recipe.update({name: "chicken"}, success, error);
+		 * @codeend
+		 * 
+		 * If OpenAjax.hub is available, the model will also
+		 * publish a "<i>modelName</i>.updated" message with
+		 * the updated instance.
+		 * 
+		 * @param {Object} attrs the model's attributes
+		 * @param {Function} success called if a successful update
+		 * @param {Function} error called if there's an error
+		 */
+		update: function( attrs, success, error ) {
+			this.attrs(attrs);
+			return this.save(success, error); //on success, we should 
+		},
+		/**
+		 * Runs the validations on this model.  You can
+		 * also pass it an array of attributes to run only those attributes.
+		 * It returns nothing if there are no errors, or an object
+		 * of errors by attribute.
+		 * 
+		 * To use validations, it's suggested you use the 
+		 * model/validations plugin.
+		 * 
+		 * @codestart
+		 * $.Model.extend("Task",{
+		 *   init : function(){
+		 *     this.validatePresenceOf("dueDate")
+		 *   }
+		 * },{});
+		 * 
+		 * var task = new Task(),
+		 *     errors = task.errors()
+		 * 
+		 * errors.dueDate[0] //-> "can't be empty"
+		 * @codeend
+		 */
+		errors: function( attrs ) {
+			if ( attrs ) {
+				attrs = $.isArray(attrs) ? attrs : $.makeArray(arguments);
+			}
+			var errors = {},
+				self = this,
+				addErrors = function( attr, funcs ) {
+					$.each(funcs, function( i, func ) {
+						var res = func.call(self);
+						if ( res ) {
+							if (!errors.hasOwnProperty(attr) ) {
+								errors[attr] = [];
+							}
+
+							errors[attr].push(res);
+						}
+
+					});
+				};
+
+			$.each(attrs || this.Class.validations || {}, function( attr, funcs ) {
+				if ( typeof attr == 'number' ) {
+					attr = funcs;
+					funcs = self.Class.validations[attr];
+				}
+				addErrors(attr, funcs || []);
+			});
+
+			for ( var attr in errors ) {
+				if ( errors.hasOwnProperty(attr) ) {
+					return errors;
+				}
+			}
+			return null;
+		},
+		/**
+		 * Gets or sets an attribute on the model using setters and 
+		 * getters if available.
+		 * 
+		 * @codestart
+		 * $.Model.extend("Recipe")
+		 * var recipe = new Recipe();
+		 * recipe.attr("foo","bar")
+		 * recipe.foo //-> "bar"
+		 * recipe.attr("foo") //-> "bar"
+		 * @codeend
+		 * 
+		 * ## Setters
+		 * 
+		 * If you add a set<i>AttributeName</i> method on your model,
+		 * it will be used to set the value.  The set method is called
+		 * with the value and is expected to return the converted value.
+		 * 
+		 * @codestart
+		 * $.Model.extend("Recipe",{
+		 *   setCreatedAt : function(raw){
+		 *     return Date.parse(raw)
+		 *   }
+		 * })
+		 * var recipe = new Recipe();
+		 * recipe.attr("createdAt","Dec 25, 1995")
+		 * recipe.createAt //-> Date
+		 * @codeend
+		 * 
+		 * ## Asynchronous Setters
+		 * 
+		 * Sometimes, you want to perform an ajax request when 
+		 * you set a property.  You can do this with setters too.
+		 * 
+		 * To do this, your setter should return undefined and
+		 * call success with the converted value.  For example:
+		 * 
+		 * @codestart
+		 * $.Model.extend("Recipe",{
+		 *   setTitle : function(title, success, error){
+		 *     $.post(
+		 *       "recipe/update/"+this.id+"/title",
+		 *       title,
+		 *       function(){
+		 *         success(title);
+		 *       },
+		 *       "json")
+		 *   }
+		 * })
+		 * 
+		 * recipe.attr("title","fish")
+		 * @codeend
+		 * 
+		 * ## Events
+		 * 
+		 * When you use attr, it can also trigger events.  This is
+		 * covered in [jQuery.Model.prototype.bind].
+		 * 
+		 * @param {String} attribute the attribute you want to set or get
+		 * @param {String|Number|Boolean} [value] value the value you want to set.
+		 * @param {Function} [success] an optional success callback.  
+		 *    This gets called if the attribute was successful.
+		 * @param {Function} [error] an optional success callback.  
+		 *    The error function is called with validation errors.
+		 */
+		attr: function( attribute, value, success, error ) {
+			var cap = classize(attribute),
+				get = "get" + cap;
+			if ( value !== undefined ) {
+				this._setProperty(attribute, value, success, error, cap);
+				return this;
+			}
+			return this[get] ? this[get]() : this[attribute];
+		},
+		/**
+		 * Binds to events on this model instance.  Typically 
+		 * you'll bind to an attribute name.  Handler will be called
+		 * every time the attribute value changes.  For example:
+		 * 
+		 * @codestart
+		 * $.Model.extend("School")
+		 * var school = new School();
+		 * school.bind("address", function(ev, address){
+		 *   alert('address changed to '+address);
+		 * })
+		 * school.attr("address","1124 Park St");
+		 * @codeend
+		 * 
+		 * You can also bind to attribute errors.
+		 * 
+		 * @codestart
+		 * $.Model.extend("School",{
+		 *   setName : function(name, success, error){
+		 *     if(!name){
+		 *        error("no name");
+		 *     }
+		 *     return error;
+		 *   }
+		 * })
+		 * var school = new School();
+		 * school.bind("error.name", function(ev, mess){
+		 *    mess // -> "no name";
+		 * })
+		 * school.attr("name","");
+		 * @codeend
+		 * 
+		 * You can also bind to created, updated, and destroyed events.
+		 * 
+		 * @param {String} eventType the name of the event.
+		 * @param {Function} handler a function to call back when an event happens on this model.
+		 * @return {model} the model instance for chaining
+		 */
+		bind: function( eventType, handler ) {
+			var wrapped = $(this);
+			wrapped.bind.apply(wrapped, arguments);
+			return this;
+		},
+		/**
+		 * Unbinds an event handler from this instance.
+		 * Read [jQuery.Model.prototype.bind] for 
+		 * more information.
+		 * @param {String} eventType
+		 * @param {Function} handler
+		 */
+		unbind: function( eventType, handler ) {
+			var wrapped = $(this);
+			wrapped.unbind.apply(wrapped, arguments);
+			return this;
+		},
+		/**
+		 * Checks if there is a set_<i>property</i> value.  If it returns true, lets it handle; otherwise
+		 * saves it.
+		 * @hide
+		 * @param {Object} property
+		 * @param {Object} value
+		 */
+		_setProperty: function( property, value, success, error, capitalized ) {
+			// the potential setter name
+			var setName = "set" + capitalized,
+				//the old value
+				old = this[property],
+				self = this,
+				errorCallback = function( errors ) {
+					var stub;
+					stub = error && error.call(self, errors);
+					$(self).triggerHandler("error." + property, errors);
+				};
+
+			// if the setter returns nothing, do not set
+			// we might want to indicate if this was set ok
+			if ( this[setName] && (value = this[setName](value, this.callback('_updateProperty', property, value, old, success, errorCallback), errorCallback)) === undefined ) {
+				return;
+			}
+			this._updateProperty(property, value, old, success, errorCallback);
+		},
+		/**
+		 * Triggers events when a property has been updated
+		 * @hide
+		 * @param {Object} property
+		 * @param {Object} value
+		 * @param {Object} old
+		 * @param {Object} success
+		 */
+		_updateProperty: function( property, value, old, success, errorCallback ) {
+			var Class = this.Class,
+				val, type = Class.attributes[property] || Class.addAttr(property, Class.guessType(value)),
+				//the converter
+				converter = Class.convert[type],
+				errors = null,
+				stub;
+
+			val = this[property] = (value === null ? //if the value is null or undefined
+			null : // it should be null
+			(converter ? converter.call(Class, value) : //convert it to something useful
+			value)); //just return it
+			//validate (only if not initializing, this is for performance)
+			if (!this._initializing ) {
+				errors = this.errors(property);
+			}
+
+			if ( errors ) {
+				errorCallback(errors);
+			} else {
+				if ( old !== val && !this._initializing ) {
+					$(this).triggerHandler(property, val);
+				}
+				stub = success && success(this);
+
+			}
+
+			//if this class has a global list, add / remove from the list.
+			if ( property == Class.id && val !== null && Class.list ) {
+				// if we didn't have an old id, add ourselves
+				if (!old ) {
+					Class.list.push(this);
+				} else if ( old != val ) {
+					// if our id has changed ... well this should be ok
+					Class.list.remove(old);
+					Class.list.push(this);
+				}
+			}
+
+		},
+		/**
+		 * Gets or sets a list of attributes. 
+		 * Each attribute is set with [jQuery.Model.prototype.attr attr].
+		 * 
+		 * @codestart
+		 * recipe.attrs({
+		 *   name: "ice water",
+		 *   instructions : "put water in a glass"
+		 * })
+		 * @codeend
+		 * 
+		 * @param {Object} [attributes]  if present, the list of attributes to send
+		 * @return {Object} the current attributes of the model
+		 */
+		attrs: function( attributes ) {
+			var key;
+			if (!attributes ) {
+				attributes = {};
+				for ( key in this.Class.attributes ) {
+					if ( this.Class.attributes.hasOwnProperty(key) ) {
+						attributes[key] = this.attr(key);
+					}
+				}
+			} else {
+				var idName = this.Class.id;
+				//always set the id last
+				for ( key in attributes ) {
+					if ( key != idName ) {
+						this.attr(key, attributes[key]);
+					}
+				}
+				if ( idName in attributes ) {
+					this.attr(idName, attributes[idName]);
+				}
+
+			}
+			return attributes;
+		},
+		/**
+		 * Returns if the instance is a new object.  This is essentially if the
+		 * id is null or undefined.
+		 * 
+		 *     new Recipe({id: 1}).isNew() //-> false
+		 * @return {Boolean} false if an id is set, true if otherwise.
+		 */
+		isNew: function() {
+			var id = this[this.Class.id];
+			return (id === undefined || id === null); //if null or undefined
+		},
+		/**
+		 * Saves the instance if there are no errors.  
+		 * If the instance is new, [jQuery.Model.static.create] is
+		 * called; otherwise, [jQuery.Model.static.update] is
+		 * called.
+		 * 
+		 * @codestart
+		 * recipe.save(success, error);
+		 * @codeend
+		 * 
+		 * If OpenAjax.hub is available, after a successful create or update, 
+		 * "<i>modelName</i>.created" or "<i>modelName</i>.updated" is published.
+		 * 
+		 * @param {Function} [success] called if a successful save.
+		 * @param {Function} [error] called if the save was not successful.
+		 */
+		save: function( success, error ) {
+			var stub;
+
+			if ( this.errors() ) {
+				//needs to send errors
+				return false;
+			}
+			stub = this.isNew() ? this.Class.create(this.attrs(), this.callback(['created', success]), error) : this.Class.update(this[this.Class.id], this.attrs(), this.callback(['updated', success]), error);
+
+			//this.is_new_record = this.Class.new_record_func;
+			return true;
+		},
+
+		/**
+		 * Destroys the instance by calling 
+		 * [jQuery.Model.static.destroy] with the id of the instance.
+		 * 
+		 * @codestart
+		 * recipe.destroy(success, error);
+		 * @codeend
+		 * 
+		 * If OpenAjax.hub is available, after a successful
+		 * destroy "<i>modelName</i>.destroyed" is published
+		 * with the model instance.
+		 * 
+		 * @param {Function} [success] called if a successful destroy
+		 * @param {Function} [error] called if an unsuccessful destroy
+		 */
+		destroy: function( success, error ) {
+			this.Class.destroy(this[this.Class.id], this.callback(["destroyed", success]), error);
+		},
+
+
+		/**
+		 * Returns a unique identifier for the model instance.  For example:
+		 * @codestart
+		 * new Todo({id: 5}).identity() //-> 'todo_5'
+		 * @codeend
+		 * Typically this is used in an element's shortName property so you can find all elements
+		 * for a model with [jQuery.Model.prototype.elements elements].
+		 * @return {String}
+		 */
+		identity: function() {
+			var id = this[this.Class.id];
+			return this.Class._fullName + '_' + (this.Class.escapeIdentity ? encodeURIComponent(id) : id);
+		},
+		/**
+		 * Returns elements that represent this model instance.  For this to work, your element's should
+		 * us the [jQuery.Model.prototype.identity identity] function in their class name.  Example:
+		 * 
+		 *     <div class='todo <%= todo.identity() %>'> ... </div>
+		 * 
+		 * This also works if you hooked up the model:
+		 * 
+		 *     <div <%= todo %>> ... </div>
+		 *     
+		 * Typically, you'll use this as a response of an OpenAjax message:
+		 * 
+		 *     "todo.destroyed subscribe": function(called, todo){
+		 *       todo.elements(this.element).remove();
+		 *     }
+		 * 
+		 * ## API
+		 * 
+		 * @param {String|jQuery|element} context If provided, only elements inside this element
+		 * that represent this model will be returned.
+		 * 
+		 * @return {jQuery} Returns a jQuery wrapped nodelist of elements that have this model instances
+		 *  identity in their class name.
+		 */
+		elements: function( context ) {
+			return $("." + this.identity(), context);
+		},
+		/**
+		 * Publishes to open ajax hub
+		 * @param {String} event
+		 * @param {Object} [opt6] data if missing, uses the instance in {data: this}
+		 */
+		publish: function( event, data ) {
+			this.Class.publish(event, data || this);
+		},
+		hookup: function( el ) {
+			var shortName = underscore(this.Class.shortName),
+				models = $.data(el, "models") || $.data(el, "models", {});
+			$(el).addClass(shortName + " " + this.identity());
+			models[shortName] = this;
+		}
+	});
+
+	$.each([
+	/**
+	 * @function created
+	 * @hide
+	 * Called by save after a new instance is created.  Publishes 'created'.
+	 * @param {Object} attrs
+	 */
+	"created",
+	/**
+	 * @function updated
+	 * @hide
+	 * Called by save after an instance is updated.  Publishes 'updated'.
+	 * @param {Object} attrs
+	 */
+	"updated",
+	/**
+	 * @function destroyed
+	 * @hide
+	 * Called after an instance is destroyed.  Publishes
+	 * "shortName.destroyed"
+	 */
+	"destroyed"], function( i, funcName ) {
+		$.Model.prototype[funcName] = function( attrs ) {
+			var stub;
+
+			if ( funcName === 'destroyed' && this.Class.list ) {
+				this.Class.list.remove(this[this.Class.id]);
+			}
+			$(this).triggerHandler(funcName);
+			stub = attrs && typeof attrs == 'object' && this.attrs(attrs.attrs ? attrs.attrs() : attrs);
+			this.publish(funcName, this);
+			return [this].concat($.makeArray(arguments));
+		};
+	});
+
+	/**
+	 *  @add jQuery.fn
+	 */
+	// break
+	/**
+	 * @function models
+	 * Returns a list of models.  If the models are of the same
+	 * type, and have a [jQuery.Model.List], it will return 
+	 * the models wrapped with the list.
+	 * 
+	 * @codestart
+	 * $(".recipes").models() //-> [recipe, ...]
+	 * @codeend
+	 * 
+	 * @param {jQuery.Class} [type] if present only returns models of the provided type.
+	 * @return {Array|jQuery.Model.List} returns an array of model instances that are represented by the contained elements.
+	 */
+	$.fn.models = function( type ) {
+		//get it from the data
+		var collection = [],
+			kind, ret, retType;
+		this.each(function() {
+			$.each($.data(this, "models") || {}, function( name, instance ) {
+				//either null or the list type shared by all classes
+				kind = kind === undefined ? instance.Class.List || null : (instance.Class.List === kind ? kind : null);
+				collection.push(instance);
+			});
+		});
+
+		retType = kind || $.Model.List || Array;
+		ret = new retType();
+
+		ret.push.apply(ret, $.unique(collection));
+		return ret;
+	};
+	/**
+	 * @function model
+	 * 
+	 * Returns the first model instance found from [jQuery.fn.models].
+	 * 
+	 * @param {Object} type
+	 */
+	$.fn.model = function( type ) {
+		if ( type && type instanceof $.Model ) {
+			type.hookup(this[0]);
+			return this;
+		} else {
+			return this.models.apply(this, arguments)[0];
+		}
+
+	};
+	/**
+	 * @page jquery.model.services Service APIs
+	 * @parent jQuery.Model
+	 * 
+	 * Models provide an abstract API for connecting to your Services.  By implementing static:
+	 * 
+	 *  - [jQuery.Model.static.findAll] 
+	 *  - [jQuery.Model.static.findOne] 
+	 *  - [jQuery.Model.static.create] 
+	 *  - [jQuery.Model.static.update] 
+	 *  - [jQuery.Model.static.destroy]
+	 *  
+	 * You can pass a model class to widgets and the widgets can interface with the
+	 * model.  This prevents the need for every widget to be configured with the ajax functionality
+	 * necessary to make a request to your services.
+	 */
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/modelBinder.html b/browserid/static/dialog/jquery/model/modelBinder.html
new file mode 100644
index 0000000000000000000000000000000000000000..3dee5ddcdf8354b3a5b6d12d2f2c0a93ac706ae7
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/modelBinder.html
@@ -0,0 +1,92 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>slider</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .error {border: solid 1px red;}
+            .error_text { color: red; font-size: 10px;}
+            td {padding: 3px;}
+			
+			#sliderWrapper {
+				border: solid 1px gray;
+				width: 300px;
+				height: 30px;
+			}
+			#slider {
+				width: 30px;
+				height: 30px;
+				background-color: green;
+			}
+        </style>
+	</head>
+	<body>
+	    <div id='sliderWrapper'><div id='slider'></div></div>
+
+		<input type='text' id='value' />
+
+		<textarea id='foo'></textarea>
+		
+		
+		<select id='bar'>
+			<option value='1'>1</option>
+			<option value='2'>2</option>
+			<option value='3'>3</option>
+			<option value='4'>4</option>
+			<option value='5'>5</option>
+			<option value='6'>6</option>
+			<option value='7'>7</option>
+			<option value='8'>8</option>
+			<option value='9'>9</option>
+			<option value='10'>10</option>
+		</select>
+<script type='text/javascript' 
+        src='../../steal/steal.js'>   
+</script>
+<script type='text/javascript'>
+	steal.plugins('jquery/model','mxui/slider').start()
+</script>
+<script type='text/javascript'>   
+	$.fn.hookup = function(inst, attr, type){
+		
+		inst.bind(attr, {jQ : this},function(ev, val){
+			if(type){
+				ev.data.jQ[type]("val", val)
+			}else{
+				ev.data.jQ.val(val)
+			}
+		})
+		this.bind("change", function(el, val){
+			if(type){
+				inst.attr(attr, val)
+			}else{
+				inst.attr(attr, $(this).val())
+			}
+		})
+		var value = inst.attr(attr);
+		if(type){
+			this[type]("val",value)
+		}else{
+			this.val(value)
+		}
+	};
+	
+	
+	
+	
+	$.Model.extend("Person",{},{});
+	
+	var person = new Person({age: 1})
+	
+	$("#slider").mxui_slider({interval: 1, min: 1, max: 10})
+		
+		.hookup(person,"age","mxui_slider");
+	
+	$('#value, #foo, #bar').hookup(person,"age");
+	
+	
+	
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/pages/encapsulate.js b/browserid/static/dialog/jquery/model/pages/encapsulate.js
new file mode 100644
index 0000000000000000000000000000000000000000..b6300a6a3c7a823bc63202f607881ce0c239bee9
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/pages/encapsulate.js
@@ -0,0 +1,162 @@
+/*
+@page jquery.model.encapsulate Service Encapsulation
+@parent jQuery.Model
+
+<h1>Service / Ajax Encapsulation</h1>
+
+Models encapsulate your application's raw data.  
+
+The majority of the time, the raw data comes from 
+services your server provides.  For example, 
+if you make a request to:
+
+<pre><code>GET /contacts.json</code></pre>
+
+The server might return something like:
+
+<pre><code>[{
+  'id': 1,
+  'name' : 'Justin Meyer',
+  'birthday': '1982-10-20'
+},
+{
+  'id': 2,
+  'name' : 'Brian Moschel',
+  'birthday': '1983-11-10'
+}]</code></pre>
+
+In most jQuery code, you'll see something like the following to retrieve contacts
+data:
+
+@codestart
+$.get('/contacts.json',
+      {type: 'tasty'}, 
+      successCallback,
+      'json')</code></pre>
+@codeend
+
+Instead, model encapsulates (wraps) this request so you call it like:
+
+@codestart
+Contact.findAll({type: 'old'}, successCallback);
+@codeend
+
+And instead of raw data, findAll returns contact instances that let you do things like:
+
+@codestart
+// destroy the contact
+contact.destroy() 
+
+// update the contact
+contact.update({name: "Jeremy"})
+
+// create a contact
+new Contact({name: "Alex"}).save();
+@codeend
+
+## Encapsulation Demo
+
+The Grid demo shows using two different models with the same widget.
+
+@demo jquery/model/demo-encapsulate.html
+
+## How to Encapsulate
+
+Think of models as a contract for creating, reading, updating, and deleting data.  
+By filling out a model, you can pass that model to a widget and the widget will use 
+the model as a proxy for your data.  
+
+The following chart shows the methods most models provide:
+
+<table>
+    <tr>
+        <td>Create</td><td><pre>Contact.create(attrs, success, error</pre></td>
+    </tr>
+    <tr>
+        <td>Read</td><td><pre>Contact.findAll(params,success,error)
+Contact.findOne(params, success, error)</pre></td>
+    </tr>
+    <tr>
+        <td>Update</td><td><pre>Contact.update(id, attrs, success, error)</pre></td>
+    </tr>
+    <tr>
+        <td>Delete</td><td><pre>Contact.destroy(id, success, error)</pre></td>
+    </tr>
+</table>
+
+By filling out these methods, you get the benefits of encapsulation, 
+AND all the other magic Model provides.  Lets see how we might fill out the
+<code>Contact.findAll</code> function:
+
+@codestart
+$.Model.extend('Contact',
+{
+  findAll : function(params, success, error){
+  
+    // do the ajax request
+    $.get('/contacts.json',
+      params, 
+      function( json ){ 
+        
+        // on success, create new Contact
+        // instances for each contact
+        var wrapped = [];
+        
+        for(var i =0; i< json.length;i++){
+          wrapped.push( new Contact(json[i] ) );
+        }
+        
+        //call success with the contacts
+        success( wrapped );
+        
+      },
+      'json');
+  }
+},
+{
+  // Prototype properties of Contact.
+  // We'll learn about this soon!
+});
+@codeend
+
+Well, that would be annoying to write out every time.  Fortunately, models have
+the wrapMany method which will make it easier:
+
+@codestart
+findAll : function(params, success, error){
+    $.get('/contacts.json',
+      params, 
+      function( json ){ 
+        success(Contact.wrapMany(json));		
+      },
+      'json');
+  }
+@codeend
+
+Model is based off JavaScriptMVC's <code>jQuery.Class</code>. It's callback allows us to pipe
+wrapMany into the success handler and make our code even shorter:
+
+@codestart
+findAll : function(params, success, error){
+    $.get('/contacts.json',
+    params, 
+    this.callback(['wrapMany', success]),
+    'json')
+  }
+@codeend
+
+If we wanted to make a list of contacts, we could do it like:
+
+@codestart
+Contact.findAll({},function(contacts){
+  var html = [];
+  for(var i =0; i < contacts.length; i++){
+    html.push('&lt;li>'+contacts[i].name + '&lt;/li>')
+  }
+  $('#contacts').html( html.join('') );
+});
+@codeend
+
+
+ */
+//s
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/pages/events.js b/browserid/static/dialog/jquery/model/pages/events.js
new file mode 100644
index 0000000000000000000000000000000000000000..acfc5d71d32fe0ab6f8f41fcbecce7163abe4a59
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/pages/events.js
@@ -0,0 +1,78 @@
+/*
+@page jquery.model.events Events
+@parent jQuery.Model
+
+Models produce events that you can listen to.  This is
+useful when there are multiple representations of the same instance on the page.
+If one representation is updated, the other representation 
+should be updated.
+   
+Events also provide a more traditional MVC approach.  View-Controllers
+bind to a specific property.  If that property changes, the
+View-Controller updates itself.
+
+Model provides two ways to listen for events on model instances:
+
+## Way 1: Bind
+
+You can [jQuery.Model.prototype.bind bind] to attribute changes in a model instance
+just like you would with events in jQuery.
+
+The following listens for contact birthday changes.
+
+@codestart
+contact.bind("birthday", function(ev, birthday){
+  // do something
+})
+@codeend
+
+The 'birthday' event is triggered whenever an attribute is
+successfully changed:
+
+@codestart
+contact.attr('birthday', "10-20-1982");
+@codeend
+
+Bind is the prefered approach if you're favoring a more
+traditional MVC architecture.  However, this can sometimes
+be more complex than the subscribe method because of
+maintaining additional event handlers.
+
+## Way 2: Subscribe
+
+If OpenAjax.hub is available, Models also publish events when 
+an instance is created, updated, or destroyed.
+
+You can subscribe to these events with OpenAjax.hub like:
+
+@codestart
+OpenAjax.hub.subscribe(
+  "contact.updated", 
+  function(called, contact){
+    //do something ...
+})
+@codeend
+
+Typically, you'll subscribe with the
+<code>jquery/controller/subscribe</code> plugin like:
+
+@codestart
+$.Controller.extend("Subscriber",{
+  
+  ...
+  
+  "todo.destroyed subscribe" : function(called, todo){
+    
+    //find the contact in this widget:
+    var el = todo.elements(this.element)
+	
+    //remove element
+    el.remove();
+  },
+  
+  ...
+})
+@codeend
+
+
+ */
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/pages/typeconversion.js b/browserid/static/dialog/jquery/model/pages/typeconversion.js
new file mode 100644
index 0000000000000000000000000000000000000000..1229ffd24ec9071451cbc5c6ae83991720b0737b
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/pages/typeconversion.js
@@ -0,0 +1,64 @@
+/**
+@page jquery.model.typeconversion Type Conversion
+@parent jQuery.Model
+
+# Type Conversion
+
+You often want to convert from what the model sends you to
+a form more useful to JavaScript.  For example, 
+contacts might be returned from the server with dates that look like:
+"1982-10-20".  We can model to convert it to something closer 
+to <code>new Date(1982,10,20)</code>. We can do this in two ways: 
+
+## Way 1: Setters
+
+The [jQuery.Model.prototype.attrs attrs]
+and [jQuery.Model.prototype.attr attr] function look for
+a <code>set<b>ATTRNAME</b></code> function to handle setting the
+date property.  
+
+By providing a function that takes the raw data and returns
+a form useful for JavaScript, we can make our models (which
+use attrs and attr) automatically convert server data.
+
+The following demo shows converting a contact's birthday into
+a string.
+
+@demo jquery/model/demo-setter.html
+
+
+## Way 2: Convert
+
+If you have a lot of dates, Setters won't scale well. 
+Instead, you can set the type of 
+an attribute and provide a function to convert that type.
+
+The following sets the birthday attribute to "date" and provides a date conversion function:
+
+@codestart
+$.Model.extend("Contact",
+{
+  attributes : { 
+    birthday : 'date'
+  },
+  convert : {
+    date : function(raw){
+      if(typeof raw == 'string'){
+        var matches = raw.match(/(\d+)-(\d+)-(\d+)/)
+        return new Date( matches[1], 
+                        (+matches[2])-1, 
+                         matches[3] )
+      }else if(raw instanceof Date){
+        return raw;
+      }
+    }
+  },
+  findAll : function( ... ){ ... }
+},
+{
+  // No prototype properties necessary
+})
+@codeend
+
+@demo jquery/model/demo-convert.html
+ */
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/qunit.html b/browserid/static/dialog/jquery/model/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..abca295f0dfb6ed54e51f584a1cf88495f456fb0
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/qunit.html
@@ -0,0 +1,17 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../funcunit/qunit/qunit.css" />
+    </head>
+    <body>
+
+    <h1 id="qunit-header">Model Test Suite</h1>
+	<h2 id="qunit-banner"></h2>
+	<div id="qunit-testrunner-toolbar"></div>
+	<h2 id="qunit-userAgent"></h2>
+    <ol id="qunit-tests"></ol>
+	<div id="qunit-test-area"></div>
+	<a href='associations/qunit.html'>associations</a>
+	<a href='list/qunit.html'>list</a>
+    <script type='text/javascript' src='../../steal/steal.js?steal[app]=jquery/model/test/qunit'></script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/service/json_rest/json_rest.js b/browserid/static/dialog/jquery/model/service/json_rest/json_rest.js
new file mode 100644
index 0000000000000000000000000000000000000000..6813d7e6aca8312ac12bbe2a7eefee6c7d866ab4
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/service/json_rest/json_rest.js
@@ -0,0 +1,109 @@
+steal.plugins('jquery/model/service').then(function(){
+
+$.Model.service.jsonRest = $.Model.service({
+	url : "",
+	type : ".json",
+	name : "",
+	getSingularUrl : function(Class, id){
+		return this.singularUrl ?
+				this.singularUrl+"/"+id+this.type :
+				this.url+this.getName(Class)+"s/"+id+this.type
+	},
+	getPluralUrl : function(Class, id){
+		return this.pluralUrl || this.url+this.getName(Class)+"s"+this.type;
+	},
+	getName : function(Class){
+		return this.name || Class.name
+	},
+	findAll : function(params){
+		var plural = this._service.getPluralUrl(this);
+		$.ajax({
+            url: plural,
+            type: 'get',
+            dataType: 'json',
+            data: params,
+            success: this.callback(['wrapMany',success]),
+            error: error,
+            fixture: true
+        })
+	},
+	getParams : function(attrs){
+		var name = this.getName(this),
+			params = {};
+		for(var n in attrs){
+			params[name+"["+n+"]"] = attrs[n];
+		}
+		return params;
+	},
+	update : function( id, attrs, success, error ) {
+        var params = this._service.getParams(attrs),
+			singular = this._service.getSingularUrl(this, id),
+			plural = this._service.getPluralUrl(this),
+			self = this;
+			
+        
+            
+        $.ajax({
+            url: singular,
+            type: 'put',
+            dataType: 'text',
+            data: params,
+            complete: function(xhr, status ){
+				if (/\w+/.test(xhr.responseText)) {
+		            return error( eval('('+xhr.responseText+')') );
+		        }
+		        success({})
+			},
+            fixture: "-restUpdate"
+            
+        })
+    },
+	destroy : function(id, success, error){
+		var singular = this._service.getSingularUrl(this,id);
+		$.ajax({
+            url: singular,
+            type: 'delete',
+            dataType: 'text',
+            success: success,
+            error: error,
+            fixture: "-restDestroy"
+        })
+	},
+	create: function( attrs, success, error ) {
+		var params = this._service.getParams(attrs),
+			plural = this._service.getPluralUrl(this),
+			self = this,
+			name = this._service.getName(this);
+			
+		$.ajax({
+		    url: plural,
+		    type: 'post',
+		    dataType: 'text',
+		    complete: function(xhr, status){
+				if (status != "success") {
+					error(xhr, status)
+				}
+		        if (/\w+/.test(xhr.responseText)) {
+		            var res = eval('('+xhr.responseText+')');
+					if(res[name]){
+						success(res[name]);
+						return;
+					}
+					return error( res );
+		        }
+		        var loc = xhr.responseText;
+			  	try{loc = xhr.getResponseHeader("location");}catch(e){};
+		        if (loc) {
+					//todo check this with prototype
+					var mtcs = loc.match(/\/[^\/]*?(\w+)?$/);
+					if(mtcs) return success({id: parseInt(mtcs[1])});
+		        }
+		        success({});
+			},
+		    data: params,
+		    fixture: "-restCreate"
+		})
+    }
+});
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/service/service.js b/browserid/static/dialog/jquery/model/service/service.js
new file mode 100644
index 0000000000000000000000000000000000000000..6efbf197adb8fd701f1ba1ccda3423a6510b7f92
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/service/service.js
@@ -0,0 +1,30 @@
+steal.plugins('jquery/model').then(function(){
+	var convert = function(method, func){
+		
+		return typeof method == 'function' ? function(){
+			var old = this._service,
+				ret;
+			this._service = func;
+			ret = method.apply(this, arguments);
+			this._service = old;
+			return ret;
+		} : method
+	}
+	/**
+	 * Creates a service
+	 * @param {Object} defaults
+	 * @param {Object} methods
+	 */
+	$.Model.service = function(properties){
+		
+		var func = function(newProps){
+			return $.Model.service( $.extend({}, properties, newProps) );
+		};
+		
+		for(var name in properties){
+			func[name] = convert(properties[name], func)
+		}
+		
+		return func;
+	}
+});
diff --git a/browserid/static/dialog/jquery/model/service/twitter/twitter.html b/browserid/static/dialog/jquery/model/service/twitter/twitter.html
new file mode 100644
index 0000000000000000000000000000000000000000..37ee00942d5eb3f1d111c0c8fc1d412c7b1f03db
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/service/twitter/twitter.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>associations</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .error {border: solid 1px red;}
+            .error_text { color: red; font-size: 10px;}
+            td {padding: 3px;}
+        </style>
+	</head>
+	<body>
+		<h1>JavaScriptMVC Tweets</h1>
+		<ul id='tweets'></ul>
+		<script type='text/javascript' 
+                src='../../../../steal/steal.js?jquery/model/service/twitter'>   
+        </script>
+		<script type='text/javascript'>
+
+			
+			$.Model.service.twitter.findAll({where : {screen_name: "javascriptmvc"}}, function(data){
+				var txt = []
+				for(var i =0; i < data.length;i++){
+					txt.push("<li>",data[i].text,"</li>")
+				}
+				$("#tweets").html(txt.join(""))
+			})
+		</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/service/twitter/twitter.js b/browserid/static/dialog/jquery/model/service/twitter/twitter.js
new file mode 100644
index 0000000000000000000000000000000000000000..8974e6fe7ffab81026a306ab18b0ce536d2796ee
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/service/twitter/twitter.js
@@ -0,0 +1,43 @@
+steal.plugins('jquery/model/service').then(function(){
+	
+	$.Model.service.twitter = $.Model.service({
+		url : "http://api.twitter.com/1/",
+		select : "*",
+		from : "statuses/user_timeline.json",
+		where : {screen_name : "javascriptmvc"},
+		/**
+		 * 
+		 * @param {Object} params
+		 */
+		findAll : function(params, success, error){
+			 
+			 
+			 var url = (params.url || this._service.url)+(params.from || this._service.from),
+			 	self = this;
+			 
+			 var twitterJson = {
+				url: url,
+				dataType: "jsonp",
+				data: params.where || this._service.where,
+				error : error
+	         }
+
+			 if(this.wrapMany){
+			 	twitterJson.success = function (data) {
+					if(data.results){
+						data = data.results
+					}
+		    		success(self.wrapMany(data))
+			    	
+			    }
+			 }else{
+			 	twitterJson.success = success;
+			 }
+			 
+	         $.ajax(twitterJson);
+		}
+	});
+	
+})
+
+
diff --git a/browserid/static/dialog/jquery/model/service/yql/yql.html b/browserid/static/dialog/jquery/model/service/yql/yql.html
new file mode 100644
index 0000000000000000000000000000000000000000..b398bde2974c5d73b04ac65108fc33bcfafa2789
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/service/yql/yql.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>associations</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .error {border: solid 1px red;}
+            .error_text { color: red; font-size: 10px;}
+            td {padding: 3px;}
+        </style>
+	</head>
+	<body>
+		<script type='text/javascript' 
+                src='../../../../steal/steal.js?steal[app]=jquery/model/service/yql&steal[env]=development'
+                package='main.js'
+                compress='false'>   
+        </script>
+		<script type='text/javascript'>
+			var yahooImages = $.Model.service.yql({from: "search.images"});
+			
+			yahooImages.findAll({where: "query='dog'"}, function(data){
+				console.log(data)
+			})
+		</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/service/yql/yql.js b/browserid/static/dialog/jquery/model/service/yql/yql.js
new file mode 100644
index 0000000000000000000000000000000000000000..895dfc190c999bd07f3d56a433704328d5d83d8a
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/service/yql/yql.js
@@ -0,0 +1,66 @@
+steal.plugins('jquery/model/service').then(function(){
+	
+	$.Model.service.yql = $.Model.service({
+		select : "*",
+		from : "flickr.photos.search",
+		convert : function (query, params) {
+			$.each( params, function (key) {
+					var name = new RegExp( "#\{" + key + "\}","g" );
+					var value = $.trim(this);
+					//if (!value.match(/^[0-9]+$/)) {
+					//   value = '"' + value + '"';
+					//}
+					query = query.replace(name, value);
+				}
+			);
+			return query;
+		},
+		/**
+		 * 
+		 * @param {Object} params
+		 */
+		findAll : function(params, success, error){
+			 params = $.extend({}, this._service, params);
+			 var query = ["SELECT",params.select,"FROM",params.from];
+			 
+			 
+			 if(params.where){
+			 	query.push("WHERE",typeof params.where == "string" || this._service.convert(params.where[0],params.where[1]))
+			 }
+			 var self = this;
+			 
+			 
+			 var yqlJson = {
+				url: "http://query.yahooapis.com/v1/public/yql",
+				dataType: "jsonp",
+				data: {
+				     q: query.join(" "),
+				     format: "json",
+				     env: 'store://datatables.org/alltableswithkeys',
+				     callback: "?"
+				 }
+	         }
+	         if (error) {
+	             yqlJson.error = error;
+	         }
+			 if(this.wrapMany){
+			 	yqlJson.success = function (data) {
+					var results = data.query.results
+					if(results){
+						for(var name in results){
+							success(self.wrapMany(data.query.results[name]));
+							break;
+						}
+					}else{
+						success([]);
+					}
+			    }
+			 }else{
+			 	yqlJson.success = success;
+			 }
+	
+	         $.ajax(yqlJson);
+		}
+	});
+	
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/test/4.json b/browserid/static/dialog/jquery/model/test/4.json
new file mode 100644
index 0000000000000000000000000000000000000000..d05cb425e1314657378178b6b2f5e2c415999fa0
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/test/4.json
@@ -0,0 +1,4 @@
+{
+	"id": 4,
+	"name" : "adler"
+}
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/test/create.json b/browserid/static/dialog/jquery/model/test/create.json
new file mode 100644
index 0000000000000000000000000000000000000000..734e4916c8f14f76a11791004c50d4cc226f68c9
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/test/create.json
@@ -0,0 +1,4 @@
+{
+	"id": 4,
+	"name" : "Highland"
+}
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/test/qunit/model_test.js b/browserid/static/dialog/jquery/model/test/qunit/model_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..0eb3880b132f8c9eb8d162dca324a1f9d0228c61
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/test/qunit/model_test.js
@@ -0,0 +1,143 @@
+module("jquery/model", { 
+	setup: function() {
+        var ids = 0;
+	    $.Model.extend("Person",{
+			findAll: function( params, success, error ) {
+				success("findAll");
+			},
+			findOne: function( params, success, error ) {
+				success("findOne");
+			},
+			create: function( params, success, error ) {
+				success({zoo: "zed", id: (++ids)},"create");
+			},
+			destroy: function( id, success, error ) {
+				success("destroy");
+			},
+			update: function( id, attrs, success, error ) {
+				success({zoo: "monkeys"},"update");
+			}
+		},{
+			prettyName: function() {
+				return "Mr. "+this.name;
+			}
+		})
+	}
+})
+
+
+test("CRUD", function(){
+   
+	Person.findAll({}, function(response){
+		equals("findAll", response)
+	})
+	Person.findOne({}, function(response){
+		equals("findOne", response)
+	})
+    var person;
+	new Person({foo: "bar"}).save(function(inst, attrs, create){
+		equals(create, "create")
+		equals("bar", inst.foo)
+		equals("zed", inst.zoo)
+		ok(inst.save, "has save function");
+		person = inst;
+	});
+    person.update({zoo: "monkey"},function(inst, attrs, update){
+		equals(inst, person, "we get back the same instance");
+		equals(person.zoo, "monkeys", "updated to monkeys zoo!  This tests that you callback with the attrs")
+	})
+})
+test("hookup and model", function(){
+	var div = $("<div/>")
+	var p = new Person({foo: "bar2", id: 5});
+	p.hookup( div[0] );
+	ok(div.hasClass("person"), "has person");
+	ok(div.hasClass("person_5"), "has person_5");
+	equals(p, div.model(),"gets model" )
+})
+test("guess type", function(){
+   equals("array", $.Model.guessType( [] )  );
+   equals("date", $.Model.guessType( new Date() )  );
+   equals("boolean", $.Model.guessType( true )  );
+   equals("number", $.Model.guessType( "1" )  );
+   equals("string", $.Model.guessType( "a" )  );
+   
+   equals("string", $.Model.guessType( "1e234234324234" ) );
+   equals("string", $.Model.guessType( "-1e234234324234" ) );
+})
+
+test("wrapMany", function(){
+	var people = Person.wrapMany([
+		{id: 1, name: "Justin"}
+	])
+	equals(people[0].prettyName(),"Mr. Justin","wraps wrapping works")
+});
+
+test("binding", 2,function(){
+	var inst = new Person({foo: "bar"});
+	
+	inst.bind("foo", function(ev, val){
+		ok(true,"updated")	
+		equals(val, "baz", "values match")
+	});
+	
+	inst.attr("foo","baz");
+	
+});
+
+test("error binding", 1, function(){
+	$.Model.extend("School",{
+	   setName : function(name, success, error){
+	     if(!name){
+	        error("no name");
+	     }
+	     return error;
+	   }
+	})
+	var school = new School();
+	school.bind("error.name", function(ev, error){
+		equals(error, "no name", "error message provided")
+	})
+	school.attr("name","");
+	
+	
+})
+
+test("auto methods",function(){
+	var School = $.Model.extend("Jquery.Model.Models.School",{
+	   findAll : steal.root.join("jquery/model/test")+"/{type}.json",
+	   findOne : steal.root.join("jquery/model/test")+"/{id}.json",
+	   create : steal.root.join("jquery/model/test")+"/create.json",
+	   update : steal.root.join("jquery/model/test")+"/update{id}.json"
+	},{})
+	stop(5000);
+	School.findAll({type:"schools"}, function(schools){
+		ok(schools,"findAll Got some data back");
+		equals(schools[0].Class.shortName,"School","there are schools")
+		
+		School.findOne({id : "4"}, function(school){
+			ok(school,"findOne Got some data back");
+			equals(school.Class.shortName,"School","a single school");
+			
+			
+			new School({name: "Highland"}).save(function(){
+				equals(this.name,"Highland","create gets the right name")
+				this.update({name: "LHS"}, function(){
+					equals(this.name,"LHS","create gets the right name")
+					start();
+				})
+			})
+			
+		})
+		
+	})
+})
+
+test("isNew", function(){
+	var p = new Person();
+	ok(p.isNew(), "nothing provided is new");
+	var p2 = new Person({id: null})
+	ok(p2.isNew(), "null id is new");
+	var p3 = new Person({id: 0})
+	ok(!p3.isNew(), "0 is not new");
+})
diff --git a/browserid/static/dialog/jquery/model/test/qunit/qunit.js b/browserid/static/dialog/jquery/model/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..6284accecc31b1344c301385929688cf0bd7fcf8
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/test/qunit/qunit.js
@@ -0,0 +1,11 @@
+//we probably have to have this only describing where the tests are
+steal
+ .plugins("jquery/model")  //load your app
+ .plugins('funcunit/qunit')  //load qunit
+ .then("model_test")
+ .plugins(
+ 	"jquery/model/associations/test/qunit",
+	"jquery/model/backup/qunit",
+	"jquery/model/list/test/qunit"
+	
+	).then("//jquery/model/validations/qunit/validations_test")
diff --git a/browserid/static/dialog/jquery/model/test/schools.json b/browserid/static/dialog/jquery/model/test/schools.json
new file mode 100644
index 0000000000000000000000000000000000000000..1b596fa06c04f73cf6066fa33247114eed5ffa35
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/test/schools.json
@@ -0,0 +1,4 @@
+[{
+	"id": 1,
+	"name" : "adler"
+}]
diff --git a/browserid/static/dialog/jquery/model/test/update4.json b/browserid/static/dialog/jquery/model/test/update4.json
new file mode 100644
index 0000000000000000000000000000000000000000..9f705c98e33bef6ddd0882585bd388d27ee9a8c4
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/test/update4.json
@@ -0,0 +1,4 @@
+{
+	"id": 4,
+	"name" : "LHS"
+}
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/validations/qunit.html b/browserid/static/dialog/jquery/model/validations/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..c003f308c275193b396637443fa844e3334d0c65
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/validations/qunit.html
@@ -0,0 +1,17 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../../funcunit/qunit/qunit.css" />
+    </head>
+    <body>
+
+    <h1 id="qunit-header">Model Test Suite</h1>
+	<h2 id="qunit-banner"></h2>
+	<div id="qunit-testrunner-toolbar"></div>
+	<h2 id="qunit-userAgent"></h2>
+    <ol id="qunit-tests"></ol>
+	<div id="qunit-test-area"></div>
+	<a href='associations/qunit.html'>associations</a>
+	<a href='list/qunit.html'>list</a>
+    <script type='text/javascript' src='../../../steal/steal.js?jquery/model/validations/qunit/validations_test.js'></script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/validations/qunit/validations_test.js b/browserid/static/dialog/jquery/model/validations/qunit/validations_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..29487526d9508cae7c38cb9886b4fe4492c84bea
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/validations/qunit/validations_test.js
@@ -0,0 +1,91 @@
+steal.plugins('funcunit/qunit','jquery/model/validations').then(function(){
+
+module("jquery/model/validations",{
+	setup : function(){
+		jQuery.Model.extend("Person",{
+		},{});
+	}
+})
+
+test("models can validate, events, callbacks", 11,function(){
+	Person.validate("age", {message : "it's a date type"},function(val){
+					return ! ( this.date instanceof Date )
+				})
+	
+	
+	var task = new Person({age: "bad"}),
+		errors = task.errors()
+		
+	
+	ok(errors, "There are errors");
+	equals(errors.age.length, 1, "there is one error");
+	equals(errors.age[0], "it's a date type", "error message is right");
+	
+	task.bind("error.age", function(ev, errs){
+		ok(this === task, "we get task back");
+		
+		ok(errs, "There are errors");
+		equals(errs.age.length, 1, "there is one error");
+		equals(errs.age[0], "it's a date type", "error message is right");
+	})
+	
+	task.attr("age","blah")
+	
+	task.unbind("error.age");
+	task.attr("age", "blaher", function(){}, function(errs){
+		ok(this === task, "we get task back");
+		
+		ok(errs, "There are errors");
+		equals(errs.age.length, 1, "there is one error");
+		equals(errs.age[0], "it's a date type", "error message is right");
+	})
+})
+
+test("validatesFormatOf", function(){
+	Person.validateFormatOf("thing",/\d-\d/)
+	
+	ok(!new Person({thing: "1-2"}).errors(),"no errors");
+	
+	var errors = new Person({thing: "foobar"}).errors();
+	
+	ok(errors, "there are errors")
+	equals(errors.thing.length,1,"one error on thing");
+	
+	equals(errors.thing[0],"is invalid","basic message");
+	
+	Person.validateFormatOf("otherThing",/\d/,{message: "not a digit"})
+	
+	var errors2 = new Person({thing: "1-2", otherThing: "a"}).errors();
+	
+	equals(errors2.otherThing[0],"not a digit", "can supply a custom message")
+});
+
+test("validatesInclusionOf", function(){
+	
+	
+})
+
+test("validatesLengthOf", function(){
+	
+})
+
+test("validatesPresenceOf", function(){
+	$.Model.extend("Task",{
+		init : function(){
+			this.validatePresenceOf("dueDate")
+		}
+	},{});
+	
+	var task = new Task(),
+		errors = task.errors();
+	
+	ok(errors)
+	ok(errors.dueDate)
+	equals(errors.dueDate[0], "can't be empty" , "right message")
+})
+
+test("validatesRangeOf", function(){
+	
+})
+
+})
diff --git a/browserid/static/dialog/jquery/model/validations/validations.html b/browserid/static/dialog/jquery/model/validations/validations.html
new file mode 100644
index 0000000000000000000000000000000000000000..59278d5f42b0e4206a69bffb9dfac7abb77e9032
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/validations/validations.html
@@ -0,0 +1,132 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>Model Validations Demo</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            li {border: solid 1px gray; padding: 5px; width: 250px;}
+			li a {color: red; font-weight: bold;}
+			p {width: 400px;}
+        </style>
+	</head>
+	<body>
+<div id="demo-instructions">
+		<h1>Model Validations Demo</h1>
+		<p>This demo demonstrates using validations to prevent
+		a person's birthday from being in the future.</p>
+		<p>Clicking a person's name will show a form to update
+		their birthday.  Change the birthday and 'blur' the 
+		input to update their listed age.</p>
+</div>
+<div id="demo-html">
+<div id='contacts1'></div>
+<div id='update'></div>
+</div>
+<script type='text/javascript' 
+        src='../../../steal/steal.js'>   
+</script>
+<script type='text/javascript'>
+steal.plugins('jquery/model',
+		'jquery/dom/fixture',
+		'jquery/model/list',
+		'jquery/model/validations').start()
+</script>
+<script type='text/javascript'>
+	CONVERSIONS = {
+		date : function(raw){
+			if(typeof raw == 'string'){
+				var matches = raw.match(/(\d+)-(\d+)-(\d+)/)
+				return new Date( +matches[1], 
+				                 (+matches[2])-1, 
+				                 +matches[3] )
+			}else if(raw instanceof Date){
+				return raw;
+			}
+		}
+	}
+	FIXTURE = function(){
+				return [[{'id': 1,'name' : 'Justin Meyer','birthday': '1982-10-20'},
+					 {'id': 2,'name' : 'Brian Moschel','birthday': '1983-11-10'},
+					 {'id': 3,'name' : 'Alex Gomes','birthday': '1980-2-10'}]];
+			}
+</script>
+<script type='text/javascript'  id="demo-source">   
+
+$.Model.extend("Contact",{
+	init : function(){
+		this.validate("birthday",function(){
+			if(this.birthday > new Date){
+				return "your birthday needs to be in the past"
+			}
+		})
+	},
+	attributes : { 
+		birthday : 'date'
+	},
+	convert : CONVERSIONS,
+	findAll : function(params, success, error){
+		$.get("/recipes.json",{},
+			this.callback(['wrapMany',success]),
+			"json",FIXTURE )
+	},
+	update : function(id, attrs, success, error){
+		$.post("/recipes.json",{},success,'json',function(){
+			return [attrs]
+		})
+	}
+},{
+	ageThisYear : function(){
+		return new Date().getFullYear() - 
+		      this.birthday.getFullYear()
+	},
+	getBirthday : function(){
+		return ""+this.birthday.getFullYear()+
+			"-"+(this.birthday.getMonth()+1)+
+			"-"+this.birthday.getDate();
+	}
+
+});
+
+makeAgeUpdater = function(contact){
+	var updater = $("#update")
+	updater.html("");
+	updater.append("<span>" +contact.name+"'s birthday </span>")
+	$('<input/>').val(contact.attr("birthday")).change(function(){
+		
+		
+		contact.attr("birthday", this.value , function(){
+			$('#error').hide();
+		}, function(errors){
+			$('#error').html(errors.birthday[0]).show();
+		})
+	}).appendTo(updater);
+	updater.append("<div id='error' style='display:none'><div>");
+}
+
+
+</script>
+
+<script type='text/javascript'>
+	// List 1
+Contact.findAll({},function(contacts){
+  var contactsEl = $('#contacts1');
+  $.each(contacts, function(i, contact){
+    var li = $('<li>')
+              .model(contact)
+              .html(contact.name+" "+contact.ageThisYear()+
+                    " <a>Show</a>")
+              .appendTo(contactsEl);
+    contact.bind("birthday", function(){
+      li.html(contact.name+" "+this.ageThisYear()+
+              " <a>Show</a>");
+    })
+  })
+  
+  contactsEl.delegate("li","click", function(){
+	 makeAgeUpdater( $(this).closest('.contact').model() );
+  });
+});
+</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/model/validations/validations.js b/browserid/static/dialog/jquery/model/validations/validations.js
new file mode 100644
index 0000000000000000000000000000000000000000..00948246da87225192f651974e845654ab462b64
--- /dev/null
+++ b/browserid/static/dialog/jquery/model/validations/validations.js
@@ -0,0 +1,178 @@
+steal.plugins('jquery/model').then(function($){
+/**
+@page jquery.model.validations Validations
+@plugin jquery/mode/validations
+@download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/model/validations/validations.js
+@test jquery/model/validations/qunit.html
+@parent jQuery.Model
+
+In many apps, it's important to validate data before sending it to the server. 
+The jquery/model/validations plugin provides validations on models.
+
+## Example
+
+To use validations, you need to call a validate method on the Model class.
+The best place to do this is in a Class's init function.
+
+@codestart
+$.Model.extend("Contact",{
+	init : function(){
+		// validates that birthday is in the future
+		this.validate("birthday",function(){
+			if(this.birthday > new Date){
+				return "your birthday needs to be in the past"
+			}
+		})
+	}
+},{});
+@codeend
+
+## Demo
+
+Click a person's name to update their birthday.  If you put the date
+in the future, say the year 2525, it will report back an error.
+
+@demo jquery/model/validations/validations.html
+ */
+
+//validations object is by property.  You can have validations that
+//span properties, but this way we know which ones to run.
+//  proc should return true if there's an error or the error message
+var validate = function(attrNames, options, proc) {
+	if(!proc){
+		proc = options;
+		options = {};
+	}
+	options = options || {};
+	attrNames = $.makeArray(attrNames)
+	var customMsg = options.message,
+		self = this;
+	
+	if(options.testIf && !options.testIf.call(this)){
+		return;
+	}
+	     
+	
+	$.each(attrNames, function(i, attrName) {
+		// Call the validate proc function in the instance context
+		if(!self.validations[attrName]){
+			self.validations[attrName] = [];
+		}
+		self.validations[attrName].push(function(){
+			var res = proc.call(this, this[attrName]);
+			return  options.message || res;
+		})
+	});
+   
+};
+
+
+$.extend($.Model, {
+   /**
+    * @function jQuery.Model.static.validate
+    * @parent jquery.model.validations
+    * Validates each of the specified attributes with the given function.  See [validation] for more on validations.
+    * @param {Array|String} attrNames Attribute name(s) to to validate
+    * @param {Function} validateProc Function used to validate each given attribute. Returns true for valid and false otherwise. Function is called in the instance context and takes the value to validate
+    * @param {Object} options (optional) Options for the validations.  Valid options include 'message' and 'testIf'.
+    */
+   validate: validate,
+
+   /**
+    * @function jQuery.Model.static.validateFormatOf
+    * @parent jquery.model.validations
+    * Validates where the values of specified attributes are of the correct form by
+    * matching it against the regular expression provided.  See [validation] for more on validations.
+    * @param {Array|String} attrNames Attribute name(s) to to validate
+    * @param {RegExp} regexp Regular expression used to match for validation
+    * @param {Object} options (optional) Options for the validations.  Valid options include 'message' and 'testIf'.
+    *
+    */
+   validateFormatOf: function(attrNames, regexp, options) {
+      validate.call(this, attrNames, options, function(value) {
+         if(  (typeof value != 'undefined' && value != '')
+         	&& String(value).match(regexp) == null )
+         {
+            return "is invalid";
+         }
+      });
+   },
+
+   /**
+    * @function jQuery.Model.static.validateInclusionOf
+    * @parent jquery.model.validations
+    * Validates whether the values of the specified attributes are available in a particular
+    * array.   See [validation] for more on validations.
+    * @param {Array|String} attrNames Attribute name(s) to to validate
+    * @param {Array} inArray Array of options to test for inclusion
+    * @param {Object} options (optional) Options for the validations.  Valid options include 'message' and 'testIf'.
+    * 
+    */
+   validateInclusionOf: function(attrNames, inArray, options) {
+      validate.call(this, attrNames, options, function(value) {
+         if(typeof value == 'undefined')
+            return;
+
+         if($.grep(inArray, function(elm) { return (elm == value);}).length == 0)
+            return "is not a valid option (perhaps out of range)";
+      });
+   },
+
+   /**
+    * @function jQuery.Model.static.validateLengthOf
+    * @parent jquery.model.validations
+    * Validates that the specified attributes' lengths are in the given range.  See [validation] for more on validations.
+    * @param {Array|String} attrNames Attribute name(s) to to validate
+    * @param {Number} min Minimum length (inclusive)
+    * @param {Number} max Maximum length (inclusive)
+    * @param {Object} options (optional) Options for the validations.  Valid options include 'message' and 'testIf'.
+    *
+    */
+   validateLengthOf: function(attrNames, min, max, options) {
+      validate.call(this, attrNames, options, function(value) {
+         if((typeof value == 'undefined' && min > 0) || value.length < min)
+            return "is too short (min=" + min + ")";
+         else if(typeof value != 'undefined' && value.length > max)
+            return "is too long (max=" + max + ")";
+      });
+   },
+
+   /**
+    * @function jQuery.Model.static.validatePresenceOf
+    * @parent jquery.model.validations
+    * Validates that the specified attributes are not blank.  See [validation] for more on validations.
+    * @param {Array|String} attrNames Attribute name(s) to to validate
+    * @param {Object} options (optional) Options for the validations.  Valid options include 'message' and 'testIf'.
+    *
+    */
+   validatePresenceOf: function(attrNames, options) {
+      validate.call(this, attrNames, options, function(value) {
+         if(typeof value == 'undefined' || value == "")
+            return "can't be empty";
+      });
+   },
+
+   /**
+    * @function jQuery.Model.static.validateRangeOf
+    * @parent jquery.model.validations
+    * Validates that the specified attributes are in the given numeric range.  See [validation] for more on validations.
+    * @param {Array|String} attrNames Attribute name(s) to to validate
+    * @param {Number} low Minimum value (inclusive)
+    * @param {Number} hi Maximum value (inclusive)
+    * @param {Object} options (optional) Options for the validations.  Valid options include 'message' and 'testIf'.
+    *
+    */
+   validateRangeOf: function(attrNames, low, hi, options) {
+      validate.call(this, attrNames, options, function(value) {
+         if(typeof value != 'undefined' && value < low || value > hi)
+            return "is out of range [" + low + "," + hi + "]";
+      });
+   }
+});
+
+
+
+
+
+	
+});
diff --git a/browserid/static/dialog/jquery/qunit.html b/browserid/static/dialog/jquery/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..f5d068705f1d2c25e5badd9daf64b5c960ddc266
--- /dev/null
+++ b/browserid/static/dialog/jquery/qunit.html
@@ -0,0 +1,15 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../funcunit/qunit/qunit.css" />
+    </head>
+    <body>
+
+    <h1 id="qunit-header">JavaScriptMVC jQuery Test Suite</h1>
+	<h2 id="qunit-banner"></h2>
+	<div id="qunit-testrunner-toolbar"></div>
+	<h2 id="qunit-userAgent"></h2>
+    <ol id="qunit-tests"></ol>
+	<div id="qunit-test-area"></div>
+    <script type='text/javascript' src='../steal/steal.js?steal[app]=jquery/test/qunit'></script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/test/qunit/qunit.js b/browserid/static/dialog/jquery/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..ea10f0acae8548c3fe1c1634f2f62da3477fadb7
--- /dev/null
+++ b/browserid/static/dialog/jquery/test/qunit/qunit.js
@@ -0,0 +1,23 @@
+//we probably have to have this only describing where the tests are
+steal('//jquery/lang/lang_test').plugins(	
+'jquery/class/test/qunit',
+'jquery/controller/test/qunit',
+'jquery/controller/view/test/qunit',
+
+'jquery/dom/compare/test/qunit',
+'jquery/dom/cur_styles/test/qunit',
+'jquery/dom/dimensions/test/qunit',
+'jquery/dom/fixture/test/qunit',
+'jquery/dom/form_params/test/qunit',
+'jquery/event/default/test/qunit',
+'jquery/event/destroyed/test/qunit',
+'jquery/event/hover/test/qunit',
+'jquery/event/drag/test/qunit',
+
+
+
+'jquery/model/test/qunit',
+
+'jquery/view/test/qunit',
+	'jquery/view/ejs/test/qunit'
+)
diff --git a/browserid/static/dialog/jquery/test/run.js b/browserid/static/dialog/jquery/test/run.js
new file mode 100644
index 0000000000000000000000000000000000000000..722bdbe54e9a71196a59304d097b69faebb93f9f
--- /dev/null
+++ b/browserid/static/dialog/jquery/test/run.js
@@ -0,0 +1,8 @@
+// loads all of jquerymx's command line tests
+
+load("jquery/download/test/run.js");
+
+load('jquery/view/test/compression/run.js');
+
+load("jquery/generate/test/run.js");
+
diff --git a/browserid/static/dialog/jquery/tie/qunit.html b/browserid/static/dialog/jquery/tie/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..853cfb5116906abd4062b84ff5e6e4d901f4ccdd
--- /dev/null
+++ b/browserid/static/dialog/jquery/tie/qunit.html
@@ -0,0 +1,20 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../funcunit/qunit/qunit.css" />
+        <title>tie QUnit Test</title>
+		<script type='text/javascript'>
+			steal = {ignoreControllers: true}
+		</script>
+		<script type='text/javascript' src='../../steal/steal.js?jquery/tie/test/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">tie Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/tie/test/qunit/qunit.js b/browserid/static/dialog/jquery/tie/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..2fda153be2c0669258b352be18f440734c75fb67
--- /dev/null
+++ b/browserid/static/dialog/jquery/tie/test/qunit/qunit.js
@@ -0,0 +1,107 @@
+steal
+  .plugins("funcunit/qunit", "jquery/tie",'jquery/model')
+  .then("tie_test").then(function(){
+  	
+	
+	module("jquery/tie",{
+		setup : function(){
+			$.Model("Person",{
+				setAge : function(age, success, error){
+					age =  +(age);
+					if(isNaN(age) || !isFinite(age) || age < 1 || age > 10){
+						error()
+					}else{
+						return age;
+					}
+				}
+			});
+		}
+	});
+	
+	test("sets age on tie", function(){
+		
+		var person1 = new Person({age: 5});
+		var inp = $("<input/>").appendTo( $("#qunit-test-area") );
+		
+		inp.tie(person1, 'age');
+		
+		equals(inp.val(), "5", "sets age");
+		
+		var person2 = new Person();
+		var inp2 = $("<input/>").appendTo( $("#qunit-test-area") );
+		inp2.tie(person2, 'age');
+		equals(inp2.val(), "", "nothing set");
+		
+		person2.attr("age",6);
+		
+		equals(inp2.val(), "6", "nothing set");
+		
+		
+	});
+	
+	test("removing the controller, removes the tie ", 3, function(){
+		var person1 = new Person({age: 5});
+		var inp = $("<div/>").appendTo( $("#qunit-test-area") );
+		
+		$.Controller("Foo",{
+			val : function(value){
+				equals(value, 5, "Foo got the value correct")
+			}
+		});
+		
+		inp.foo().tie(person1,"age");
+		var foo = inp.controller('foo'),
+			tie = inp.controller('tie');
+		inp.foo("destroy");
+		
+		person1.attr("age",7)
+		ok(foo._destroyed, "Foo is destroyed");
+		ok(tie._destroyed, "Tie is destroyed")
+	})
+	
+	test("destroying the person, removes the tie", function(){
+		var person1 = new Person({age: 5});
+		var inp = $("<div/>").appendTo( $("#qunit-test-area") );
+		
+		$.Controller("Foo",{
+			val : function(value){
+				equals(value, 5, "Foo got the value correct")
+			}
+		});
+		
+		inp.foo().tie(person1,"age");
+		var foo = inp.controller('foo'),
+			tie = inp.controller('tie');
+		
+		person1.destroyed();
+		
+		person1.attr("age",7)
+		ok(!foo._destroyed, "Foo is not destroyed");
+		ok(tie._destroyed, "Tie is destroyed")
+	})
+	
+	test("tie on a specific controller", function(){});
+	
+	test("no controller with val, only listen", function(){
+		var person1 = new Person({age: 5});
+		var inp = $("<div/>").appendTo( $("#qunit-test-area") );
+		
+		inp.tie(person1,"age");
+		
+		inp.trigger("change",7);
+		equals(7, person1.attr('age'), "persons age set on change event");
+	});
+	
+	test("input error recovery", function(){
+		var person1 = new Person({age: 5});
+		var inp = $("<input/>").appendTo( $("#qunit-test-area") );
+		
+		inp.tie(person1, 'age');
+		
+		inp.val(100).trigger('change');
+		
+		equals(inp.val(), "5", "input value stays the same");
+		equals(person1.attr('age'), "5", "persons age stays the same");
+	})
+		
+ });
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/tie/tie.html b/browserid/static/dialog/jquery/tie/tie.html
new file mode 100644
index 0000000000000000000000000000000000000000..48dd1664d1f9fc6edb7eb9f90f8f4f1b0a0aa39a
--- /dev/null
+++ b/browserid/static/dialog/jquery/tie/tie.html
@@ -0,0 +1,117 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>tie</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .error {border: solid 1px red;}
+            .error_text { color: red; font-size: 10px;}
+            td {padding: 3px;}
+			
+			#sliderWrapper {
+				border: solid 1px gray;
+				width: 300px;
+				height: 30px;
+			}
+			.mxui_slider {
+				width: 30px;
+				height: 30px;
+				background-color: green;
+			}
+			.rating .selected {
+				font-size: 20px;
+				font-weight: bold;
+				color: red;
+			}
+        </style>
+	</head>
+	<body>
+		
+		<div id='sliderWrapper'><div id='age1'></div></div>
+		<div id='rating'></div>
+		<input type='text' id='age2' />
+
+		<textarea id='age3'></textarea>
+		
+		
+		<select id='age4'>
+			<option value='1'>1</option>
+			<option value='2'>2</option>
+			<option value='3'>3</option>
+			<option value='4'>4</option>
+			<option value='5'>5</option>
+			<option value='6'>6</option>
+			<option value='7'>7</option>
+			<option value='8'>8</option>
+			<option value='9'>9</option>
+			<option value='10'>10</option>
+		</select>
+		
+		
+		<script type='text/javascript' 
+                src='../../steal/steal.js'>   
+        </script>
+		<script type='text/javascript'>
+			steal.plugins('jquery/model','jquery/tie','mxui/slider').start()
+		</script>
+		<script type='text/javascript'>
+			
+			$.Model.extend("Person",{
+				init : function(){
+					this.validateFormatOf(["email"], /\w+\@\w+\.(com|net)/, "not a valid email")
+					this.validate("birthday",function(){
+						if(this.birthday > new Date){
+							return "your birthday needs to be in the past"
+						}
+					})
+				}
+			},{
+				setAge : function(age, success, error){
+					age =  +(age);
+					if(isNaN(age) || !isFinite(age) || age < 1 || age > 10){
+						error()
+					}else{
+						$.ajax({
+							url: "/update/age",
+							data: {
+								age: age
+							},
+							success: success,
+							error: error
+						})
+					}
+				}
+			});
+			$.Controller.extend("Rating",{
+				init : function(){
+					var html = [];
+					for(var i =0; i < 15; i++){
+						html.push("<a href='javascript://'>"+(i+1)+".</a>")
+					}
+					this.element.html(html.join(" "))
+				},
+				val : function(num){
+					var selected = this.element.find(".selected");
+					if(num){
+						selected.removeClass("selected");
+						this.element.find("a").eq(num-1)
+							.addClass("selected")
+					}else{
+						return selected.text();
+					}
+				},
+				"a click" : function(el){
+					this.element.find(".selected").removeClass('selected');
+					el.addClass('selected');
+					this.element.trigger("change",el.text())
+				}
+			})
+			
+			person = new Person({age: 1});
+			$("#age1").mxui_slider({interval: 1, min: 1, max: 10});
+			$("#rating").rating();
+			$("#age1, #age2, #age3, #age4, #rating").tie(person,"age")
+		</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/tie/tie.js b/browserid/static/dialog/jquery/tie/tie.js
new file mode 100644
index 0000000000000000000000000000000000000000..afefd82b3fd21ae8c4517775a3293fc87275c672
--- /dev/null
+++ b/browserid/static/dialog/jquery/tie/tie.js
@@ -0,0 +1,85 @@
+steal.plugins('jquery/controller').then(function($){
+
+/**
+ * @core
+ * @class jQuery.Tie
+ * 
+ * The $.fn.tie plugin binds form elements and controllers with 
+ * models and vice versa.  The result is that a change in 
+ * a model will automatically update the form element or controller
+ * AND a change event on the element will update the model.
+ * 
+ * 
+ * 
+ * 
+ * 
+ */
+$.Controller.extend("jQuery.Tie",{
+	init : function(el, inst, attr, type){
+		// if there's a controller
+		if(!type){
+			//find the first one that implements val
+			var controllers = this.element.data("controllers") || {};
+			for(var name in controllers){
+				var controller = controllers[name];
+				if(typeof controller.val == 'function'){
+					type = name;
+					break;
+				}
+			}
+		}
+		
+		this.type = type;
+		this.attr = attr;
+		this.inst = inst;
+		this.bind(inst, attr, "attrChanged");
+		
+		//destroy this controller if the model instance is destroyed
+		this.bind(inst, "destroyed", "destroy");
+		
+		var value = inst.attr(attr);
+		//set the value
+		this.lastValue = value;
+		if(type){
+			
+			//destroy this controller if the controller is destroyed
+			this.bind(this.element.data("controllers")[type],"destroyed","destroy");
+			this.element[type]("val",value);
+			
+		}else{
+			this.element.val(value)
+		}
+	},
+	attrChanged : function(inst, ev, val){
+		if (val !== this.lastValue) {
+			this.setVal(val);
+			this.lastValue = val;
+		}
+	},
+	setVal : function(val){
+		if (this.type) {
+			this.element[this.type]("val", val)
+		}
+		else {
+			this.element.val(val)
+		}
+	},
+	change : function(el, ev, val){
+		if(!this.type && val === undefined){
+			val = this.element.val();
+		}
+		
+		this.inst.attr(this.attr, val, null, this.callback('setBack'))
+		
+	},
+	setBack : function(){
+		this.setVal(this.lastValue);
+	},
+	destroy : function(){
+		this.inst = null;
+		this._super();
+	}
+});
+
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/update b/browserid/static/dialog/jquery/update
new file mode 100644
index 0000000000000000000000000000000000000000..bd181bb17db1c1d43fc5b1198f6d2f5bc356373d
--- /dev/null
+++ b/browserid/static/dialog/jquery/update
@@ -0,0 +1,5 @@
+load('steal/rhino/steal.js')
+
+steal('//steal/get/get', function(s) {
+	s.get('http://github.com/jupiterjs/jquerymx/', {name: 'jquery'});
+})
diff --git a/browserid/static/dialog/jquery/view/compress.js b/browserid/static/dialog/jquery/view/compress.js
new file mode 100644
index 0000000000000000000000000000000000000000..20b0ae2c24b4ae9a670009ad59dd87e16510278c
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/compress.js
@@ -0,0 +1,7 @@
+//js view/compress.js
+
+var compressPage = 'view/view.html';
+var outputFolder = 'view';
+load("steal/compress/compress.js")
+var compress = new Steal.Compress([compressPage, outputFolder]);
+compress.init();
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/ejs/ejs.html b/browserid/static/dialog/jquery/view/ejs/ejs.html
new file mode 100644
index 0000000000000000000000000000000000000000..81c8cf92f2cac3cfd5203b80d9c4a7c74c49d8a8
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/ejs/ejs.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>ejs</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .error {border: solid 1px red;}
+            .error_text { color: red; font-size: 10px;}
+            td {padding: 3px;}
+        </style>
+	</head>
+	<body>
+	    <h1>Welcome to JavaScriptMVC 3.0!</h1>
+        <ul>
+            <li>Include plugins and files in <i>jquery/view/ejs/ejs.js</i>.</li>
+            <li>Change to production mode by changing <i>development</i> to <i>production</i> in this file.</li>
+        </ul>
+		<script type='text/javascript' 
+                src='../../../steal/steal.js?steal[app]=jquery/view/ejs&steal[env]=development'
+                package='main.js'
+                compress='false'>   
+        </script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/ejs/ejs.js b/browserid/static/dialog/jquery/view/ejs/ejs.js
new file mode 100644
index 0000000000000000000000000000000000000000..1904bf3c2694270e2dd9b58c036d863d6792a3c7
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/ejs/ejs.js
@@ -0,0 +1,537 @@
+/*jslint evil: true */
+
+
+
+steal.plugins('jquery/view', 'jquery/lang/rsplit').then(function( $ ) {
+	var myEval = function(script){
+			eval(script);
+		}
+
+	//helpers we use 
+	var chop = function( string ) {
+		return string.substr(0, string.length - 1);
+	},
+		extend = $.extend,
+		isArray = $.isArray,
+		EJS = function( options ) {
+			//returns a renderer function
+			if ( this.constructor != EJS ) {
+				var ejs = new EJS(options);
+				return function( data, helpers ) {
+					return ejs.render(data, helpers);
+				};
+			}
+
+			if ( typeof options == "function" ) {
+				this.template = {};
+				this.template.process = options;
+				return;
+			}
+			//set options on self
+			$.extend(this, EJS.options, options);
+
+			var template = new EJS.Compiler(this.text, this.type);
+
+			template.compile(options, this.name);
+
+			this.template = template;
+		},
+		defaultSplitter = /(\[%%)|(%%\])|(\[%=)|(\[%#)|(\[%)|(%\]\n)|(%\])|(\n)/;
+	/**
+	 * @class jQuery.EJS
+	 * 
+	 * @plugin jquery/view/ejs
+	 * @parent jQuery.View
+	 * @download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/view/ejs/ejs.js
+	 * @test jquery/view/ejs/qunit.html
+	 * 
+	 * 
+	 * Ejs provides <a href="http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/">ERB</a> 
+	 * style client side templates.  Use them with controllers to easily build html and inject
+	 * it into the DOM.
+	 * <h3>Example</h3>
+	 * The following generates a list of tasks:
+	 * @codestart html
+	 * &lt;ul>
+	 * &lt;% for(var i = 0; i < tasks.length; i++){ %>
+	 *     &lt;li class="task &lt;%= tasks[i].identity %>">&lt;%= tasks[i].name %>&lt;/li>
+	 * &lt;% } %>
+	 * &lt;/ul>
+	 * @codeend
+	 * For the following examples, we assume this view is in <i>'views\tasks\list.ejs'</i>
+	 * <h2>Use</h2>
+	 * There are 2 common ways to use Views: 
+	 * <ul>
+	 *     <li>Controller's [jQuery.Controller.prototype.view view function]</li>
+	 *     <li>The jQuery Helpers: [jQuery.fn.after after], 
+	 *                             [jQuery.fn.append append], 
+	 *                             [jQuery.fn.before before], 
+	 *                             [jQuery.fn.before html], 
+	 *                             [jQuery.fn.before prepend], 
+	 *                             [jQuery.fn.before replace], and 
+	 *                             [jQuery.fn.before text].</li>
+	 * </ul>
+	 * <h3>View</h3>
+	 * jQuery.Controller.prototype.view is the preferred way of rendering a view.  
+	 * You can find all the options for render in 
+	 * its [jQuery.Controller.prototype.view documentation], but here is a brief example of rendering the 
+	 * <i>list.ejs</i> view from a controller:
+	 * @codestart
+	 * $.Controller.extend("TasksController",{
+	 *     init: function( el ) {
+	 *         Task.findAll({},this.callback('list'))
+	 *     },
+	 *     list: function( tasks ) {
+	 *         this.element.html(
+	 *          this.view("list", {tasks: tasks})
+	 *        )
+	 *     }
+	 * })
+	 * @codeend
+	 * 
+	 * ## Hooking up controllers
+	 * 
+	 * After drawing some html, you often want to add other widgets and plugins inside that html.
+	 * View makes this easy.  You just have to return the Contoller class you want to be hooked up.
+	 * 
+	 * @codestart
+	 * &lt;ul &lt;%= Mxui.Tabs%>>...&lt;ul>
+	 * @codeend
+	 * 
+	 * You can even hook up multiple controllers:
+	 * 
+	 * @codestart
+	 * &lt;ul &lt;%= [Mxui.Tabs, Mxui.Filler]%>>...&lt;ul>
+	 * @codeend
+	 * 
+	 * <h2>View Helpers</h2>
+	 * View Helpers return html code.  View by default only comes with 
+	 * [jQuery.EJS.Helpers.prototype.view view] and [jQuery.EJS.Helpers.prototype.text text].
+	 * You can include more with the view/helpers plugin.  But, you can easily make your own!
+	 * Learn how in the [jQuery.EJS.Helpers Helpers] page.
+	 * 
+	 * @constructor Creates a new view
+	 * @param {Object} options A hash with the following options
+	 * <table class="options">
+	 *     <tbody><tr><th>Option</th><th>Default</th><th>Description</th></tr>
+	 *     <tr>
+	 *      <td>url</td>
+	 *      <td>&nbsp;</td>
+	 *      <td>loads the template from a file.  This path should be relative to <i>[jQuery.root]</i>.
+	 *      </td>
+	 *     </tr>
+	 *     <tr>
+	 *      <td>text</td>
+	 *      <td>&nbsp;</td>
+	 *      <td>uses the provided text as the template. Example:<br/><code>new View({text: '&lt;%=user%>'})</code>
+	 *      </td>
+	 *     </tr>
+	 *     <tr>
+	 *      <td>element</td>
+	 *      <td>&nbsp;</td>
+	 *      <td>loads a template from the innerHTML or value of the element.
+	 *      </td>
+	 *     </tr>
+	 *     <tr>
+	 *      <td>type</td>
+	 *      <td>'<'</td>
+	 *      <td>type of magic tags.  Options are '&lt;' or '['
+	 *      </td>
+	 *     </tr>
+	 *     <tr>
+	 *      <td>name</td>
+	 *      <td>the element ID or url </td>
+	 *      <td>an optional name that is used for caching.
+	 *      </td>
+	 *     </tr>
+	 *     <tr>
+	 *      <td>cache</td>
+	 *      <td>true in production mode, false in other modes</td>
+	 *      <td>true to cache template.
+	 *      </td>
+	 *     </tr>
+	 *     
+	 *    </tbody></table>
+	 */
+	$.EJS = EJS;
+	/** 
+	 * @Prototype
+	 */
+	EJS.prototype = {
+		constructor: EJS,
+		/**
+		 * Renders an object with extra view helpers attached to the view.
+		 * @param {Object} object data to be rendered
+		 * @param {Object} extra_helpers an object with additonal view helpers
+		 * @return {String} returns the result of the string
+		 */
+		render: function( object, extraHelpers ) {
+			object = object || {};
+			this._extra_helpers = extraHelpers;
+			var v = new EJS.Helpers(object, extraHelpers || {});
+			return this.template.process.call(object, object, v);
+		},
+		out: function() {
+			return this.template.out;
+		}
+	};
+	/* @Static */
+
+
+	EJS.
+	/**
+	 * Used to convert what's in &lt;%= %> magic tags to a string
+	 * to be inserted in the rendered output.
+	 * 
+	 * Typically, it's a string, and the string is just inserted.  However,
+	 * if it's a function or an object with a hookup method, it can potentially be 
+	 * be ran on the element after it's inserted into the page.
+	 * 
+	 * This is a very nice way of adding functionality through the view.
+	 * Usually this is done with [jQuery.EJS.Helpers.prototype.plugin]
+	 * but the following fades in the div element after it has been inserted:
+	 * 
+	 * @codestart
+	 * &lt;%= function(el){$(el).fadeIn()} %>
+	 * @codeend
+	 * 
+	 * @param {String|Object|Function} input the value in between the
+	 * write majic tags: &lt;%= %>
+	 * @return {String} returns the content to be added to the rendered
+	 * output.  The content is different depending on the type:
+	 * 
+	 *   * string - a bac
+	 *   * foo - bar
+	 */
+	text = function( input ) {
+		if ( typeof input == 'string' ) {
+			return input;
+		}
+		var myid;
+		if ( input === null || input === undefined ) {
+			return '';
+		}
+		if ( input instanceof Date ) {
+			return input.toDateString();
+		}
+		if ( input.hookup ) {
+			myid = $.View.hookup(function( el, id ) {
+				input.hookup.call(input, el, id);
+			});
+			return "data-view-id='" + myid + "'";
+		}
+		if ( typeof input == 'function' ) {
+			return "data-view-id='" + $.View.hookup(input) + "'";
+		}
+
+		if ( isArray(input) ) {
+			myid = $.View.hookup(function( el, id ) {
+				for ( var i = 0; i < input.length; i++ ) {
+					var stub;
+					stub = input[i].hookup ? input[i].hookup(el, id) : input[i](el, id);
+				}
+			});
+			return "data-view-id='" + myid + "'";
+		}
+		if ( input.nodeName || input.jQuery ) {
+			throw "elements in views are not supported";
+		}
+
+		if ( input.toString ) {
+			return myid ? input.toString(myid) : input.toString();
+		}
+		return '';
+	};
+
+
+
+
+	// used to break text into tolkens
+	EJS.Scanner = function( source, left, right ) {
+
+		// add these properties to the scanner
+		extend(this, {
+			leftDelimiter: left + '%',
+			rightDelimiter: '%' + right,
+			doubleLeft: left + '%%',
+			doubleRight: '%%' + right,
+			leftEqual: left + '%=',
+			leftComment: left + '%#'
+		});
+
+
+		// make a regexp that can split on these token
+		this.splitRegexp = (left == '[' ? defaultSplitter : new RegExp("(" + [this.doubleLeft, this.doubleRight, this.leftEqual, this.leftComment, this.leftDelimiter, this.rightDelimiter + '\n', this.rightDelimiter, '\n'].join(")|(") + ")"));
+
+		this.source = source;
+		this.lines = 0;
+	};
+
+
+	EJS.Scanner.prototype = {
+		// calls block with each token
+		scan: function( block ) {
+			var regex = this.splitRegexp;
+			if ( this.source ) {
+				var source_split = $.String.rsplit(this.source, /\n/);
+				for ( var i = 0; i < source_split.length; i++ ) {
+					var item = source_split[i];
+					this.scanline(item, regex, block);
+				}
+			}
+		},
+		scanline: function( line, regex, block ) {
+			this.lines++;
+			var line_split = $.String.rsplit(line, regex),
+				token;
+			for ( var i = 0; i < line_split.length; i++ ) {
+				token = line_split[i];
+				if ( token !== null ) {
+					try {
+						block(token, this);
+					} catch (e) {
+						throw {
+							type: 'jQuery.EJS.Scanner',
+							line: this.lines
+						};
+					}
+				}
+			}
+		}
+	};
+
+	// a line and script buffer
+	// we use this so we know line numbers when there
+	// is an error.  
+	// pre and post are setup and teardown for the buffer
+	EJS.Buffer = function( pre_cmd, post_cmd ) {
+		this.line = [];
+		this.script = [];
+		this.post_cmd = post_cmd;
+
+		// add the pre commands to the first line
+		this.push.apply(this, pre_cmd);
+	};
+	EJS.Buffer.prototype = {
+		//need to maintain your own semi-colons (for performance)
+		push: function() {
+			this.line.push.apply(this.line, arguments);
+		},
+
+		cr: function() {
+			this.script.push(this.line.join(''), "\n");
+			this.line = [];
+		},
+		//returns the script too
+		close: function() {
+			var stub;
+
+			if ( this.line.length > 0 ) {
+				this.script.push(this.line.join(''));
+				this.line = [];
+			}
+
+			stub = this.post_cmd.length && this.push.apply(this, this.post_cmd);
+
+			this.script.push(";"); //makes sure we always have an ending /
+			return this.script.join("");
+		}
+
+	};
+	// compiles a template
+	EJS.Compiler = function( source, left ) {
+		//normalize line endings
+		this.source = source.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
+
+		left = left || '<';
+		var right = '>';
+		switch ( left ) {
+		case '[':
+			right = ']';
+			break;
+		case '<':
+			break;
+		default:
+			throw left + ' is not a supported deliminator';
+		}
+		this.scanner = new EJS.Scanner(this.source, left, right);
+		this.out = '';
+	};
+	EJS.Compiler.prototype = {
+		compile: function( options, name ) {
+
+			options = options || {};
+
+			this.out = '';
+
+			var put_cmd = "___v1ew.push(",
+				insert_cmd = put_cmd,
+				buff = new EJS.Buffer(['var ___v1ew = [];'], []),
+				content = '',
+				clean = function( content ) {
+					return content.replace(/\\/g, '\\\\').replace(/\n/g, '\\n').replace(/"/g, '\\"');
+				},
+				put = function( content ) {
+					buff.push(put_cmd, '"', clean(content), '");');
+				},
+				startTag = null;
+
+			this.scanner.scan(function( token, scanner ) {
+				// if we don't have a start pair
+				if ( startTag === null ) {
+					switch ( token ) {
+					case '\n':
+						content = content + "\n";
+						put(content);
+						//buff.push(put_cmd , '"' , clean(content) , '");');
+						buff.cr();
+						content = '';
+						break;
+					case scanner.leftDelimiter:
+					case scanner.leftEqual:
+					case scanner.leftComment:
+						startTag = token;
+						if ( content.length > 0 ) {
+							put(content);
+						}
+						content = '';
+						break;
+
+						// replace <%% with <%
+					case scanner.doubleLeft:
+						content = content + scanner.leftDelimiter;
+						break;
+					default:
+						content = content + token;
+						break;
+					}
+				}
+				else {
+					switch ( token ) {
+					case scanner.rightDelimiter:
+						switch ( startTag ) {
+						case scanner.leftDelimiter:
+							if ( content[content.length - 1] == '\n' ) {
+								content = chop(content);
+								buff.push(content, ";");
+								buff.cr();
+							}
+							else {
+								buff.push(content, ";");
+							}
+							break;
+						case scanner.leftEqual:
+							buff.push(insert_cmd, "(jQuery.EJS.text(", content, ")));");
+							break;
+						}
+						startTag = null;
+						content = '';
+						break;
+					case scanner.doubleRight:
+						content = content + scanner.rightDelimiter;
+						break;
+					default:
+						content = content + token;
+						break;
+					}
+				}
+			});
+			if ( content.length > 0 ) {
+				// Should be content.dump in Ruby
+				buff.push(put_cmd, '"', clean(content) + '");');
+			}
+			var template = buff.close();
+			this.out = 'try { with(_VIEW) { with (_CONTEXT) {' + template + " return ___v1ew.join('');}}}catch(e){e.lineNumber=null;throw e;}";
+			//use eval instead of creating a function, b/c it is easier to debug
+			myEval.call(this,'this.process = (function(_CONTEXT,_VIEW){' + this.out + '});\r\n//@ sourceURL='+name+".js")
+		}
+	};
+	
+
+	//type, cache, folder
+	/**
+	 * @attribute options
+	 * Sets default options for all views
+	 * <table class="options">
+	 * <tbody><tr><th>Option</th><th>Default</th><th>Description</th></tr>
+	 * <tr>
+	 * <td>type</td>
+	 * <td>'<'</td>
+	 * <td>type of magic tags.  Options are '&lt;' or '['
+	 * </td>
+	 * </tr>
+	 * <tr>
+	 * <td>cache</td>
+	 * <td>true in production mode, false in other modes</td>
+	 * <td>true to cache template.
+	 * </td>
+	 * </tr>
+	 * </tbody></table>
+	 * 
+	 */
+	EJS.options = {
+		cache: true,
+		type: '<',
+		ext: '.ejs'
+	};
+
+
+
+
+	/**
+	 * @class jQuery.EJS.Helpers
+	 * @parent jQuery.EJS
+	 * By adding functions to jQuery.EJS.Helpers.prototype, those functions will be available in the 
+	 * views.
+	 * @constructor Creates a view helper.  This function is called internally.  You should never call it.
+	 * @param {Object} data The data passed to the view.  Helpers have access to it through this._data
+	 */
+	EJS.Helpers = function( data, extras ) {
+		this._data = data;
+		this._extras = extras;
+		extend(this, extras);
+	};
+	/* @prototype*/
+	EJS.Helpers.prototype = {
+		/**
+		 * Makes a plugin
+		 * @param {String} name the plugin name
+		 */
+		plugin: function( name ) {
+			var args = $.makeArray(arguments),
+				widget = args.shift();
+			return function( el ) {
+				var jq = $(el);
+				jq[widget].apply(jq, args);
+			};
+		},
+		/**
+		 * Renders a partial view.  This is deprecated in favor of <code>$.View()</code>.
+		 */
+		view: function( url, data, helpers ) {
+			helpers = helpers || this._extras;
+			data = data || this._data;
+			return $.View(url, data, helpers); //new EJS(options).render(data, helpers);
+		}
+	};
+
+
+	$.View.register({
+		suffix: "ejs",
+		//returns a function that renders the view
+		script: function( id, src ) {
+			return "jQuery.EJS(function(_CONTEXT,_VIEW) { " + new EJS({
+				text: src
+			}).out() + " })";
+		},
+		renderer: function( id, text ) {
+			var ejs = new EJS({
+				text: text,
+				name: id
+			});
+			return function( data, helpers ) {
+				return ejs.render.call(ejs, data, helpers);
+			};
+		}
+	});
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/ejs/funcunit.html b/browserid/static/dialog/jquery/view/ejs/funcunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..18e35cd862540b4b4d62b3235c158b96d6f7149b
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/ejs/funcunit.html
@@ -0,0 +1,21 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../../steal/test/qunit/qunit.css" />
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+		<script type='text/javascript' src='../../../steal/steal.js?steal[app]=jquery/view/ejs/test/funcunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">ejs Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/ejs/other.js b/browserid/static/dialog/jquery/view/ejs/other.js
new file mode 100644
index 0000000000000000000000000000000000000000..fec1636f6d7262d3b5114af751a5de9d28f2fe45
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/ejs/other.js
@@ -0,0 +1,47 @@
+var ___v1ew = [];  
+   var previous = "", res, current, title;;
+___v1ew.push("\n");
+___v1ew.push("\n");
+ if(selected && selected.length) { ;___v1ew.push("\n");
+___v1ew.push("	<div id='selected'>\n");
+___v1ew.push("		    "); for(var i =0; i < selected.length; i++){;___v1ew.push("\n");
+___v1ew.push("				");  current = selected[i];
+		 			title = (current.title ? current.title: current.name);
+					res = calculateDisplay(previous, title);
+					name = normalizeName(current.name) ;___v1ew.push("\n");
+___v1ew.push("		<div class=\"topCorner\"><div>&nbsp;</div></div>\n");
+___v1ew.push("		<div class=\"content\">\n");
+___v1ew.push("			    <a href=\"#&who=");___v1ew.push((jQuery.View.EJS.text(name)));___v1ew.push("\" class='selected choice ");___v1ew.push((jQuery.View.EJS.text(current.type)));___v1ew.push("' style=\"padding-left: ");___v1ew.push((jQuery.View.EJS.text( res.length * 20)));___v1ew.push("px\">\n");
+___v1ew.push("			    	<span class='remove' title=\"close\"></span>\n");
+___v1ew.push("					");___v1ew.push((jQuery.View.EJS.text(res.name.replace("jQuery","$"))));___v1ew.push("\n");
+___v1ew.push("					\n");
+___v1ew.push("				</a>\n");
+___v1ew.push("				"); previous = title;___v1ew.push("\n");
+___v1ew.push("		</div>\n");
+___v1ew.push("		<div class=\"bottomCorner\"><div>&nbsp;</div></div>\n");
+___v1ew.push("			"); if(i<(selected.length-1)){ ;___v1ew.push("\n");
+___v1ew.push("		<div class=\"spacer\"><div>&nbsp;</div></div>\n");
+___v1ew.push("			");};___v1ew.push("\n");
+___v1ew.push("			");};___v1ew.push("\n");
+___v1ew.push("	</div>\n");
+};___v1ew.push("\n");
+___v1ew.push("<div id='results' style=\"display: ");___v1ew.push((jQuery.View.EJS.text( hide? 'none' : 'block')));___v1ew.push("\">\n");
+___v1ew.push("	<div class=\"topCorner\"><div>&nbsp;</div></div>\n");
+___v1ew.push("	<div class=\"content\">\n");
+___v1ew.push("	    "); for(var i =0; i < list.length; i++){;___v1ew.push("\n");
+___v1ew.push("			"); current = list[i];
+			   if(current.hide){ continue; }
+			   title = (current.title ? current.title: current.name);
+	           res = calculateDisplay(previous, title);
+			   name = normalizeName(current.name) ;___v1ew.push("\n");
+___v1ew.push("		    <a href=\"");___v1ew.push((jQuery.View.EJS.text(current.type == 'prototype' || current.type == 'static' ? 'javascript://': '#&who='+name)));___v1ew.push("\" class='result choice ");___v1ew.push((jQuery.View.EJS.text(current.type)));___v1ew.push("' style=\"padding-left: ");___v1ew.push((jQuery.View.EJS.text( res.length * 20)));___v1ew.push("px\">\n");
+___v1ew.push("		    	");___v1ew.push((jQuery.View.EJS.text(res.name.replace("jQuery","$"))));___v1ew.push("\n");
+___v1ew.push("			</a>\n");
+___v1ew.push("			"); previous = title;___v1ew.push("\n");
+___v1ew.push("		");};___v1ew.push("\n");
+___v1ew.push("	</div>\n");
+___v1ew.push("	<div class=\"bottomCorner\"><div>&nbsp;</div></div>\n");
+___v1ew.push("</div>\n");
+___v1ew.push("\n");
+___v1ew.push("\n");
+;
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/ejs/qunit.html b/browserid/static/dialog/jquery/view/ejs/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..140f12e993a272bd5cc2d1099f62d57fc9eda411
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/ejs/qunit.html
@@ -0,0 +1,21 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../../funcunit/qunit/qunit.css" />
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+		<script type='text/javascript' src='../../../steal/steal.js?jquery/view/ejs/test/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">ejs Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/ejs/test/qunit/ejs_test.js b/browserid/static/dialog/jquery/view/ejs/test/qunit/ejs_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..42d8b98315374b67cadfa3730daea78e8c336767
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/ejs/test/qunit/ejs_test.js
@@ -0,0 +1,62 @@
+module("jquery/view/ejs, rendering",{
+	setup : function(){
+
+		this.animals = ['sloth', 'bear', 'monkey']
+		if(!this.animals.each){
+			this.animals.each = function(func){
+				for(var i =0; i < this.length; i++){
+					func(this[i])
+				}
+			}
+		}
+		
+		this.squareBrackets = "<ul>[% this.animals.each(function(animal){%]" +
+		               "<li>[%= animal %]</li>" + 
+			      "[%});%]</ul>"
+	    this.squareBracketsNoThis = "<ul>[% animals.each(function(animal){%]" +
+		               "<li>[%= animal %]</li>" + 
+			      "[%});%]</ul>"
+	    this.angleBracketsNoThis  = "<ul><% animals.each(function(animal){%>" +
+		               "<li><%= animal %></li>" + 
+			      "<%});%></ul>";
+
+	}
+})
+test("render with left bracket", function(){
+	var compiled = new $.EJS({text: this.squareBrackets, type: '['}).render({animals: this.animals})
+	equals(compiled, "<ul><li>sloth</li><li>bear</li><li>monkey</li></ul>", "renders with bracket")
+})
+test("render with with", function(){
+	var compiled = new $.EJS({text: this.squareBracketsNoThis, type: '['}).render({animals: this.animals}) ;
+	equals(compiled, "<ul><li>sloth</li><li>bear</li><li>monkey</li></ul>", "renders bracket with no this")
+})
+test("default carrot", function(){
+	var compiled = new $.EJS({text: this.angleBracketsNoThis}).render({animals: this.animals}) ;
+
+	equals(compiled, "<ul><li>sloth</li><li>bear</li><li>monkey</li></ul>")
+})
+test("render with double angle", function(){
+	var text = "<%% replace_me %>"+
+			  "<ul><% animals.each(function(animal){%>" +
+	               "<li><%= animal %></li>" + 
+		      "<%});%></ul>";
+	var compiled = new $.EJS({text: text}).render({animals: this.animals}) ;
+	equals(compiled, "<% replace_me %><ul><li>sloth</li><li>bear</li><li>monkey</li></ul>", "works")
+});
+
+test("comments", function(){
+	var text = "<%# replace_me %>"+
+			  "<ul><% animals.each(function(animal){%>" +
+	               "<li><%= animal %></li>" + 
+		      "<%});%></ul>";
+	var compiled = new $.EJS({text: text}).render({animals: this.animals}) ;
+	equals(compiled,"<ul><li>sloth</li><li>bear</li><li>monkey</li></ul>" )
+});
+
+test("multi line", function(){
+	var text = "a \n b \n c",
+		result = new $.EJS({text: text}).render({}) ;
+		
+	equals(result, text)
+})
+//test("multi line sourc")
diff --git a/browserid/static/dialog/jquery/view/ejs/test/qunit/qunit.js b/browserid/static/dialog/jquery/view/ejs/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..3383d1c04a89c25d305da94b564108f80af5a87f
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/ejs/test/qunit/qunit.js
@@ -0,0 +1,6 @@
+//we probably have to have this only describing where the tests are
+steal
+ .plugins("jquery/view/ejs")  //load your app
+ .plugins('funcunit/qunit')  //load qunit
+ .then("ejs_test")
+ 
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/fulljslint.js b/browserid/static/dialog/jquery/view/fulljslint.js
new file mode 100644
index 0000000000000000000000000000000000000000..1a924f2f62dae4ae01bd9a82a7b996248855fa65
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/fulljslint.js
@@ -0,0 +1,3774 @@
+// jslint.js
+// 2007-12-10
+/*
+Copyright (c) 2002 Douglas Crockford  (www.JSLint.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+The Software shall be used for Good, not Evil.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+/*
+    JSLINT is a global function. It takes two parameters.
+
+        var myResult = JSLINT(source, option);
+
+    The first parameter is either a string or an array of strings. If it is a
+    string, it will be split on '\n' or '\r'. If it is an array of strings, it
+    is assumed that each string represents one line. The source can be a
+    JavaScript text, or HTML text, or a Konfabulator text.
+
+    The second parameter is an optional object of options which control the
+    operation of JSLINT. All of the options are booleans. All are optional and
+    have a default value of false.
+
+    If it checks out, JSLINT returns true. Otherwise, it returns false.
+
+    If false, you can inspect JSLINT.errors to find out the problems.
+    JSLINT.errors is an array of objects containing these members:
+
+    {
+        line      : The line (relative to 0) at which the lint was found
+        character : The character (relative to 0) at which the lint was found
+        reason    : The problem
+        evidence  : The text line in which the problem occurred
+        raw       : The raw message before the details were inserted
+        a         : The first detail
+        b         : The second detail
+        c         : The third detail
+        d         : The fourth detail
+    }
+
+    If a fatal error was found, a null will be the last element of the
+    JSLINT.errors array.
+
+    You can request a Function Report, which shows all of the functions
+    and the parameters and vars that they use. This can be used to find
+    implied global variables and other problems. The report is in HTML and
+    can be inserted in a <body>.
+
+        var myReport = JSLINT.report(option);
+
+    If the option is true, then the report will be limited to only errors.
+*/
+
+/*jslint evil: true, nomen: false */
+
+/*members "\b", "\t", "\n", "\f", "\r", "\"", "(begin)", "(context)",
+    "(end)", "(global)", "(identifier)", "(line)", "(name)", "(params)",
+    "(scope)", "(verb)", ")", "++", "--", "\/", ADSAFE, Array, Boolean, COM,
+    Canvas, CustomAnimation, Date, Debug, Error, EvalError, FadeAnimation,
+    Frame, Function, HotKey, Image, Math, MenuItem, MoveAnimation, Number,
+    Object, Point, RangeError, ReferenceError, RegExp, RotateAnimation,
+    ScrollBar, String, SyntaxError, Text, TextArea, TypeError, URIError,
+    URL, Window, XMLDOM, XMLHttpRequest, "\\", "]", a, abbr, "about-box",
+    "about-image", "about-text", "about-version", acronym, action, address,
+    adsafe, alert, alignment, anchorstyle, animator, appleScript, applet,
+    apply, area, author, autohide, b, background, base, bdo, beep, beget,
+    bgcolor, bgcolour, bgopacity, big, bitwise, block, blockquote, blur,
+    body, br, browser, button, bytesToUIString, c, call, callee, caller,
+    canvas, cap, caption, cases, center, charAt, charCodeAt, character,
+    checked, chooseColor, chooseFile, chooseFolder, cite, clearInterval,
+    clearTimeout, cliprect, clone, close, closeWidget, closed, code, col,
+    colgroup, color, colorize, colour, columns, combine, company, condition,
+    confirm, console, constructor, content, contextmenuitems,
+    convertPathToHFS, convertPathToPlatform, copyright, d, data, dd, debug,
+    decodeURI, decodeURIComponent, defaultStatus, defaulttracking,
+    defaultvalue, defineClass, del, description, deserialize, dfn, dir,
+    directory, div, dl, doAttribute, doBegin, doIt, doTagName, document, dt,
+    dynsrc, editable, em, embed, empty, enabled, encodeURI,
+    encodeURIComponent, entityify, eqeqeq, errors, escape, eval, event,
+    evidence, evil, exec, exps, extension, fieldset, file, filesystem,
+    fillmode, flags, floor, focus, focusWidget, font, fontstyle, forin,
+    form, fragment, frame, frames, frameset, from, fromCharCode, fud,
+    function, gc, getComputedStyle, group, h1, h2, h3, h4, h5, h6, halign,
+    handlelinks, hasOwnProperty, head, height, help, hidden, history,
+    hlinesize, hoffset, hotkey, hr, href, hregistrationpoint, hscrollbar,
+    hsladjustment, hsltinting, html, i, iTunes, icon, id, identifier,
+    iframe, image, img, include, indexOf, init, input, ins, interval,
+    isAlpha, isApplicationRunning, isDigit, isFinite, isNaN, join, kbd, key,
+    kind, konfabulatorVersion, label, labelled, laxbreak, lbp, led, left,
+    legend, length, level, li, line, lines, link, load, loadClass,
+    loadingsrc, location, locked, log, lowsrc, map, match, max, maxlength,
+    menu, menuitem, message, meta, min, minimumversion, minlength,
+    missingsrc, modifier, moveBy, moveTo, name, navigator, new, noframes,
+    nomen, noscript, notsaved, nud, object, ol, on, onblur, onclick,
+    oncontextmenu, ondragdrop, ondragenter, ondragexit, onerror,
+    onfirstdisplay, onfocus, ongainfocus, onimageloaded, onkeydown,
+    onkeypress, onkeyup, onload, onlosefocus, onmousedown, onmousedrag,
+    onmouseenter, onmouseexit, onmousemove, onmouseup, onmousewheel,
+    onmulticlick, onresize, onselect, ontextinput, ontimerfired, onunload,
+    onvaluechanged, opacity, open, openURL, opener, opera, optgroup, option,
+    optionvalue, order, orientation, p, pagesize, param, parent, parseFloat,
+    parseInt, passfail, play, plusplus, pop, popupMenu, pre, preference,
+    preferenceGroups, preferencegroup, preferences, print, prompt,
+    prototype, push, q, quit, random, raw, reach, readFile, readUrl, reason,
+    reloadWidget, remoteasync, replace, report, requiredplatform, reserved,
+    resizeBy, resizeTo, resolvePath, resumeUpdates, rhino, right, root,
+    rotation, runCommand, runCommandInBg, samp, saveAs, savePreferences,
+    screen, script, scroll, scrollBy, scrollTo, scrollbar, scrolling,
+    scrollx, scrolly, seal, search, secure, select, self, serialize,
+    setInterval, setTimeout, setting, settings, shadow, shift,
+    showWidgetPreferences, size, skip, sleep, slice, small, sort, source,
+    span, spawn, speak, special, spellcheck, split, src, srcheight,
+    srcwidth, status, strong, style, sub, substr, subviews, sup, superview,
+    supplant, suppressUpdates, sync, system, table, tag, tbody, td,
+    tellWidget, test, text, textarea, tfoot, th, thead, this, thumbcolor,
+    ticking, ticklabel, ticks, tileorigin, timer, title, toLowerCase,
+    toSource, toString, toint32, token, tooltip, top, tr, tracking, trigger,
+    truncation, tt, type, u, ul, undef, unescape, unwatch, updateNow, url,
+    usefileicon, valign, value, valueOf, var, version, visible, vlinesize,
+    voffset, vregistrationpoint, vscrollbar, watch, white, widget, width,
+    window, wrap, yahooCheckLogin, yahooLogin, yahooLogout, zorder
+*/
+
+// We build the application inside a function so that we produce only a single
+// global variable. The function will be invoked, its return value is the JSLINT
+// function itself.
+
+var JSLINT;
+JSLINT = function () {
+
+// These are words that should not be permitted in third party ads.
+
+    var adsafe = {
+        apply           : true,
+        call            : true,
+        callee          : true,
+        caller          : true,
+        clone           : true,
+        constructor     : true,
+        'eval'          : true,
+        'new'           : true,
+        prototype       : true,
+        source          : true,
+        'this'          : true,
+        toSource        : true,
+        toString        : true,
+        unwatch         : true,
+        valueOf         : true,
+        watch           : true
+    },
+
+// These are all of the JSLint options.
+
+        allOptions = {
+            adsafe     : true, // if use of some browser features should be restricted
+            bitwise    : true, // if bitwise operators should not be allowed
+            browser    : true, // if the standard browser globals should be predefined
+            cap        : true, // if upper case HTML should be allowed
+            debug      : true, // if debugger statements should be allowed
+            eqeqeq     : true, // if === should be required
+            evil       : true, // if eval should be allowed
+            forin      : true, // if for in statements must filter
+            fragment   : true, // if HTML fragments should be allowed
+            laxbreak   : true, // if line breaks should not be checked
+            nomen      : true, // if names should be checked
+            on         : true, // if HTML event handlers should be allowed
+            passfail   : true, // if the scan should stop on first error
+            plusplus   : true, // if increment/decrement should not be allowed
+            rhino      : true, // if the Rhino environment globals should be predefined
+            undef      : true, // if variables should be declared before used
+            white      : true, // if strict whitespace rules apply
+            widget     : true  // if the Yahoo Widgets globals should be predefined
+        },
+
+        anonname,   // The guessed name for anonymous functions.
+
+// browser contains a set of global names which are commonly provided by a
+// web browser environment.
+
+        browser = {
+            alert           : true,
+            blur            : true,
+            clearInterval   : true,
+            clearTimeout    : true,
+            close           : true,
+            closed          : true,
+            confirm         : true,
+            console         : true,
+            Debug           : true,
+            defaultStatus   : true,
+            document        : true,
+            event           : true,
+            focus           : true,
+            frames          : true,
+            getComputedStyle: true,
+            history         : true,
+            Image           : true,
+            length          : true,
+            location        : true,
+            moveBy          : true,
+            moveTo          : true,
+            name            : true,
+            navigator       : true,
+            onblur          : true,
+            onerror         : true,
+            onfocus         : true,
+            onload          : true,
+            onresize        : true,
+            onunload        : true,
+            open            : true,
+            opener          : true,
+            opera           : true,
+            parent          : true,
+            print           : true,
+            prompt          : true,
+            resizeBy        : true,
+            resizeTo        : true,
+            screen          : true,
+            scroll          : true,
+            scrollBy        : true,
+            scrollTo        : true,
+            self            : true,
+            setInterval     : true,
+            setTimeout      : true,
+            status          : true,
+            top             : true,
+            window          : true,
+            XMLHttpRequest  : true
+        },
+
+        escapes = {
+            '\b': '\\b',
+            '\t': '\\t',
+            '\n': '\\n',
+            '\f': '\\f',
+            '\r': '\\r',
+            '"' : '\\"',
+            '/' : '\\/',
+            '\\': '\\\\'
+        },
+
+        funct,          // The current function
+        functions,      // All of the functions
+
+        href = {
+            background  : true,
+            content     : true,
+            data        : true,
+            dynsrc      : true,
+            href        : true,
+            lowsrc      : true,
+            value       : true,
+            src         : true,
+            style       : true
+        },
+
+        global,         // The global object
+        globals,        // The current globals
+        implied,        // Implied globals
+        inblock,
+        indent,
+        jsonmode,
+        lines,
+        lookahead,
+        member,
+        membersOnly,
+        nexttoken,
+        noreach,
+        option,
+        prereg,
+        prevtoken,
+
+        rhino = {
+            defineClass : true,
+            deserialize : true,
+            gc          : true,
+            help        : true,
+            load        : true,
+            loadClass   : true,
+            print       : true,
+            quit        : true,
+            readFile    : true,
+            readUrl     : true,
+            runCommand  : true,
+            seal        : true,
+            serialize   : true,
+            spawn       : true,
+            sync        : true,
+            toint32     : true,
+            version     : true
+        },
+
+        scope,      // The current scope
+        src,
+        stack,
+
+// standard contains the global names that are provided by the
+// ECMAScript standard.
+
+        standard = {
+            Array               : true,
+            Boolean             : true,
+            Date                : true,
+            decodeURI           : true,
+            decodeURIComponent  : true,
+            encodeURI           : true,
+            encodeURIComponent  : true,
+            Error               : true,
+            escape              : true,
+            'eval'              : true,
+            EvalError           : true,
+            Function            : true,
+            isFinite            : true,
+            isNaN               : true,
+            Math                : true,
+            Number              : true,
+            Object              : true,
+            parseInt            : true,
+            parseFloat          : true,
+            RangeError          : true,
+            ReferenceError      : true,
+            RegExp              : true,
+            String              : true,
+            SyntaxError         : true,
+            TypeError           : true,
+            unescape            : true,
+            URIError            : true
+        },
+
+        syntax = {},
+        token,
+        warnings,
+
+// widget contains the global names which are provided to a Yahoo
+// (fna Konfabulator) widget.
+
+        widget = {
+            alert                   : true,
+            appleScript             : true,
+            animator                : true,
+            appleScript             : true,
+            beep                    : true,
+            bytesToUIString         : true,
+            Canvas                  : true,
+            chooseColor             : true,
+            chooseFile              : true,
+            chooseFolder            : true,
+            convertPathToHFS        : true,
+            convertPathToPlatform   : true,
+            closeWidget             : true,
+            COM                     : true,
+            CustomAnimation         : true,
+            escape                  : true,
+            FadeAnimation           : true,
+            filesystem              : true,
+            focusWidget             : true,
+            form                    : true,
+            Frame                   : true,
+            HotKey                  : true,
+            Image                   : true,
+            include                 : true,
+            isApplicationRunning    : true,
+            iTunes                  : true,
+            konfabulatorVersion     : true,
+            log                     : true,
+            MenuItem                : true,
+            MoveAnimation           : true,
+            openURL                 : true,
+            play                    : true,
+            Point                   : true,
+            popupMenu               : true,
+            preferenceGroups        : true,
+            preferences             : true,
+            print                   : true,
+            prompt                  : true,
+            random                  : true,
+            reloadWidget            : true,
+            resolvePath             : true,
+            resumeUpdates           : true,
+            RotateAnimation         : true,
+            runCommand              : true,
+            runCommandInBg          : true,
+            saveAs                  : true,
+            savePreferences         : true,
+            screen                  : true,
+            ScrollBar               : true,
+            showWidgetPreferences   : true,
+            sleep                   : true,
+            speak                   : true,
+            suppressUpdates         : true,
+            system                  : true,
+            tellWidget              : true,
+            Text                    : true,
+            TextArea                : true,
+            unescape                : true,
+            updateNow               : true,
+            URL                     : true,
+            widget                  : true,
+            Window                  : true,
+            XMLDOM                  : true,
+            XMLHttpRequest          : true,
+            yahooCheckLogin         : true,
+            yahooLogin              : true,
+            yahooLogout             : true
+        },
+
+//  xmode is used to adapt to the exceptions in XML parsing.
+//  It can have these states:
+//      false   .js script file
+//      "       A " attribute
+//      '       A ' attribute
+//      content The content of a script tag
+//      CDATA   A CDATA block
+
+        xmode,
+
+//  xtype identifies the type of document being analyzed.
+//  It can have these states:
+//      false   .js script file
+//      html    .html file
+//      widget  .kon Konfabulator file
+
+        xtype,
+
+// unsafe comment
+        ax = /@cc|<\/?script|\]\]|&/i,
+// unsafe character
+        cx = /[\u0000-\u0008\u000a-\u001f\u007f-\u009f\u2028\u2029\ufff0-\uffff]/,
+// token
+        tx = /^\s*([(){}\[.,:;'"~]|\](\]>)?|\?>?|==?=?|\/(\*(global|extern|jslint|member|members)?|=|\/)?|\*[\/=]?|\+[+=]?|-[\-=]?|%[=>]?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=%\?]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,
+// star slash
+        lx = /\*\/|\/\*/,
+// identifier
+        ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,
+// javascript url
+        jx = /(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i,
+// url badness
+        ux = /&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i;
+
+    function object(o) {
+        function F() {}
+        F.prototype = o;
+        return new F();
+    }
+
+    object_combine = function (object, o) {
+        var n;
+        for (n in o) if (o.hasOwnProperty(n)) {
+            object[n] = o[n];
+        }
+    };
+
+    String.prototype.entityify = function () {
+        return this.
+            replace(/&/g, '&amp;').
+            replace(/</g, '&lt;').
+            replace(/>/g, '&gt;');
+    };
+
+    String.prototype.isAlpha = function () {
+        return (this >= 'a' && this <= 'z\uffff') ||
+            (this >= 'A' && this <= 'Z\uffff');
+    };
+
+
+    String.prototype.isDigit = function () {
+        return (this >= '0' && this <= '9');
+    };
+
+
+    String.prototype.supplant = function (o) {
+        return this.replace(/\{([^{}]*)\}/g, function (a, b) {
+            var r = o[b];
+            return typeof r === 'string' || typeof r === 'number' ? r : a;
+        });
+    };
+
+    String.prototype.name = function () {
+
+// If the string looks like an identifier, then we can return it as is.
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can simply slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe
+// sequences.
+
+
+        if (ix.test(this)) {
+            return this;
+        }
+        if (/[&<"\/\\\x00-\x1f]/.test(this)) {
+            return '"' + this.replace(/[&<"\/\\\x00-\x1f]/g, function (a) {
+                var c = escapes[a];
+                if (c) {
+                    return c;
+                }
+                c = a.charCodeAt();
+                return '\\u00' +
+                    Math.floor(c / 16).toString(16) +
+                    (c % 16).toString(16);
+            }) + '"';
+        }
+        return '"' + this + '"';
+    };
+
+
+    function populateGlobals() {
+        if (option.adsafe) {
+            object_combine(globals, {ADSAFE: true});
+        } else {
+            if (option.rhino) {
+                object_combine(globals, rhino);
+            }
+            if (option.browser) {
+                object_combine(globals, browser);
+            }
+            if (option.widget) {
+                object_combine(globals, widget);
+            }
+        }
+    }
+
+
+// Produce an error warning.
+
+    function quit(m, l, ch) {
+        throw {
+            name: 'JSLintError',
+            line: l,
+            character: ch,
+            message: m + " (" + Math.floor((l / lines.length) * 100) +
+                    "% scanned)."
+        };
+    }
+
+    function warning(m, t, a, b, c, d) {
+        var ch, l, w;
+        t = t || nexttoken;
+        if (t.id === '(end)') {
+            t = token;
+        }
+        l = t.line || 0;
+        ch = t.from || 0;
+        w = {
+            id: '(error)',
+            raw: m,
+            evidence: lines[l] || '',
+            line: l,
+            character: ch,
+            a: a,
+            b: b,
+            c: c,
+            d: d
+        };
+        w.reason = m.supplant(w);
+        JSLINT.errors.push(w);
+        if (option.passfail) {
+            quit('Stopping. ', l, ch);
+        }
+        warnings += 1;
+        if (warnings === 50) {
+            quit("Too many errors.", l, ch);
+        }
+        return w;
+    }
+
+    function warningAt(m, l, ch, a, b, c, d) {
+        return warning(m, {
+            line: l,
+            from: ch
+        }, a, b, c, d);
+    }
+
+    function error(m, t, a, b, c, d) {
+        var w = warning(m, t, a, b, c, d);
+        quit("Stopping, unable to continue.", w.line, w.character);
+    }
+
+    function errorAt(m, l, ch, a, b, c, d) {
+        return error(m, {
+            line: l,
+            from: ch
+        }, a, b, c, d);
+    }
+
+
+
+// lexical analysis
+
+    var lex = function () {
+        var character, from, line, s;
+
+// Private lex methods
+
+        function nextLine() {
+            var at;
+            line += 1;
+            if (line >= lines.length) {
+                return false;
+            }
+            character = 0;
+            s = lines[line];
+            at = s.search(cx);
+            if (at >= 0) {
+                warningAt("Unsafe character.", line, at);
+            }
+            return true;
+        }
+
+// Produce a token object.  The token inherits from a syntax symbol.
+
+        function it(type, value) {
+            var i, t;
+            if (type === '(punctuator)' ||
+                    (type === '(identifier)' && syntax.hasOwnProperty(value))) {
+                t = syntax[value];
+
+// Mozilla bug workaround.
+
+                if (!t.id) {
+                    t = syntax[type];
+                }
+            } else {
+                t = syntax[type];
+            }
+            t = object(t);
+            if (type === '(string)') {
+                if (jx.test(value)) {
+                    warningAt("Script URL.", line, from);
+                }
+            } else if (type === '(identifier)') {
+                if (option.nomen && value.charAt(0) === '_') {
+                    warningAt("Unexpected '_' in '{a}'.", line, from, value);
+                } else if (option.adsafe &&
+                        (adsafe[value] === true || value.slice(-2) === '__')) {
+                    warning("ADsafe restricted word '{a}'.",
+                            {line: line, from: character}, value);
+                }
+            }
+            t.value = value;
+            t.line = line;
+            t.character = character;
+            t.from = from;
+            i = t.id;
+            if (i !== '(endline)') {
+                prereg = i &&
+                        (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) ||
+                        i === 'return');
+            }
+            return t;
+        }
+
+// Public lex methods
+
+        return {
+            init: function (source) {
+                if (typeof source === 'string') {
+                    lines = source.
+                        replace(/\r\n/g, '\n').
+                        replace(/\r/g, '\n').
+                        split('\n');
+                } else {
+                    lines = source;
+                }
+                line = -1;
+                nextLine();
+                from = 0;
+            },
+
+// token -- this is called by advance to get the next token.
+
+            token: function () {
+                var b, c, captures, d, depth, high, i, l, low, q, t;
+
+                function match(x) {
+                    var r = x.exec(s), r1;
+                    if (r) {
+                        l = r[0].length;
+                        r1 = r[1];
+                        c = r1.charAt(0);
+                        s = s.substr(l);
+                        character += l;
+                        from = character - r1.length;
+                        return r1;
+                    }
+                }
+
+                function string(x) {
+                    var c, j, r = '';
+
+                    if (jsonmode && x !== '"') {
+                        warningAt("Strings must use doublequote.",
+                                line, character);
+                    }
+
+                    if (xmode === x || xmode === 'string') {
+                        return it('(punctuator)', x);
+                    }
+
+                    function esc(n) {
+                        var i = parseInt(s.substr(j + 1, n), 16);
+                        j += n;
+                        if (i >= 32 && i <= 127 &&
+                                i !== 34 && i !== 92 && i !== 39) {
+                            warningAt("Unnecessary escapement.", line, character);
+                        }
+                        character += n;
+                        c = String.fromCharCode(i);
+                    }
+                    j = 0;
+                    for (;;) {
+                        while (j >= s.length) {
+                            j = 0;
+                            if (xmode !== 'xml' || !nextLine()) {
+                                errorAt("Unclosed string.", line, from);
+                            }
+                        }
+                        c = s.charAt(j);
+                        if (c === x) {
+                            character += 1;
+                            s = s.substr(j + 1);
+                            return it('(string)', r, x);
+                        }
+                        if (c < ' ') {
+                            if (c === '\n' || c === '\r') {
+                                break;
+                            }
+                            warningAt("Control character in string: {a}.",
+                                    line, character + j, s.slice(0, j));
+                        } else if (c === '<') {
+                            if (option.adsafe && xmode === 'xml') {
+                                warningAt("ADsafe string violation.",
+                                        line, character + j);
+                            } else if (s.charAt(j + 1) === '/' && ((xmode && xmode !== 'CDATA') || option.adsafe)) {
+                                warningAt("Expected '<\\/' and instead saw '</'.", line, character);
+                            }
+                        } else if (c === '\\') {
+                            if (option.adsafe && xmode === 'xml') {
+                                warningAt("ADsafe string violation.",
+                                        line, character + j);
+                            }
+                            j += 1;
+                            character += 1;
+                            c = s.charAt(j);
+                            switch (c) {
+                            case '\\':
+                            case '\'':
+                            case '"':
+                            case '/':
+                                break;
+                            case 'b':
+                                c = '\b';
+                                break;
+                            case 'f':
+                                c = '\f';
+                                break;
+                            case 'n':
+                                c = '\n';
+                                break;
+                            case 'r':
+                                c = '\r';
+                                break;
+                            case 't':
+                                c = '\t';
+                                break;
+                            case 'u':
+                                esc(4);
+                                break;
+                            case 'v':
+                                c = '\v';
+                                break;
+                            case 'x':
+                                if (jsonmode) {
+                                    warningAt("Avoid \\x-.", line, character);
+                                }
+                                esc(2);
+                                break;
+                            default:
+                                warningAt("Bad escapement.", line, character);
+                            }
+                        }
+                        r += c;
+                        character += 1;
+                        j += 1;
+                    }
+                }
+
+                for (;;) {
+                    if (!s) {
+                        return it(nextLine() ? '(endline)' : '(end)', '');
+                    }
+                    t = match(tx);
+                    if (!t) {
+                        t = '';
+                        c = '';
+                        while (s && s < '!') {
+                            s = s.substr(1);
+                        }
+                        if (s) {
+                            errorAt("Unexpected '{a}'.",
+                                    line, character, s.substr(0, 1));
+                        }
+                    }
+
+//      identifier
+
+                    if (c.isAlpha() || c === '_' || c === '$') {
+                        return it('(identifier)', t);
+                    }
+
+//      number
+
+                    if (c.isDigit()) {
+                        if (!isFinite(Number(t))) {
+                            warningAt("Bad number '{a}'.",
+                                line, character, t);
+                        }
+                        if (s.substr(0, 1).isAlpha()) {
+                            warningAt("Missing space after '{a}'.",
+                                    line, character, t);
+                        }
+                        if (c === '0') {
+                            d = t.substr(1, 1);
+                            if (d.isDigit()) {
+                                warningAt("Don't use extra leading zeros '{a}'.",
+                                        line, character, t);
+                            } else if (jsonmode && (d === 'x' || d === 'X')) {
+                                warningAt("Avoid 0x-. '{a}'.",
+                                        line, character, t);
+                            }
+                        }
+                        if (t.substr(t.length - 1) === '.') {
+                            warningAt(
+    "A trailing decimal point can be confused with a dot '{a}'.",
+                                    line, character, t);
+                        }
+                        return it('(number)', t);
+                    }
+
+//      string
+
+                    switch (t) {
+                    case '"':
+                    case "'":
+                        return string(t);
+
+//      // comment
+
+                    case '//':
+                        if (src || (xmode && !(xmode === 'script' || xmode === 'CDATA'))) {
+                            warningAt("Unexpected comment.", line, character);
+                        }
+                        if (option.adsafe && ax.test(s)) {
+                            warningAt("ADsafe comment violation.", line, character);
+                        }
+                        s = '';
+                        break;
+
+//      /* comment
+
+                    case '/*':
+                        if (src || (xmode && !(xmode === 'script' || xmode === 'CDATA'))) {
+                            warningAt("Unexpected comment.", line, character);
+                        }
+                        if (option.adsafe && ax.test(s)) {
+                            warningAt("ADsafe comment violation.", line, character);
+                        }
+                        for (;;) {
+                            i = s.search(lx);
+                            if (i >= 0) {
+                                break;
+                            }
+                            if (!nextLine()) {
+                                errorAt("Unclosed comment.", line, character);
+                            } else {
+                                if (option.adsafe && ax.test(s)) {
+                                    warningAt("ADsafe comment violation.", line, character);
+                                }
+                            }
+                        }
+                        character += i + 2;
+                        if (s.substr(i, 1) === '/') {
+                            errorAt("Nested comment.", line, character);
+                        }
+                        s = s.substr(i + 2);
+                        break;
+
+//      /*global /*extern /*members /*jslint */
+
+                    case '/*global':
+                    case '/*extern':
+                    case '/*members':
+                    case '/*member':
+                    case '/*jslint':
+                    case '*/':
+                        return {
+                            value: t,
+                            type: 'special',
+                            line: line,
+                            character: character,
+                            from: from
+                        };
+
+                    case '':
+                        break;
+//      /
+                    case '/':
+                        if (prereg) {
+                            depth = 0;
+                            captures = 0;
+                            l = 0;
+                            for (;;) {
+                                b = true;
+                                c = s.charAt(l);
+                                l += 1;
+                                switch (c) {
+                                case '':
+                                    errorAt("Unclosed regular expression.", line, from);
+                                    return;
+                                case '/':
+                                    if (depth > 0) {
+                                        warningAt("Unescaped '{a}'.", line, from + l, '/');
+                                    }
+                                    c = s.substr(0, l - 1);
+                                    if (s.charAt(l) === 'g') {
+                                        l += 1;
+                                    }
+                                    if (s.charAt(l) === 'i') {
+                                        l += 1;
+                                    }
+                                    if (s.charAt(l) === 'm') {
+                                        l += 1;
+                                    }
+                                    character += l;
+                                    s = s.substr(l);
+                                    return it('(regex)', c);
+                                case '\\':
+                                    l += 1;
+                                    break;
+                                case '(':
+                                    depth += 1;
+                                    b = false;
+                                    if (s.charAt(l) === '?') {
+                                        l += 1;
+                                        switch (s.charAt(l)) {
+                                        case ':':
+                                        case '=':
+                                        case '!':
+                                            l += 1;
+                                            break;
+                                        default:
+                                            warningAt("Expected '{a}' and instead saw '{b}'.", line, from + l, ':', s.charAt(l));
+                                        }
+                                    } else {
+                                        captures += 1;
+                                    }
+                                    break;
+                                case ')':
+                                    if (depth === 0) {
+                                        warningAt("Unescaped '{a}'.", line, from + l, ')');
+                                    } else {
+                                        depth -= 1;
+                                    }
+                                    break;
+                                case ' ':
+                                    q = 1;
+                                    while (s.charAt(l) === ' ') {
+                                        l += 1;
+                                        q += 1;
+                                    }
+                                    if (q > 1) {
+                                        warningAt("Spaces are hard to count. Use {{a}}.", line, from + l, q);
+                                    }
+                                    break;
+                                case '[':
+                                    if (s.charAt(l) === '^') {
+                                        l += 1;
+                                    }
+                                    q = false;
+klass:                              for (;;) {
+                                        c = s.charAt(l);
+                                        l += 1;
+                                        switch (c) {
+                                        case '[':
+                                        case '^':
+                                            warningAt("Unescaped '{a}'.", line, from + l, c);
+                                            q = true;
+                                            break;
+                                        case '-':
+                                            if (q) {
+                                                q = false;
+                                            } else {
+                                                warningAt("Unescaped '{a}'.", line, from + l, '-');
+                                                q = true;
+                                            }
+                                            break;
+                                        case ']':
+                                            if (!q) {
+                                                warningAt("Unescaped '{a}'.", line, from + l - 1, '-');
+                                            }
+                                            break klass;
+                                        case '\\':
+                                            l += 1;
+                                            q = true;
+                                            break;
+                                        default:
+                                            if (c < ' ') {
+                                                errorAt(c ? "Control character in a regular expression" :
+                                                    "Unclosed regular expression.", line, from + l);
+                                            }
+                                            q = true;
+                                        }
+                                    }
+                                    break;
+                                case ']':
+                                case '?':
+                                case '{':
+                                case '}':
+                                case '+':
+                                case '*':
+                                    warningAt("Unescaped '{a}'.", line, from + l, c);
+                                    break;
+                                default:
+                                    if (c < ' ') {
+                                        warningAt("Control character in a regular expression", line, from + l);
+                                    }
+                                }
+                                if (b) {
+                                    switch (s.charAt(l)) {
+                                    case '?':
+                                    case '+':
+                                    case '*':
+                                        l += 1;
+                                        if (s.charAt(l) === '?') {
+                                            l += 1;
+                                        }
+                                        break;
+                                    case '{':
+                                        l += 1;
+                                        c = s.charAt(l);
+                                        if (c < '0' || c > '9') {
+                                            warningAt("Expected a number and instead saw '{a}'.", line, from + l, c);
+                                        }
+                                        l += 1;
+                                        low = +c;
+                                        for (;;) {
+                                            c = s.charAt(l);
+                                            if (c < '0' || c > '9') {
+                                                break;
+                                            }
+                                            l += 1;
+                                            low = +c + (low * 10);
+                                        }
+                                        high = low;
+                                        if (c === ',') {
+                                            l += 1;
+                                            high = Infinity;
+                                            c = s.charAt(l);
+                                            if (c >= '0' && c <= '9') {
+                                                l += 1;
+                                                high = +c;
+                                                for (;;) {
+                                                    c = s.charAt(l);
+                                                    if (c < '0' || c > '9') {
+                                                        break;
+                                                    }
+                                                    l += 1;
+                                                    high = +c + (high * 10);
+                                                }
+                                            }
+                                        }
+                                        if (s.charAt(l) !== '}') {
+                                            warningAt("Expected '{a}' and instead saw '{b}'.", line, from + l, '}', c);
+                                        } else {
+                                            l += 1;
+                                        }
+                                        if (s.charAt(l) === '?') {
+                                            l += 1;
+                                        }
+                                        if (low > high) {
+                                            warningAt("'{a}' should not be greater than '{b}'.", line, from + l, low, high);
+                                        }
+                                    }
+                                }
+                            }
+                            c = s.substr(0, l - 1);
+                            character += l;
+                            s = s.substr(l);
+                            return it('(regex)', c);
+                        }
+                        return it('(punctuator)', t);
+
+//      punctuator
+
+                    default:
+                        return it('(punctuator)', t);
+                    }
+                }
+            },
+
+// skip -- skip past the next occurrence of a particular string.
+// If the argument is empty, skip to just before the next '<' character.
+// This is used to ignore HTML content. Return false if it isn't found.
+
+            skip: function (p) {
+                var i, t = p;
+                if (nexttoken.id) {
+                    if (!t) {
+                        t = '';
+                        if (nexttoken.id.substr(0, 1) === '<') {
+                            lookahead.push(nexttoken);
+                            return true;
+                        }
+                    } else if (nexttoken.id.indexOf(t) >= 0) {
+                        return true;
+                    }
+                }
+                token = nexttoken;
+                nexttoken = syntax['(end)'];
+                for (;;) {
+                    i = s.indexOf(t || '<');
+                    if (i >= 0) {
+                        character += i + t.length;
+                        s = s.substr(i + t.length);
+                        return true;
+                    }
+                    if (!nextLine()) {
+                        break;
+                    }
+                }
+                return false;
+            }
+        };
+    }();
+
+
+    function addlabel(t, type) {
+
+        if (t === 'hasOwnProperty') {
+            error("'hasOwnProperty' is a really bad name.");
+        }
+        if (option.adsafe && scope === global) {
+            warning('ADsafe global: ' + t + '.', token);
+        }
+
+// Define t in the current function in the current scope.
+
+        if (funct.hasOwnProperty(t)) {
+            warning(funct[t] === true ?
+                "'{a}' was used before it was defined." :
+                "'{a}' is already defined.",
+                nexttoken, t);
+        }
+        scope[t] = funct;
+        funct[t] = type;
+        if (funct['(global)'] && implied.hasOwnProperty(t)) {
+            warning("'{a}' was used before it was defined.",
+                nexttoken, t);
+            delete implied[t];
+        }
+    }
+
+
+    function doOption() {
+        var b, obj, filter, o = nexttoken.value, t, v;
+        switch (o) {
+        case '*/':
+            error("Unbegun comment.");
+            break;
+        case '/*global':
+        case '/*extern':
+            if (option.adsafe) {
+                warning("ADsafe restriction.");
+            }
+            obj = globals;
+            break;
+        case '/*members':
+        case '/*member':
+            o = '/*members';
+            if (!membersOnly) {
+                membersOnly = {};
+            }
+            obj = membersOnly;
+            break;
+        case '/*jslint':
+            if (option.adsafe) {
+                warning("ADsafe restriction.");
+            }
+            obj = option;
+            filter = allOptions;
+        }
+        for (;;) {
+            t = lex.token();
+            if (t.id === ',') {
+                t = lex.token();
+            }
+            while (t.id === '(endline)') {
+                t = lex.token();
+            }
+            if (t.type === 'special' && t.value === '*/') {
+                break;
+            }
+            if (t.type !== '(string)' && t.type !== '(identifier)' &&
+                    o !== '/*members') {
+                error("Bad option.", t);
+            }
+            if (filter) {
+                if (filter[t.value] !== true) {
+                    error("Bad option.", t);
+                }
+                v = lex.token();
+                if (v.id !== ':') {
+                    error("Expected '{a}' and instead saw '{b}'.",
+                            t, ':', t.value);
+                }
+                v = lex.token();
+                if (v.value === 'true') {
+                    b = true;
+                } else if (v.value === 'false') {
+                    b = false;
+                } else {
+                    error("Expected '{a}' and instead saw '{b}'.",
+                            t, 'true', t.value);
+                }
+            } else {
+                b = true;
+            }
+            obj[t.value] = b;
+        }
+        if (filter) {
+            populateGlobals();
+        }
+    }
+
+
+// We need a peek function. If it has an argument, it peeks that much farther
+// ahead. It is used to distinguish
+//     for ( var i in ...
+// from
+//     for ( var i = ...
+
+    function peek(p) {
+        var i = p || 0, j = 0, t;
+
+        while (j <= i) {
+            t = lookahead[j];
+            if (!t) {
+                t = lookahead[j] = lex.token();
+            }
+            j += 1;
+        }
+        return t;
+    }
+
+
+    var badbreak = {
+        ')': true,
+        ']': true,
+        '++': true,
+        '--': true
+    };
+
+// Produce the next token. It looks for programming errors.
+
+    function advance(id, t) {
+        var l;
+        switch (token.id) {
+        case '(number)':
+            if (nexttoken.id === '.') {
+                warning(
+"A dot following a number can be confused with a decimal point.", token);
+            }
+            break;
+        case '-':
+            if (nexttoken.id === '-' || nexttoken.id === '--') {
+                warning("Confusing minusses.");
+            }
+            break;
+        case '+':
+            if (nexttoken.id === '+' || nexttoken.id === '++') {
+                warning("Confusing plusses.");
+            }
+            break;
+        }
+        if (token.type === '(string)' || token.identifier) {
+            anonname = token.value;
+        }
+
+        if (id && nexttoken.id !== id) {
+            if (t) {
+                if (nexttoken.id === '(end)') {
+                    warning("Unmatched '{a}'.", t, t.id);
+                } else {
+                    warning("Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
+                            nexttoken, id, t.id, t.line + 1, nexttoken.value);
+                }
+            } else {
+                warning("Expected '{a}' and instead saw '{b}'.",
+                        nexttoken, id, nexttoken.value);
+            }
+        }
+        prevtoken = token;
+        token = nexttoken;
+        for (;;) {
+            nexttoken = lookahead.shift() || lex.token();
+            if (nexttoken.type === 'special') {
+                doOption();
+            } else {
+                if (nexttoken.id === '<![') {
+                    if (option.adsafe) {
+                        error("ADsafe violation.", nexttoken);
+                    }
+                    if (xtype === 'html') {
+                        error("Unexpected '{a}'.", nexttoken, '<![');
+                    }
+                    if (xmode === 'script') {
+                        nexttoken = lex.token();
+                        if (nexttoken.value !== 'CDATA') {
+                            error("Missing '{a}'.", nexttoken, 'CDATA');
+                        }
+                        nexttoken = lex.token();
+                        if (nexttoken.id !== '[') {
+                            error("Missing '{a}'.", nexttoken, '[');
+                        }
+                        xmode = 'CDATA';
+                    } else if (xmode === 'xml') {
+                        lex.skip(']]>');
+                    } else {
+                        error("Unexpected '{a}'.", nexttoken, '<![');
+                    }
+                } else if (nexttoken.id === ']]>') {
+                    if (xmode === 'CDATA') {
+                        xmode = 'script';
+                    } else {
+                        error("Unexpected '{a}'.", nexttoken, ']]>');
+                    }
+                } else if (nexttoken.id !== '(endline)') {
+                    break;
+                }
+                if (xmode === '"' || xmode === "'") {
+                    error("Missing '{a}'.", token, xmode);
+                }
+                l = !xmode && !option.laxbreak &&
+                    (token.type === '(string)' || token.type === '(number)' ||
+                    token.type === '(identifier)' || badbreak[token.id]);
+            }
+        }
+        if (l) {
+            switch (nexttoken.id) {
+            case '{':
+            case '}':
+            case ']':
+                break;
+            case ')':
+                switch (token.id) {
+                case ')':
+                case '}':
+                case ']':
+                    break;
+                default:
+                    warning("Line breaking error '{a}'.", token, ')');
+                }
+                break;
+            default:
+                warning("Line breaking error '{a}'.",
+                        token, token.value);
+            }
+        }
+        if (xtype === 'widget' && xmode === 'script' && nexttoken.id) {
+            l = nexttoken.id.charAt(0);
+            if (l === '<' || l === '&') {
+                nexttoken.nud = nexttoken.led = null;
+                nexttoken.lbp = 0;
+                nexttoken.reach = true;
+            }
+        }
+    }
+
+
+// This is the heart of JSLINT, the Pratt parser. In addition to parsing, it
+// is looking for ad hoc lint patterns. We add to Pratt's model .fud, which is
+// like nud except that it is only used on the first token of a statement.
+// Having .fud makes it much easier to define JavaScript. I retained Pratt's
+// nomenclature.
+
+// .nud     Null denotation
+// .fud     First null denotation
+// .led     Left denotation
+//  lbp     Left binding power
+//  rbp     Right binding power
+
+// They are key to the parsing method called Top Down Operator Precedence.
+
+    function parse(rbp, initial) {
+        var left;
+        var o;
+        if (nexttoken.id === '(end)') {
+            error("Unexpected early end of program.", token);
+        }
+        advance();
+        if (option.adsafe && token.value === 'ADSAFE') {
+            if (nexttoken.id !== '.' || !(peek(0).identifier) ||
+                    peek(1).id !== '(') {
+                warning('ADsafe violation.', token);
+            }
+        }
+        if (initial) {
+            anonname = 'anonymous';
+            funct['(verb)'] = token.value;
+        }
+        if (initial && token.fud) {
+            left = token.fud();
+        } else {
+            if (token.nud) {
+                o = token.exps;
+                left = token.nud();
+            } else {
+                if (nexttoken.type === '(number)' && token.id === '.') {
+                    warning(
+"A leading decimal point can be confused with a dot: '.{a}'.",
+                            token, nexttoken.value);
+                    advance();
+                    return token;
+                } else {
+                    error("Expected an identifier and instead saw '{a}'.",
+                            token, token.id);
+                }
+            }
+            while (rbp < nexttoken.lbp) {
+                o = nexttoken.exps;
+                advance();
+                if (token.led) {
+                    left = token.led(left);
+                } else {
+                    error("Expected an operator and instead saw '{a}'.",
+                        token, token.id);
+                }
+            }
+            if (initial && !o) {
+                warning(
+"Expected an assignment or function call and instead saw an expression.",
+                        token);
+            }
+        }
+        if (!option.evil && left && left.value === 'eval') {
+            warning("eval is evil.", left);
+        }
+        return left;
+    }
+
+
+// Functions for conformance of style.
+
+    function adjacent(left, right) {
+        left = left || token;
+        right = right || nexttoken;
+        if (option.white) {
+            if (left.character !== right.from) {
+                warning("Unexpected space after '{a}'.",
+                        nexttoken, left.value);
+            }
+        }
+    }
+
+
+    function nospace(left, right) {
+        left = left || token;
+        right = right || nexttoken;
+        if (option.white) {
+            if (left.line === right.line) {
+                adjacent(left, right);
+            }
+        }
+    }
+
+
+    function nonadjacent(left, right) {
+        left = left || token;
+        right = right || nexttoken;
+        if (option.white) {
+            if (left.character === right.from) {
+                warning("Missing space after '{a}'.",
+                        nexttoken, left.value);
+            }
+        }
+    }
+
+    function indentation(bias) {
+        var i;
+        if (option.white && nexttoken.id !== '(end)') {
+            i = indent + (bias || 0);
+            if (nexttoken.from !== i) {
+                warning("Expected '{a}' to have an indentation of {b} instead of {c}.",
+                        nexttoken, nexttoken.value, i, nexttoken.from);
+            }
+        }
+    }
+
+    function nolinebreak(t) {
+        if (t.line !== nexttoken.line) {
+            warning("Line breaking error '{a}'.", t, t.id);
+        }
+    }
+
+
+// Parasitic constructors for making the symbols that will be inherited by
+// tokens.
+
+    function symbol(s, p) {
+        var x = syntax[s];
+        if (!x || typeof x !== 'object') {
+            syntax[s] = x = {
+                id: s,
+                lbp: p,
+                value: s
+            };
+        }
+        return x;
+    }
+
+
+    function delim(s) {
+        return symbol(s, 0);
+    }
+
+
+    function stmt(s, f) {
+        var x = delim(s);
+        x.identifier = x.reserved = true;
+        x.fud = f;
+        return x;
+    }
+
+
+    function blockstmt(s, f) {
+        var x = stmt(s, f);
+        x.block = true;
+        return x;
+    }
+
+
+    function reserveName(x) {
+        var c = x.id.charAt(0);
+        if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
+            x.identifier = x.reserved = true;
+        }
+        return x;
+    }
+
+
+    function prefix(s, f) {
+        var x = symbol(s, 150);
+        reserveName(x);
+        x.nud = (typeof f === 'function') ? f: function () {
+            if (option.plusplus && (this.id === '++' || this.id === '--')) {
+                warning("Unexpected use of '{a}'.", this, this.id);
+            }
+            parse(150);
+            return this;
+        };
+        return x;
+    }
+
+
+    function type(s, f) {
+        var x = delim(s);
+        x.type = s;
+        x.nud = f;
+        return x;
+    }
+
+
+    function reserve(s, f) {
+        var x = type(s, f);
+        x.identifier = x.reserved = true;
+        return x;
+    }
+
+
+    function reservevar(s) {
+        return reserve(s, function () {
+            return this;
+        });
+    }
+
+
+    function infix(s, f, p) {
+        var x = symbol(s, p);
+        reserveName(x);
+        x.led = (typeof f === 'function') ? f: function (left) {
+            nonadjacent(prevtoken, token);
+            nonadjacent(token, nexttoken);
+            return [this.id, left, parse(p)];
+        };
+        return x;
+    }
+
+
+    function relation(s, f) {
+        var x = symbol(s, 100);
+        x.led = function (left) {
+            nonadjacent(prevtoken, token);
+            nonadjacent(token, nexttoken);
+            var right = parse(100);
+            if ((left && left.id === 'NaN') || (right && right.id === 'NaN')) {
+                warning("Use the isNaN function to compare with NaN.", this);
+            } else if (f) {
+                f.apply(this, [left, right]);
+            }
+            return [this.id, left, right];
+        };
+        return x;
+    }
+
+
+    function isPoorRelation(node) {
+        return (node.type === '(number)' && !+node.value) ||
+               (node.type === '(string)' && !node.value) ||
+                node.type === 'true' ||
+                node.type === 'false' ||
+                node.type === 'undefined' ||
+                node.type === 'null';
+    }
+
+
+    function assignop(s, f) {
+        symbol(s, 20).exps = true;
+        return infix(s, function (left) {
+            var l;
+            nonadjacent(prevtoken, token);
+            nonadjacent(token, nexttoken);
+            if (adsafe) {
+                l = left;
+                do {
+                    if (l.value === 'ADSAFE') {
+                        warning('ADsafe violation.', l);
+                    }
+                    l = l.left;
+                } while (l);
+            }
+            if (left) {
+                if (left.id === '.' || left.id === '[' ||
+                        (left.identifier && !left.reserved)) {
+                    parse(19);
+                    return left;
+                }
+                if (left === syntax['function']) {
+                    warning(
+"Expected an identifier in an assignment and instead saw a function invocation.",
+                                token);
+                }
+            }
+            error("Bad assignment.", this);
+        }, 20);
+    }
+
+    function bitwise(s, f, p) {
+        var x = symbol(s, p);
+        reserveName(x);
+        x.led = (typeof f === 'function') ? f: function (left) {
+            if (option.bitwise) {
+                warning("Unexpected use of '{a}'.", this, this.id);
+            }
+            nonadjacent(prevtoken, token);
+            nonadjacent(token, nexttoken);
+            return [this.id, left, parse(p)];
+        };
+        return x;
+    }
+
+    function bitwiseassignop(s) {
+        symbol(s, 20).exps = true;
+        return infix(s, function (left) {
+            if (option.bitwise) {
+                warning("Unexpected use of '{a}'.", this, this.id);
+            }
+            nonadjacent(prevtoken, token);
+            nonadjacent(token, nexttoken);
+            if (left) {
+                if (left.id === '.' || left.id === '[' ||
+                        (left.identifier && !left.reserved)) {
+                    parse(19);
+                    return left;
+                }
+                if (left === syntax['function']) {
+                    warning(
+"Expected an identifier in an assignment, and instead saw a function invocation.",
+                                token);
+                }
+            }
+            error("Bad assignment.", this);
+        }, 20);
+    }
+
+
+    function suffix(s, f) {
+        var x = symbol(s, 150);
+        x.led = function (left) {
+            if (option.plusplus) {
+                warning("Unexpected use of '{a}'.", this, this.id);
+            }
+            return [f, left];
+        };
+        return x;
+    }
+
+
+    function optionalidentifier() {
+        if (nexttoken.reserved) {
+            warning("Expected an identifier and instead saw '{a}' (a reserved word).",
+                    nexttoken, nexttoken.id);
+        }
+        if (nexttoken.identifier) {
+            advance();
+            return token.value;
+        }
+    }
+
+
+    function identifier() {
+        var i = optionalidentifier();
+        if (i) {
+            return i;
+        }
+        if (token.id === 'function' && nexttoken.id === '(') {
+            warning("Missing name in function statement.");
+        } else {
+            error("Expected an identifier and instead saw '{a}'.",
+                    nexttoken, nexttoken.value);
+        }
+    }
+
+    function reachable(s) {
+        var i = 0, t;
+        if (nexttoken.id !== ';' || noreach) {
+            return;
+        }
+        for (;;) {
+            t = peek(i);
+            if (t.reach) {
+                return;
+            }
+            if (t.id !== '(endline)') {
+                if (t.id === 'function') {
+                    warning(
+"Inner functions should be listed at the top of the outer function.", t);
+                    break;
+                }
+                warning("Unreachable '{a}' after '{b}'.", t, t.value, s);
+                break;
+            }
+            i += 1;
+        }
+    }
+
+
+    function statement(noindent) {
+        var i = indent, r, s = scope, t = nexttoken;
+
+// We don't like the empty statement.
+
+        if (t.id === ';') {
+            warning("Unnecessary semicolon.", t);
+            advance(';');
+            return;
+        }
+
+// Is this a labelled statement?
+
+        if (t.identifier && !t.reserved && peek().id === ':') {
+            advance();
+            advance(':');
+            scope = object(s);
+            addlabel(t.value, 'label');
+            if (!nexttoken.labelled) {
+                warning("Label '{a}' on {b} statement.",
+                        nexttoken, t.value, nexttoken.value);
+            }
+            if (jx.test(t.value + ':')) {
+                warning("Label '{a}' looks like a javascript url.",
+                        t, t.value);
+            }
+            nexttoken.label = t.value;
+            t = nexttoken;
+        }
+
+// Parse the statement.
+
+        if (!noindent) {
+            indentation();
+        }
+        r = parse(0, true);
+
+// Look for the final semicolon.
+
+        if (!t.block) {
+            if (nexttoken.id !== ';') {
+                warningAt("Missing semicolon.", token.line,
+                        token.from + token.value.length);
+            } else {
+                adjacent(token, nexttoken);
+                advance(';');
+                nonadjacent(token, nexttoken);
+            }
+        }
+
+// Restore the indentation.
+
+        indent = i;
+        scope = s;
+        return r;
+    }
+
+
+    function statements() {
+        var a = [];
+        while (!nexttoken.reach && nexttoken.id !== '(end)') {
+            if (nexttoken.id === ';') {
+                warning("Unnecessary semicolon.");
+                advance(';');
+            } else {
+                a.push(statement());
+            }
+        }
+        return a;
+    }
+
+
+    function block(f) {
+        var a, b = inblock, s = scope;
+        inblock = f;
+        if (f) {
+            scope = object(scope);
+        }
+        nonadjacent(token, nexttoken);
+        var t = nexttoken;
+        if (nexttoken.id === '{') {
+            advance('{');
+            if (nexttoken.id !== '}' || token.line !== nexttoken.line) {
+                indent += 4;
+                if (!f && nexttoken.from === indent + 4) {
+                    indent += 4;
+                }
+                a = statements();
+                indent -= 4;
+                indentation();
+            }
+            advance('}', t);
+        } else {
+            warning("Expected '{a}' and instead saw '{b}'.",
+                    nexttoken, '{', nexttoken.value);
+            noreach = true;
+            a = [statement()];
+            noreach = false;
+        }
+        funct['(verb)'] = null;
+        scope = s;
+        inblock = b;
+        return a;
+    }
+
+
+// An identity function, used by string and number tokens.
+
+    function idValue() {
+        return this;
+    }
+
+
+    function countMember(m) {
+        if (membersOnly && membersOnly[m] !== true) {
+            warning("Unexpected /*member '{a}'.", nexttoken, m);
+        }
+        if (typeof member[m] === 'number') {
+            member[m] += 1;
+        } else {
+            member[m] = 1;
+        }
+    }
+
+    function note_implied(token) {
+        var name = token.value, line = token.line + 1, a = implied[name];
+        if (!a) {
+            a = [line];
+            implied[name] = a;
+        } else if (a[a.length - 1] !== line) {
+            a.push(line);
+        }
+    }
+
+
+// XML types. Currently we support html and widget.
+
+    var xmltype = {
+        html: {
+            doBegin: function (n) {
+                xtype = 'html';
+                option.browser = true;
+                populateGlobals();
+            },
+            doTagName: function (n, p) {
+                var i, t = xmltype.html.tag[n], x;
+                src = false;
+                if (!t) {
+                    error("Unrecognized tag '<{a}>'.",
+                            nexttoken,
+                            n === n.toLowerCase() ? n :
+                                n + ' (capitalization error)');
+                }
+                x = t.parent;
+                if (!option.fragment || stack.length !== 1 || !stack[0].fragment) {
+                    if (x) {
+                        if (x.indexOf(' ' + p + ' ') < 0) {
+                            error("A '<{a}>' must be within '<{b}>'.",
+                                    token, n, x);
+                        }
+                    } else {
+                        i = stack.length;
+                        do {
+                            if (i <= 0) {
+                                error("A '<{a}>' must be within '<{b}>'.",
+                                        token, n, 'body');
+                            }
+                            i -= 1;
+                        } while (stack[i].name !== 'body');
+                    }
+                }
+                return t.empty;
+            },
+            doAttribute: function (n, a) {
+                if (!a) {
+                    warning("Missing attribute name.", token);
+                }
+                a = a.toLowerCase();
+                if (n === 'script') {
+                    if (a === 'src') {
+                        src = true;
+                        return 'href';
+                    } else if (a === 'language') {
+                        warning("The 'language' attribute is deprecated.",
+                                token);
+                        return false;
+                    }
+                } else if (n === 'style') {
+                    if (a === 'type' && option.adsafe) {
+                        warning("Don't bother with 'type'.", token);
+                    }
+                }
+                if (href[a] === true) {
+                    return 'href';
+                }
+                if (a.slice(0, 2) === 'on') {
+                    if (!option.on) {
+                        warning("Avoid HTML event handlers.");
+                    }
+                    return 'script';
+                } else {
+                    return 'value';
+                }
+            },
+            doIt: function (n) {
+                return n === 'script' ? 'script' : n !== 'html' &&
+                        xmltype.html.tag[n].special && 'special';
+            },
+            tag: {
+                a:        {},
+                abbr:     {},
+                acronym:  {},
+                address:  {},
+                applet:   {},
+                area:     {empty: true, parent: ' map '},
+                b:        {},
+                base:     {empty: true, parent: ' head '},
+                bdo:      {},
+                big:      {},
+                blockquote: {},
+                body:     {parent: ' html noframes '},
+                br:       {empty: true},
+                button:   {},
+                canvas:   {parent: ' body p div th td '},
+                caption:  {parent: ' table '},
+                center:   {},
+                cite:     {},
+                code:     {},
+                col:      {empty: true, parent: ' table colgroup '},
+                colgroup: {parent: ' table '},
+                dd:       {parent: ' dl '},
+                del:      {},
+                dfn:      {},
+                dir:      {},
+                div:      {},
+                dl:       {},
+                dt:       {parent: ' dl '},
+                em:       {},
+                embed:    {},
+                fieldset: {},
+                font:     {},
+                form:     {},
+                frame:    {empty: true, parent: ' frameset '},
+                frameset: {parent: ' html frameset '},
+                h1:       {},
+                h2:       {},
+                h3:       {},
+                h4:       {},
+                h5:       {},
+                h6:       {},
+                head:     {parent: ' html '},
+                html:     {},
+                hr:       {empty: true},
+                i:        {},
+                iframe:   {},
+                img:      {empty: true},
+                input:    {empty: true},
+                ins:      {},
+                kbd:      {},
+                label:    {},
+                legend:   {parent: ' fieldset '},
+                li:       {parent: ' dir menu ol ul '},
+                link:     {empty: true, parent: ' head '},
+                map:      {},
+                menu:     {},
+                meta:     {empty: true, parent: ' head noframes noscript '},
+                noframes: {parent: ' html body '},
+                noscript: {parent: ' head html noframes '},
+                object:   {},
+                ol:       {},
+                optgroup: {parent: ' select '},
+                option:   {parent: ' optgroup select '},
+                p:        {},
+                param:    {empty: true, parent: ' applet object '},
+                pre:      {},
+                q:        {},
+                samp:     {},
+                script:   {parent: ' body div frame head iframe p pre span '},
+                select:   {},
+                small:    {},
+                span:     {},
+                strong:   {},
+                style:    {parent: ' head ', special: true},
+                sub:      {},
+                sup:      {},
+                table:    {},
+                tbody:    {parent: ' table '},
+                td:       {parent: ' tr '},
+                textarea: {},
+                tfoot:    {parent: ' table '},
+                th:       {parent: ' tr '},
+                thead:    {parent: ' table '},
+                title:    {parent: ' head '},
+                tr:       {parent: ' table tbody thead tfoot '},
+                tt:       {},
+                u:        {},
+                ul:       {},
+                'var':    {}
+            }
+        },
+        widget: {
+            doBegin: function (n) {
+                xtype = 'widget';
+                option.widget = true;
+                option.cap = true;
+                populateGlobals();
+            },
+            doTagName: function (n, p) {
+                var t = xmltype.widget.tag[n];
+                if (!t) {
+                    error("Unrecognized tag '<{a}>'.", nexttoken, n);
+                }
+                var x = t.parent;
+                if (x.indexOf(' ' + p + ' ') < 0) {
+                    error("A '<{a}>' must be within '<{b}>'.",
+                            token, n, x);
+                }
+            },
+            doAttribute: function (n, a) {
+                var t = xmltype.widget.tag[a];
+                if (!t) {
+                    error("Unrecognized attribute '<{a} {b}>'.", nexttoken, n, a);
+                }
+                var x = t.parent;
+                if (x.indexOf(' ' + n + ' ') < 0) {
+                    error("Attribute '{a}' does not belong in '<{b}>'.", nexttoken, a, n);
+                }
+                return t.script ?
+                        'script' :
+                        a === 'name' && n !== 'setting' ?
+                            'define' : 'string';
+            },
+            doIt: function (n) {
+                var x = xmltype.widget.tag[n];
+                return x && x.script && 'script';
+            },
+            tag: {
+                "about-box":            {parent: ' widget '},
+                "about-image":          {parent: ' about-box '},
+                "about-text":           {parent: ' about-box '},
+                "about-version":        {parent: ' about-box '},
+                action:                 {parent: ' widget ', script: true},
+                alignment:              {parent: ' canvas frame image scrollbar text textarea window '},
+                anchorstyle:            {parent: ' text '},
+                author:                 {parent: ' widget '},
+                autohide:               {parent: ' scrollbar '},
+                beget:                  {parent: ' canvas frame image scrollbar text window '},
+                bgcolor:                {parent: ' text textarea '},
+                bgcolour:               {parent: ' text textarea '},
+                bgopacity:              {parent: ' text textarea '},
+                canvas:                 {parent: ' frame window '},
+                charset:                {parent: ' script '},
+                checked:                {parent: ' image menuitem '},
+                cliprect:               {parent: ' image '},
+                color:                  {parent: ' about-text about-version shadow text textarea '},
+                colorize:               {parent: ' image '},
+                colour:                 {parent: ' about-text about-version shadow text textarea '},
+                columns:                {parent: ' textarea '},
+                company:                {parent: ' widget '},
+                contextmenuitems:       {parent: ' canvas frame image scrollbar text textarea window '},
+                copyright:              {parent: ' widget '},
+                data:                   {parent: ' about-text about-version text textarea '},
+                debug:                  {parent: ' widget '},
+                defaultvalue:           {parent: ' preference '},
+                defaulttracking:        {parent: ' widget '},
+                description:            {parent: ' preference '},
+                directory:              {parent: ' preference '},
+                editable:               {parent: ' textarea '},
+                enabled:                {parent: ' menuitem '},
+                extension:              {parent: ' preference '},
+                file:                   {parent: ' action preference '},
+                fillmode:               {parent: ' image '},
+                font:                   {parent: ' about-text about-version text textarea '},
+                fontstyle:              {parent: ' textarea '},
+                frame:                  {parent: ' frame window '},
+                group:                  {parent: ' preference '},
+                halign:                 {parent: ' canvas frame image scrollbar text textarea '},
+                handlelinks:            {parent: ' textarea '},
+                height:                 {parent: ' canvas frame image scrollbar text textarea window '},
+                hidden:                 {parent: ' preference '},
+                hlinesize:              {parent: ' frame '},
+                hoffset:                {parent: ' about-text about-version canvas frame image scrollbar shadow text textarea window '},
+                hotkey:                 {parent: ' widget '},
+                hregistrationpoint:     {parent: ' canvas frame image scrollbar text '},
+                hscrollbar:             {parent: ' frame '},
+                hsladjustment:          {parent: ' image '},
+                hsltinting:             {parent: ' image '},
+                icon:                   {parent: ' preferencegroup '},
+                id:                     {parent: ' canvas frame hotkey image preference text textarea timer scrollbar widget window '},
+                image:                  {parent: ' about-box frame window widget '},
+                interval:               {parent: ' action timer '},
+                key:                    {parent: ' hotkey '},
+                kind:                   {parent: ' preference '},
+                level:                  {parent: ' window '},
+                lines:                  {parent: ' textarea '},
+                loadingsrc:             {parent: ' image '},
+                locked:                 {parent: ' window '},
+                max:                    {parent: ' scrollbar '},
+                maxlength:              {parent: ' preference '},
+                menuitem:               {parent: ' contextmenuitems '},
+                min:                    {parent: ' scrollbar '},
+                minimumversion:         {parent: ' widget '},
+                minlength:              {parent: ' preference '},
+                missingsrc:             {parent: ' image '},
+                modifier:               {parent: ' hotkey '},
+                name:                   {parent: ' canvas frame hotkey image preference preferencegroup scrollbar setting text textarea timer widget window '},
+                notsaved:               {parent: ' preference '},
+                onclick:                {parent: ' canvas frame image scrollbar text textarea ', script: true},
+                oncontextmenu:          {parent: ' canvas frame image scrollbar text textarea window ', script: true},
+                ondragdrop:             {parent: ' canvas frame image scrollbar text textarea ', script: true},
+                ondragenter:            {parent: ' canvas frame image scrollbar text textarea ', script: true},
+                ondragexit:             {parent: ' canvas frame image scrollbar text textarea ', script: true},
+                onfirstdisplay:         {parent: ' window ', script: true},
+                ongainfocus:            {parent: ' textarea window ', script: true},
+                onkeydown:              {parent: ' hotkey text textarea window ', script: true},
+                onkeypress:             {parent: ' textarea window ', script: true},
+                onkeyup:                {parent: ' hotkey text textarea window ', script: true},
+                onimageloaded:          {parent: ' image ', script: true},
+                onlosefocus:            {parent: ' textarea window ', script: true},
+                onmousedown:            {parent: ' canvas frame image scrollbar text textarea window ', script: true},
+                onmousedrag:            {parent: ' canvas frame image scrollbar text textarea window ', script: true},
+                onmouseenter:           {parent: ' canvas frame image scrollbar text textarea window ', script: true},
+                onmouseexit:            {parent: ' canvas frame image scrollbar text textarea window ', script: true},
+                onmousemove:            {parent: ' canvas frame image scrollbar text textarea window ', script: true},
+                onmouseup:              {parent: ' canvas frame image scrollbar text textarea window ', script: true},
+                onmousewheel:           {parent: ' frame ', script: true},
+                onmulticlick:           {parent: ' canvas frame image scrollbar text textarea window ', script: true},
+                onselect:               {parent: ' menuitem ', script: true},
+                ontextinput:            {parent: ' window ', script: true},
+                ontimerfired:           {parent: ' timer ', script: true},
+                onvaluechanged:         {parent: ' scrollbar ', script: true},
+                opacity:                {parent: ' canvas frame image scrollbar shadow text textarea window '},
+                option:                 {parent: ' preference widget '},
+                optionvalue:            {parent: ' preference '},
+                order:                  {parent: ' preferencegroup '},
+                orientation:            {parent: ' scrollbar '},
+                pagesize:               {parent: ' scrollbar '},
+                preference:             {parent: ' widget '},
+                preferencegroup:        {parent: ' widget '},
+                remoteasync:            {parent: ' image '},
+                requiredplatform:       {parent: ' widget '},
+                root:                   {parent: ' window '},
+                rotation:               {parent: ' canvas frame image scrollbar text '},
+                script:                 {parent: ' widget ', script: true},
+                scrollbar:              {parent: ' frame text textarea window '},
+                scrolling:              {parent: ' text '},
+                scrollx:                {parent: ' frame '},
+                scrolly:                {parent: ' frame '},
+                secure:                 {parent: ' preference textarea '},
+                setting:                {parent: ' settings '},
+                settings:               {parent: ' widget '},
+                shadow:                 {parent: ' about-text about-version text window '},
+                size:                   {parent: ' about-text about-version text textarea '},
+                spellcheck:             {parent: ' textarea '},
+                src:                    {parent: ' image script '},
+                srcheight:              {parent: ' image '},
+                srcwidth:               {parent: ' image '},
+                style:                  {parent: ' about-text about-version canvas frame image preference scrollbar text textarea window '},
+                subviews:               {parent: ' frame '},
+                superview:              {parent: ' canvas frame image scrollbar text textarea '},
+                text:                   {parent: ' frame text textarea window '},
+                textarea:               {parent: ' frame window '},
+                timer:                  {parent: ' widget '},
+                thumbcolor:             {parent: ' scrollbar textarea '},
+                ticking:                {parent: ' timer '},
+                ticks:                  {parent: ' preference '},
+                ticklabel:              {parent: ' preference '},
+                tileorigin:             {parent: ' image '},
+                title:                  {parent: ' menuitem preference preferencegroup window '},
+                tooltip:                {parent: ' frame image text textarea '},
+                tracking:               {parent: ' canvas image '},
+                trigger:                {parent: ' action '},
+                truncation:             {parent: ' text '},
+                type:                   {parent: ' preference '},
+                url:                    {parent: ' about-box about-text about-version '},
+                usefileicon:            {parent: ' image '},
+                valign:                 {parent: ' canvas frame image scrollbar text textarea '},
+                value:                  {parent: ' preference scrollbar setting '},
+                version:                {parent: ' widget '},
+                visible:                {parent: ' canvas frame image scrollbar text textarea window '},
+                vlinesize:              {parent: ' frame '},
+                voffset:                {parent: ' about-text about-version canvas frame image scrollbar shadow text textarea window '},
+                vregistrationpoint:     {parent: ' canvas frame image scrollbar text '},
+                vscrollbar:             {parent: ' frame '},
+                width:                  {parent: ' canvas frame image scrollbar text textarea window '},
+                window:                 {parent: ' canvas frame image scrollbar text textarea widget '},
+                wrap:                   {parent: ' text '},
+                zorder:                 {parent: ' canvas frame image scrollbar text textarea window '}
+            }
+        }
+    };
+
+    function xmlword(tag) {
+        var w = nexttoken.value;
+        if (!nexttoken.identifier) {
+            if (nexttoken.id === '<') {
+                if (tag) {
+                    error("Expected '{a}' and instead saw '{b}'.",
+                        token, '&lt;', '<');
+                } else {
+                    error("Missing '{a}'.", token, '>');
+                }
+            } else if (nexttoken.id === '(end)') {
+                error("Bad structure.");
+            } else {
+                warning("Missing quote.", token);
+            }
+        }
+        advance();
+        while (nexttoken.id === '-' || nexttoken.id === ':') {
+            w += nexttoken.id;
+            advance();
+            if (!nexttoken.identifier) {
+                error("Bad name '{a}'.", nexttoken, w + nexttoken.value);
+            }
+            w += nexttoken.value;
+            advance();
+        }
+        if (option.cap) {
+            w = w.toLowerCase();
+        }
+        return w;
+    }
+
+    function closetag(n) {
+        return '</' + n + '>';
+    }
+
+    function xml() {
+        var a, e, n, q, t, wmode;
+        xmode = 'xml';
+        stack = null;
+        for (;;) {
+            switch (nexttoken.value) {
+            case '<':
+                if (!stack) {
+                    stack = [];
+                }
+                advance('<');
+                t = nexttoken;
+                n = xmlword(true);
+                t.name = n;
+                if (!xtype) {
+                    if (option.fragment && option.adsafe &&
+                            n !== 'div' && n !== 'iframe') {
+                        error("ADsafe HTML fragment violation.", token);
+                    }
+                    if (xmltype[n]) {
+                        xmltype[n].doBegin();
+                        n = xtype;
+                        e = false;
+                    } else {
+                        if (option.fragment) {
+                            xmltype.html.doBegin();
+                        } else {
+                            error("Unrecognized tag '<{a}>'.", nexttoken, n);
+                        }
+                    }
+                } else {
+                    if (stack.length === 0) {
+                        error("What the hell is this?");
+                    }
+                    e = xmltype[xtype].doTagName(n,
+                            stack[stack.length - 1].name);
+                }
+                t.type = n;
+                for (;;) {
+                    if (nexttoken.id === '/') {
+                        advance('/');
+                        if (nexttoken.id !== '>') {
+                            warning("Expected '{a}' and instead saw '{b}'.",
+                                    nexttoken, '>', nexttoken.value);
+                        }
+                        e = true;
+                        break;
+                    }
+                    if (nexttoken.id && nexttoken.id.substr(0, 1) === '>') {
+                        break;
+                    }
+                    a = xmlword();
+                    switch (xmltype[xtype].doAttribute(n, a)) {
+                    case 'script':
+                        xmode = 'string';
+                        advance('=');
+                        q = nexttoken.id;
+                        if (q !== '"' && q !== "'") {
+                            error("Missing quote.");
+                        }
+                        xmode = q;
+                        wmode = option.white;
+                        option.white = false;
+                        advance(q);
+                        statements();
+                        option.white = wmode;
+                        if (nexttoken.id !== q) {
+                            error("Missing close quote on script attribute.");
+                        }
+                        xmode = 'xml';
+                        advance(q);
+                        break;
+                    case 'value':
+                        advance('=');
+                        if (!nexttoken.identifier &&
+                                nexttoken.type !== '(string)' &&
+                                nexttoken.type !== '(number)') {
+                            error("Bad value '{a}'.",
+                                    nexttoken, nexttoken.value);
+                        }
+                        advance();
+                        break;
+                    case 'string':
+                        advance('=');
+                        if (nexttoken.type !== '(string)') {
+                            error("Bad value '{a}'.",
+                                    nexttoken, nexttoken.value);
+                        }
+                        advance();
+                        break;
+                    case 'href':
+                        advance('=');
+                        if (nexttoken.type !== '(string)') {
+                            error("Bad value '{a}'.",
+                                    nexttoken, nexttoken.value);
+                        }
+                        if (option.adsafe && ux.test(nexttoken.value)) {
+                            error("ADsafe URL violation.");
+                        }
+                        advance();
+                        break;
+                    case 'define':
+                        advance('=');
+                        if (nexttoken.type !== '(string)') {
+                            error("Bad value '{a}'.",
+                                    nexttoken, nexttoken.value);
+                        }
+                        addlabel(nexttoken.value, 'var');
+                        advance();
+                        break;
+                    default:
+                        if (nexttoken.id === '=') {
+                            advance('=');
+                            if (!nexttoken.identifier &&
+                                    nexttoken.type !== '(string)' &&
+                                    nexttoken.type !== '(number)') {
+                                error("Bad value '{a}'.",
+                                        nexttoken, nexttoken.value);
+                            }
+                            advance();
+                        }
+                    }
+                }
+                switch (xmltype[xtype].doIt(n)) {
+                case 'script':
+                    xmode = 'script';
+                    advance('>');
+                    indent = nexttoken.from;
+                    if (src) {
+                        if (option.fragment && option.adsafe) {
+                            warning("ADsafe script violation.", token);
+                        }
+                    } else {
+                        statements();
+                    }
+                    if (nexttoken.id !== '</' && nexttoken.id !== '(end)') {
+                        warning("Expected '{a}' and instead saw '{b}'.",
+                                nexttoken, '<\/script>', nexttoken.value);
+                    }
+                    xmode = 'xml';
+                    break;
+                case 'special':
+                    e = true;
+                    n = closetag(t.name);
+                    if (!lex.skip(n)) {
+                        error("Missing '{a}'.", t, n);
+                    }
+                    break;
+                default:
+                    lex.skip('>');
+                }
+                if (!e) {
+                    stack.push(t);
+                }
+                break;
+            case '</':
+                advance('</');
+                n = xmlword(true);
+                t = stack.pop();
+                if (!t) {
+                    error("Unexpected '{a}'.", nexttoken, closetag(n));
+                }
+                if (t.name !== n) {
+                    error("Expected '{a}' and instead saw '{b}'.",
+                            nexttoken, closetag(t.name), closetag(n));
+                }
+                if (nexttoken.id !== '>') {
+                    error("Missing '{a}'.", nexttoken, '>');
+                }
+                if (stack.length > 0) {
+                    lex.skip('>');
+                } else {
+                    advance('>');
+                }
+                break;
+            case '<!':
+                if (option.adsafe) {
+                    error("ADsafe HTML violation.");
+                }
+                for (;;) {
+                    advance();
+                    if (nexttoken.id === '>') {
+                        break;
+                    }
+                    if (nexttoken.id === '<' || nexttoken.id === '(end)') {
+                        error("Missing '{a}'.", token, '>');
+                    }
+                }
+                lex.skip('>');
+                break;
+            case '<!--':
+                if (option.adsafe) {
+                    error("ADsafe comment violation.");
+                }
+                lex.skip('-->');
+                break;
+            case '<%':
+                if (option.adsafe) {
+                    error("ADsafe HTML violation.");
+                }
+                lex.skip('%>');
+                break;
+            case '<?':
+                if (option.adsafe) {
+                    error("ADsafe HTML violation.");
+                }
+                for (;;) {
+                    advance();
+                    if (nexttoken.id === '?>') {
+                        break;
+                    }
+                    if (nexttoken.id === '<?' || nexttoken.id === '<' ||
+                            nexttoken.id === '>' || nexttoken.id === '(end)') {
+                        error("Missing '{a}'.", token, '?>');
+                    }
+                }
+                lex.skip('?>');
+                break;
+            case '<=':
+            case '<<':
+            case '<<=':
+                error("Missing '{a}'.", nexttoken, '&lt;');
+                break;
+            case '(end)':
+                return;
+            }
+            if (stack && stack.length === 0) {
+                return;
+            }
+            if (!lex.skip('')) {
+                if (!stack) {
+                    error("Bad XML.");
+                }
+                t = stack.pop();
+                if (t.value) {
+                    error("Missing '{a}'.", t, closetag(t.name));
+                } else {
+                    return;
+                }
+            }
+            advance();
+        }
+    }
+
+
+// Build the syntax table by declaring the syntactic elements of the language.
+
+    type('(number)', idValue);
+    type('(string)', idValue);
+
+    syntax['(identifier)'] = {
+        type: '(identifier)',
+        lbp: 0,
+        identifier: true,
+        nud: function () {
+            var v = this.value,
+                s = scope[v];
+
+// The name is in scope and defined in the current function.
+
+            if (s && (s === funct || s === funct['(global)'])) {
+
+//      If we are not also in the global scope, change 'unused' to 'var',
+//      and reject labels.
+
+                if (!funct['(global)']) {
+                    switch (funct[v]) {
+                    case 'unused':
+                        funct[v] = 'var';
+                        break;
+                    case 'label':
+                        warning("'{a}' is a statement label.", token, v);
+                        break;
+                    }
+                }
+
+// The name is not defined in the function.  If we are in the global scope,
+// then we have an undefined variable.
+
+            } else if (funct['(global)']) {
+                if (option.undef) {
+                    warning("'{a}' is undefined.", token, v);
+                }
+                note_implied(token);
+
+// If the name is already defined in the current
+// function, but not as outer, then there is a scope error.
+
+            } else {
+                switch (funct[v]) {
+                case 'closure':
+                case 'function':
+                case 'var':
+                case 'unused':
+                    warning("'{a}' used out of scope.", token, v);
+                    break;
+                case 'label':
+                    warning("'{a}' is a statement label.", token, v);
+                    break;
+                case 'outer':
+                case true:
+                    break;
+                default:
+
+// If the name is defined in an outer function, make an outer entry, and if
+// it was unused, make it var.
+
+                    if (s === true) {
+                        funct[v] = true;
+                    } else if (typeof s !== 'object') {
+                        if (option.undef) {
+                            warning("'{a}' is undefined.", token, v);
+                        } else {
+                            funct[v] = true;
+                        }
+                        note_implied(token);
+                    } else {
+                        switch (s[v]) {
+                        case 'function':
+                        case 'var':
+                        case 'unused':
+                            s[v] = 'closure';
+                            funct[v] = 'outer';
+                            break;
+                        case 'closure':
+                        case 'parameter':
+                            funct[v] = 'outer';
+                            break;
+                        case 'label':
+                            warning("'{a}' is a statement label.", token, v);
+                        }
+                    }
+                }
+            }
+            return this;
+        },
+        led: function () {
+            error("Expected an operator and instead saw '{a}'.",
+                    nexttoken, nexttoken.value);
+        }
+    };
+
+    type('(regex)', function () {
+        return [this.id, this.value, this.flags];
+    });
+
+    delim('(endline)');
+    delim('(begin)');
+    delim('(end)').reach = true;
+    delim('</').reach = true;
+    delim('<![').reach = true;
+    delim('<%');
+    delim('<?');
+    delim('<!');
+    delim('<!--');
+    delim('%>');
+    delim('?>');
+    delim('(error)').reach = true;
+    delim('}').reach = true;
+    delim(')');
+    delim(']');
+    delim(']]>').reach = true;
+    delim('"').reach = true;
+    delim("'").reach = true;
+    delim(';');
+    delim(':').reach = true;
+    delim(',');
+    reserve('else');
+    reserve('case').reach = true;
+    reserve('catch');
+    reserve('default').reach = true;
+    reserve('finally');
+    reservevar('arguments');
+    reservevar('eval');
+    reservevar('false');
+    reservevar('Infinity');
+    reservevar('NaN');
+    reservevar('null');
+    reservevar('this');
+    reservevar('true');
+    reservevar('undefined');
+    assignop('=', 'assign', 20);
+    assignop('+=', 'assignadd', 20);
+    assignop('-=', 'assignsub', 20);
+    assignop('*=', 'assignmult', 20);
+    assignop('/=', 'assigndiv', 20).nud = function () {
+        error("A regular expression literal can be confused with '/='.");
+    };
+    assignop('%=', 'assignmod', 20);
+    bitwiseassignop('&=', 'assignbitand', 20);
+    bitwiseassignop('|=', 'assignbitor', 20);
+    bitwiseassignop('^=', 'assignbitxor', 20);
+    bitwiseassignop('<<=', 'assignshiftleft', 20);
+    bitwiseassignop('>>=', 'assignshiftright', 20);
+    bitwiseassignop('>>>=', 'assignshiftrightunsigned', 20);
+    infix('?', function (left) {
+        parse(10);
+        advance(':');
+        parse(10);
+    }, 30);
+
+    infix('||', 'or', 40);
+    infix('&&', 'and', 50);
+    bitwise('|', 'bitor', 70);
+    bitwise('^', 'bitxor', 80);
+    bitwise('&', 'bitand', 90);
+    relation('==', function (left, right) {
+        if (option.eqeqeq) {
+            warning("Expected '{a}' and instead saw '{b}'.",
+                    this, '===', '==');
+        } else if (isPoorRelation(left)) {
+            warning("Use '{a}' to compare with '{b}'.",
+                this, '===', left.value);
+        } else if (isPoorRelation(right)) {
+            warning("Use '{a}' to compare with '{b}'.",
+                this, '===', right.value);
+        }
+        return ['==', left, right];
+    });
+    relation('===');
+    relation('!=', function (left, right) {
+        if (option.eqeqeq) {
+            warning("Expected '{a}' and instead saw '{b}'.",
+                    this, '!==', '!=');
+        } else if (isPoorRelation(left)) {
+            warning("Use '{a}' to compare with '{b}'.",
+                    this, '!==', left.value);
+        } else if (isPoorRelation(right)) {
+            warning("Use '{a}' to compare with '{b}'.",
+                    this, '!==', right.value);
+        }
+        return ['!=', left, right];
+    });
+    relation('!==');
+    relation('<');
+    relation('>');
+    relation('<=');
+    relation('>=');
+    bitwise('<<', 'shiftleft', 120);
+    bitwise('>>', 'shiftright', 120);
+    bitwise('>>>', 'shiftrightunsigned', 120);
+    infix('in', 'in', 120);
+    infix('instanceof', 'instanceof', 120);
+    infix('+', function (left) {
+        nonadjacent(prevtoken, token);
+        nonadjacent(token, nexttoken);
+        var right = parse(130);
+        if (left && right && left.id === '(string)' && right.id === '(string)') {
+            left.value += right.value;
+            left.character = right.character;
+            if (jx.test(left.value)) {
+                warning("JavaScript URL.", left);
+            }
+            return left;
+        }
+        return [this.id, left, right];
+    }, 130);
+    prefix('+', 'num');
+    infix('-', 'sub', 130);
+    prefix('-', 'neg');
+    infix('*', 'mult', 140);
+    infix('/', 'div', 140);
+    infix('%', 'mod', 140);
+
+    suffix('++', 'postinc');
+    prefix('++', 'preinc');
+    syntax['++'].exps = true;
+
+    suffix('--', 'postdec');
+    prefix('--', 'predec');
+    syntax['--'].exps = true;
+    prefix('delete', function () {
+        var p = parse(0);
+        if (p.id !== '.' && p.id !== '[') {
+            warning("Expected '{a}' and instead saw '{b}'.",
+                    nexttoken, '.', nexttoken.value);
+        }
+    }).exps = true;
+
+
+    prefix('~', function () {
+        if (option.bitwise) {
+            warning("Unexpected '{a}'.", this, '~');
+        }
+        parse(150);
+        return this;
+    });
+    prefix('!', 'not');
+    prefix('typeof', 'typeof');
+    prefix('new', function () {
+        var c = parse(155), i;
+        if (c) {
+            if (c.identifier) {
+                c['new'] = true;
+                switch (c.value) {
+                case 'Object':
+                    warning("Use the object literal notation {}.", token);
+                    break;
+                case 'Array':
+                    warning("Use the array literal notation [].", token);
+                    break;
+                case 'Number':
+                case 'String':
+                case 'Boolean':
+                    warning("Do not use the {a} function as a constructor.",
+                            token, c.value);
+                    break;
+                case 'Function':
+                    if (!option.evil) {
+                        warning("The Function constructor is eval.");
+                    }
+                    break;
+                default:
+                    if (c.id !== 'function') {
+                        i = c.value.substr(0, 1);
+                        if (i < 'A' || i > 'Z') {
+                            warning(
+                    "A constructor name should start with an uppercase letter.",
+                                token);
+                        }
+                    }
+                }
+            } else {
+                if (c.id !== '.' && c.id !== '[' && c.id !== '(') {
+                    warning("Bad constructor.", token);
+                }
+            }
+        } else {
+            warning("Weird construction. Delete 'new'.", this);
+        }
+        adjacent(token, nexttoken);
+        if (nexttoken.id === '(') {
+            advance('(');
+            nospace();
+            if (nexttoken.id !== ')') {
+                for (;;) {
+                    parse(10);
+                    if (nexttoken.id !== ',') {
+                        break;
+                    }
+                    advance(',');
+                }
+            }
+            advance(')');
+            nospace(prevtoken, token);
+        } else {
+            warning("Missing '()' invoking a constructor.");
+        }
+        return syntax['function'];
+    });
+    syntax['new'].exps = true;
+
+    infix('.', function (left) {
+        adjacent(prevtoken, token);
+        var m = identifier();
+        if (typeof m === 'string') {
+            countMember(m);
+        }
+        if (!option.evil && left && left.value === 'document' &&
+                (m === 'write' || m === 'writeln')) {
+            warning("document.write can be a form of eval.", left);
+        }
+        this.left = left;
+        this.right = m;
+        return this;
+    }, 160);
+
+    infix('(', function (left) {
+        adjacent(prevtoken, token);
+        nospace();
+        var n = 0;
+        var p = [];
+        if (left && left.type === '(identifier)') {
+            if (left.value.match(/^[A-Z](.*[a-z].*)?$/)) {
+                if (left.value !== 'Number' && left.value !== 'String' &&
+                        left.value !== 'Boolean' && left.value !== 'Date') {
+                    warning("Missing 'new' prefix when invoking a constructor.",
+                            left);
+                }
+            }
+        }
+        if (nexttoken.id !== ')') {
+            for (;;) {
+                p[p.length] = parse(10);
+                n += 1;
+                if (nexttoken.id !== ',') {
+                    break;
+                }
+                advance(',');
+                nonadjacent(token, nexttoken);
+            }
+        }
+        advance(')');
+        nospace(prevtoken, token);
+        if (typeof left === 'object') {
+            if (left.value === 'parseInt' && n === 1) {
+                warning("Missing radix parameter.", left);
+            }
+            if (!option.evil) {
+                if (left.value === 'eval' || left.value === 'Function') {
+                    warning("eval is evil.", left);
+                } else if (p[0] && p[0].id === '(string)' &&
+                       (left.value === 'setTimeout' ||
+                        left.value === 'setInterval')) {
+                    warning(
+    "Implied eval is evil. Pass a function instead of a string.", left);
+                }
+            }
+            if (!left.identifier && left.id !== '.' &&
+                    left.id !== '[' && left.id !== '(') {
+                warning("Bad invocation.", left);
+            }
+
+        }
+        return syntax['function'];
+    }, 155).exps = true;
+
+    prefix('(', function () {
+        nospace();
+        var v = parse(0);
+        advance(')', this);
+        nospace(prevtoken, token);
+        return v;
+    });
+
+    infix('[', function (left) {
+        if (option.adsafe) {
+            warning('ADsafe subscripting.');
+        }
+        nospace();
+        var e = parse(0), s;
+        if (e && e.type === '(string)') {
+            countMember(e.value);
+            if (ix.test(e.value)) {
+                s = syntax[e.value];
+                if (!s || !s.reserved) {
+                    warning("['{a}'] is better written in dot notation.",
+                            e, e.value);
+                }
+            }
+        }
+        advance(']', this);
+        nospace(prevtoken, token);
+        this.left = left;
+        this.right = e;
+        return this;
+    }, 160);
+
+    prefix('[', function () {
+        if (nexttoken.id === ']') {
+            advance(']');
+            return;
+        }
+        var b = token.line !== nexttoken.line;
+        if (b) {
+            indent += 4;
+            if (nexttoken.from === indent + 4) {
+                indent += 4;
+            }
+        }
+        for (;;) {
+            if (b && token.line !== nexttoken.line) {
+                indentation();
+            }
+            parse(10);
+            if (nexttoken.id === ',') {
+                adjacent(token, nexttoken);
+                advance(',');
+                if (nexttoken.id === ',' || nexttoken.id === ']') {
+                    warning("Extra comma.", token);
+                }
+                nonadjacent(token, nexttoken);
+            } else {
+                if (b) {
+                    indent -= 4;
+                    indentation();
+                }
+                advance(']', this);
+                return;
+            }
+        }
+    }, 160);
+
+    (function (x) {
+        x.nud = function () {
+            var i, s;
+            if (nexttoken.id === '}') {
+                advance('}');
+                return;
+            }
+            var b = token.line !== nexttoken.line;
+            if (b) {
+                indent += 4;
+                if (nexttoken.from === indent + 4) {
+                    indent += 4;
+                }
+            }
+            for (;;) {
+                if (b) {
+                    indentation();
+                }
+                i = optionalidentifier(true);
+                if (!i) {
+                    if (nexttoken.id === '(string)') {
+                        i = nexttoken.value;
+                        if (ix.test(i)) {
+                            s = syntax[i];
+                        }
+                        advance();
+                    } else if (nexttoken.id === '(number)') {
+                        i = nexttoken.value.toString();
+                        advance();
+                    } else {
+                        error("Expected '{a}' and instead saw '{b}'.",
+                                nexttoken, '}', nexttoken.value);
+                    }
+                }
+                countMember(i);
+                advance(':');
+                nonadjacent(token, nexttoken);
+                parse(10);
+                if (nexttoken.id === ',') {
+                    adjacent(token, nexttoken);
+                    advance(',');
+                    if (nexttoken.id === ',' || nexttoken.id === '}') {
+                        warning("Extra comma.", token);
+                    }
+                    nonadjacent(token, nexttoken);
+                } else {
+                    if (b) {
+                        indent -= 4;
+                        indentation();
+                    }
+                    advance('}', this);
+                    return;
+                }
+            }
+        };
+        x.fud = function () {
+            error("Expected to see a statement and instead saw a block.", token);
+        };
+    })(delim('{'));
+
+
+    function varstatement() {
+
+// JavaScript does not have block scope. It only has function scope. So,
+// declaring a variable in a block can have unexpected consequences.
+
+        for (;;) {
+            nonadjacent(token, nexttoken);
+            addlabel(identifier(), 'unused');
+            if (nexttoken.id === '=') {
+                nonadjacent(token, nexttoken);
+                advance('=');
+                nonadjacent(token, nexttoken);
+                if (peek(0).id === '=') {
+                    error("Variable {a} was not declared correctly.",
+                            nexttoken, nexttoken.value);
+                }
+                parse(20);
+            }
+            if (nexttoken.id !== ',') {
+                return;
+            }
+            adjacent(token, nexttoken);
+            advance(',');
+            nonadjacent(token, nexttoken);
+        }
+    }
+
+
+    stmt('var', varstatement);
+
+    stmt('new', function () {
+        error("'new' should not be used as a statement.");
+    });
+
+
+    function functionparams() {
+        var i, t = nexttoken, p = [];
+        advance('(');
+        nospace();
+        if (nexttoken.id === ')') {
+            advance(')');
+            nospace(prevtoken, token);
+            return;
+        }
+        for (;;) {
+            i = identifier();
+            p.push(i);
+            addlabel(i, 'parameter');
+            if (nexttoken.id === ',') {
+                advance(',');
+                nonadjacent(token, nexttoken);
+            } else {
+                advance(')', t);
+                nospace(prevtoken, token);
+                return p.join(', ');
+            }
+        }
+    }
+
+    function doFunction(i) {
+        var s = scope;
+        scope = object(s);
+        funct = {
+            '(name)'    : i || '"' + anonname + '"',
+            '(line)'    : nexttoken.line + 1,
+            '(context)' : funct,
+            '(scope)'   : scope
+        };
+        functions.push(funct);
+        if (i) {
+            addlabel(i, 'function');
+        }
+        funct['(params)'] = functionparams();
+
+        block(false);
+        scope = s;
+        funct = funct['(context)'];
+    }
+
+
+    blockstmt('function', function () {
+        if (inblock) {
+            warning(
+"Function statements cannot be placed in blocks. Use a function expression or move the statement to the top of the outer function.", token);
+
+        }
+        var i = identifier();
+        adjacent(token, nexttoken);
+        addlabel(i, 'unused');
+        doFunction(i);
+        if (nexttoken.id === '(' && nexttoken.line === token.line) {
+            error(
+"Function statements are not invocable. Wrap the function expression in parens.");
+        }
+    });
+
+    prefix('function', function () {
+        var i = optionalidentifier();
+        if (i) {
+            adjacent(token, nexttoken);
+        } else {
+            nonadjacent(token, nexttoken);
+        }
+        doFunction(i);
+    });
+
+    blockstmt('if', function () {
+        var t = nexttoken;
+        advance('(');
+        nonadjacent(this, t);
+        nospace();
+        parse(20);
+        if (nexttoken.id === '=') {
+            warning("Assignment in control part.");
+            advance('=');
+            parse(20);
+        }
+        advance(')', t);
+        nospace(prevtoken, token);
+        block(true);
+        if (nexttoken.id === 'else') {
+            nonadjacent(token, nexttoken);
+            advance('else');
+            if (nexttoken.id === 'if' || nexttoken.id === 'switch') {
+                statement(true);
+            } else {
+                block(true);
+            }
+        }
+        return this;
+    });
+
+    blockstmt('try', function () {
+        var b, e, s;
+        block(false);
+        if (nexttoken.id === 'catch') {
+            advance('catch');
+            nonadjacent(token, nexttoken);
+            advance('(');
+            s = scope;
+            scope = object(s);
+            e = nexttoken.value;
+            if (nexttoken.type !== '(identifier)') {
+                warning("Expected an identifier and instead saw '{a}'.",
+                    nexttoken, e);
+            } else {
+                addlabel(e, 'unused');
+            }
+            advance();
+            advance(')');
+            block(false);
+            b = true;
+            scope = s;
+        }
+        if (nexttoken.id === 'finally') {
+            advance('finally');
+            block(false);
+            return;
+        } else if (!b) {
+            error("Expected '{a}' and instead saw '{b}'.",
+                    nexttoken, 'catch', nexttoken.value);
+        }
+    });
+
+    blockstmt('while', function () {
+        var t = nexttoken;
+        advance('(');
+        nonadjacent(this, t);
+        nospace();
+        parse(20);
+        if (nexttoken.id === '=') {
+            warning("Assignment in control part.");
+            advance('=');
+            parse(20);
+        }
+        advance(')', t);
+        nospace(prevtoken, token);
+        block(true);
+    }).labelled = true;
+
+    reserve('with');
+
+    blockstmt('switch', function () {
+        var t = nexttoken;
+        var g = false;
+        advance('(');
+        nonadjacent(this, t);
+        nospace();
+        this.condition = parse(20);
+        advance(')', t);
+        nospace(prevtoken, token);
+        nonadjacent(token, nexttoken);
+        t = nexttoken;
+        advance('{');
+        nonadjacent(token, nexttoken);
+        indent += 4;
+        this.cases = [];
+        for (;;) {
+            switch (nexttoken.id) {
+            case 'case':
+                switch (funct['(verb)']) {
+                case 'break':
+                case 'case':
+                case 'continue':
+                case 'return':
+                case 'switch':
+                case 'throw':
+                    break;
+                default:
+                    warning(
+                        "Expected a 'break' statement before 'case'.",
+                        token);
+                }
+                indentation(-4);
+                advance('case');
+                this.cases.push(parse(20));
+                g = true;
+                advance(':');
+                funct['(verb)'] = 'case';
+                break;
+            case 'default':
+                switch (funct['(verb)']) {
+                case 'break':
+                case 'continue':
+                case 'return':
+                case 'throw':
+                    break;
+                default:
+                    warning(
+                        "Expected a 'break' statement before 'default'.",
+                        token);
+                }
+                indentation(-4);
+                advance('default');
+                g = true;
+                advance(':');
+                break;
+            case '}':
+                indent -= 4;
+                indentation();
+                advance('}', t);
+                if (this.cases.length === 1 || this.condition.id === 'true' ||
+                        this.condition.id === 'false') {
+                    warning("This 'switch' should be an 'if'.", this);
+                }
+                return;
+            case '(end)':
+                error("Missing '{a}'.", nexttoken, '}');
+                return;
+            default:
+                if (g) {
+                    switch (token.id) {
+                    case ',':
+                        error("Each value should have its own case label.");
+                        return;
+                    case ':':
+                        statements();
+                        break;
+                    default:
+                        error("Missing ':' on a case clause.", token);
+                    }
+                } else {
+                    error("Expected '{a}' and instead saw '{b}'.",
+                        nexttoken, 'case', nexttoken.value);
+                }
+            }
+        }
+    }).labelled = true;
+
+    stmt('debugger', function () {
+        if (!option.debug) {
+            warning("All 'debugger' statements should be removed.");
+        }
+    });
+
+    stmt('do', function () {
+        block(true);
+        advance('while');
+        var t = nexttoken;
+        nonadjacent(token, t);
+        advance('(');
+        nospace();
+        parse(20);
+        advance(')', t);
+        nospace(prevtoken, token);
+    }).labelled = true;
+
+    blockstmt('for', function () {
+        var s, t = nexttoken;
+        advance('(');
+        nonadjacent(this, t);
+        nospace();
+        if (peek(nexttoken.id === 'var' ? 1 : 0).id === 'in') {
+            if (nexttoken.id === 'var') {
+                advance('var');
+                addlabel(identifier(), 'var');
+            } else {
+                advance();
+            }
+            advance('in');
+            parse(20);
+            advance(')', t);
+            if (nexttoken.id === 'if') {
+                nolinebreak(token);
+                statement(true);
+            } else {
+                s = block(true);
+                if (!option.forin && (s.length > 1 || typeof s[0] !== 'object' ||
+                        s[0].value !== 'if')) {
+                    warning("The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.", this);
+                }
+            }
+            return this;
+        } else {
+            if (nexttoken.id !== ';') {
+                if (nexttoken.id === 'var') {
+                    advance('var');
+                    varstatement();
+                } else {
+                    for (;;) {
+                        parse(0);
+                        if (nexttoken.id !== ',') {
+                            break;
+                        }
+                        advance(',');
+                    }
+                }
+            }
+            advance(';');
+            if (nexttoken.id !== ';') {
+                parse(20);
+            }
+            advance(';');
+            if (nexttoken.id === ';') {
+                error("Expected '{a}' and instead saw '{b}'.",
+                        nexttoken, ')', ';');
+            }
+            if (nexttoken.id !== ')') {
+                for (;;) {
+                    parse(0);
+                    if (nexttoken.id !== ',') {
+                        break;
+                    }
+                    advance(',');
+                }
+            }
+            advance(')', t);
+            nospace(prevtoken, token);
+            block(true);
+        }
+    }).labelled = true;
+
+
+    stmt('break', function () {
+        var v = nexttoken.value;
+        nolinebreak(this);
+        if (nexttoken.id !== ';') {
+            if (funct[v] !== 'label') {
+                warning("'{a}' is not a statement label.", nexttoken, v);
+            } else if (scope[v] !== funct) {
+                warning("'{a}' is out of scope.", nexttoken, v);
+            }
+            advance();
+        }
+        reachable('break');
+    });
+
+
+    stmt('continue', function () {
+        var v = nexttoken.value;
+        nolinebreak(this);
+        if (nexttoken.id !== ';') {
+            if (funct[v] !== 'label') {
+                warning("'{a}' is not a statement label.", nexttoken, v);
+            } else if (scope[v] !== funct) {
+                warning("'{a}' is out of scope.", nexttoken, v);
+            }
+            advance();
+        }
+        reachable('continue');
+    });
+
+
+    stmt('return', function () {
+        nolinebreak(this);
+        if (nexttoken.id !== ';' && !nexttoken.reach) {
+            nonadjacent(token, nexttoken);
+            parse(20);
+        }
+        reachable('return');
+    });
+
+
+    stmt('throw', function () {
+        nolinebreak(this);
+        nonadjacent(token, nexttoken);
+        parse(20);
+        reachable('throw');
+    });
+
+
+//  Superfluous reserved words
+
+    reserve('abstract');
+    reserve('boolean');
+    reserve('byte');
+    reserve('char');
+    reserve('class');
+    reserve('const');
+    reserve('double');
+    reserve('enum');
+    reserve('export');
+    reserve('extends');
+    reserve('final');
+    reserve('float');
+    reserve('goto');
+    reserve('implements');
+    reserve('import');
+    reserve('int');
+    reserve('interface');
+    reserve('long');
+    reserve('native');
+    reserve('package');
+    reserve('private');
+    reserve('protected');
+    reserve('public');
+    reserve('short');
+    reserve('static');
+    reserve('super');
+    reserve('synchronized');
+    reserve('throws');
+    reserve('transient');
+    reserve('void');
+    reserve('volatile');
+
+
+    function jsonValue() {
+
+        function jsonObject() {
+            var t = nexttoken;
+            advance('{');
+            if (nexttoken.id !== '}') {
+                for (;;) {
+                    if (nexttoken.id === '(end)') {
+                        error("Missing '}' to match '{' from line {a}.",
+                                nexttoken, t.line + 1);
+                    } else if (nexttoken.id === '}') {
+                        warning("Unexpected comma.", token);
+                        break;
+                    } else if (nexttoken.id === ',') {
+                        error("Unexpected comma.", nexttoken);
+                    } else if (nexttoken.id !== '(string)') {
+                        warning("Expected a string and instead saw {a}.",
+                                nexttoken, nexttoken.value);
+                    }
+                    advance();
+                    advance(':');
+                    jsonValue();
+                    if (nexttoken.id !== ',') {
+                        break;
+                    }
+                    advance(',');
+                }
+            }
+            advance('}');
+        }
+
+        function jsonArray() {
+            var t = nexttoken;
+            advance('[');
+            if (nexttoken.id !== ']') {
+                for (;;) {
+                    if (nexttoken.id === '(end)') {
+                        error("Missing ']' to match '[' from line {a}.",
+                                nexttoken, t.line + 1);
+                    } else if (nexttoken.id === ']') {
+                        warning("Unexpected comma.", token);
+                        break;
+                    } else if (nexttoken.id === ',') {
+                        error("Unexpected comma.", nexttoken);
+                    }
+                    jsonValue();
+                    if (nexttoken.id !== ',') {
+                        break;
+                    }
+                    advance(',');
+                }
+            }
+            advance(']');
+        }
+
+        switch (nexttoken.id) {
+        case '{':
+            jsonObject();
+            break;
+        case '[':
+            jsonArray();
+            break;
+        case 'true':
+        case 'false':
+        case 'null':
+        case '(number)':
+        case '(string)':
+            advance();
+            break;
+        case '-':
+            advance('-');
+            if (token.character !== nexttoken.from) {
+                warning("Unexpected space after '-'.", token);
+            }
+            adjacent(token, nexttoken);
+            advance('(number)');
+            break;
+        default:
+            error("Expected a JSON value.", nexttoken);
+        }
+    }
+
+
+// The actual JSLINT function itself.
+
+    var itself = function (s, o) {
+        if (o) {
+            if (o.adsafe) {
+                o.browser = false;
+                o.debug   = false;
+                o.eqeqeq  = true;
+                o.evil    = false;
+                o.forin   = false;
+                o.on      = false;
+                o.rhino   = false;
+                o.undef   = true;
+                o.widget  = false;
+            }
+            option = o;
+        } else {
+            option = {};
+        }
+        globals = option.adsafe ? {} : object(standard);
+        JSLINT.errors = [];
+        global = object(globals);
+        scope = global;
+        funct = {'(global)': true, '(name)': '(global)', '(scope)': scope};
+        functions = [];
+        src = false;
+        xmode = false;
+        xtype = '';
+        stack = null;
+        member = {};
+        membersOnly = null;
+        implied = {};
+        inblock = false;
+        lookahead = [];
+        indent = 0;
+        jsonmode = false;
+        warnings = 0;
+        lex.init(s);
+        prereg = true;
+
+        prevtoken = token = nexttoken = syntax['(begin)'];
+        populateGlobals();
+
+        try {
+            advance();
+            if (nexttoken.value.charAt(0) === '<') {
+                xml();
+            } else if (nexttoken.id === '{' || nexttoken.id === '[') {
+                option.laxbreak = true;
+                jsonmode = true;
+                jsonValue();
+            } else {
+                statements();
+            }
+            advance('(end)');
+        } catch (e) {
+            if (e) {
+                JSLINT.errors.push({
+                    reason    : e.message,
+                    line      : e.line || nexttoken.line,
+                    character : e.character || nexttoken.from
+                }, null);
+            }
+        }
+        return JSLINT.errors.length === 0;
+    };
+
+    function to_array(o) {
+        var a = [], k;
+        for (k in o) if (o.hasOwnProperty(k)) {
+            a.push(k);
+        }
+        return a;
+    }
+
+// Report generator.
+
+    itself.report = function (option) {
+        var a = [], c, e, f, i, k, l, m = '', n, o = [], s, v, cl, va, un, ou, gl, la;
+
+        function detail(h, s) {
+            if (s.length) {
+                o.push('<div><i>' + h + '</i> ' +
+                        s.sort().join(', ') + '</div>');
+            }
+        }
+
+        s = to_array(implied);
+
+        k = JSLINT.errors.length;
+        if (k || s.length > 0) {
+            o.push('<div id=errors><i>Error:</i>');
+            if (s.length > 0) {
+                s.sort();
+                for (i = 0; i < s.length; i += 1) {
+                    s[i] = '<code>' + s[i] + '</code>&nbsp;<i>' +
+                        implied[s[i]].join(' ') +
+                        '</i>';
+                }
+                o.push('<p><i>Implied global:</i> ' + s.join(', ') + '</p>');
+                c = true;
+            }
+            for (i = 0; i < k; i += 1) {
+                c = JSLINT.errors[i];
+                if (c) {
+                    e = c.evidence || '';
+                    o.push('<p>Problem' + (isFinite(c.line) ? ' at line ' + (c.line + 1) +
+                            ' character ' + (c.character + 1) : '') +
+                            ': ' + c.reason.entityify() +
+                            '</p><p class=evidence>' +
+                            (e && (e.length > 80 ? e.slice(0, 77) + '...' :
+                            e).entityify()) + '</p>');
+                }
+            }
+            o.push('</div>');
+            if (!c) {
+                return o.join('');
+            }
+        }
+
+        if (!option) {
+
+            o.push('<div id=functions>');
+
+            s = to_array(scope);
+            if (s.length === 0) {
+                o.push('<div><i>No new global variables introduced.</i></div>');
+            } else {
+                o.push('<div><i>Global</i> ' + s.sort().join(', ') + '</div>');
+            }
+
+            for (i = 0; i < functions.length; i += 1) {
+                f = functions[i];
+                cl = [];
+                va = [];
+                un = [];
+                ou = [];
+                gl = [];
+                la = [];
+                for (k in f) if (f.hasOwnProperty(k)) {
+                    v = f[k];
+                    switch (v) {
+                    case 'closure':
+                        cl.push(k);
+                        break;
+                    case 'var':
+                        va.push(k);
+                        break;
+                    case 'unused':
+                        un.push(k);
+                        break;
+                    case 'label':
+                        la.push(k);
+                        break;
+                    case 'outer':
+                        ou.push(k);
+                        break;
+                    case true:
+                        if (k !== '(context)') {
+                            gl.push(k);
+                        }
+                        break;
+                    }
+                }
+                o.push('<br><div class=function><i>' + f['(line)'] + '</i> ' +
+                        (f['(name)'] || '') + '(' +
+                        (f['(params)'] || '') + ')</div>');
+                detail('Closure', cl);
+                detail('Variable', va);
+                detail('Unused', un);
+                detail('Label', la);
+                detail('Outer', ou);
+                detail('Global', gl);
+            }
+            a = [];
+            for (k in member) {
+                if (typeof member[k] === 'number') {
+                    a.push(k);
+                }
+            }
+            if (a.length) {
+                a = a.sort();
+                m = '<br><pre>/*members ';
+                l = 10;
+                for (i = 0; i < a.length; i += 1) {
+                    k = a[i];
+                    n = k.name();
+                    if (l + n.length > 72) {
+                        o.push(m + '<br>');
+                        m = '    ';
+                        l = 1;
+                    }
+                    l += n.length + 2;
+                    if (member[k] === 1) {
+                        n = '<i>' + n + '</i>';
+                    }
+                    if (i < a.length - 1) {
+                        n += ', ';
+                    }
+                    m += n;
+                }
+                o.push(m + '<br>*/</pre>');
+            }
+            o.push('</div>');
+        }
+        return o.join('');
+    };
+
+    return itself;
+
+}();
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/helpers/helpers.js b/browserid/static/dialog/jquery/view/helpers/helpers.js
new file mode 100644
index 0000000000000000000000000000000000000000..f12e01f1413d9ac5df996278ed8589ec4da2ab5b
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/helpers/helpers.js
@@ -0,0 +1,348 @@
+steal.plugins('jquery/view/ejs').then(function($){
+
+/**
+ * @add jQuery.EJS.Helpers.prototype
+ */
+$.extend($.EJS.Helpers.prototype, {
+	/**
+	 * Converts response to text.
+	 */
+	text: function( input, null_text ) {
+		if ( input == null || input === undefined ) return null_text || '';
+		if ( input instanceof Date ) return input.toDateString();
+		if ( input.toString ) return input.toString().replace(/\n/g, '<br />').replace(/''/g, "'");
+		return '';
+	},
+	
+	// treyk 06/11/2009 - Pulled from old MVC.Date plugin for now.  Will look for a suitable jQuery Date plugin
+	 month_names: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
+   
+    /**
+     * Creates a check box tag
+     * @plugin view/helpers
+     * @param {Object} name
+     * @param {Object} value
+     * @param {Object} options
+     * @param {Object} checked
+     */
+	check_box_tag: function( name, value, options, checked ) {
+        options = options || {};
+        if(checked) options.checked = "checked";
+        return this.input_field_tag(name, value, 'checkbox', options);
+    },
+    /**
+     * @plugin view/helpers
+     * @param {Object} name
+     * @param {Object} value
+     * @param {Object} html_options
+     */
+    date_tag: function( name, value , html_options ) {
+	    if(! (value instanceof Date)) value = new Date();
+       
+		var years = [], months = [], days =[];
+		var year = value.getFullYear(), month = value.getMonth(), day = value.getDate();
+		for(var y = year - 15; y < year+15 ; y++) years.push({value: y, text: y});
+		for(var m = 0; m < 12; m++) months.push({value: (m), text: $View.Helpers.month_names[m]});
+		for(var d = 0; d < 31; d++) days.push({value: (d+1), text: (d+1)});
+		
+		var year_select = this.select_tag(name+'[year]', year, years, {id: name+'[year]'} );
+		var month_select = this.select_tag(name+'[month]', month, months, {id: name+'[month]'});
+		var day_select = this.select_tag(name+'[day]', day, days, {id: name+'[day]'});
+		
+	    return year_select+month_select+day_select;
+	},
+    /**
+     * @plugin view/helpers
+     * @param {Object} name
+     * @param {Object} value
+     * @param {Object} html_options
+     * @param {Object} interval - specified in minutes
+     */
+	time_tag: function( name, value, html_options, interval ) {	
+		var times = [];
+		
+		if (interval == null || interval == 0)
+			interval = 60;
+
+		for(var h = 0; h < 24 ; h++)
+			for(var m = 0; m < 60; m+=interval)
+			{
+				var time = (h < 10 ? '0' : '') + h + ':' + (m < 10 ? '0' : '') + m;
+				times.push({ text: time, value: time });
+			}
+
+		return this.select_tag(name, value, times, html_options );
+	},
+    /**
+     * @plugin view/helpers
+     * @param {Object} name
+     * @param {Object} value
+     * @param {Object} html_options
+     */
+	file_tag: function( name, value, html_options ) {
+	    return this.input_field_tag(name+'[file]', value , 'file', html_options);
+	},
+    /**
+     * @plugin view/helpers
+     * @param {Object} url_for_options
+     * @param {Object} html_options
+     */
+	form_tag: function( url_for_options, html_options ) {
+	    html_options = html_options  || {};
+		if(html_options.multipart == true) {
+	        html_options.method = 'post';
+	        html_options.enctype = 'multipart/form-data';
+	    }
+		html_options.action = url_for_options;
+	    return this.start_tag_for('form', html_options);
+	},
+    /**
+     * @plugin view/helpers
+     */
+	form_tag_end: function() { return this.tag_end('form'); },
+	/**
+	 * @plugin view/helpers
+	 * @param {Object} name
+	 * @param {Object} value
+	 * @param {Object} html_options
+	 */
+    hidden_field_tag: function( name, value, html_options ) { 
+	    return this.input_field_tag(name, value, 'hidden', html_options); 
+	},
+    /**
+     * @plugin view/helpers
+     * @param {Object} name
+     * @param {Object} value
+     * @param {Object} inputType
+     * @param {Object} html_options
+     */
+	input_field_tag: function( name, value , inputType, html_options ) {
+	    html_options = html_options || {};
+	    html_options.id  = html_options.id  || name;
+	    html_options.value = value || '';
+	    html_options.type = inputType || 'text';
+	    html_options.name = name;
+	    return this.single_tag_for('input', html_options);
+	},
+    /**
+	 * @plugin view/helpers
+	 * @param {Object} text
+	 * @param {Object} html_options
+	 */
+	label_tag: function( text, html_options ) {
+		html_options = html_options || {};
+		return this.start_tag_for('label', html_options) + text + this.tag_end('label');
+	},
+	/**
+     * @plugin view/helpers
+     * @param {Object} name
+     * @param {Object} url
+     * @param {Object} html_options
+     */
+	link_to: function( name, url, html_options ) {
+	    if(!name) var name = 'null';
+	    if(!html_options) var html_options = {};
+		this.set_confirm(html_options);
+		html_options.href=url;
+		return this.start_tag_for('a', html_options)+name+ this.tag_end('a');
+	},
+    /**
+     * @plugin view/helpers
+     * @param {Object} condition
+     * @param {Object} name
+     * @param {Object} url
+     * @param {Object} html_options
+     */
+    link_to_if: function( condition, name, url, html_options ) {
+		return this.link_to_unless((!condition), name, url, html_options);
+	},
+    /**
+     * @plugin view/helpers
+     * @param {Object} condition
+     * @param {Object} name
+     * @param {Object} url
+     * @param {Object} html_options
+     */
+    link_to_unless: function( condition, name, url, html_options ) {
+        if(condition) return name;
+        return this.link_to(name, url, html_options);
+    },
+    /**
+     * @plugin view/helpers
+     * @param {Object} html_options
+     */
+	set_confirm: function( html_options ) {
+		if(html_options.confirm){
+			html_options.onclick = html_options.onclick || '';
+			html_options.onclick = html_options.onclick+
+			"; var ret_confirm = confirm(\""+html_options.confirm+"\"); if(!ret_confirm){ return false;} ";
+			html_options.confirm = null;
+		}
+	},
+    /**
+     * @plugin view/helpers
+     * @param {Object} name
+     * @param {Object} options
+     * @param {Object} html_options
+     * @param {Object} post
+     */
+	submit_link_to: function( name, options, html_options, post ) {
+		if(!name) var name = 'null';
+	    if(!html_options) html_options = {};
+		html_options.type = 'submit';
+	    html_options.value = name;
+		this.set_confirm(html_options);
+		html_options.onclick=html_options.onclick+';window.location="'+options+'"; return false;';
+		return this.single_tag_for('input', html_options);
+	},
+    /**
+     * @plugin view/helpers
+     * @param {Object} name
+     * @param {Object} value
+     * @param {Object} html_options
+     */
+	password_field_tag: function( name, value, html_options ) { return this.input_field_tag(name, value, 'password', html_options); },
+	/**
+	 * @plugin view/helpers
+	 * @param {Object} name
+	 * @param {Object} value
+	 * @param {Object} choices
+	 * @param {Object} html_options
+	 */
+    select_tag: function( name, value, choices, html_options ) {     
+	    html_options = html_options || {};
+	    html_options.id  = html_options.id  || name;
+	    //html_options.value = value;
+		html_options.name = name;
+	    var txt = '';
+	    txt += this.start_tag_for('select', html_options);
+	    for(var i = 0; i < choices.length; i++)
+	    {
+	        var choice = choices[i];
+	        if(typeof choice == 'string') choice = {value: choice};
+			if(!choice.text) choice.text = choice.value;
+			if(!choice.value) choice.text = choice.text;
+			
+			var optionOptions = {value: choice.value};
+	        if(choice.value == value)
+	            optionOptions.selected ='selected';
+	        txt += this.start_tag_for('option', optionOptions )+choice.text+this.tag_end('option');
+	    }
+	    txt += this.tag_end('select');
+	    return txt;
+	},
+    /**
+     * @plugin view/helpers
+     * @param {Object} tag
+     * @param {Object} html_options
+     */
+	single_tag_for: function( tag, html_options ) { return this.tag(tag, html_options, '/>');},
+	/**
+	 * @plugin view/helpers
+	 * @param {Object} tag
+	 * @param {Object} html_options
+	 */
+    start_tag_for: function( tag, html_options ) { return this.tag(tag, html_options); },
+	/**
+	 * @plugin view/helpers
+	 * @param {Object} name
+	 * @param {Object} html_options
+	 */
+    submit_tag: function( name, html_options ) {  
+	    html_options = html_options || {};
+	    html_options.type = html_options.type  || 'submit';
+	    html_options.value = name || 'Submit';
+	    return this.single_tag_for('input', html_options);
+	},
+    /**
+     * @plugin view/helpers
+     * @param {Object} tag
+     * @param {Object} html_options
+     * @param {Object} end
+     */
+	tag: function( tag, html_options, end ) {
+	    end = end || '>';
+	    var txt = ' ';
+	    for(var attr in html_options) { 
+	       if(html_options.hasOwnProperty(attr)){
+			   value = html_options[attr] != null ? html_options[attr].toString() : '';
+
+		       if(attr == "Class" || attr == "klass") attr = "class";
+		       if( value.indexOf("'") != -1 )
+		            txt += attr+'=\"'+value+'\" ' ;
+		       else
+		            txt += attr+"='"+value+"' " ;
+		   }
+	    }
+	    return '<'+tag+txt+end;
+	},
+    /**
+     * @plugin view/helpers
+     * @param {Object} tag
+     */
+	tag_end: function( tag ) { return '</'+tag+'>'; },
+	/**
+	 * @plugin view/helpers
+	 * @param {Object} name
+	 * @param {Object} value
+	 * @param {Object} html_options
+	 */
+    text_area_tag: function( name, value, html_options ) { 
+	    html_options = html_options || {};
+	    html_options.id  = html_options.id  || name;
+	    html_options.name  = html_options.name  || name;
+		value = value || '';
+	    if(html_options.size) {
+	        html_options.cols = html_options.size.split('x')[0];
+	        html_options.rows = html_options.size.split('x')[1];
+	        delete html_options.size;
+	    }
+	    html_options.cols = html_options.cols  || 50;
+	    html_options.rows = html_options.rows  || 4;
+	    return  this.start_tag_for('textarea', html_options)+value+this.tag_end('textarea');
+	},
+	/**
+	 * @plugin view/helpers
+	 * @param {Object} name
+	 * @param {Object} value
+	 * @param {Object} html_options
+	 */
+    text_field_tag: function( name, value, html_options ) { return this.input_field_tag(name, value, 'text', html_options); },
+	/**
+	 * @plugin view/helpers
+	 * @param {Object} image_location
+	 * @param {Object} options
+	 */
+    img_tag: function( image_location, options ) {
+		options = options || {};
+		options.src = steal.root.join("resources/images/"+image_location);
+		return this.single_tag_for('img', options);
+	}
+	
+});
+
+$.EJS.Helpers.prototype.text_tag = $.EJS.Helpers.prototype.text_area_tag;
+
+// Private variables (in the (function($){})(jQuery) scope)   
+var data = {};
+var name = 0;
+
+$.EJS.Helpers.link_data = function(store){
+	var functionName = name++;
+	data[functionName] = store;	
+	return "_data='"+functionName+"'";
+};
+$.EJS.Helpers.get_data = function(el){
+	if(!el) return null;
+	var dataAt = el.getAttribute('_data');
+	if(!dataAt) return null;
+	return data[parseInt(dataAt)];
+};
+$.EJS.Helpers.prototype.link_data = function(store){
+	return $.EJS.Helpers.link_data(store)
+};
+$.EJS.Helpers.prototype.get_data = function(el){
+	return $.EJS.Helpers.get_data(el)
+};
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/jaml/jaml.js b/browserid/static/dialog/jquery/view/jaml/jaml.js
new file mode 100644
index 0000000000000000000000000000000000000000..91748ecf98f8e6afd79bc383db3dc60123783d58
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/jaml/jaml.js
@@ -0,0 +1,372 @@
+steal.plugins("jquery/view").then(function(){
+	
+
+
+/**
+ * @class Jaml
+ * @plugin jquery/view/jaml
+ * @parent jQuery.View
+ * @author Ed Spencer (http://edspencer.net)
+ * Jaml is a simple JavaScript library which makes 
+ * HTML generation easy and pleasurable.
+ * 
+ * Instead of magic tags, Jaml is pure JS.  It looks like:
+ * 
+ * @codestart
+ * function(data) {
+ *   h3(data.message);
+ * }
+ * @codeend
+ * 
+ * Jaml is integrated into jQuery.View so you can use it like:
+ * 
+ * @codestart
+ * $("#foo").html('//app/views/template.jaml',{});
+ * @codeend
+ * 
+ * ## Use
+ * 
+ * For more info check out:
+ * 
+ *  - [http://edspencer.net/2009/11/jaml-beautiful-html-generation-for-javascript.html introduction]
+ *  - [http://edspencer.github.com/jaml examples]
+ * 
+ */
+Jaml = function() {
+  return {
+    templates: {},
+    helpers  : {},
+    
+    /**
+     * Registers a template by name
+     * @param {String} name The name of the template
+     * @param {Function} template The template function
+     */
+    register: function(name, template ) {
+      this.templates[name] = template;
+    },
+    
+    /**
+     * Renders the given template name with an optional data object
+     * @param {String} name The name of the template to render
+     * @param {Object} data Optional data object
+     */
+    render: function(name, data ) {
+      var template = this.templates[name],
+          renderer = new Jaml.Template(template);
+          
+      return renderer.render(data);
+    },
+    
+    /**
+     * Registers a helper function
+     * @param {String} name The name of the helper
+     * @param {Function} helperFn The helper function
+     */
+    registerHelper: function(name, helperFn ) {
+      this.helpers[name] = helperFn;
+    }
+  };
+}();
+
+
+
+/**
+ * @class
+ * @constructor
+ * @param {String} tagName The tag name this node represents (e.g. 'p', 'div', etc)
+ */
+Jaml.Node = function(tagName) {
+  /**
+   * @attribute tagName
+   * @type String
+   * This node's current tag
+   */
+  this.tagName = tagName;
+  
+  /**
+   * @attribute attributes
+   * @type Object
+   * Sets of attributes on this node (e.g. 'cls', 'id', etc)
+   */
+  this.attributes = {};
+  
+  /**
+   * @attribute children
+   * @type Array
+   * Array of rendered child nodes that will be steald as this node's innerHTML
+   */
+  this.children = [];
+};
+
+Jaml.Node.prototype = {
+  /**
+   * Adds attributes to this node
+   * @param {Object} attrs Object containing key: value pairs of node attributes
+   */
+  setAttributes: function(attrs ) {
+    for (var key in attrs) {
+      //convert cls to class
+      var mappedKey = key == 'cls' ? 'class' : key;
+      
+      this.attributes[mappedKey] = attrs[key];
+    }
+  },
+  
+  /**
+   * Adds a child string to this node. This can be called as often as needed to add children to a node
+   * @param {String} childText The text of the child node
+   */
+  addChild: function(childText ) {
+    this.children.push(childText);
+  },
+  
+  /**
+   * Renders this node with its attributes and children
+   * @param {Number} lpad Amount of whitespace to add to the left of the string (defaults to 0)
+   * @return {String} The rendered node
+   */
+  render: function(lpad ) {
+    lpad = lpad || 0;
+    
+    var node      = [],
+        attrs     = [],
+        textnode  = (this instanceof Jaml.TextNode),
+        multiline = this.multiLineTag();
+    
+    for (var key in this.attributes) {
+      attrs.push(key + '=' + this.attributes[key]);
+    }
+    
+    //add any left padding
+    if (!textnode) node.push(this.getPadding(lpad));
+    
+    //open the tag
+    node.push("<" + this.tagName);
+    
+    //add any tag attributes
+    for (var key in this.attributes) {
+      node.push(" " + key + "=\"" + this.attributes[key] + "\"");
+    }
+    
+    if (this.isSelfClosing()) {
+      node.push(" />\n");
+    } else {
+      node.push(">");
+      
+      if (multiline) node.push("\n");
+      
+      for (var i=0; i < this.children.length; i++) {
+        node.push(this.children[i].render(lpad + 2));
+      }
+      
+      if (multiline) node.push(this.getPadding(lpad));
+      node.push("</", this.tagName, ">\n");
+    }
+    
+    return node.join("");
+  },
+  
+  /**
+   * Returns true if this tag should be rendered with multiple newlines (e.g. if it contains child nodes)
+   * @return {Boolean} True to render this tag as multi-line
+   */
+  multiLineTag: function() {
+    var childLength = this.children.length,
+        multiLine   = childLength > 0;
+    
+    if (childLength == 1 && this.children[0] instanceof Jaml.TextNode) multiLine = false;
+    
+    return multiLine;
+  },
+  
+  /**
+   * Returns a string with the given number of whitespace characters, suitable for padding
+   * @param {Number} amount The number of whitespace characters to add
+   * @return {String} A padding string
+   */
+  getPadding: function(amount ) {
+    return new Array(amount + 1).join(" ");
+  },
+  
+  /**
+   * Returns true if this tag should close itself (e.g. no </tag> element)
+   * @return {Boolean} True if this tag should close itself
+   */
+  isSelfClosing: function() {
+    var selfClosing = false;
+    
+    for (var i = this.selfClosingTags.length - 1; i >= 0; i--){
+      if (this.tagName == this.selfClosingTags[i]) selfClosing = true;
+    }
+    
+    return selfClosing;
+  },
+  
+  /**
+   * @attribute selfClosingTags
+   * @type Array
+   * An array of all tags that should be self closing
+   */
+  selfClosingTags: ['img', 'meta', 'br', 'hr']
+};
+
+Jaml.TextNode = function(text) {
+  this.text = text;
+};
+
+Jaml.TextNode.prototype = {
+  render: function() {
+    return this.text;
+  }
+};
+
+/**
+ * Represents a single registered template. Templates consist of an arbitrary number
+ * of trees (e.g. there may be more than a single root node), and are not compiled.
+ * When a template is rendered its node structure is computed with any provided template
+ * data, culminating in one or more root nodes.  The root node(s) are then joined together
+ * and returned as a single output string.
+ * 
+ * The render process uses two dirty but necessary hacks.  First, the template function is
+ * decompiled into a string (but is not modified), so that it can be eval'ed within the scope
+ * of Jaml.Template.prototype. This allows the second hack, which is the use of the 'with' keyword.
+ * This allows us to keep the pretty DSL-like syntax, though is not as efficient as it could be.
+ */
+Jaml.Template = function(tpl) {
+  /**
+   * @attribute tpl
+   * @type Function
+   * The function this template was created from
+   */
+  this.tpl = tpl;
+  
+  this.nodes = [];
+};
+
+Jaml.Template.prototype = {
+  /**
+   * Renders this template given the supplied data
+   * @param {Object} data Optional data object
+   * @return {String} The rendered HTML string
+   */
+  render: function(data ) {
+    data = data || {};
+    
+    //the 'data' argument can come in two flavours - array or non-array. Normalise it
+    //here so that it always looks like an array.
+    if (data.constructor.toString().indexOf("Array") == -1) {
+      data = [data];
+    }
+    
+    with(this) {
+      for (var i=0; i < data.length; i++) {
+        eval("(" + this.tpl.toString() + ")(data[i])");
+      };
+    }
+    
+    var roots  = this.getRoots(),
+        output = "";
+    
+    for (var i=0; i < roots.length; i++) {
+      output += roots[i].render();
+    };
+    
+    return output;
+  },
+  
+  /**
+   * Returns all top-level (root) nodes in this template tree.
+   * Templates are tree structures, but there is no guarantee that there is a
+   * single root node (e.g. a single DOM element that all other elements nest within)
+   * @return {Array} The array of root nodes
+   */
+  getRoots: function() {
+    var roots = [];
+    
+    for (var i=0; i < this.nodes.length; i++) {
+      var node = this.nodes[i];
+      
+      if (node.parent == undefined) roots.push(node);
+    };
+    
+    return roots;
+  },
+  
+  tags: [
+    "html", "head", "body", "script", "meta", "title", "link", "script",
+    "div", "p", "span", "a", "img", "br", "hr",
+    "table", "tr", "th", "td", "thead", "tbody",
+    "ul", "ol", "li", 
+    "dl", "dt", "dd",
+    "h1", "h2", "h3", "h4", "h5", "h6", "h7",
+    "form", "input", "label"
+  ]
+};
+
+/**
+ * Adds a function for each tag onto Template's prototype
+ */
+(function() {
+  var tags = Jaml.Template.prototype.tags;
+  
+  for (var i = tags.length - 1; i >= 0; i--){
+    var tagName = tags[i];
+    
+    /**
+     * This function is created for each tag name and assigned to Template's
+     * prototype below
+     */
+    var fn = function(tagName) {
+      return function(attrs) {
+        var node = new Jaml.Node(tagName);
+        
+        var firstArgIsAttributes =  (typeof attrs == 'object')
+                                 && !(attrs instanceof Jaml.Node)
+                                 && !(attrs instanceof Jaml.TextNode);
+
+        if (firstArgIsAttributes) node.setAttributes(attrs);
+
+        var startIndex = firstArgIsAttributes ? 1 : 0;
+
+        for (var i=startIndex; i < arguments.length; i++) {
+          var arg = arguments[i];
+
+          if (typeof arg == "string" || arg == undefined) {
+            arg = new Jaml.TextNode(arg || "");
+          }
+          
+          if (arg instanceof Jaml.Node || arg instanceof Jaml.TextNode) {
+            arg.parent = node;
+          }
+
+          node.addChild(arg);
+        };
+        
+        this.nodes.push(node);
+        
+        return node;
+      };
+    };
+    
+    Jaml.Template.prototype[tagName] = fn(tagName);
+  };
+})();
+
+$.View.register({
+	suffix : "jaml",
+	script: function(id, str ) {
+		return "((function(){ Jaml.register("+id+", "+str+"); return function(data){return Jaml.render("+id+", data)} })())"
+	},
+	renderer: function(id, text ) {
+		var func;
+		eval("func = ("+text+")");
+		Jaml.register(id, func);
+		return function(data){
+			return Jaml.render(id, data)
+		}
+	}
+})
+
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/micro/micro.js b/browserid/static/dialog/jquery/view/micro/micro.js
new file mode 100644
index 0000000000000000000000000000000000000000..891fb2aaa5e615fe0002b806aa8e868f2a2b8626
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/micro/micro.js
@@ -0,0 +1,81 @@
+steal.plugins('jquery/view').then(function(){
+// Simple JavaScript Templating
+// John Resig - http://ejohn.org/ - MIT Licensed
+
+  var cache = {};
+  /**
+   * @function Micro
+   * @parent jQuery.View
+   * @plugin jquery/view/micro
+   * A very lightweight template engine. 
+   * Magic tags look like:
+   * 
+   * @codestart
+   * <h3>{%= message %}</h3>
+   * @codeend
+   * 
+   * Micro is integrated in JavaScriptMVC so 
+   * you can use it like:
+   * 
+   * @codestart
+   * $("#foo").html('//app/views/bar.micro',{});
+   * @codeend
+   * 
+   * ## Pros
+   * 
+   *  - Very Lightweight
+   *  
+   * ## Cons
+   * 
+   *  - Doesn't handle nested tags.
+   *  - Doesn't handle {%= "%}" %}. 
+   *  - More difficult to debug.
+   *  - Removes newlines and tabs.
+   * 
+   * ## Use
+   * 
+   * For more information on micro, see John Resig's
+   * [http://ejohn.org/blog/javascript-micro-templating/ write up].
+   * 
+   * @param {String} str template content.
+   * @param {Object} data render's the template with this content.
+   */
+  function Micro(str, data){
+	var body =  
+		"var p=[],print=function(){p.push.apply(p,arguments);};" +
+        
+        // Introduce the data as local variables using with(){}
+        "with(obj){p.push('" +
+        
+        // Convert the template into pure JavaScript
+        str.replace(/[\r\t\n]/g, " ")
+   .replace(/'(?=[^%]*%})/g,"\t")
+   .split("'").join("\\'")
+   .split("\t").join("'")
+   .replace(/{%=(.+?)%}/g, "',$1,'")
+   .split("{%").join("');")
+   .split("%}").join("p.push('")+ "');}return p.join('');"
+	
+    var fn =  new Function("obj",body);
+	fn.body = body;
+    
+    // Provide some basic currying to the user
+    return data ? fn( data ) : fn;
+  };
+
+	$.View.register({
+		suffix : "micro",
+		renderer: function( id, text ) {
+			var mt = Micro(text)
+			return function(data){
+				return mt(data)
+			}
+		},
+		script: function( id, str ) {
+			return "function(obj){"+Micro(str).body+"}";
+		}
+	})
+	jQuery.View.ext = ".micro"
+	
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/qunit.html b/browserid/static/dialog/jquery/view/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..26f38aba04ef7c6dc41400c813f3c3b1948ab86f
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/qunit.html
@@ -0,0 +1,16 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../funcunit/qunit/qunit.css" />
+		<script type='text/javascript' src='../../steal/steal.js?steal[app]=jquery/view/test/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">view Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/test/compression/compression.html b/browserid/static/dialog/jquery/view/test/compression/compression.html
new file mode 100644
index 0000000000000000000000000000000000000000..433ca3486d3a93bfa4510cff2d17337a565cd9f4
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/test/compression/compression.html
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>compression</title>
+	</head>
+	<div id='target'></div>
+		<script type='text/javascript' 
+                src='../../../../steal/steal.production.js?jquery/view/test/compression'>   
+        </script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/test/compression/compression.js b/browserid/static/dialog/jquery/view/test/compression/compression.js
new file mode 100644
index 0000000000000000000000000000000000000000..e1d5babbf4d37091559bf7b03370714f1b00ca6c
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/test/compression/compression.js
@@ -0,0 +1,11 @@
+steal.plugins('jquery/view/ejs', 'jquery/view/ejs', 'jquery/view/tmpl')
+     .views('relative.ejs', 
+	 		'//jquery/view/test/compression/views/absolute.ejs', 
+			'tmplTest.tmpl')
+	 .then(function(){
+	 	$(function(){
+	 		$("#target").append($.View('//jquery/view/test/compression/views/relative.ejs', {} ))
+	 					.append($.View('//jquery/view/test/compression/views/absolute.ejs', {} ))
+	 					.append($.View('//jquery/view/test/compression/views/tmplTest.tmpl', {message: "Jquery Tmpl"} ))
+		})
+	 })
diff --git a/browserid/static/dialog/jquery/view/test/compression/run.js b/browserid/static/dialog/jquery/view/test/compression/run.js
new file mode 100644
index 0000000000000000000000000000000000000000..3fca5a34b2fcf3434820b1b5d84025bd125b47d4
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/test/compression/run.js
@@ -0,0 +1,49 @@
+// load('steal/compress/test/run.js')
+
+/**
+ * Tests compressing a very basic page and one that is using steal
+ */
+
+load('steal/rhino/steal.js')
+steal('//steal/test/test', function(s){
+	
+	s.test.module("jquery/view/compression")
+	STEALPRINT = false;
+	
+	s.test.test("templates" , function(t){
+		
+		
+		steal.File("jquery/view/test/compression/views/absolute.ejs").save("<h1>Absolute</h1>");
+		steal.File("jquery/view/test/compression/views/relative.ejs").save("<h1>Relative</h1>");
+		steal.File("jquery/view/test/compression/views/tmplTest.tmpl").save("<h1>${message}</h1>");
+		s.test.clear();
+		
+		load("steal/rhino/steal.js");
+		steal.plugins('steal/build','steal/build/scripts','steal/build/styles',function(){
+			steal.build('jquery/view/test/compression/compression.html',{to: 'jquery/view/test/compression'});
+		});
+		s.test.clear();
+		s.test.remove("jquery/view/test/compression/views/absolute.ejs")
+		s.test.remove("jquery/view/test/compression/views/relative.ejs")
+		s.test.remove("jquery/view/test/compression/views/tmplTest.tmpl")
+		
+		
+		steal = {env: "production"};
+		
+		s.test.open('jquery/view/test/compression/compression.html')
+		s.test.ok(  /Relative/i.test( $(document.body).text() ), "Relative not in page!" );
+		s.test.ok(  /Absolute/i.test( $(document.body).text() ), "Absolute not in page!" );
+		s.test.ok(  /Jquery Tmpl/i.test( $(document.body).text() ), "Jquery Tmpl not in page!" );
+		
+		s.test.clear();
+		s.test.remove("jquery/view/test/compression/production.js")
+			
+	})
+	
+
+	
+	
+	
+	
+	
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/test/compression/views/keep.me b/browserid/static/dialog/jquery/view/test/compression/views/keep.me
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/browserid/static/dialog/jquery/view/test/qunit/hookup.ejs b/browserid/static/dialog/jquery/view/test/qunit/hookup.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..4b49fd2678c719330525b6bb0ffb14af1656329d
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/test/qunit/hookup.ejs
@@ -0,0 +1 @@
+<%= function(){} %>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/test/qunit/large.ejs b/browserid/static/dialog/jquery/view/test/qunit/large.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..671ef3b7004ce6381b4c9ba8f8e270bebf3435d5
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/test/qunit/large.ejs
@@ -0,0 +1,373 @@
+<style>
+    body  {font-family: verdana;}
+</style>
+
+<p>Complex JavaScript applications are mostly about making it easy to create, 
+read, update, and delete (CRUD) data.  But being so close to the UI, 
+most JavaScript developers ignore the data layer and focus on 
+making animated drag-drop effects.  
+</p>
+<p>We're doing ourselves a disservice! A strong Model layer can make an architecture infinitely more robust, reusable, and maintainable. 
+</p>
+<p>JavaScriptMVC's model layer is designed to be as flexible and lightweight as possible. 
+ The remainder of this article highlights the features of jQuery.Model, 
+ how to use them, and why they are important.
+</p>
+<h2>Downloads</h2>
+<ul>
+	<li><a href='http://v3.javascriptmvc.com/jquery/dist/jquery.model.js'>jquery.model.js</a></li>
+	<li><a href='http://v3.javascriptmvc.com/jquery/dist/jquery.model.associations.js'>jquery.model.associations.js</a></li>
+	<li><a href='http://v3.javascriptmvc.com/jquery/dist/jquery.model.backup.js'>jquery.model.backup.js</a></li>
+	<li><a href='http://v3.javascriptmvc.com/jquery/dist/jquery.model.list.js'>jquery.model.list.js</a></li>
+	<li><a href='http://v3.javascriptmvc.com/jquery/dist/jquery.model.cookie.js'>jquery.model.list.cookie.js</a></li>
+	<li><a href='http://v3.javascriptmvc.com/jquery/dist/jquery.model.validations.js'>jquery.model.validations.js</a></li>
+</ul>
+<h2>Features</h2>
+<ul>
+    <li>Service / Ajax encapsulation</li>
+    <li>Type Conversion</li>
+    <li>Data Helper Methods</li>
+	<li>DOM Helper Functions</li>
+	<li>Events and Propety Binding</li>
+    <li>Lists</li>
+	<li>Local Storage</li>
+	<li>Associations</li>
+    <li>Backup / Restore</li>
+    <li>Validations</li>
+</ul>
+
+
+<h2>Service / Ajax Encapsulation</h2>
+
+<p>Models encapsulate your application's raw data.  
+The majority of the time, the raw data comes from services your server provides.  For example, if you make a request to:
+</p>
+<pre><code>GET /contacts.json</code></pre>
+<p>
+The server might return something like:
+</p>
+<pre><code>
+[{
+  'id': 1,
+  'name' : 'Justin Meyer',
+  'birthday': '1982-10-20'
+},
+{
+  'id': 2,
+  'name' : 'Brian Moschel',
+  'birthday': '1983-11-10'
+}]</code></pre>
+<p>
+In most jQuery code, you'll see something like the following to retrieve contacts
+data:
+</p>
+<pre><code>
+$.get('/contacts.json',
+      {type: 'tasty'}, 
+      successCallback,
+      'json')</code></pre>
+<p>
+Instead, model encapsulates (wraps) this request so you call it like:
+</p>
+<pre><code>
+Contact.findAll({type: 'old'}, successCallback);
+</code></pre>
+<p>
+This might seem like unnecessary overhead, but by encapsulating your 
+application's data, your application benefits in two significant ways:
+</p>
+
+<h3>Benefit 1: Localized Changes</h3>
+
+
+<p>
+Over the development lifecycle of an application, is very likely that 
+your services will change.  Models help localize your application's use of 
+services to a single (<b>TESTABLE!</b>) location.
+</p>
+
+<h3>Benefit 2: Normalized Service Requests</h3>
+
+<p>
+Complex widgets, like Grids and Trees, need to make Ajax requests to operate correctly.  Often these widgets need to be configured by a variety of options and callbacks.  There's no uniformity, and sometimes you have to change your service to match the needs of the widget.
+</p>
+<p>
+Instead, models normalize how widgets access your services, making it easy to use 
+different models for the same widget.
+</p>
+<h3>Encapsulation Demo</h3>
+
+<p><a href='http://v3.javascriptmvc.com/jquery/model/demo-encapsulate.html'>The encapsulation demo</a> shows using two different models with the same widget.</p>
+<h3>How to Encapsulate</h3>
+<p>
+Think of models as a contract for creating, reading, updating, and deleting data.  
+By filling out a model, you can pass that model to a widget and the 
+widget will use the model as a proxy for your data.  
+</p>
+<p>
+The following chart shows the methods most models provide:
+</p>
+<table>
+    <tr>
+        <td>Create</td><td><pre>Contact.create(attrs, success, error</pre></td>
+    </tr>
+    <tr>
+        <td>Read</td><td><pre>Contact.findAll(params,success,error)
+Contact.findOne(params, success, error)</pre></td>
+    </tr>
+    <tr>
+        <td>Update</td><td><pre>Contact.update(id, attrs, success, error)</pre></td>
+    </tr>
+    <tr>
+        <td>Delete</td><td><pre>Contact.destroy(id, success, error)</pre></td>
+    </tr>
+</table>
+<p>By filling out these methods, you get the benefits of encapsulation, 
+AND all the other magic Model provides.  Lets see how we might fill out the
+<code>Contact.findAll</code> function:</p>
+<pre><code>$.Model.extend('Contact',
+{
+  findAll : function(params, success, error){
+  
+    // do the ajax request
+    $.get('/contacts.json',
+      params, 
+      function( json ){ 
+        
+        // on success, create new Contact
+        // instances for each contact
+        var wrapped = [];
+        
+        for(var i =0; i< json.length;i++){
+          wrapped.push( new Contact(json[i] ) );
+        }
+        
+        //call success with the contacts
+        success( wrapped );
+        
+      },
+      'json');
+  }
+},
+{
+  // Prototype properties of Contact.
+  // We'll learn about this soon!
+});</code></pre>
+
+<p>Well, that would be annoying to write out every time.  Fortunately, 
+models have
+the <a href='http://v3.javascriptmvc.com/index.html#&who=jQuery.Model.static.wrapMany'>wrapMany</a> method which will make it easier:</p>
+<pre><code>  findAll : function(params, success, error){
+    $.get('/contacts.json',
+      params, 
+      function( json ){ 
+        success(Contact.wrapMany(json));		
+      },
+      'json');
+  }
+</code></pre>
+<p>Model is based off JavaScriptMVC's 
+<a href='http://jupiterjs.com/news/a-simple-powerful-lightweight-class-for-jquery'><code>jQuery.Class</code></a>. It's 
+<a href='http://v3.javascriptmvc.com/index.html#&who=jQuery.Class.static.callback'>callback method</a> allows us to pipe
+wrapMany into the success handler and make our code even shorter:</p>
+<pre><code>  findAll : function(params, success, error){
+    $.get('/contacts.json',
+    params, 
+    this.callback(['wrapMany', success]),
+    'json')
+  }
+</code></pre>
+<p>If we wanted to make a list of contacts, we could do it like:</p>
+<pre><code>Contact.findAll({},function(contacts){
+  var html = [];
+  for(var i =0; i < contacts.length; i++){
+    html.push('&lt;li>'+contacts[i].name + '&lt;/li>')
+  }
+  $('#contacts').html( html.join('') );
+});</code></pre>
+<p>Read JavaScriptMVC's <a href='http://v3.javascriptmvc.com/index.html#&who=jquery.model.encapsulate'>
+	encapsulation documentation</a> on how to fill out the other CRUD methods
+of the CRUD-Contract.  Once this is done, you'll get all the following magic.</p>
+<h2>Type Conversion</h2>
+<p>By creating instances of Contact with the data from the server, it
+lets us wrap and manipulate the data into a more usable format.
+</p>
+<p>
+    You notice that the server sends back Contact birthdays like:
+    <code>'1982-10-20'</code>.  
+	A string representation of dates
+     is not terribly convient.  
+	 We can use our model to convert it to something closer to
+     <code>new Date(1982,10,20)</code>.  We can do this in two ways:
+    
+</p>
+
+<h3>Way 1: Setters</h3>
+<p>In our Contact model, we can add a setBirthday method 
+that will convert the raw
+data passed from the server to a 
+format more useful for JavaScript:  </p>
+<pre><code>$.Model.extend("Contact",
+{
+  findAll : function( ... ){ ... }
+},
+{
+  setBirthday : function(raw){
+    if(typeof raw == 'string'){
+      var matches = raw.match(/(\d+)-(\d+)-(\d+)/)
+      return new Date( matches[1], 
+                      (+matches[2])-1, 
+                       matches[3] )
+    }else if(raw instanceof Date){
+      return raw;
+    }
+  }
+})</code></pre>
+<p>The <code>setBirthday</code> setter function takes the 
+raw string date, parses it returns the JavaScript friendly
+date.</p>
+<h3>Way 2: Attributes and Converters</h3>
+<p>If you have a lot of dates, <B>Setters</B> won't scale well.  Instead, you can
+set the type of an attribute and provide a function to convert that type.</p>
+<p>The following sets the birthday attribute to "date" and provides a date
+conversion function:</p>
+<pre><code>$.Model.extend("Contact",
+{
+  attributes : { 
+    birthday : 'date'
+  },
+  convert : {
+    date : function(raw){
+      if(typeof raw == 'string'){
+        var matches = raw.match(/(\d+)-(\d+)-(\d+)/)
+        return new Date( matches[1], 
+                        (+matches[2])-1, 
+                         matches[3] )
+      }else if(raw instanceof Date){
+        return raw;
+      }
+    }
+  },
+  findAll : function( ... ){ ... }
+},
+{
+  // No prototype properties necessary
+})</code></pre>
+<p>This technique uses a Model's 
+<a href='http://v3.javascriptmvc.com/index.html#&who=jQuery.Model.static.attributes'>
+	attributes</a> and 
+	<a href='http://v3.javascriptmvc.com/index.html#&who=jQuery.Model.static.convert'>
+		convert</a> properties.</p>
+
+<p>Now our recipe instances will have a nice <code>Date</code> 
+birthday property. 
+We can use it to list how old each person will be this year:
+
+</p>
+<pre><code>
+var age = function(birthday){
+   return new Date().getFullYear() - 
+          birthday.getFullYear()
+}
+
+Contact.findAll({},function(contacts){
+  var html = [];
+  for(var i =0; i < contacts.length; i++){
+    html.push('&lt;li>'+age(contacts[i].birthday) + '&lt;/li>')
+  }
+  $('#contacts').html( html.join('') );
+});</code></pre>
+<p>But what if some other code wants to use age?  Well, they'll have to use ...</p>
+
+<h2>Data Helper Methods</h2><!-- ------------------------------------- -->
+
+
+
+<p>You can add domain specific helper methods to your models.  The following adds
+<code>ageThisYear</code> to contact instances:</p>
+<pre><code>$.Model.extend("Contact",
+{
+  attributes : { ... },
+  convert : { ... },
+  findAll : function( ... ){ ... }
+},
+{
+  ageThisYear : function(){
+    return new Date().getFullYear() - 
+          this.birthday.getFullYear()
+  }
+})</code></pre>
+<p>Now we can write out the ages a little cleaner:</p>
+<pre><code>Contact.findAll({},function(contacts){
+  var html = [];
+  for(var i =0; i < contacts.length; i++){
+    html.push('&lt;li>'+ contacts[i].ageThisYear() + '&lt;/li>')
+  }
+  $('#contacts').html( html.join('') );
+});</code></pre>
+
+<p>Now that we are showing contacts on the page, lets do something with them.
+  First, we'll need a way to get back our models from the page.  For this we'll use ...  
+</p>
+
+<h2>DOM Helper Functions</h2>
+<p>It's common practice with jQuery to put additional data 'on' html elements
+with 
+<a href='http://api.jquery.com/jQuery.data/'>jQuery.data</a>.  
+It's a great technique because you can remove the elements
+and jQuery will clean the data (letting the Garbage Collector do its work).  
+</p>
+<p>Model supports something similar with the 
+<code>model</code> and <code>models</code> helpers.
+They let us set and retrieve model instances on elements.
+</p>
+<p>For example, lets say we wanted to let developer delete contacts like
+in the <a href='http://v3.javascriptmvc.com/jquery/model/demo-dom.html'>
+	Model DOM Demo</a>.</p>
+<p>First, we'll add a <code>DELETE</code> link like:</p>
+<pre><code>Contact.findAll({},function(contacts){
+  var contactsEl = $('#contacts');
+  for(var i =0; i < contacts.length; i++){
+   $('&lt;li>').model(contacts[i])
+            .html(contacts[i].ageThisYear()+
+                  " &lt;a>DELETE&lt;/a>")
+            .appendTo(contactsEl)
+  }
+});</code></pre>
+<p>When a model is added to an element's data, it also adds it's name a unique 
+identifier to the element.  For example, the first <code>li</code> element
+will look like:</p>
+<pre><code>&lt;li class='contact contact_5'> ... &lt;/li></code></pre>
+<p>When someone clicks on <code>DELETE</code>, we want to remove that contact.  
+We implement it like:</p>
+<pre><code>$("#contacts a").live('click', function(){
+  //get the element for this recipe
+  var contactEl = $(this).closest('.contact')
+  
+  // get the conctact instance
+  contactEl.model()
+           // call destroy on the instance
+           .destroy(function(){
+                      // remove the element
+                      contactEl.remove();
+                    })
+		  
+})</code></pre>
+<p>This assumes we've filled out <code>Contact.destroy</code>.  
+</p>
+<p>There's one more very useful DOM helper: <code>contact.elements()</code>.
+<a href='http://v3.javascriptmvc.com/index.html#&who=jQuery.Model.prototype.elements'>Elements</a> returns the elements that 
+have a particular model instance.
+We'll see how this helps us in the next section.
+</p>
+
+
+<h2>Events</h2>
+<p>Consider the case where we have two representations of the 
+same recipe data on the page.  Maybe when we click a contact,
+we show additional information on the page, like an input to change the
+contact's birthday.
+</p>
+<p>See this in action in the <a href='http://v3.javascriptmvc.com/jquery/model/demo-events.html'>events demo</a>.</p>
+<p>When the birthday is updated, we want the list's contact
+display to also update it's age.  Model provides two ways of doing this.</p>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/test/qunit/nested_plugin.ejs b/browserid/static/dialog/jquery/view/test/qunit/nested_plugin.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..4895410b03d8e376bd677f65b63bbc43f0ccc90d
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/test/qunit/nested_plugin.ejs
@@ -0,0 +1 @@
+<div <%=plugin("text", "Here is something")%> id='something'></div>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/test/qunit/plugin.ejs b/browserid/static/dialog/jquery/view/test/qunit/plugin.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..a9ab605f1c60d18027652e1f7dbbf201c65fd164
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/test/qunit/plugin.ejs
@@ -0,0 +1 @@
+<div <%=plugin("html", "<span>Here is something</span>")%> id='something'></div>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/test/qunit/qunit.js b/browserid/static/dialog/jquery/view/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..21dcdd2e732f400fe3218925a085ed2f90fd97c6
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/test/qunit/qunit.js
@@ -0,0 +1,9 @@
+//we probably have to have this only describing where the tests are
+steal
+ .plugins("jquery/view","jquery/view/micro","jquery/view/ejs","jquery/view/jaml","jquery/view/tmpl")  //load your app
+ .plugins('funcunit/qunit')  //load qunit
+ .then("view_test","//jquery/view/tmpl/tmpl_test.js")
+ 
+if(steal.browser.rhino){
+  steal.plugins('funcunit/qunit/env')
+}
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/test/qunit/temp.ejs b/browserid/static/dialog/jquery/view/test/qunit/temp.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..01caddd75555c0251351f2a0ba9adb23fb1aecb6
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/test/qunit/temp.ejs
@@ -0,0 +1 @@
+<h3><%= message %></h3>
diff --git a/browserid/static/dialog/jquery/view/test/qunit/template.ejs b/browserid/static/dialog/jquery/view/test/qunit/template.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..01caddd75555c0251351f2a0ba9adb23fb1aecb6
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/test/qunit/template.ejs
@@ -0,0 +1 @@
+<h3><%= message %></h3>
diff --git a/browserid/static/dialog/jquery/view/test/qunit/template.jaml b/browserid/static/dialog/jquery/view/test/qunit/template.jaml
new file mode 100644
index 0000000000000000000000000000000000000000..2b75f22fe64908c214535ff70f2575906e9434b1
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/test/qunit/template.jaml
@@ -0,0 +1,3 @@
+function(data) {
+  h3(data.message);
+}
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/test/qunit/template.micro b/browserid/static/dialog/jquery/view/test/qunit/template.micro
new file mode 100644
index 0000000000000000000000000000000000000000..16fa35257834f8364d8006365d8d9d875f7fdd47
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/test/qunit/template.micro
@@ -0,0 +1 @@
+<h3>{%= message %}</h3>
diff --git a/browserid/static/dialog/jquery/view/test/qunit/template.tmpl b/browserid/static/dialog/jquery/view/test/qunit/template.tmpl
new file mode 100644
index 0000000000000000000000000000000000000000..0b02edfa4a4dd7dc8e73ad1c2d96445598900fad
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/test/qunit/template.tmpl
@@ -0,0 +1 @@
+<h3>${message}</h3>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/test/qunit/view_test.js b/browserid/static/dialog/jquery/view/test/qunit/view_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..918e573010bd0ece2964cc2d85171038294c8735
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/test/qunit/view_test.js
@@ -0,0 +1,80 @@
+
+module("jquery/view")
+test("multipel template types work", function(){
+	
+	$.each(["micro","ejs","jaml", "tmpl"], function(){
+		$("#qunit-test-area").html("");
+		ok($("#qunit-test-area").children().length == 0,this+ ": Empty To Start")
+		
+		$("#qunit-test-area").html("//jquery/view/test/qunit/template."+this,{"message" :"helloworld"})
+		ok($("#qunit-test-area").find('h3').length, this+": h3 written for ")
+		ok( /helloworld\s*/.test( $("#qunit-test-area").text()), this+": hello world present for ")
+	})
+})
+test("plugin in ejs", function(){
+	$("#qunit-test-area").html("");
+	$("#qunit-test-area").html("//jquery/view/test/qunit/plugin.ejs",{})
+	ok(/something/.test( $("#something").text()),"something has something");
+	$("#qunit-test-area").html("");
+})
+test("nested plugins", function(){
+	$("#qunit-test-area").html("");
+	$("#qunit-test-area").html("//jquery/view/test/qunit/nested_plugin.ejs",{})
+	ok(/something/.test( $("#something").text()),"something has something");
+})
+
+test("async templates, and caching work", function(){
+	$("#qunit-test-area").html("");
+	stop();
+	var i = 0;
+	$("#qunit-test-area").html("//jquery/view/test/qunit/temp.ejs",{"message" :"helloworld"}, function(text){
+		ok( /helloworld\s*/.test( $("#qunit-test-area").text()))
+		ok(/helloworld\s*/.test(text), "we got a rendered template");
+		i++;
+		equals(i, 2, "Ajax is not synchronous");
+		equals(this.attr("id"), "qunit-test-area" )
+		start();
+	});
+	i++;
+	equals(i, 1, "Ajax is not synchronous")
+})
+test("caching works", function(){
+	// this basically does a large ajax request and makes sure 
+	// that the second time is always faster
+	$("#qunit-test-area").html("");
+	stop();
+	var startT = new Date(),
+		first;
+	$("#qunit-test-area").html("//jquery/view/test/qunit/large.ejs",{"message" :"helloworld"}, function(text){
+		first = new Date();
+		ok(text, "we got a rendered template");
+		
+		
+		$("#qunit-test-area").html("");
+		$("#qunit-test-area").html("//jquery/view/test/qunit/large.ejs",{"message" :"helloworld"}, function(text){
+			var lap2 = new Date - first ,
+				lap1 =  first-startT;
+				
+			ok(lap2 < lap1, "faster this time "+(lap1 - lap2) )
+			
+			start();
+			$("#qunit-test-area").html("");
+		})
+		
+	})
+})
+test("hookup", function(){
+	$("#qunit-test-area").html("");
+	
+	$("#qunit-test-area").html("//jquery/view/test/qunit/hookup.ejs",{}); //makes sure no error happens
+})
+
+test("inline templates other than 'tmpl' like ejs", function(){
+        $("#qunit-test-area").html("");
+
+        $("#qunit-test-area").html($('<script type="test/ejs" id="test_ejs"><span id="new_name"><%= name %></span></script>'));
+
+        $("#qunit-test-area").html('test_ejs', {name: 'Henry'});
+        equal( $("#new_name").text(), 'Henry');
+	$("#qunit-test-area").html("");
+})
diff --git a/browserid/static/dialog/jquery/view/tmpl/test.tmpl b/browserid/static/dialog/jquery/view/tmpl/test.tmpl
new file mode 100644
index 0000000000000000000000000000000000000000..f06c7690412e6c7038dfe93bb71924d91ea16588
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/tmpl/test.tmpl
@@ -0,0 +1 @@
+{{if 1}}<h1>Hello World</h1>{{/if}}
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/tmpl/tmpl.js b/browserid/static/dialog/jquery/view/tmpl/tmpl.js
new file mode 100644
index 0000000000000000000000000000000000000000..067882258b8056ac09f1e800aa83048f8f608303
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/tmpl/tmpl.js
@@ -0,0 +1,522 @@
+// jQuery Templates Plugin
+// http://github.com/jquery/jquery-tmpl
+// 
+// Copyright Software Freedom Conservancy, Inc.
+// Dual licensed under the MIT or GPL Version 2 licenses.
+// http://jquery.org/license
+
+/**
+ * @class jQuery.tmpl
+ * @parent jQuery.View
+ * @plugin jquery/view/tmpl
+ * Provides basic templating with magic tags that look like:
+ * @codestart
+ * ${value}
+ * @codeend
+ * [jQuery.View] integrates jQuery.tmpl templates into
+ * your build process.  You can use a jQuery.tmpl like:
+ * 
+ * @codestart
+ * $('#area').html('//path/to/template.tmpl',{ data });
+ * @codeend
+ * 
+ * For more information on jQuery.tmpl read 
+ * [http://api.jquery.com/category/plugins/templates/ it's documentation].
+ */
+steal.plugins('jquery/view').then(function(){
+		// Override the DOM manipulation function
+	var oldManip = jQuery.fn.domManip, tmplItmAtt = "_tmplitem", htmlExpr = /^[^<]*(<[\w\W]+>)[^>]*$|\{\{\! /,
+		newTmplItems = {}, wrappedItems = {}, appendToTmplItems, topTmplItem = { key: 0, data: {} }, itemKey = 0, cloneIndex = 0, stack = [];
+
+	function newTmplItem( options, parentItem, fn, data ) {
+		// Returns a template item data structure for a new rendered instance of a template (a 'template item').
+		// The content field is a hierarchical array of strings and nested items (to be
+		// removed and replaced by nodes field of dom elements, once inserted in DOM).
+		var newItem = {
+			data: data || (parentItem ? parentItem.data : {}),
+			_wrap: parentItem ? parentItem._wrap : null,
+			tmpl: null,
+			parent: parentItem || null,
+			nodes: [],
+			calls: tiCalls,
+			nest: tiNest,
+			wrap: tiWrap,
+			html: tiHtml,
+			update: tiUpdate
+		};
+		if ( options ) {
+			jQuery.extend( newItem, options, { nodes: [], parent: parentItem } );
+		}
+		if ( fn ) {
+			// Build the hierarchical content to be used during insertion into DOM
+			newItem.tmpl = fn;
+			newItem._ctnt = newItem._ctnt || newItem.tmpl( jQuery, newItem );
+			newItem.key = ++itemKey;
+			// Keep track of new template item, until it is stored as jQuery Data on DOM element
+			(stack.length ? wrappedItems : newTmplItems)[itemKey] = newItem;
+		}
+		return newItem;
+	}
+
+	// Override appendTo etc., in order to provide support for targeting multiple elements. (This code would disappear if integrated in jquery core).
+	jQuery.each({
+		appendTo: "append",
+		prependTo: "prepend",
+		insertBefore: "before",
+		insertAfter: "after",
+		replaceAll: "replaceWith"
+	}, function( name, original ) {
+		jQuery.fn[ name ] = function( selector ) {
+			var ret = [], insert = jQuery( selector ), elems, i, l, tmplItems,
+				parent = this.length === 1 && this[0].parentNode;
+
+			appendToTmplItems = newTmplItems || {};
+			if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
+				insert[ original ]( this[0] );
+				ret = this;
+			} else {
+				for ( i = 0, l = insert.length; i < l; i++ ) {
+					cloneIndex = i;
+					elems = (i > 0 ? this.clone(true) : this).get();
+					jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
+					ret = ret.concat( elems );
+				}
+				cloneIndex = 0;
+				ret = this.pushStack( ret, name, insert.selector );
+			}
+			tmplItems = appendToTmplItems;
+			appendToTmplItems = null;
+			jQuery.tmpl.complete( tmplItems );
+			return ret;
+		};
+	});
+
+	jQuery.fn.extend({
+		// Use first wrapped element as template markup.
+		// Return wrapped set of template items, obtained by rendering template against data.
+		tmpl: function( data, options, parentItem ) {
+			return jQuery.tmpl( this[0], data, options, parentItem );
+		},
+
+		// Find which rendered template item the first wrapped DOM element belongs to
+		tmplItem: function() {
+			return jQuery.tmplItem( this[0] );
+		},
+
+		// Consider the first wrapped element as a template declaration, and get the compiled template or store it as a named template.
+		template: function( name ) {
+			return jQuery.template( name, this[0] );
+		},
+
+		domManip: function( args, table, callback, options ) {
+			// This appears to be a bug in the appendTo, etc. implementation
+			// it should be doing .call() instead of .apply(). See #6227
+			if ( args[0] && args[0].nodeType ) {
+				var dmArgs = jQuery.makeArray( arguments ), argsLength = args.length, i = 0, tmplItem;
+				while ( i < argsLength && !(tmplItem = jQuery.data( args[i++], "tmplItem" ))) {}
+				if ( argsLength > 1 ) {
+					dmArgs[0] = [jQuery.makeArray( args )];
+				}
+				if ( tmplItem && cloneIndex ) {
+					dmArgs[2] = function( fragClone ) {
+						// Handler called by oldManip when rendered template has been inserted into DOM.
+						jQuery.tmpl.afterManip( this, fragClone, callback );
+					};
+				}
+				oldManip.apply( this, dmArgs );
+			} else {
+				oldManip.apply( this, arguments );
+			}
+			cloneIndex = 0;
+			if ( !appendToTmplItems ) {
+				jQuery.tmpl.complete( newTmplItems );
+			}
+			return this;
+		}
+	});
+
+	jQuery.extend({
+		// Return wrapped set of template items, obtained by rendering template against data.
+		tmpl: function( tmpl, data, options, parentItem ) {
+			var ret, topLevel = !parentItem;
+			if ( topLevel ) {
+				// This is a top-level tmpl call (not from a nested template using {{tmpl}})
+				parentItem = topTmplItem;
+				tmpl = jQuery.template[tmpl] || jQuery.template( null, tmpl );
+				wrappedItems = {}; // Any wrapped items will be rebuilt, since this is top level
+			} else if ( !tmpl ) {
+				// The template item is already associated with DOM - this is a refresh.
+				// Re-evaluate rendered template for the parentItem
+				tmpl = parentItem.tmpl;
+				newTmplItems[parentItem.key] = parentItem;
+				parentItem.nodes = [];
+				if ( parentItem.wrapped ) {
+					updateWrapped( parentItem, parentItem.wrapped );
+				}
+				// Rebuild, without creating a new template item
+				return jQuery( build( parentItem, null, parentItem.tmpl( jQuery, parentItem ) ));
+			}
+			if ( !tmpl ) {
+				return []; // Could throw...
+			}
+			if ( typeof data === "function" ) {
+				data = data.call( parentItem || {} );
+			}
+			if ( options && options.wrapped ) {
+				updateWrapped( options, options.wrapped );
+			}
+			ret = jQuery.isArray( data ) ? 
+				jQuery.map( data, function( dataItem ) {
+					return dataItem ? newTmplItem( options, parentItem, tmpl, dataItem ) : null;
+				}) :
+				[ newTmplItem( options, parentItem, tmpl, data ) ];
+			return topLevel ? jQuery( build( parentItem, null, ret ) ) : ret;
+		},
+
+		// Return rendered template item for an element.
+		tmplItem: function( elem ) {
+			var tmplItem;
+			if ( elem instanceof jQuery ) {
+				elem = elem[0];
+			}
+			while ( elem && elem.nodeType === 1 && !(tmplItem = jQuery.data( elem, "tmplItem" )) && (elem = elem.parentNode) ) {}
+			return tmplItem || topTmplItem;
+		},
+
+		// Set:
+		// Use $.template( name, tmpl ) to cache a named template,
+		// where tmpl is a template string, a script element or a jQuery instance wrapping a script element, etc.
+		// Use $( "selector" ).template( name ) to provide access by name to a script block template declaration.
+
+		// Get:
+		// Use $.template( name ) to access a cached template.
+		// Also $( selectorToScriptBlock ).template(), or $.template( null, templateString )
+		// will return the compiled template, without adding a name reference.
+		// If templateString includes at least one HTML tag, $.template( templateString ) is equivalent
+		// to $.template( null, templateString )
+		template: function( name, tmpl ) {
+			if (tmpl) {
+				// Compile template and associate with name
+				if ( typeof tmpl === "string" ) {
+					// This is an HTML string being passed directly in.
+					tmpl = buildTmplFn( tmpl )
+				} else if ( tmpl instanceof jQuery ) {
+					tmpl = tmpl[0] || {};
+				}
+				if ( tmpl.nodeType ) {
+					// If this is a template block, use cached copy, or generate tmpl function and cache.
+					tmpl = jQuery.data( tmpl, "tmpl" ) || jQuery.data( tmpl, "tmpl", buildTmplFn( tmpl.innerHTML ));
+				}
+				return typeof name === "string" ? (jQuery.template[name] = tmpl) : tmpl;
+			}
+			// Return named compiled template
+			return name ? (typeof name !== "string" ? jQuery.template( null, name ): 
+				(jQuery.template[name] || 
+					// If not in map, treat as a selector. (If integrated with core, use quickExpr.exec) 
+					jQuery.template( null, htmlExpr.test( name ) ? name : jQuery( name )))) : null; 
+		},
+
+		encode: function( text ) {
+			// Do HTML encoding replacing < > & and ' and " by corresponding entities.
+			return ("" + text).split("<").join("&lt;").split(">").join("&gt;").split('"').join("&#34;").split("'").join("&#39;");
+		}
+	});
+
+	jQuery.extend( jQuery.tmpl, {
+		tag: {
+			"tmpl": {
+				_default: { $2: "null" },
+				open: "if($notnull_1){_=_.concat($item.nest($1,$2));}"
+				// tmpl target parameter can be of type function, so use $1, not $1a (so not auto detection of functions)
+				// This means that {{tmpl foo}} treats foo as a template (which IS a function). 
+				// Explicit parens can be used if foo is a function that returns a template: {{tmpl foo()}}.
+			},
+			"wrap": {
+				_default: { $2: "null" },
+				open: "$item.calls(_,$1,$2);_=[];",
+				close: "call=$item.calls();_=call._.concat($item.wrap(call,_));"
+			},
+			"each": {
+				_default: { $2: "$index, $value" },
+				open: "if($notnull_1){$.each($1a,function($2){with(this){",
+				close: "}});}"
+			},
+			"if": {
+				open: "if(($notnull_1) && $1a){",
+				close: "}"
+			},
+			"else": {
+				_default: { $1: "true" },
+				open: "}else if(($notnull_1) && $1a){"
+			},
+			"html": {
+				// Unecoded expression evaluation. 
+				open: "if($notnull_1){_.push($1a);}"
+			},
+			"=": {
+				// Encoded expression evaluation. Abbreviated form is ${}.
+				_default: { $1: "$data" },
+				open: "if($notnull_1){_.push($.encode($1a));}"
+			},
+			"!": {
+				// Comment tag. Skipped by parser
+				open: ""
+			}
+		},
+
+		// This stub can be overridden, e.g. in jquery.tmplPlus for providing rendered events
+		complete: function( items ) {
+			newTmplItems = {};
+		},
+
+		// Call this from code which overrides domManip, or equivalent
+		// Manage cloning/storing template items etc.
+		afterManip: function afterManip( elem, fragClone, callback ) {
+			// Provides cloned fragment ready for fixup prior to and after insertion into DOM
+			var content = fragClone.nodeType === 11 ?
+				jQuery.makeArray(fragClone.childNodes) :
+				fragClone.nodeType === 1 ? [fragClone] : [];
+
+			// Return fragment to original caller (e.g. append) for DOM insertion
+			callback.call( elem, fragClone );
+
+			// Fragment has been inserted:- Add inserted nodes to tmplItem data structure. Replace inserted element annotations by jQuery.data.
+			storeTmplItems( content );
+			cloneIndex++;
+		}
+	});
+
+	//========================== Private helper functions, used by code above ==========================
+
+	function build( tmplItem, nested, content ) {
+		// Convert hierarchical content into flat string array 
+		// and finally return array of fragments ready for DOM insertion
+		var frag, ret = content ? jQuery.map( content, function( item ) {
+			return (typeof item === "string") ? 
+				// Insert template item annotations, to be converted to jQuery.data( "tmplItem" ) when elems are inserted into DOM.
+				(tmplItem.key ? item.replace( /(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g, "$1 " + tmplItmAtt + "=\"" + tmplItem.key + "\" $2" ) : item) :
+				// This is a child template item. Build nested template.
+				build( item, tmplItem, item._ctnt );
+		}) : 
+		// If content is not defined, insert tmplItem directly. Not a template item. May be a string, or a string array, e.g. from {{html $item.html()}}. 
+		tmplItem;
+		if ( nested ) {
+			return ret;
+		}
+
+		// top-level template
+		ret = ret.join("");
+
+		// Support templates which have initial or final text nodes, or consist only of text
+		// Also support HTML entities within the HTML markup.
+		ret.replace( /^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/, function( all, before, middle, after) {
+			frag = jQuery( middle ).get();
+
+			storeTmplItems( frag );
+			if ( before ) {
+				frag = unencode( before ).concat(frag);
+			}
+			if ( after ) {
+				frag = frag.concat(unencode( after ));
+			}
+		});
+		return frag ? frag : unencode( ret );
+	}
+
+	function unencode( text ) {
+		// Use createElement, since createTextNode will not render HTML entities correctly
+		var el = document.createElement( "div" );
+		el.innerHTML = text;
+		return jQuery.makeArray(el.childNodes);
+	}
+
+	// Generate a reusable function that will serve to render a template against data
+	function buildTmplFn( markup ) {
+		return new Function("jQuery","$item",
+			"var $=jQuery,call,_=[],$data=$item.data;" +
+
+			// Introduce the data as local variables using with(){}
+			"with($data){_.push('" +
+
+			// Convert the template into pure JavaScript
+			jQuery.trim(markup)
+				.replace( /([\\'])/g, "\\$1" )
+				.replace( /[\r\t\n]/g, " " )
+				.replace( /\$\{([^\}]*)\}/g, "{{= $1}}" )
+				.replace( /\{\{(\/?)(\w+|.)(?:\(((?:[^\}]|\}(?!\}))*?)?\))?(?:\s+(.*?)?)?(\(((?:[^\}]|\}(?!\}))*?)\))?\s*\}\}/g,
+				function( all, slash, type, fnargs, target, parens, args ) {
+					var tag = jQuery.tmpl.tag[ type ], def, expr, exprAutoFnDetect;
+					if ( !tag ) {
+						throw "Template command not found: " + type;
+					}
+					def = tag._default || [];
+					if ( parens && !/\w$/.test(target)) {
+						target += parens;
+						parens = "";
+					}
+					if ( target ) {
+						target = unescape( target ); 
+						args = args ? ("," + unescape( args ) + ")") : (parens ? ")" : "");
+						// Support for target being things like a.toLowerCase();
+						// In that case don't call with template item as 'this' pointer. Just evaluate...
+						expr = parens ? (target.indexOf(".") > -1 ? target + parens : ("(" + target + ").call($item" + args)) : target;
+						exprAutoFnDetect = parens ? expr : "(typeof(" + target + ")==='function'?(" + target + ").call($item):(" + target + "))";
+					} else {
+						exprAutoFnDetect = expr = def.$1 || "null";
+					}
+					fnargs = unescape( fnargs );
+					return "');" + 
+						tag[ slash ? "close" : "open" ]
+							.split( "$notnull_1" ).join( target ? "typeof(" + target + ")!=='undefined' && (" + target + ")!=null" : "true" )
+							.split( "$1a" ).join( exprAutoFnDetect )
+							.split( "$1" ).join( expr )
+							.split( "$2" ).join( fnargs ?
+								fnargs.replace( /\s*([^\(]+)\s*(\((.*?)\))?/g, function( all, name, parens, params ) {
+									params = params ? ("," + params + ")") : (parens ? ")" : "");
+									return params ? ("(" + name + ").call($item" + params) : all;
+								})
+								: (def.$2||"")
+							) +
+						"_.push('";
+				}) +
+			"');}return _;"
+		);
+	}
+	function updateWrapped( options, wrapped ) {
+		// Build the wrapped content. 
+		options._wrap = build( options, true, 
+			// Suport imperative scenario in which options.wrapped can be set to a selector or an HTML string.
+			jQuery.isArray( wrapped ) ? wrapped : [htmlExpr.test( wrapped ) ? wrapped : jQuery( wrapped ).html()]
+		).join("");
+	}
+
+	function unescape( args ) {
+		return args ? args.replace( /\\'/g, "'").replace(/\\\\/g, "\\" ) : null;
+	}
+	function outerHtml( elem ) {
+		var div = document.createElement("div");
+		div.appendChild( elem.cloneNode(true) );
+		return div.innerHTML;
+	}
+
+	// Store template items in jQuery.data(), ensuring a unique tmplItem data data structure for each rendered template instance.
+	function storeTmplItems( content ) {
+		var keySuffix = "_" + cloneIndex, elem, elems, newClonedItems = {}, i, l, m;
+		for ( i = 0, l = content.length; i < l; i++ ) {
+			if ( (elem = content[i]).nodeType !== 1 ) {
+				continue;
+			}
+			elems = elem.getElementsByTagName("*");
+			for ( m = elems.length - 1; m >= 0; m-- ) {
+				processItemKey( elems[m] );
+			}
+			processItemKey( elem );
+		}
+		function processItemKey( el ) {
+			var pntKey, pntNode = el, pntItem, tmplItem, key;
+			// Ensure that each rendered template inserted into the DOM has its own template item,
+			if ( (key = el.getAttribute( tmplItmAtt ))) {
+				while ( pntNode.parentNode && (pntNode = pntNode.parentNode).nodeType === 1 && !(pntKey = pntNode.getAttribute( tmplItmAtt ))) { }
+				if ( pntKey !== key ) {
+					// The next ancestor with a _tmplitem expando is on a different key than this one.
+					// So this is a top-level element within this template item
+					// Set pntNode to the key of the parentNode, or to 0 if pntNode.parentNode is null, or pntNode is a fragment.
+					pntNode = pntNode.parentNode ? (pntNode.nodeType === 11 ? 0 : (pntNode.getAttribute( tmplItmAtt ) || 0)) : 0;
+					if ( !(tmplItem = newTmplItems[key]) ) {
+						// The item is for wrapped content, and was copied from the temporary parent wrappedItem.
+						tmplItem = wrappedItems[key];
+						tmplItem = newTmplItem( tmplItem, newTmplItems[pntNode]||wrappedItems[pntNode], null, true );
+						tmplItem.key = ++itemKey;
+						newTmplItems[itemKey] = tmplItem;
+					}
+					if ( cloneIndex ) {
+						cloneTmplItem( key );
+					}
+				}
+				el.removeAttribute( tmplItmAtt );
+			} else if ( cloneIndex && (tmplItem = jQuery.data( el, "tmplItem" )) ) {
+				// This was a rendered element, cloned during append or appendTo etc.
+				// TmplItem stored in jQuery data has already been cloned in cloneCopyEvent. We must replace it with a fresh cloned tmplItem.
+				cloneTmplItem( tmplItem.key );
+				newTmplItems[tmplItem.key] = tmplItem;
+				pntNode = jQuery.data( el.parentNode, "tmplItem" );
+				pntNode = pntNode ? pntNode.key : 0;
+			}
+			if ( tmplItem ) {
+				pntItem = tmplItem;
+				// Find the template item of the parent element. 
+				// (Using !=, not !==, since pntItem.key is number, and pntNode may be a string)
+				while ( pntItem && pntItem.key != pntNode ) { 
+					// Add this element as a top-level node for this rendered template item, as well as for any
+					// ancestor items between this item and the item of its parent element
+					pntItem.nodes.push( el );
+					pntItem = pntItem.parent;
+				}
+				// Delete content built during rendering - reduce API surface area and memory use, and avoid exposing of stale data after rendering...
+				delete tmplItem._ctnt;
+				delete tmplItem._wrap;
+				// Store template item as jQuery data on the element
+				jQuery.data( el, "tmplItem", tmplItem );
+			}
+			function cloneTmplItem( key ) {
+				key = key + keySuffix;
+				tmplItem = newClonedItems[key] = 
+					(newClonedItems[key] || newTmplItem( tmplItem, newTmplItems[tmplItem.parent.key + keySuffix] || tmplItem.parent, null, true ));
+			}
+		}
+	}
+
+	//---- Helper functions for template item ----
+
+	function tiCalls( content, tmpl, data, options ) {
+		if ( !content ) {
+			return stack.pop();
+		}
+		stack.push({ _: content, tmpl: tmpl, item:this, data: data, options: options });
+	}
+
+	function tiNest( tmpl, data, options ) {
+		// nested template, using {{tmpl}} tag
+		return jQuery.tmpl( jQuery.template( tmpl ), data, options, this );
+	}
+
+	function tiWrap( call, wrapped ) {
+		// nested template, using {{wrap}} tag
+		var options = call.options || {};
+		options.wrapped = wrapped;
+		// Apply the template, which may incorporate wrapped content, 
+		return jQuery.tmpl( jQuery.template( call.tmpl ), call.data, options, call.item );
+	}
+
+	function tiHtml( filter, textOnly ) {
+		var wrapped = this._wrap;
+		return jQuery.map(
+			jQuery( jQuery.isArray( wrapped ) ? wrapped.join("") : wrapped ).filter( filter || "*" ),
+			function(e) {
+				return textOnly ?
+					e.innerText || e.textContent :
+					e.outerHTML || outerHtml(e);
+			});
+	}
+
+	function tiUpdate() {
+		var coll = this.nodes;
+		jQuery.tmpl( null, null, null, this).insertBefore( coll[0] );
+		jQuery( coll ).remove();
+	}
+	
+	$.View.register({
+		suffix : "tmpl",
+		renderer: function( id, text ) {
+			return function(data){
+				return $.tmpl( text, data);
+				//$(text).tmpl(data);//jQuery.render( text, data );
+			}
+		},
+		script: function( id, str ) {
+			var tmpl = $.template( null, str );
+			return "function(data){return ("+tmpl+").call(jQuery, jQuery, {data: data}).join(''); }";
+		}
+	})
+	jQuery.View.ext = ".tmpl"
+})
diff --git a/browserid/static/dialog/jquery/view/tmpl/tmpl_test.js b/browserid/static/dialog/jquery/view/tmpl/tmpl_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..d462b126988c3353e1e33bcdcd4f51bf055cc6b9
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/tmpl/tmpl_test.js
@@ -0,0 +1,11 @@
+steal.plugins('funcunit/qunit','jquery/view/tmpl').then(function(){
+// use the view/qunit.html test to run this test script
+module("jquery/view/tmpl")
+
+test("ifs work", function(){
+	$("#qunit-test-area").html("");
+	
+	$("#qunit-test-area").html("//jquery/view/tmpl/test.tmpl",{});
+	ok($("#qunit-test-area").find('h1').length, "There's an h1")
+})
+});
diff --git a/browserid/static/dialog/jquery/view/view.html b/browserid/static/dialog/jquery/view/view.html
new file mode 100644
index 0000000000000000000000000000000000000000..0332f33ca161cafc2c014ac1df945a6180d09f9b
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/view.html
@@ -0,0 +1,80 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>view</title>
+
+		<style>
+			body{
+				font-family: verdana;
+			}
+			pre {
+				font-family: "Courier New", Courier, monospace;
+			}
+			.out {
+				border: dashed 1px blue;
+			}
+			.temp{
+				border: dashed 1px red;
+			}
+			h2 {
+				font-size: 1em;
+				font-weight: bold;
+				color: green;
+			}
+			h3 {font-size: 0.95em;}
+		</style>
+	</head>
+	<body>
+		<h2>JAML</h2>
+		<pre><code class='javascript'>$("#jaml").html("template.jaml",{message: "Hello World"})</code></pre>
+		<pre class='temp' id='temp'><code>function(data) {
+  h3(data.message);
+}</code></pre>
+		<div id='jaml' class='out'></div>
+		<h2>EJS</h2>
+		<pre><code class='javascript'>$("#ejs").html("template.ejs",{message: "Hello World"})</code></pre>
+		<pre class='temp'>&lt;h3><%= message %>&lt;/h3></pre>
+		<div id='ejs' class='out'></div>
+		<h2>MICRO</h2>
+		<pre><code class='javascript'>$("#micro").html("template.micro",{message: "Hello World"})</code></pre>
+		<pre class='temp'>&lt;h3>{%= message %}&lt;/h3></pre>
+		<div id='micro'  class='out'></div>
+		<h2>TMPL</h2>
+		<pre><code class='javascript'>$("#tmpl").html("template.tmpl",{message: "Hello World"})</code></pre>
+		<pre class='temp'>&lt;h3>{%= message %}&lt;/h3></pre>
+		<div id='tmpl'  class='out'></div>
+		<script type='text/javascript' src='../../steal/steal.js'>   
+        </script>
+<script type='text/javascript'>
+steal.plugins('jquery/view/jaml',
+	'jquery/view/micro',
+	'jquery/view/ejs',
+	'jquery/view/tmpl')
+	.then(function(){
+		
+	$.each(["micro","ejs","jaml",'tmpl'], function(){
+		$("#"+this).html("test/qunit/template."+this,{"message" :"Hello World"})
+	})
+	
+})	.then("//jmvcdoc/resources/highlight",
+		'//jmvcdoc/resources/languages/javascript',
+		'//jmvcdoc/resources/languages/www',
+function(){
+	 var names = []
+	 $("code").each(function(){
+			names.push( this.parentNode.className)
+			
+		})
+	 hljs.initHighlighting();
+	$(function(){
+		$.each($("code"),function(i){
+			this.parentNode.className = names[i];
+		})
+	})
+		
+	
+}).start();
+		</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/jquery/view/view.js b/browserid/static/dialog/jquery/view/view.js
new file mode 100644
index 0000000000000000000000000000000000000000..8a0d071874e90c48c499ec9e6b17fa7f13cb115c
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/view.js
@@ -0,0 +1,546 @@
+steal.plugins("jquery").then(function( $ ) {
+
+	// converts to an ok dom id
+	var toId = function( src ) {
+		return src.replace(/^\/\//, "").replace(/[\/\.]/g, "_");
+	},
+		// used for hookup ids
+		id = 1;
+
+	/**
+	 * @class jQuery.View
+	 * @tag core
+	 * @plugin jquery/view
+	 * @test jquery/view/qunit.html
+	 * @download dist/jquery.view.js
+	 * 
+	 * View provides a uniform interface for using templates with 
+	 * jQuery. When template engines [jQuery.View.register register] 
+	 * themselves, you are able to:
+	 * 
+	 *  - Use views with jQuery extensions [jQuery.fn.after after], [jQuery.fn.append append],
+	 *   [jQuery.fn.before before], [jQuery.fn.html html], [jQuery.fn.prepend prepend],
+	 *      [jQuery.fn.replace replace], [jQuery.fn.replaceWith replaceWith], [jQuery.fn.text text].
+	 *  - Template loading from html elements and external files.
+	 *  - Synchronous and asynchronous template loading.
+	 *  - Template caching.
+	 *  - Bundling of processed templates in production builds.
+	 *  - Hookup jquery plugins directly in the template.
+	 *  
+	 * ## Use
+	 * 
+	 * 
+	 * When using views, you're almost always wanting to insert the results 
+	 * of a rendered template into the page. jQuery.View overwrites the 
+	 * jQuery modifiers so using a view is as easy as: 
+	 * 
+	 *     $("#foo").html('mytemplate.ejs',{message: 'hello world'})
+	 *
+	 * This code:
+	 * 
+	 *  - Loads the template a 'mytemplate.ejs'. It might look like:
+	 *    <pre><code>&lt;h2>&lt;%= message %>&lt;/h2></pre></code>
+	 *  
+	 *  - Renders it with {message: 'hello world'}, resulting in:
+	 *    <pre><code>&lt;div id='foo'>"&lt;h2>hello world&lt;/h2>&lt;/div></pre></code>
+	 *  
+	 *  - Inserts the result into the foo element. Foo might look like:
+	 *    <pre><code>&lt;div id='foo'>&lt;h2>hello world&lt;/h2>&lt;/div></pre></code>
+	 * 
+	 * ## jQuery Modifiers
+	 * 
+	 * You can use a template with the following jQuery modifiers:
+	 * 
+	 * <table>
+	 * <tr><td>[jQuery.fn.after after]</td><td> <code>$('#bar').after('temp.jaml',{});</code></td></tr>
+	 * <tr><td>[jQuery.fn.after append] </td><td>  <code>$('#bar').append('temp.jaml',{});</code></td></tr>
+	 * <tr><td>[jQuery.fn.after before] </td><td> <code>$('#bar').before('temp.jaml',{});</code></td></tr>
+	 * <tr><td>[jQuery.fn.after html] </td><td> <code>$('#bar').html('temp.jaml',{});</code></td></tr>
+	 * <tr><td>[jQuery.fn.after prepend] </td><td> <code>$('#bar').prepend('temp.jaml',{});</code></td></tr>
+	 * <tr><td>[jQuery.fn.after replace] </td><td> <code>$('#bar').replace('temp.jaml',{});</code></td></tr>
+	 * <tr><td>[jQuery.fn.after replaceWith] </td><td> <code>$('#bar').replaceWidth('temp.jaml',{});</code></td></tr>
+	 * <tr><td>[jQuery.fn.after text] </td><td> <code>$('#bar').text('temp.jaml',{});</code></td></tr>
+	 * </table>
+	 * 
+	 * You always have to pass a string and an object (or function) for the jQuery modifier 
+	 * to user a template.
+	 * 
+	 * ## Template Locations
+	 * 
+	 * View can load from script tags or from files. 
+	 * 
+	 * ## From Script Tags
+	 * 
+	 * To load from a script tag, create a script tag with your template and an id like: 
+	 * 
+	 * <pre><code>&lt;script type='text/ejs' id='recipes'>
+	 * &lt;% for(var i=0; i &lt; recipes.length; i++){ %>
+	 *   &lt;li>&lt;%=recipes[i].name %>&lt;/li>
+	 * &lt;%} %>
+	 * &lt;/script></code></pre>
+	 * 
+	 * Render with this template like: 
+	 * 
+	 * @codestart
+	 * $("#foo").html('recipes',recipeData)
+	 * @codeend
+	 * 
+	 * Notice we passed the id of the element we want to render.
+	 * 
+	 * ## From File
+	 * 
+	 * You can pass the path of a template file location like:
+	 * 
+	 *     $("#foo").html('templates/recipes.ejs',recipeData)
+	 * 
+	 * However, you typically want to make the template work from whatever page they 
+	 * are called from.  To do this, use // to look up templates from JMVC root:
+	 * 
+	 *     $("#foo").html('//app/views/recipes.ejs',recipeData)
+	 *     
+	 * Finally, the [jQuery.Controller.prototype.view controller/view] plugin can make looking
+	 * up a thread (and adding helpers) even easier:
+	 * 
+	 *     $("#foo").html( this.view('recipes', recipeData) )
+	 * 
+	 * ## Packaging Templates
+	 * 
+	 * If you're making heavy use of templates, you want to organize 
+	 * them in files so they can be reused between pages and applications.
+	 * 
+	 * But, this organization would come at a high price 
+	 * if the browser has to 
+	 * retrieve each template individually. The additional 
+	 * HTTP requests would slow down your app. 
+	 * 
+	 * Fortunately, [steal.static.views steal.views] can build templates 
+	 * into your production files. You just have to point to the view file like: 
+	 * 
+	 *     steal.views('path/to/the/view.ejs');
+     *
+	 * ## Asynchronous
+	 * 
+	 * By default, retrieving requests is done synchronously. This is 
+	 * fine because StealJS packages view templates with your JS download. 
+	 * 
+	 * However, some people might not be using StealJS or want to delay loading 
+	 * templates until necessary. If you have the need, you can 
+	 * provide a callback paramter like: 
+	 * 
+	 *     $("#foo").html('recipes',recipeData, function(result){
+	 *       this.fadeIn()
+	 *     });
+	 * 
+	 * The callback function will be called with the result of the 
+	 * rendered template and 'this' will be set to the original jQuery object.
+	 * 
+	 * ## Just Render Templates
+	 * 
+	 * Sometimes, you just want to get the result of a rendered 
+	 * template without inserting it, you can do this with $.View: 
+	 * 
+	 *     var out = $.View('path/to/template.jaml',{});
+	 *     
+     * ## Preloading Templates
+	 * 
+	 * You can preload templates asynchronously like:
+	 * 
+	 *     $.View('path/to/template.jaml',{}, function(){});
+	 * 
+	 * ## Supported Template Engines
+	 * 
+	 * JavaScriptMVC comes with the following template languages:
+	 * 
+	 *   - EmbeddedJS
+	 *     <pre><code>&lt;h2>&lt;%= message %>&lt;/h2></code></pre>
+	 *     
+	 *   - JAML
+	 *     <pre><code>h2(data.message);</code></pre>
+	 *     
+	 *   - Micro
+	 *     <pre><code>&lt;h2>{%= message %}&lt;/h2></code></pre>
+	 *     
+	 *   - jQuery.Tmpl
+	 *     <pre><code>&lt;h2>${message}&lt;/h2></code></pre>
+
+	 * 
+	 * The popular <a href='http://awardwinningfjords.com/2010/08/09/mustache-for-javascriptmvc-3.html'>Mustache</a> 
+	 * template engine is supported in a 2nd party plugin.
+	 * 
+	 * ## Using other Template Engines
+	 * 
+	 * It's easy to integrate your favorite template into $.View and Steal.  Read 
+	 * how in [jQuery.View.register].
+	 * 
+	 * @constructor
+	 * 
+	 * Looks up a template, processes it, caches it, then renders the template
+	 * with data and optional helpers.
+	 * 
+	 * With [stealjs StealJS], views are typically bundled in the production build.
+	 * This makes it ok to use views synchronously like:
+	 * 
+	 * @codestart
+	 * $.View("//myplugin/views/init.ejs",{message: "Hello World"})
+	 * @codeend
+	 * 
+	 * If you aren't using StealJS, it's best to use views asynchronously like:
+	 * 
+	 * @codestart
+	 * $.View("//myplugin/views/init.ejs",
+	 *        {message: "Hello World"}, function(result){
+	 *   // do something with result
+	 * })
+	 * @codeend
+	 * 
+	 * @param {String} view The url or id of an element to use as the template's source.
+	 * @param {Object} data The data to be passed to the view.
+	 * @param {Object} [helpers] Optional helper functions the view might use. Not all
+	 * templates support helpers.
+	 * @param {Object} [callback] Optional callback function.  If present, the template is 
+	 * retrieved asynchronously.  This is a good idea if you aren't compressing the templates
+	 * into your view.
+	 * @return {String} The rendered result of the view.
+	 */
+
+	var $view, render, checkText, get;
+
+	$view = $.View = function( view, data, helpers, callback ) {
+		var suffix = view.match(/\.[\w\d]+$/),
+			type, el, id, renderer, url = view;
+                // if we have an inline template, derive the suffix from the 'text/???' part
+                // this only supports '<script></script>' tags
+                if ( el = document.getElementById(view)) {
+                  suffix = el.type.match(/\/[\d\w]+$/)[0].replace(/^\//, '.');
+                }
+		if ( typeof helpers === 'function' ) {
+			callback = helpers;
+			helpers = undefined;
+		}
+		//if there is no suffix, add one
+		if (!suffix ) {
+			suffix = $.View.ext;
+			url = url + $.View.ext;
+		}
+
+		//convert to a unique and valid id
+		id = toId(url);
+
+		//if a absolute path, use steal to get it
+		if ( url.match(/^\/\//) ) {
+			url = steal.root.join(url.substr(2)); //can steal be removed?
+		}
+
+		//get the template engine
+		type = $.View.types[suffix];
+
+		//get the renderer function
+		renderer =
+		$.View.cached[id] ? // is it cached?
+		$.View.cached[id] : // use the cached version
+		((el = document.getElementById(view)) ? //is it in the document?
+		type.renderer(id, el.innerHTML) : //use the innerHTML of the elemnt
+		get(type, id, url, data, helpers, callback) //do an ajax request for it
+		);
+		// we won't always get a renderer (if async ajax)
+		return renderer && render(renderer, type, id, data, helpers, callback);
+	};
+	// caches the template, renders the content, and calls back if it should
+	render = function( renderer, type, id, data, helpers, callback ) {
+		var res, stub;
+		if ( $.View.cache ) {
+			$.View.cached[id] = renderer;
+		}
+		res = renderer.call(type, data, helpers);
+		stub = callback && callback(res);
+		return res;
+	};
+	// makes sure there's a template
+	checkText = function( text, url ) {
+		if (!text.match(/[^\s]/) ) {
+			throw "$.View ERROR: There is no template or an empty template at " + url;
+		}
+	};
+	// gets a template, if there's a callback, renders and calls back its;ef
+	get = function( type, id, url, data, helpers, callback ) {
+		if ( callback ) {
+			$.ajax({
+				url: url,
+				dataType: "text",
+				error: function() {
+					checkText("", url);
+				},
+				success: function( text ) {
+					checkText(text, url);
+					render(type.renderer(id, text), type, id, data, helpers, callback);
+				}
+			});
+		} else {
+			var text = $.ajax({
+				async: false,
+				url: url,
+				dataType: "text",
+				error: function() {
+					checkText("", url);
+				}
+			}).responseText;
+			checkText(text, url);
+			return type.renderer(id, text);
+		}
+
+	};
+
+
+	$.extend($.View, {
+		/**
+		 * @attribute hookups
+		 * @hide
+		 * A list of pending 'hookups'
+		 */
+		hookups: {},
+		/**
+		 * @function hookup
+		 * Registers a hookup function to be called back after the html is put on the page
+		 * @param {Function} cb a callback function to be called with the element
+		 * @param {Number} the hookup number
+		 */
+		hookup: function( cb ) {
+			var myid = ++id;
+			$view.hookups[myid] = cb;
+			return myid;
+		},
+		/**
+		 * @attribute cached
+		 * @hide
+		 * Cached are put in this object
+		 */
+		cached: {},
+		/**
+		 * @attribute cache
+		 * Should the views be cached or reloaded from the server. Defaults to true.
+		 */
+		cache: true,
+		/**
+		 * @function register
+		 * Registers a template engine to be used with 
+		 * view helpers and compression.  
+		 * 
+		 * ## Example
+		 * 
+		 * @codestart
+		 * $.View.register({
+		 * 	suffix : "tmpl",
+		 * 	renderer: function( id, text ) {
+		 * 		return function(data){
+		 * 			return jQuery.render( text, data );
+		 * 		}
+		 * 	},
+		 * 	script: function( id, text ) {
+		 * 		var tmpl = $.tmpl(text).toString();
+		 * 		return "function(data){return ("+
+		 * 		  	tmpl+
+		 * 			").call(jQuery, jQuery, data); }";
+		 * 	}
+		 * })
+		 * @codeend
+		 * Here's what each property does:
+		 * 
+ 		 *    * suffix - files that use this suffix will be processed by this template engine
+ 		 *    * renderer - returns a function that will render the template provided by text
+ 		 *    * script - returns a string form of the processed template function.
+		 * 
+		 * @param {Object} info a object of method and properties 
+		 * 
+		 * that enable template integration:
+		 * <ul>
+		 *   <li>suffix - the view extension.  EX: 'ejs'</li>
+		 *   <li>script(id, src) - a function that returns a string that when evaluated returns a function that can be 
+		 *    used as the render (i.e. have func.call(data, data, helpers) called on it).</li>
+		 *   <li>renderer(id, text) - a function that takes the id of the template and the text of the template and
+		 *    returns a render function.</li>
+		 * </ul>
+		 */
+		register: function( info ) {
+			this.types["." + info.suffix] = info;
+		},
+		types: {},
+		/**
+		 * @attribute ext
+		 * The default suffix to use if none is provided in the view's url.  
+		 * This is set to .ejs by default.
+		 */
+		ext: ".ejs",
+		/**
+		 * Returns the text that 
+		 * @hide 
+		 * @param {Object} type
+		 * @param {Object} id
+		 * @param {Object} src
+		 */
+		registerScript: function( type, id, src ) {
+			return "$.View.preload('" + id + "'," + $.View.types["." + type].script(id, src) + ");";
+		},
+		/**
+		 * @hide
+		 * Called by a production script to pre-load a renderer function
+		 * into the view cache.
+		 * @param {String} id
+		 * @param {Function} renderer
+		 */
+		preload: function( id, renderer ) {
+			$.View.cached[id] = function( data, helpers ) {
+				return renderer.call(data, data, helpers);
+			};
+		}
+
+	});
+
+
+	//---- ADD jQUERY HELPERS -----
+	//converts jquery functions to use views	
+	var convert, modify, isTemplate, getCallback, hookupView, funcs;
+
+	convert = function( func_name ) {
+		var old = $.fn[func_name];
+
+		$.fn[func_name] = function() {
+			var args = $.makeArray(arguments),
+				callbackNum, callback, self = this;
+
+			//check if a template
+			if ( isTemplate(args) ) {
+
+				// if we should operate async
+				if ((callbackNum = getCallback(args))) {
+					callback = args[callbackNum];
+					args[callbackNum] = function( result ) {
+						modify.call(self, [result], old);
+						callback.call(self, result);
+					};
+					$.View.apply($.View, args);
+					return this;
+				}
+
+				//otherwise do the template now
+				args = [$.View.apply($.View, args)];
+			}
+
+			return modify.call(this, args, old);
+		};
+	};
+	// modifies the html of the element
+	modify = function( args, old ) {
+		var res, stub, hooks;
+
+		//check if there are new hookups
+		for ( var hasHookups in jQuery.View.hookups ) {
+			break;
+		}
+
+		//if there are hookups, get jQuery object
+		if ( hasHookups ) {
+			hooks = $.View.hookups;
+			$.View.hookups = {};
+			args[0] = $(args[0]);
+		}
+		res = old.apply(this, args);
+
+		//now hookup hookups
+		if ( hasHookups ) {
+			hookupView(args[0], hooks);
+		}
+		return res;
+	};
+
+	// returns true or false if the args indicate a template is being used
+	isTemplate = function( args ) {
+		var secArgType = typeof args[1];
+
+		return typeof args[0] == "string" && (secArgType == 'object' || secArgType == 'function') && !args[1].nodeType && !args[1].jquery;
+	};
+
+	//returns the callback if there is one (for async view use)
+	getCallback = function( args ) {
+		return typeof args[3] === 'function' ? 3 : typeof args[2] === 'function' && 2;
+	};
+
+	hookupView = function( els , hooks) {
+		//remove all hookups
+		var hookupEls, 
+			len, i = 0,
+			id, func;
+		els = els.filter(function(){
+			return this.nodeType != 3; //filter out text nodes
+		})
+		hookupEls = els.add("[data-view-id]", els);
+		len = hookupEls.length;
+		for (; i < len; i++ ) {
+			if ( hookupEls[i].getAttribute && (id = hookupEls[i].getAttribute('data-view-id')) && (func = hooks[id]) ) {
+				func(hookupEls[i], id);
+				delete hooks[id];
+				hookupEls[i].removeAttribute('data-view-id');
+			}
+		}
+		//copy remaining hooks back
+		$.extend($.View.hookups, hooks);
+	};
+
+	/**
+	 *  @add jQuery.fn
+	 */
+	funcs = [
+	/**
+	 *  @function prepend
+	 *  @parent jQuery.View
+	 *  abc
+	 */
+	"prepend",
+	/**
+	 *  @function append
+	 *  @parent jQuery.View
+	 *  abc
+	 */
+	"append",
+	/**
+	 *  @function after
+	 *  @parent jQuery.View
+	 *  abc
+	 */
+	"after",
+	/**
+	 *  @function before
+	 *  @parent jQuery.View
+	 *  abc
+	 */
+	"before",
+	/**
+	 *  @function replace
+	 *  @parent jQuery.View
+	 *  abc
+	 */
+	"replace",
+	/**
+	 *  @function text
+	 *  @parent jQuery.View
+	 *  abc
+	 */
+	"text",
+	/**
+	 *  @function html
+	 *  @parent jQuery.View
+	 *  abc
+	 */
+	"html",
+	/**
+	 *  @function replaceWith
+	 *  @parent jQuery.View
+	 *  abc
+	 */
+	"replaceWith"];
+
+	//go through helper funcs and convert
+	for ( var i = 0; i < funcs.length; i++ ) {
+		convert(funcs[i]);
+	}
+
+});
diff --git a/browserid/static/dialog/jquery/view/vieww.html b/browserid/static/dialog/jquery/view/vieww.html
new file mode 100644
index 0000000000000000000000000000000000000000..390461c946756d7282fa3efe41d57513d9dc3b1d
--- /dev/null
+++ b/browserid/static/dialog/jquery/view/vieww.html
@@ -0,0 +1,294 @@
+<style>
+    body  {font-family: verdana;}
+</style>
+<p>
+	Everyone loves client side templates. 
+	They are a great way to create html 
+	which is something JavaScript apps do all the time.
+</p> 
+
+<p>In February, a jQuery templating system was 
+<a href='http://github.com/nje/jquery/wiki/jquery-templates-proposal'>proposed<a/> and resulted in a tremendous amount of 
+<a href='http://forum.jquery.com/topic/jquery-templates-proposal'>discussion</a>, followed by an 
+official templating engine for jQuery - <a href='http://www.borismoore.com/2010/10/jquery-templates-is-now-official-jquery.html'>jquery-tmpl</a>.
+</p> 
+
+<p>
+Although jquery-tmpl is a solid templating engine, 
+the discussion highlighted three 
+extremely important facts about developers and client side templates:
+</p> 
+
+<h4>
+Fact 1: Everyone has their favorite templating engine
+</h4> 
+
+<p>
+There's a whole slew of templating languages people like:
+</p> 
+
+<ul>
+	<li><a href='http://EmbeddedJS.com'>EmbeddedJS</a></li>
+	<li><a href='http://code.google.com/p/trimpath/wiki/JavaScriptTemplates'>TrimJunction's JavaScript Templates</a></li>
+	<li><a href='http://github.com/edspencer/jaml'>Jaml</a></li>
+	<li><a href='http://github.com/jquery/jquery-tmpl'>jquery-tmpl</a></li>
+	<li><a href='http://github.com/janl/mustache.js/'>mustache</a></li>
+	<li><a href='http://ejohn.org/blog/javascript-micro-templating/'>micro</a></li>
+	<li><a href='http://github.com/raid-ox/chain.js/wiki'>chain.js</a></li>  
+</ul> 
+
+<p>
+Most of these template engines have distinct advantages and dissadvantages.
+It's impossible to expect a single template engine to meet everyone's needs.
+</p> 
+<h4>Fact 2: Most templating engines provide the exact same features</h4>
+<p>
+	I've yet to encounter a template that does't provide:
+</p>
+<ul>
+	<li>A way of loading templates (typically from HTMLElement or files)</li>
+	<li>A way of caching processed templates.</li>
+	<li>An interface to render the template with arbitrary data.</li>
+</ul>
+<h4>Fact 3: Very few people are familiar with 
+the complexities of using templates</h4>
+<p>There's more than just syntax and magic tag preference that goes
+into a templating system.  Consider:</p>
+<ul>
+	<li>How can I build and share plugins that uses templates?</li>
+	<li>How can I share templates across pages / apps?</li>
+	<li>How can I organize template files?</li>
+</ul>
+<h2>jQuery.View</h2>
+
+<p>
+<a href='http://v3.javascriptmvc.com/index.html#&who=jQuery.View'>jQuery.View</a> 
+is a templating interface that takes 
+care of the complexities of using templates, 
+while being completely template agnostic.  
+</p> 
+<p>This means that you can use any templating language in the exact
+same way and get all the additional features that jQuery.View provides.</p>
+
+<h2>Features</h2>
+<ul>
+	<li>Convenient syntax.</li>
+	<li>Template loading from html elements and <b>external files</b>.</li>
+	<li>Synchronous and asynchronous template loading.</li>
+	<li>Template preloading.</li>
+	<li>Caching of processed templates.</li>
+	<li>Bundling of processed templates in production builds.</li>
+</ul>
+<h2>Downloads</h2>
+<ul>
+	<li>jquery.view.js</li>
+	<li>jquery.view.ejs.js</li>
+	<li>jquery.view.jaml.js</li>
+	<li>jquery.view.micro.js</li>
+	<li>jquery.view.tmpl.js</li>
+</ul>
+<h2>Use</h2> 
+
+<p>
+When using views, you're almost always wanting to insert the results of a rendered template into the page.  jQuery.View overwrites the jQuery modifiers so using a view is as easy as:
+</p> 
+
+<pre><code>$("#foo").html('mytemplate.ejs',{message: 'hello world'})</code>
+</pre> 
+
+<p>
+This code:</p> 
+<ol>
+	<li>
+		<p>Loads the template a 'mytemplate.ejs'.  It might look like:</p>
+		<pre><code>&lt;h2>&lt;%= message %>&lt;/h2></code></pre>
+	</li>
+	<li>
+		<p>Renders it with {message: 'hello world'}, resulting in:</p>
+		<pre><code>"&lt;h2>hello world&lt;/h2>"</code></pre>
+	</li>
+	<li>
+		<p>Inserts the result into the foo element.  Foo might look like:</p>
+		<pre><code>&lt;div id='foo'>&lt;h2>hello world&lt;/h2>&lt;/div></code></pre>
+	</li>
+</ol>
+
+
+
+<h3>jQuery Modifiers</h3>
+<p>
+You can use a template with the following jQuery modifier methods:
+</p> 
+<table>
+	<tr><td><a href='http://api.jquery.com/after/'>after</a> </td><td> <code>$('#bar').after('temp.jaml',{});</code></td></tr>
+	<tr><td><a href='http://api.jquery.com/append/'>append</a> </td><td>  <code>$('#bar').append('temp.jaml',{});</code></td></tr>
+	<tr><td><a href='http://api.jquery.com/before/'>before</a> </td><td> <code>$('#bar').before('temp.jaml',{});</code></td></tr>
+	<tr><td><a href='http://api.jquery.com/html/'>html</a> </td><td> <code>$('#bar').html('temp.jaml',{});</code></td></tr>
+	<tr><td><a href='http://api.jquery.com/prepend/'>prepend</a> </td><td> <code>$('#bar').prepend('temp.jaml',{});</code></td></tr>
+	<tr><td><a href='http://api.jquery.com/replace/'>replace</a> </td><td> <code>$('#bar').replace('temp.jaml',{});</code></td></tr>
+	<tr><td><a href='http://api.jquery.com/replaceWidth/'>replaceWidth</a> </td><td> <code>$('#bar').replaceWidth('temp.jaml',{});</code></td></tr>
+	<tr><td><a href='http://api.jquery.com/text/'>text</a> </td><td> <code>$('#bar').text('temp.jaml',{});</code></td></tr>
+</table>
+<h3>
+Template Locations
+</h3> 
+
+<p>
+View can load from script tags or from files.  To load from a script tag, create a script tag with your template and an id like:
+</p> 
+
+<p>
+<pre><code>&lt;script type='text/ejs' id='recipes'>
+&lt;% for(var i=0; i &lt; recipes.length; i++){ %>
+  &lt;li>&lt;%=recipes[i].name %>&lt;/li>
+&lt;%} %>
+&lt;/script></code></pre>
+</p> 
+
+<p>
+Render with this template like:
+</p> 
+<pre><code>$("#foo").html('recipes',recipeData)</code></pre>
+<p>Notice we passed the id of the element we want to render.</p>
+
+<h3>Packaging Templates</h3> 
+<p>If you're making heavy use of templates, 
+you want to organize them in files so they can be reused between pages and
+applications.</p>
+<p>But, this organization would come at a high price if the browser has 
+to retrieve each template individually.  The additional HTTP requests would slow 
+down your app.
+</p>
+
+<p>
+Fortunately, <a href='htttp://stealjs.com'>StealJS</a> can build templates 
+into your production files.  
+You just have to point to the view file like:
+</p> 
+
+<pre><code>steal.views('path/to/the/view.ejs');
+</pre></code>
+<p>This will pre-process the view and insert it into a compressed single file with
+your other JS code.</p>
+<p><i>Note:  Steal 1.1 will even let you <b>not</b> load the view engine in 
+production if all your templates are packaged.</i></p>
+<h3>
+Asynchronous
+</h3> 
+
+<p>
+By default, retrieving requests is done synchronously.  
+This is fine because <a href='http://stealjs.com/'>StealJS</a> 
+ packages view templates with your JS download.  </p>
+<p>
+However, some people might not be using StealJS or 
+want to delay loading templates until necessary.  
+If you have the need, you can provide a callback paramter like:
+</p> 
+
+
+<pre><code>$("#foo").html('recipes',recipeData, function(result){
+   this.fadeIn()
+});</code></pre>
+<p>The callback function will be called with the result of the
+rendered template and 'this' will be set to the original jQuery
+object.</p>
+
+<h3>
+Just Render Templates
+</h3> 
+
+<p>
+Sometimes, you just want to get the result of a rendered template without inserting it, you can do this with $.View:
+</p> 
+
+<pre><code>var out = $.View('path/to/template.jaml',{});
+</pre></code>
+
+<h3>Preloading Templates</h3> 
+
+<p>
+You can preload templates asynchronously like:
+</p> 
+
+<pre><code>$.View('path/to/template.jaml',{}, function(){});</pre></code>
+<p>
+When it comes time to use them in your app, they will be ready for the user.
+</p> 
+<h3>
+Supported Templates
+</h3> 
+<p>
+JavaScriptMVC comes with the following templates:
+</p> 
+<ul>
+	<li><p>EmbeddedJS</p>
+		<pre><code>&lt;h2>&lt;%= message %>&lt;/h2></code></pre></li>
+	<li><p>JAML</p>
+		<pre><code>h2(data.message);</code></pre></li>
+	<li><p>Micro</p>
+		<pre><code>&lt;h2>{%= message %}&lt;/h2></code></pre></li>
+	<li><p>jQuery.Tmpl</p>
+		<pre><code>&lt;h2>${message}&lt;/h2></code></pre></li>
+</ul>
+<p><a href='http://awardwinningfjords.com/2010/08/09/mustache-for-javascriptmvc-3.html'>Mustache</a> is supported in a 2nd party plugin.
+
+</p>
+
+<h3>
+Using Other Templates:
+</h3> 
+
+<p>
+Integrating into $.View (and StealJS's build process) is easy, you just have to register your script like:
+</p> 
+
+<pre><code>$.View.register({
+	suffix : "tmpl",
+	renderer: function( id, text ) {
+		return function(data){
+			return jQuery.render( text, data );
+		}
+	},
+	script: function( id, text ) {
+		var tmpl = $.tmpl(text).toString();
+		return "function(data){return ("+
+			tmpl+
+			").call(jQuery, jQuery, data); }";
+	}
+})</pre></code>
+
+<p>
+Here's what each property does:</p>
+<ul>
+	<li><code>suffix</code> - files that use this suffix will be processed by this template engine</li>
+	<li><code>renderer</code> - returns a function that will render the template provided by text</li>
+	<li><code>script</code> - returns a string form of the processed template function.</li>
+</ul>
+
+<h2>Conclusion</h2>
+<p>
+	Templates are great, but there's a lot of extra work that goes into 
+	making a template engine useful.
+	But, almost all of that extra work can be abstracted and reused.
+</p>
+<p> This is exactly what jQuery.View is!  It's a tool so future template 
+engines don't have to worry about loading, caching, and bundling templates.</p>
+<p>Even better, as it is a uniform template API, it enables plugin authors
+to write widgets that accept arbitrary template types.</p>
+
+<p>I personally feel like this would be a good canidate for jQuery an
+official jQuery plugin of its own.  Imagine customizing the layout of a 
+widget by passing it a template:
+   
+</p>
+
+<pre><code>$("#upcoming").srchr_search_result({
+	modelType : Srchr.Models.Upcoming,
+	resultView : "//srchr/views/upcoming.ejs"
+});</code></pre>
+<p>P.S. This is actual code from our
+<a href='http://github.com/jupiterjs/srchr'>JavaScriptMVC version of Srchr</a>.
+Read about it <a href='http://jupiterjs.com/news/organizing-a-jquery-application'>here</a>.
+We customize search results panels with a Model used to retrieve
+searches and a view to output the results.</p>
\ No newline at end of file
diff --git a/browserid/static/dialog/main.js b/browserid/static/dialog/main.js
index 0f4fd9554604fa0080b2f8ccb19279a1bede71cd..e17f0ce41c3b9bd7410781ae12e8f6b2ea17a71c 100644
--- a/browserid/static/dialog/main.js
+++ b/browserid/static/dialog/main.js
@@ -19,35 +19,6 @@
     return undefined;
   }
 
-  function showDialog(name, args) {
-    // there must be a better way to do this
-    $('#main').show();
-    $('#main').html(DIALOGS[name].render(args).el.innerHTML);
-  }
-
-  var DIALOGS = {};
-  
-  var AuthenticateView = Backbone.View.extend({
-      tagName: 'div',
-      className: 'dialog',
-      render : function() {
-        $(this.el).html(ich.authenticate_dialog());
-        return this;
-      }
-    });
-
-  DIALOGS['authenticate'] = new AuthenticateView();
-
-  var SigninView = Backbone.View.extend({
-      className: 'dialog',
-      render: function(args) {
-        $(this.el).html(ich.sign_in_dialog(args));
-        return this;
-      }
-    });
-
-  DIALOGS['signin'] = new SigninView();
-
   function checkAuthStatus(authcb, notauthcb, onsuccess, onerror) {
     runWaitingDialog(
       "Communicating with server",
@@ -178,8 +149,6 @@
   }
 
   function runSignInDialog(onsuccess, onerror) {
-    return showDialog('signin', {sitename: remoteOrigin});
-
     $(".dialog").hide();
 
     $("#back").hide();
diff --git a/browserid/static/dialog/steal/.gitignore b/browserid/static/dialog/steal/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..0514b94f50988587f20ec82e765ef6e0853c7ef0
--- /dev/null
+++ b/browserid/static/dialog/steal/.gitignore
@@ -0,0 +1,2 @@
+.tmp*
+dist
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/README b/browserid/static/dialog/steal/README
new file mode 100644
index 0000000000000000000000000000000000000000..2c92566279ce0f537c8b9b1cebea76c55abfca88
--- /dev/null
+++ b/browserid/static/dialog/steal/README
@@ -0,0 +1,29 @@
+TOC:
+  A.  How to get (and contribute) to JMVC
+
+
+A.  How to get (and contribute) JMVC
+
+  1.  Start a new project in git.
+  
+  2.  Fork ....
+           http://github.com/jupiterjs/steal     and 
+           http://github.com/jupiterjs/jquerymx  and 
+           http://github.com/jupiterjs/funcunit  and 
+           http://github.com/jupiterjs/documentjs
+  
+  3.  Add steal, javascriptmvc, funcunit, and documentjs as submodules of your project...
+           git submodule add git@github.com:_YOU_/steal.git steal
+           git submodule add git@github.com:_YOU_/jquerymx.git jquery
+           git submodule add git@github.com:_YOU_/funcunit.git funcunit
+           git submodule add git@github.com:_YOU_/documentjs.git documentjs
+           
+      * Notice javascriptmvc is under the jquery folder
+  
+  4.  Learn a little more about submodules ...
+           http://johnleach.co.uk/words/archives/2008/10/12/323/git-submodules-in-n-easy-steps
+           
+  5.  Make changes in steal or jmvc, and push them back to your fork.
+  
+  6.  Make a pull request to your fork.
+ 
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/apps/apps.js b/browserid/static/dialog/steal/build/apps/apps.js
new file mode 100644
index 0000000000000000000000000000000000000000..90acf8064208735322c321fa0e33ae62eb048061
--- /dev/null
+++ b/browserid/static/dialog/steal/build/apps/apps.js
@@ -0,0 +1,204 @@
+steal(function( steal ) {
+
+	// recursively goes through steals and their dependencies.
+	var addDependencies = function( steel, files, app ) {
+		//add self to files
+		if (!files[steel.path] ) {
+
+			var source = readFile(steel.path);
+			if ( steel.type && steal.build.types[steel.type] ) {
+
+				source = steal.build.types[steel.type]({
+					text: source,
+					id: steal.cleanId(steel.path)
+				});
+				print(" converting " + steel.path + " ");
+			} else {
+				print(" compressing " + steel.path + " ");
+
+			}
+			source = steal.build.builders.scripts.clean(source);
+			source = "" + steal.build.compressor(source, true);
+			//need to convert to other types.
+
+			files[steel.path] = {
+				path: steel.path,
+				apps: [],
+				dependencies: {},
+				size: source.length,
+				packaged: false,
+				source: source
+			}
+		}
+
+		var data = files[steel.path];
+
+		data.apps.push(app);
+		for ( var d = 0; d < steel.dependencies.length; d++ ) {
+			var dependency = steel.dependencies[d];
+			if ( dependency.dependencies ) { //this dependency was actually loaded
+				data.dependencies[dependency.path] = addDependencies(dependency, files, app);
+			}
+		}
+		return data;
+	},
+		/**
+		 * Adds an order to a directed acyclic graph 
+		 * @param {Object} appFiles
+		 */
+		orderFiles = function( appFiles ) {
+			var order = 0
+
+			function visit(f) {
+				if ( f.order === undefined ) {
+					for ( var name in f.dependencies ) {
+						visit(f.dependencies[name])
+					}
+					f.order = (order++);
+				}
+			}
+			for ( var d = 0; d < appFiles.length; d++ ) {
+				visit(appFiles[d])
+			}
+		},
+		getMostShared = function( files ) {
+			var shared = []; // count
+			for ( var fileName in files ) {
+				var file = files[fileName];
+				if ( file.packaged ) {
+					continue;
+				}
+				if (!shared[file.apps.length] ) {
+					shared[file.apps.length] = {};
+				}
+				var level = shared[file.apps.length]; //how many apps it is shared in (5?)
+
+				var appsName = file.apps.sort().join();
+
+
+
+				if (!level[appsName] ) {
+					level[appsName] = {
+						totalSize: 0,
+						files: [],
+						apps: file.apps
+					};
+				}
+				//add file, the count is how many files are shared among this many apps
+				level[appsName].files.push(file);
+				level[appsName].totalSize += file.size;
+			}
+			if (!shared.length ) {
+				return null;
+			}
+			//get the most
+			var mostShared = shared.pop(),
+				mostSize = 0,
+				most;
+			for ( var apps in mostShared ) {
+				if ( mostShared[apps].totalSize > mostSize ) {
+					most = mostShared[apps];
+					mostSize = most.totalSize;
+				}
+			}
+			//mark files 
+			for ( var i = 0; i < most.files.length; i++ ) {
+				var f = most.files[i];
+				f.packaged = true;
+			}
+			return most;
+		}
+
+
+		steal.build.apps = function( list, options ) {
+			options = steal.opts(options || {}, {
+				//compress everything, regardless of what you find
+				depth: 1,
+				//folder to build to, defaults to the folder the page is in
+				to: 1
+			});
+			// set the compressor globally
+			steal.build.compressor = steal.build.builders.scripts.compressors[options.compressor || "localClosure"]();
+
+			//a list of files hashed by their path
+			var files = {},
+
+				//keeps track of the packages an app needs
+				apps = {},
+
+				//a list of the apps (top most dependencies)
+				appFiles = [];
+
+			//set defaults
+			options.depth = options.depth || 2;
+			options.to = options.to || "packages/"
+
+			//go through, open each app, and make dependency graph
+			for ( var i = 0; i < list.length; i++ ) {
+				var startFile = list[i] + "/" + steal.File(list[i]).basename() + ".js"
+
+				var opener = steal.build.open('steal/rhino/blank.html', {
+					startFile: startFile
+				})
+				appFiles.push(addDependencies(opener.steal._start, files, list[i]));
+				apps[list[i]] = [];
+
+			}
+
+			//add an order so we can sort them nicely
+			orderFiles(appFiles);
+
+			// will be set to the biggest group
+			var pack,
+			//the package number
+			packageCount = 0;
+
+			//while there are files left to be packaged, get the most shared and largest package
+			while ((pack = getMostShared(files))) {
+
+				print('\njoining shared by ' + pack.apps.join(", "))
+
+				//the source of the package
+				var src = [],
+
+					//order the files, most base file first
+					ordered = pack.files.sort(function( f1, f2 ) {
+						return f1.order - f2.order;
+					});
+
+				// paths to files this package represents
+				var paths = [];
+
+				//go through files, put in src, and track
+				for ( var i = 0; i < ordered.length; i++ ) {
+					var f = ordered[i];
+					src.push("/* " + f.path + " */\n" + f.source);
+					print("  " + f.order + ":" + f.path);
+					paths.push(f.path)
+				}
+
+				//the final source, includes a steal of all the files in this source
+				var source = "steal('//" + paths.join("'\n,'//") + "');\nsteal.end();\n" + src.join(";steal.end();\n"),
+
+					//the path to save
+					saveFile = pack.apps.length == 1 ? pack.apps[0] + "/production.js" : "packages/" + packageCount + ".js";
+
+				//if we are the top most, replace production file with the following
+				if ( pack.apps.length == 1 ) {
+					var packages = apps[pack.apps[0]];
+					source = "steal.packs('" + packages.join("','") + "', function(){\n" + source + "\n});"
+				}
+
+				//save the file
+				print("saving " + saveFile);
+				steal.File(saveFile).save(source);
+
+				//add this package to the app's packages list
+				for ( var pa = 0; pa < pack.apps.length; pa++ ) {
+					apps[pack.apps[pa]].push(packageCount);
+				}
+				packageCount++;
+			}
+
+		}
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/apps/test.js b/browserid/static/dialog/steal/build/apps/test.js
new file mode 100644
index 0000000000000000000000000000000000000000..7c905ab241e1a8bb1019d347a47ead1096747b22
--- /dev/null
+++ b/browserid/static/dialog/steal/build/apps/test.js
@@ -0,0 +1,3 @@
+// load("steal/build/apps/test.js")
+_args = ['cookbook', 'mxui/combobox', 'mxui/modal'];
+load("steal/buildjs");
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/build.js b/browserid/static/dialog/steal/build/build.js
new file mode 100644
index 0000000000000000000000000000000000000000..c8096a420a48ee543801fe10f282026d93584d64
--- /dev/null
+++ b/browserid/static/dialog/steal/build/build.js
@@ -0,0 +1,292 @@
+//used to build a page's script
+/*global steal : false, Envjs : false, jQuery : false*/
+
+steal(function( steal ) {
+	var window = (function() {
+		return this;
+	}).call(null, 0);
+
+	/**
+	 * 
+	 * @parent stealjs
+	 * 
+	 * <p>Builds an html page's JavaScript and CSS files by compressing and concatenating them into
+	 * a single or several files.
+	 * </p>
+	 * <p>Steal can also build multiple applications at the same time and separate 
+	 * 	shared dependencies into standalone cache-able scripts.</p>
+	 * <h2>How it works</h2>
+	 * <p><code>Steal.build</code> opens a page in Envjs to extract all scripts and styles
+	 * from the page.  It compresses the resources into production.js and production.css
+	 * files.</p>
+	 * <p>Steal.build works with or without using steal.js, so it could work with other script loaders.</p>
+	 * 
+	 * 
+	 * <h2>Building with steal.js.</h2>
+	 * <p>Building with steal is easy, just point the <code>steal/buildjs</code> script at your page and
+	 * give it the name of your application folder:</p>
+	 * @codestart no-highlight
+	 * js steal/buildjs path/to/page.html -to myapp
+	 * @codeend 
+	 * <p>If you generated a steal app or plugin, there's a handy script already ready for you:</p>
+	 * @codestart no-highlight
+	 * js myapp/scripts/build.js
+	 * @codeend 
+	 * <h2>Building without steal.js</h2>
+	 * You can compress and package any page's JavaScript by adding <code>compress="true"</code>
+	 * attributes to your script tag like the following:
+	 * @codestart html
+	 * &lt;script src="file1.js" type="text/javascript" compress="true">&lt;/script>
+	 * &lt;script src="file2.js" type="text/javascript" compress="true">&lt;/script>		
+	 * @codeend
+	 * and then running either:
+	 * @codestart no-highlight
+	 * js steal/buildjs path/to/page.html -to [OUTPUT_FOLDER]
+	 * @codeend 
+	 * or: 
+	 * @codestart no-highlight
+	 * js steal/buildjs http://hostname/path/page.html -to [OUTPUT_FOLDER]
+	 * @codeend  
+	 * This will compress file1.js and file2.js into a file package named production.js an put it in OUTPUT_FOLDER.
+	 * 
+	 * <h2>Common Problems</h2>
+	 * <p>If you are getting errors building a production build, it's almost certainly because Envjs is
+	 * close, but not quite a fully featured browser.  So, you have to avoid doing things in your page that
+	 * Envjs doesn't like before onload.  The most common problems are:</p>
+	 * <h5>Malformed HTML or unescaped characters</h5>
+	 * <p>Steal does not have as tolerant of an HTML parser as Firefox.  Make sure your page's tags look good.
+	 * Also, make sure you escape characters like &amp; to &amp;amp;
+	 * </p>
+	 * <h5>DOM manipulations before onload</h5>
+	 * <p>EnvJS supports most DOM manipulations.  But, it's not a graphical browser so it completely punts
+	 * on styles and dimensional DOM features.  It's easy to protect against this, just wait until 
+	 * document ready or onload to do these things.
+	 * </p>
+	 * <h5>Unending timeouts or intervals before onload</h5>
+	 * <p>Envjs won't quit running until all timeouts or intervals have completed.  If you have a reoccuring
+	 * 'process', consider starting it on document ready or onload.</p>
+	 * <h2>Building With Shared Dependencies</h2>
+	 * <p>
+	 * If you are using steal in a setting with multiple pages loading similar
+	 * functionality, it's typically a good idea to build the shared functionality in
+	 * its own script.  This way when a user switches pages, they don't have to load
+	 * that functionality again.
+	 * </p>
+	 * <p>
+	 * To do this, use the buildjs script with the names of your apps:
+	 * </p>
+	 * @codestart
+	 * ./js steal/buildjs myco/search myco/searchresults music
+	 * @codeend
+	 * <h2>steal.build function</h2>
+	 * Takes a url, extracts
+	 * @param {String} url an html page to compress
+	 * @param {Object} options An object literal with the following optional values:
+	 * <table class='options'>
+	 *       <tr>
+	 *           <th>Name</th><th>Description</th>
+	 *       </tr>
+	 *       <tr><td>to</td>
+	 *           <td>The folder to put the production.js and production.css files.</td></tr>
+	 *       <tr><td>all</td>
+	 *       <td>Concat and compress all scripts and styles.  By default, this is set to false, meaning
+	 *           scripts and styles have to opt into being compress with the <code>compress='true'</code> attribute.</td></tr>
+	 *     </table>
+	 */
+	steal.build = function( url, options ) {
+
+		//convert options (which might be an array) into an object
+		options = steal.opts(options || {}, {
+			//compress everything, regardless of what you find
+			all: 1,
+			//folder to build to, defaults to the folder the page is in
+			to: 1
+		});
+
+		// to is the folder packages will be put in
+		options.to = options.to || (url.match(/https?:\/\//) ? "" : url.substr(0, url.lastIndexOf('/')));
+
+		// make sure to ends with /
+		if ( options.to.match(/\\$/) === null && options.to !== '' ) {
+			options.to += "/";
+		}
+
+		steal.print("Building to " + options.to);
+
+		var opener = steal.build.open(url);
+
+		// iterates through the types of builders.  For now
+		// there are just scripts and styles builders
+		for ( var builder in steal.build.builders ) {
+			steal.build.builders[builder](opener, options);
+		}
+	};
+
+	// a place for the builders
+	steal.build.builders = {}; //builders
+	// a helper function that gets the src of a script and returns
+	// the content for that script
+	var loadScriptText = function( src ) {
+		var text = "",
+			base = "" + window.location,
+			url = src.match(/([^\?#]*)/)[1];
+
+		if ( url.match(/^\/\//) ) {
+			url = steal.root.join(url.substr(2)); //can steal be removed?
+		}
+		url = Envjs.uri(url, base);
+
+		if ( url.match(/^file\:/) ) {
+			url = url.replace("file:/", "");
+			text = readFile("/" + url);
+		}
+
+		if ( url.match(/^http\:/) ) {
+			text = readUrl(url);
+		}
+
+		return text;
+	},
+		checkText = function(text, id){
+			if(!text){
+				print("\n!! There is nothing at "+id+"!!")
+			}
+		};
+	
+	// types conversion
+	// the idea is for each type to return JavaScript (or css) that
+	// should be in its place
+	steal.build.types = {
+		'text/javascript': function( script ) {
+			if ( script.src ) {
+				return loadScriptText(script.src, script);
+			}
+			else {
+				return script.text;
+			}
+		},
+		'text/css': function( script ) {
+			if ( script.href ) {
+				return loadScriptText(script.href, script);
+			}
+			else {
+				return script.text;
+			}
+		},
+		'text/ejs': function( script ) {
+			var text = script.text || loadScriptText(script.src),
+				id = script.id || script.getAttribute("id");
+				checkText(text, script.src || id);
+			return jQuery.View.registerScript("ejs", id, text);
+		},
+		'text/micro': function( script ) {
+			var text = script.text || loadScriptText(script.src),
+				id = script.id || script.getAttribute("id");
+				checkText(text, script.src || id);
+			return jQuery.View.registerScript("micro", id, text);
+		},
+		'text/jaml': function( script ) {
+			var text = script.text || loadScriptText(script.src),
+				id = script.id || script.getAttribute("id");
+				checkText(text, script.src || id);
+			return jQuery.View.registerScript("jaml", id, text);
+		},
+		'text/tmpl': function( script ) {
+			var text = script.text || loadScriptText(script.src),
+				id = script.id || script.getAttribute("id");
+				checkText(text, script.src || id);
+			return jQuery.View.registerScript("tmpl", id, text);
+		},
+		loadScriptText: loadScriptText
+	};
+
+	/**
+	 * @function open
+	 * Opens a page by:
+	 *   temporarily deleting the rhino steal
+	 *   opening the page with Envjs
+	 *   setting back rhino steal, saving envjs's steal as steal._steal;
+	 * @param {String} url the html page to open
+	 * @return {Object} an object with properties that makes extracting 
+	 * the content for a certain tag slightly easier.
+	 * 
+	 */
+	steal.build.open = function( url, stealData ) {
+		var scripts = [],
+
+			// save and remove the old steal
+			oldSteal = window.steal || steal,
+			newSteal;
+		delete window.steal;
+		if ( stealData ) {
+			window.steal = stealData;
+		}
+		// get envjs
+		load('steal/rhino/env.js'); //reload every time
+		// open the url
+		Envjs(url, {
+			scriptTypes: {
+				"text/javascript": true,
+				"text/envjs": true,
+				"": true
+			},
+			fireLoad: false,
+			logLevel: 2,
+			afterScriptLoad: {
+				".*": function( script ) {
+					scripts.push(script);
+				}
+			},
+			onLoadUnknownTypeScript: function( script ) {
+				scripts.push(script);
+			},
+			afterInlineScriptLoad: function( script ) {
+				scripts.push(script);
+			},
+			dontPrintUserAgent: true,
+			killTimersAfterLoad: true
+		});
+
+		// set back steal
+		newSteal = window.steal;
+		window.steal = oldSteal;
+		window.steal._steal = newSteal;
+
+
+		// check if newSteal added any build types (used to convert less to css for example).
+		if(newSteal && newSteal.build && newSteal.build.types){
+			for ( var buildType in newSteal.build.types ) {
+				oldSteal.build.types[buildType] = newSteal.build.types[buildType];
+			}
+		}
+		
+
+		// return the helper
+		return {
+			/**
+			 * @hide
+			 * Gets all elements of a type, extracts their converted content, and calls a callback function with  
+			 * each element and its converted content.
+			 * @param {Object} [type] the tag to get
+			 * @param {Object} func a function to call back with the element and its content
+			 */
+			each: function( type, func ) {
+				if ( typeof type == 'function' ) {
+					func = type;
+					type = 'script';
+				}
+				var scripts = document.getElementsByTagName(type);
+				for ( var i = 0; i < scripts.length; i++ ) {
+					func(scripts[i], this.getScriptContent(scripts[i]), i);
+				}
+			},
+			getScriptContent: function( script ) {
+				return steal.build.types[script.type] && steal.build.types[script.type](script, loadScriptText);
+			},
+			// the 
+			steal: newSteal,
+			url: url
+		};
+	};
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/pluginify/parse.js b/browserid/static/dialog/steal/build/pluginify/parse.js
new file mode 100644
index 0000000000000000000000000000000000000000..d72f91b54291fbcf72373b730d4a6167012ca4b9
--- /dev/null
+++ b/browserid/static/dialog/steal/build/pluginify/parse.js
@@ -0,0 +1,47 @@
+steal("//steal/build/pluginify/tokens").
+	plugins('steal/build').then(function(){
+
+steal.build.parse = function(str){
+		//print("Breaking up strs")
+		var tokens = str.tokens('=<>!+-*&|/%^', '=<>&|'),
+			tokenNum = 0;
+			
+		var moveNext = function(){
+			var next = tokens[tokenNum++];
+			if(next){
+				//print("Next TOken = "+next.value);
+			}
+			return next;
+		}
+		
+		return {
+			moveNext : moveNext,
+			next : function(){
+				return tokens[tokenNum];
+			},
+			until: function(){
+				var token, 
+					matchCounts = [];
+				for(var i =0; i < arguments.length;i++){
+					matchCounts[i] =0;
+					if(typeof arguments[i] == "string"){
+						arguments[i] = [arguments[i]]
+					}
+				}
+				while (token = moveNext() ) {
+					for(var i =0; i< arguments.length; i++){
+						if( token.type !== "string" && 
+							token.value === arguments[i][matchCounts[i]]){
+							matchCounts[i] = matchCounts[i]+1;
+							if(matchCounts[i] === arguments[i].length){
+								return token;
+							}
+						}else{
+							matchCounts[i] = 0;
+						}
+					}
+				}
+			}
+		}
+	};
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/pluginify/pluginify.js b/browserid/static/dialog/steal/build/pluginify/pluginify.js
new file mode 100644
index 0000000000000000000000000000000000000000..57127829e82a4518be6d1b9e1ebd359742a59d79
--- /dev/null
+++ b/browserid/static/dialog/steal/build/pluginify/pluginify.js
@@ -0,0 +1,193 @@
+// usage: 
+// js steal\scripts\pluginify.js funcunit/functional -destination funcunit/dist/funcunit.js
+// js steal\scripts\pluginify.js jquery/controller
+// js steal\scripts\pluginify.js jquery/event/drag -exclude jquery/lang/vector/vector.js jquery/event/livehack/livehack.js
+// load("steal/rhino/steal.js");
+
+steal("//steal/build/pluginify/parse").plugins('steal/build/scripts').then(
+ function(s) {
+
+	/**
+	 * Builds a 'steal-less' version of your application.  To use this, files that use steal must
+	 * have their code within a callback function.  
+	 * @param {Object} plugin
+	 * @param {Object} opts
+	 */
+	s.build.pluginify = function( plugin, opts ) {
+		print(""+plugin+" >");
+		var jq = true,
+			othervar,
+			opts = steal.opts(opts, {
+				"destination": 1,
+				"exclude": -1,
+				"nojquery": 0,
+				"global" : 0,
+				"compress" : 0
+			}),
+			destination = opts.destination || plugin+"/"+plugin.replace("/",".") + ".js";
+
+		opts.exclude = !opts.exclude ? [] : (steal.isArray(opts.exclude) ? opts.exclude : [opts.exclude]);
+
+		if ( opts.nojquery ) {
+			jq = false;
+			//othervar = opts.nojquery;
+			opts.exclude.push('jquery.js');
+		}
+		opts.exclude.push("steal/dev/")
+		rhinoLoader = {
+			callback: function( s ) {
+				s.plugins(plugin);
+			}
+		};
+
+		steal.win().build_in_progress = true;
+
+		var pageSteal = steal.build.open("steal/rhino/empty.html").steal,
+			out = [],
+			str, i, inExclude = function( path ) {
+				for ( var i = 0; i < opts.exclude.length; i++ ) {
+					if ( path.indexOf(opts.exclude[i]) > -1 ) {
+						return true;
+					}
+				}
+				return false;
+			},
+			steals = pageSteal.total;
+
+		for ( i = 0; i < steals.length; i++ ) {
+			if(!inExclude(steals[i].path)){
+				
+				var content = steal.build.pluginify.content(steals[i], opts.global ? opts.global : "jQuery" );
+				if(content){
+					print("  > "+steals[i].path)
+					out.push(steal.build.builders.scripts.clean(content));
+				}
+			}
+		}
+
+		var output = out.join(";\n");
+		if(opts.compress) {
+			var compressorName = (typeof(opts.compress) == "string") ? opts.compress : "localClosure";
+			var compressor = steal.build.builders.scripts.compressors[compressorName]()
+			output = compressor(output);
+		}
+
+		print("--> " + destination);
+		new steal.File(destination).save(output);
+		//print("pluginified " + plugin)
+	};
+	
+	
+	//keeps track of which 'then' we are in with steal
+	var funcCount = {};
+	
+	//gets content from a steal
+	s.build.pluginify.content = function(steal, param){
+		if(steal.func){
+			// if it's a function, go to the file it's in ... pull out the content
+			var index = funcCount[steal.path] || 0,
+				contents = readFile(steal.path);
+			 //print("FOOO "+steal.path);
+			 funcCount[steal.path]++;
+			 return "("+s.build.pluginify.getFunction(contents, index)+")("+param+")";
+		}else{
+			var content = readFile(steal.path);
+			if( /steal[.\(]/.test(content) ){
+				return;
+			}
+			//make sure steal isn't in here
+			return content;
+		}
+	};
+	s.build.pluginify.getFunction = function(content, ith){
+
+		var p = s.build.parse(content),
+			token,
+			funcs = [];
+
+		while (token = p.moveNext() ) {
+			//print(token.value)
+			if(token.type !== "string"){
+				switch(token.value){
+					case "/" : 
+						comment(p)
+						break;
+					case "steal" : 
+						stealPull(p, content, function(func){
+							funcs.push(func)
+						});
+						break;
+				}
+			}
+		}
+		return funcs[ith||0];
+		
+	};
+	//gets a function from steal
+	var stealPull = function(p, content, cb){
+		var token = p.next(),
+			startToken,
+			endToken;
+		if(!token || (token.value != "." && token.value != "(")){
+			// we said steal .. but we don't care
+			return;
+		}else{
+			p.moveNext();
+		}
+		if(token.value == "."){
+			p.until("(")
+		}
+		token = p.until("function",")");
+
+		if(token.value == "function"){
+			
+			startToken = p.until("{");
+
+			endToken = nextBracket(p);
+			cb(content.substring(token.from, endToken.to))
+			//print("CONTENT\n"+  );
+			p.moveNext();
+		}else{
+			
+		}
+		stealPull(p,content, cb );
+		
+	},
+	//moves across a comment
+	comment = function(p){ //we don't really need this anymore
+		var n =p.next()
+		if(n.value == "*" && n.value != 'string'){
+			p.until(["*","/"])
+		}
+	},
+	//gets the next bracket
+	nextBracket = function(p){
+		var count = 1, token, last, prev;
+		while(token = p.moveNext()){
+			//print(token.value)
+			if(token.type == 'operator'){
+				switch(token.value){
+					case "{": 
+						
+						count++;
+						//print("  +"+count+" "+prev+" "+last)
+						break;
+					case "}" :
+						
+						count--;
+						//print("  -"+count+" "+prev+" "+last)
+						if(count === 0){
+							return token;
+						}
+						break;
+					case "/" : 
+						comment(p);
+						break;
+				}
+			}
+			
+			prev = last;
+			last = (token.value)
+		}
+	}
+});
diff --git a/browserid/static/dialog/steal/build/pluginify/test/firstFunc.js b/browserid/static/dialog/steal/build/pluginify/test/firstFunc.js
new file mode 100644
index 0000000000000000000000000000000000000000..5276ecd15e200aec7ca3beeb76a2f9de14f875dd
--- /dev/null
+++ b/browserid/static/dialog/steal/build/pluginify/test/firstFunc.js
@@ -0,0 +1,8 @@
+function(abc){
+	(function(){});
+	"abc(){};";
+	/* steal */
+	// steal
+	
+	boom	
+}
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/pluginify/test/pluginify_test.js b/browserid/static/dialog/steal/build/pluginify/test/pluginify_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..a4c5f8733b646354aef3a53e32cea6d3bb65ae19
--- /dev/null
+++ b/browserid/static/dialog/steal/build/pluginify/test/pluginify_test.js
@@ -0,0 +1,52 @@
+// load('steal/compress/test/run.js')
+/**
+ * Tests compressing a very basic page and one that is using steal
+ */
+load('steal/rhino/steal.js')
+steal.plugins('steal/test','steal/build/pluginify').then( function( s ) {
+	STEALPRINT = false;
+	s.test.module("steal/build/pluginify")
+	
+	s.test.test("getFunctions", function(t){
+		
+		var js = readFile('steal/build/pluginify/test/test_steals.js');
+		var firstFunc = steal.build.pluginify.getFunction(js, 0);
+		
+		t.equals(firstFunc, readFile('steal/build/pluginify/test/firstFunc.js'));
+		
+		var secondFunc = steal.build.pluginify.getFunction(js, 1);
+		
+		t.equals(secondFunc, readFile('steal/build/pluginify/test/secondFunc.js'))
+		
+	})
+	s.test.test("getFunctions2", function(t){
+		
+		var js = readFile('jquery/view/micro/micro.js');
+		var firstFunc = steal.build.pluginify.getFunction(js, 0);
+		//print(firstFunc);
+	})
+	s.test.test("parse", function(t){
+		var js = readFile('jquery/class/class.js');
+		var tokens = js.tokens('=<>!+-*&|/%^', '=<>&|');
+		
+		var js = readFile('jquery/view/ejs/ejs.js');
+		var tokens = js.tokens('=<>!+-*&|/%^', '=<>&|');
+		
+		var js = readFile('jquery/lang/vector/vector.js');
+		var tokens = js.tokens('=<>!+-*&|/%^', '=<>&|');
+		
+		var js = readFile('jquery/dom/fixture/fixture.js');
+		var tokens = js.tokens('=<>!+-*&|/%^', '=<>&|');
+		
+		var js = readFile('jquery/view/view.js');
+		var tokens = js.tokens('=<>!+-*&|/%^', '=<>&|');
+		
+		var js = readFile('jquery/lang/json/json.js');
+		var tokens = js.tokens('=<>!+-*&|/%^', '=<>&|');
+		
+		js = readFile('steal/build/pluginify/test/weirdRegexps.js');
+		var tokens = js.tokens('=<>!+-*&|/%^', '=<>&|');
+		
+	})	
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/pluginify/test/secondFunc.js b/browserid/static/dialog/steal/build/pluginify/test/secondFunc.js
new file mode 100644
index 0000000000000000000000000000000000000000..52e20cbed5b8dd10be8bb08f9fc47e287dc6d47a
--- /dev/null
+++ b/browserid/static/dialog/steal/build/pluginify/test/secondFunc.js
@@ -0,0 +1,3 @@
+function($,foo){
+	//yes
+}
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/pluginify/test/test_steals.js b/browserid/static/dialog/steal/build/pluginify/test/test_steals.js
new file mode 100644
index 0000000000000000000000000000000000000000..b13995588c75eaf184b6115658ad1ebddf06eb97
--- /dev/null
+++ b/browserid/static/dialog/steal/build/pluginify/test/test_steals.js
@@ -0,0 +1,20 @@
+/**
+ * steal something
+ */
+
+steal.foo().bar(function(abc){
+	(function(){});
+	"abc(){};";
+	/* steal */
+	// steal
+	
+	boom	
+}).plugins("boom").then(function($,foo){
+	//yes
+})
+
+abc.def
+
+asdfas
+
+
diff --git a/browserid/static/dialog/steal/build/pluginify/test/weirdRegexps.js b/browserid/static/dialog/steal/build/pluginify/test/weirdRegexps.js
new file mode 100644
index 0000000000000000000000000000000000000000..dcf2155b9f249327ffacbed2b237c020fdbad22e
--- /dev/null
+++ b/browserid/static/dialog/steal/build/pluginify/test/weirdRegexps.js
@@ -0,0 +1,3 @@
+steal.then(function(){
+	/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/pluginify/tokens.js b/browserid/static/dialog/steal/build/pluginify/tokens.js
new file mode 100644
index 0000000000000000000000000000000000000000..88af4eb6d37b46ac9df9dc0f88e4da0ab9222fe6
--- /dev/null
+++ b/browserid/static/dialog/steal/build/pluginify/tokens.js
@@ -0,0 +1,343 @@
+// tokens.js
+// 2009-05-17
+
+// (c) 2006 Douglas Crockford
+
+// Produce an array of simple token objects from a string.
+// A simple token object contains these members:
+//      type: 'name', 'string', 'number', 'operator'
+//      value: string or number value of the token
+//      from: index of first character of the token
+//      to: index of the last character + 1
+
+// Comments of the // type are ignored.
+
+// Operators are by default single characters. Multicharacter
+// operators can be made by supplying a string of prefix and
+// suffix characters.
+// characters. For example,
+//      '<>+-&', '=>&:'
+// will match any of these:
+//      <=  >>  >>>  <>  >=  +: -: &: &&: &&
+
+
+
+String.prototype.tokens = function (prefix, suffix) {
+    var c;                      // The current character.
+    var from;                   // The index of the start of the token.
+    var i = 0;                  // The index of the current character.
+    var length = this.length;
+    var n;                      // The number value.
+    var q;                      // The quote character.
+    var str;                    // The string value.
+
+    var result = [];            // An array to hold the results.
+	var prereg = true;
+    var make = function (type, value) {
+
+// Make a token object.
+		
+		//prereg = i &&
+        //            (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) ||
+         //           i === 'return')
+		//print(type+":"+value+"-")
+        prereg = (type == 'operator' || type === 'name') &&
+				 (value === 'return' ||   ('(,=:[!&|?{};'.indexOf(value.charAt(value.length - 1)) >= 0 ) )
+		//print(type+" : "+value+" - "+prereg)
+		return {
+            type: type,
+            value: value,
+            from: from,
+            to: i
+        };
+		
+    };
+	var has = function(thIs, before){
+		var j = i+1;
+        for (;;) {
+            c = this.charAt(j);
+            if(c === thIs){
+				return true;
+			}
+			//print("|"+c+"|"+(c=="\n" || c=="\r"));
+			if (before.test(c) || c === '') {
+                return false;
+            }
+            j += 1;
+        }
+	}
+	
+// Begin tokenization. If the source string is empty, return nothing.
+
+    if (!this) {
+        return;
+    }
+
+// If prefix and suffix strings are not provided, supply defaults.
+
+    if (typeof prefix !== 'string') {
+        prefix = '<>+-&';
+    }
+    if (typeof suffix !== 'string') {
+        suffix = '=>&:';
+    }
+
+
+// Loop through this text, one character at a time.
+
+    c = this.charAt(i);
+    while (c) {
+        from = i;
+		//print(c);
+// Ignore whitespace.
+
+        if (c <= ' ') {
+            i += 1;
+            c = this.charAt(i);
+
+// name.
+
+        } else if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') {
+            str = c;
+            i += 1;
+            for (;;) {
+                c = this.charAt(i);
+                if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
+                        (c >= '0' && c <= '9') || c === '_') {
+                    str += c;
+                    i += 1;
+                } else {
+                    break;
+                }
+            }
+			//print(str);
+            result.push(make('name', str));
+
+// number.
+
+// A number cannot start with a decimal point. It must start with a digit,
+// possibly '0'.
+
+        } else if (c >= '0' && c <= '9') {
+            str = c;
+            i += 1;
+
+// Look for more digits.
+
+            for (;;) {
+                c = this.charAt(i);
+                if (c < '0' || c > '9') {
+                    break;
+                }
+                i += 1;
+                str += c;
+            }
+
+// Look for a decimal fraction part.
+
+            if (c === '.') {
+                i += 1;
+                str += c;
+                for (;;) {
+                    c = this.charAt(i);
+                    if (c < '0' || c > '9') {
+                        break;
+                    }
+                    i += 1;
+                    str += c;
+                }
+            }
+
+// Look for an exponent part.
+
+            if (c === 'e' || c === 'E') {
+                i += 1;
+                str += c;
+                c = this.charAt(i);
+                if (c === '-' || c === '+') {
+                    i += 1;
+                    str += c;
+                    c = this.charAt(i);
+                }
+                if (c < '0' || c > '9') {
+                    make('number', str).error("Bad exponent");
+                }
+                do {
+                    i += 1;
+                    str += c;
+                    c = this.charAt(i);
+                } while (c >= '0' && c <= '9');
+            }
+
+// Make sure the next character is not a letter.
+
+            if (c >= 'a' && c <= 'z') {
+                str += c;
+                i += 1;
+				print(this.substr(i-20,20))
+				print(this.substr(i,20))				
+                make('number', str).error("Bad number");
+            }
+
+// Convert the string value to a number. If it is finite, then it is a good
+// token.
+
+            n = +str;
+            if (isFinite(n)) {
+                result.push(make('number', n));
+            } else {
+                make('number', str).error("Bad number");
+            }
+
+// string
+
+        } else if (c === '\'' || c === '"') {
+            str = '';
+            q = c;
+            i += 1;
+            //print("----")
+			for (;;) {
+                c = this.charAt(i);
+				//print(this[i])
+                if (c < ' ') {
+					print(this.substr(i-20,20))
+					print(this.substr(i,20))
+                    make('string', str).error(c === '\n' || c === '\r' || c === '' ?
+                        "Unterminated string." :
+                        "Control character in string.", make('', str));
+                }
+
+// Look for the closing quote.
+
+                if (c === q) {
+                    break;
+                }
+
+// Look for escapement.
+
+                if (c === '\\') {
+                    i += 1;
+                    if (i >= length) {
+                        make('string', str).error("Unterminated string");
+                    }
+                    c = this.charAt(i);
+                    switch (c) {
+                    case 'b':
+                        c = '\b';
+                        break;
+                    case 'f':
+                        c = '\f';
+                        break;
+                    case 'n':
+                        c = '\n';
+                        break;
+                    case 'r':
+                        c = '\r';
+                        break;
+                    case 't':
+                        c = '\t';
+                        break;
+                    case 'u':
+                        if (i >= length) {
+                            make('string', str).error("Unterminated string");
+                        }
+                        c = parseInt(this.substr(i + 1, 4), 16);
+                        if (!isFinite(c) || c < 0) {
+                            make('string', str).error("Unterminated string");
+                        }
+                        c = String.fromCharCode(c);
+                        i += 4;
+                        break;
+                    }
+                }
+                str += c;
+                i += 1;
+            }
+            i += 1;
+			//print("str = "+str)
+            result.push(make('string', str));
+            c = this.charAt(i);
+
+		
+// comment.
+		
+        } else if (c === '/' && this.charAt(i + 1) === '*') {
+            i += 1;
+            for (;;) {
+                c = this.charAt(i);
+                if (c === '*' && this.charAt(i+1) == "/") {
+					i += 1;
+					i += 1;
+                    break;
+                }
+                i += 1;
+            }
+		}  else if (c === '/' && this.charAt(i + 1) === '/') {
+            i += 1;
+            for (;;) {
+                c = this.charAt(i);
+                if (c === '\n' || c === '\r' || c === '') {
+                    break;
+                }
+                i += 1;
+            }
+// regexp
+		} else if (c === '/' && has.call(this, "/", /[\n\r]/) && prereg) { // what about /2
+            //print('matcing regexp')
+			i += 1;
+			var str = c;
+            for (;;) {
+                c = this.charAt(i);
+                if(c === "\\"){ //skip over \
+					str += c;
+                	i += 1;
+					//print("adding "+c)
+					c = this.charAt(i);
+					
+					str += c;
+					//print("adding "+c)
+                	i += 1;
+					c = this.charAt(i);
+					continue;
+				}
+				
+				if (c === '/' ) {
+					str += c;
+					i += 1;
+					c = this.charAt(i);
+					while(/\w/.test(c)){ //get stuff after /a/m
+						str += c;
+						i += 1;
+						c = this.charAt(i);
+					}
+					result.push(make('regexp', str));
+					//print("regexp = "+str)
+                    break;
+                }
+				str += c;
+                i += 1;
+            }
+// combining
+        } else if (prefix.indexOf(c) >= 0) {
+            str = c;
+            i += 1;
+            while (i < length) {
+                c = this.charAt(i);
+                if (suffix.indexOf(c) < 0) {
+                    break;
+                }
+                str += c;
+                i += 1;
+            }
+            result.push(make('operator', str));
+
+// single-character operator
+
+        } else {
+            i += 1;
+            result.push(make('operator', c));
+            c = this.charAt(i);
+        }
+    }
+    return result;
+};
diff --git a/browserid/static/dialog/steal/build/scripts/compiler.jar b/browserid/static/dialog/steal/build/scripts/compiler.jar
new file mode 100644
index 0000000000000000000000000000000000000000..da053a7dddb81aca37d80e60ab0727284db24e07
Binary files /dev/null and b/browserid/static/dialog/steal/build/scripts/compiler.jar differ
diff --git a/browserid/static/dialog/steal/build/scripts/scripts.js b/browserid/static/dialog/steal/build/scripts/scripts.js
new file mode 100644
index 0000000000000000000000000000000000000000..42dbbf74c453e5a2678cab46d93f213d0e8bfdc2
--- /dev/null
+++ b/browserid/static/dialog/steal/build/scripts/scripts.js
@@ -0,0 +1,155 @@
+steal(function( steal ) {
+
+	/**
+	 * Builds JavaScripts
+	 * @param {Object} opener the result of a steal.build.open
+	 * @param {Object} options options passed to the build script
+	 */
+	var scripts = (steal.build.builders.scripts = function( opener, options ) {
+		steal.print("\nBUILDING SCRIPTS --------------- ");
+
+		// get the compressor
+		var compressor = scripts.compressors[options.compressor || "localClosure"](),
+
+			// packages that can be compressed somewhere
+			packages = {},
+
+			// the current package
+			currentPackage = [];
+
+		// compress all scripts by default
+		if ( options.all ) {
+			packages['production.js'] = currentPackage;
+		}
+
+		// for each script we find
+		opener.each("script", function( script, text, i ) {
+
+			// if we should ignore it, ignore it
+			if ( script.getAttribute('ignore') == "true" ) {
+				if ( script.src ) {
+					steal.print('   ignoring ' + script.src);
+				}
+				return;
+			}
+
+			// if it has a src, let people know we are compressing it
+			if ( script.src ) {
+				steal.print("   " + script.src.replace(/\?.*$/, "").replace(/^(\.\.\/)+/, ""));
+			}
+
+			// get the package, this will be production.js
+			var pack = script.getAttribute('package');
+
+
+			if ( pack ) {
+				//if we don't have it, create it and set it to the current package
+				if (!packages[pack] ) {
+					packages[pack] = [];
+				}
+				currentPackage = packages[pack];
+			}
+
+			// clean out any remove-start style comments
+			text = scripts.clean(text);
+
+			// if we should compress the script, compress it
+			if ( script.getAttribute('compress') == "true" || options.all ) {
+				text = compressor(text, true);
+			}
+
+			// put the result in the package
+			currentPackage.push(text);
+		});
+
+		steal.print("");
+
+		// go through all the packages
+		for ( var p in packages ) {
+			if ( packages[p].length ) {
+				//join them
+				var compressed = packages[p].join(";\n");
+				//save them
+				new steal.File(options.to + p).save(compressed);
+				steal.print("SCRIPT BUNDLE > " + options.to + p);
+			}
+		}
+	});
+	// removes  dev comments from text
+	scripts.clean = function( text ) {
+		return String(java.lang.String(text).replaceAll("(?s)\/\/@steal-remove-start(.*?)\/\/@steal-remove-end", "").replaceAll("steal[\n\s\r]*\.[\n\s\r]*dev[\n\s\r]*\.[\n\s\r]*(\\w+)[\n\s\r]*\\([^\\)]*\\)", ""));
+	};
+
+	//various compressors
+	scripts.compressors = {
+		// needs shrinksafe.jar at steal/build/javascripts/shrinksafe.jar
+		shrinksafe: function() {
+			steal.print("steal.compress - Using ShrinkSafe");
+			// importPackages/Class doesn't really work
+			var URLClassLoader = Packages.java.net.URLClassLoader,
+				URL = java.net.URL,
+				File = java.io.File,
+				ss = new File("steal/build/javascripts/shrinksafe.jar"),
+				ssurl = ss.toURL(),
+				urls = java.lang.reflect.Array.newInstance(URL, 1);
+			urls[0] = new URL(ssurl);
+
+			var clazzLoader = new URLClassLoader(urls),
+				mthds = clazzLoader.loadClass("org.dojotoolkit.shrinksafe.Compressor").getDeclaredMethods(),
+				rawCompress = null;
+
+			//iterate through methods to find the one we are looking for
+			for ( var i = 0; i < mthds.length; i++ ) {
+				var meth = mthds[i];
+				if ( meth.toString().match(/compressScript\(java.lang.String,int,int,boolean\)/) ) {
+					rawCompress = meth;
+				}
+			}
+			return function( src ) {
+				var zero = new java.lang.Integer(0),
+					one = new java.lang.Integer(1),
+					tru = new java.lang.Boolean(false),
+					script = new java.lang.String(src);
+				return rawCompress.invoke(null, script, zero, one, tru);
+			};
+		},
+		closureService: function() {
+			steal.print("steal.compress - Using Google Closure Service");
+
+			return function( src ) {
+				var xhr = new XMLHttpRequest();
+				xhr.open("POST", "http://closure-compiler.appspot.com/compile", false);
+				xhr.setRequestHeader["Content-Type"] = "application/x-www-form-urlencoded";
+				var params = "js_code=" + encodeURIComponent(src) + "&compilation_level=WHITESPACE_ONLY" + "&output_format=text&output_info=compiled_code";
+				xhr.send(params);
+				return "" + xhr.responseText;
+			};
+		},
+		localClosure: function() {
+			//was unable to use SS import method, so create a temp file
+			steal.print("steal.compress - Using Google Closure app");
+			return function( src, quiet ) {
+				var rnd = Math.floor(Math.random() * 1000000 + 1),
+					filename = "tmp" + rnd + ".js",
+					tmpFile = new steal.File(filename);
+
+				tmpFile.save(src);
+
+				var outBaos = new java.io.ByteArrayOutputStream(),
+					output = new java.io.PrintStream(outBaos);
+				if ( quiet ) {
+					runCommand("java", "-jar", "steal/build/scripts/compiler.jar", "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--js", filename, {
+						output: output
+					});
+				} else {
+					runCommand("java", "-jar", "steal/build/scripts/compiler.jar", "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--js", filename, {
+						output: output
+					});
+				}
+				tmpFile.remove();
+
+				return outBaos.toString();
+			};
+		}
+	};
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/styles/cssmin.js b/browserid/static/dialog/steal/build/styles/cssmin.js
new file mode 100644
index 0000000000000000000000000000000000000000..01300a566e9b8234f63cec4b6bb757cbaa5c0a18
--- /dev/null
+++ b/browserid/static/dialog/steal/build/styles/cssmin.js
@@ -0,0 +1,13 @@
+steal(function( steal ) {
+	var comments = /\/\*.*?\*\//g,
+		newLines = /\n*/g,
+		space = /[ ]+/g,
+		spaceChars = /\s?([;:{},+>])\s?/g,
+		lastSemi = /;}/g;
+
+
+	steal.cssMin = function( css ) {
+		//remove comments
+		return css.replace(comments, "").replace(newLines, "").replace(space, " ").replace(spaceChars, '$1').replace(lastSemi, '}')
+	}
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/styles/styles.js b/browserid/static/dialog/steal/build/styles/styles.js
new file mode 100644
index 0000000000000000000000000000000000000000..88c9a6b3ce25c308ab29cafae8f39cb7b307a4ba
--- /dev/null
+++ b/browserid/static/dialog/steal/build/styles/styles.js
@@ -0,0 +1,84 @@
+steal(function( steal ) {
+
+	/**
+	 * Builds and compresses CSS files.
+	 * @param {Object} opener
+	 * @param {Object} options
+	 */
+	var styles = (steal.build.builders.styles = function( opener, options ) {
+		steal.print("\nBUILDING STYLES --------------- ");
+		//where we are putting stuff
+		var folder = options.to.substr(0, options.to.length - 1),
+			//where the page is
+			pageFolder = steal.File(opener.url).dir(),
+			currentPackage = [];
+
+		opener.each('link', function( link, text, i ) {
+			steal.print(link.type)
+			//let people know we are adding it
+			if ( link.href && steal.build.types[link.type] ) {
+				steal.print(link.href)
+
+				var loc = steal.File(pageFolder).join(link.href),
+					converted = convert(text, loc, folder)
+
+
+					currentPackage.push(steal.cssMin(converted))
+
+			}
+
+		});
+		steal.print("")
+		if ( currentPackage.length ) {
+			steal.print("STYLE BUNDLE > " + folder + "/production.css\n")
+			steal.File(folder + "/production.css").save(currentPackage.join('\n'));
+		} else {
+			steal.print("no styles\n")
+		}
+
+
+
+	});
+	//used to convert css referencs in one file so they will make sense from prodLocation
+	var convert = function( css, cssLocation, prodLocation ) {
+		//how do we go from prod to css
+		var cssLoc = new steal.File(cssLocation).dir(),
+			newCSss = css.replace(/url\(['"]?([^'"\)]*)['"]?\)/g, function( whole, part ) {
+
+				//check if url is relative
+				if (!isRelative(part) ) {
+					return whole
+				}
+
+				//it's a relative path from cssLocation, need to convert to
+				// prodLocation
+				var imagePath = steal.File(part).joinFrom(cssLoc),
+					fin = steal.File(imagePath).toReferenceFromSameDomain(prodLocation);
+				//print("  -> "+imagePath);
+				steal.print("  " + part + " > " + fin);
+				return "url(" + fin + ")";
+			});
+		return newCSss;
+	},
+		isRelative = function( part ) {
+			// http://, https://, / 
+			return !/^(http:\/\/|https:\/\/|\/)/.test(part)
+		}
+
+		var comments = /\/\*.*?\*\//g,
+		newLines = /\n*/g,
+		space = /[ ]+/g,
+		spaceChars = /\s?([;:{},+>])\s?/g,
+		lastSemi = /;}/g;
+
+
+	steal.cssMin = function( css ) {
+		//remove comments
+		return css.replace(comments, "")
+			.replace(newLines, "")
+			.replace(space, " ")
+			.replace(spaceChars, '$1')
+			.replace(lastSemi, '}')
+	}
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/styles/test/css/css1.css b/browserid/static/dialog/steal/build/styles/test/css/css1.css
new file mode 100644
index 0000000000000000000000000000000000000000..fb514897a3ecf5677ca0455e73c64e0c7090e644
--- /dev/null
+++ b/browserid/static/dialog/steal/build/styles/test/css/css1.css
@@ -0,0 +1,6 @@
+.background1a { background-image: url(justin.png) }
+.background1b { background-image: url(../upload.png) }
+.background1c { background-image: url('justin.png') }
+.background1d { background-image: url('../upload.png') }
+
+
diff --git a/browserid/static/dialog/steal/build/styles/test/css/justin.png b/browserid/static/dialog/steal/build/styles/test/css/justin.png
new file mode 100644
index 0000000000000000000000000000000000000000..2def9a6e496413855d9957e04f9872b8eabda652
Binary files /dev/null and b/browserid/static/dialog/steal/build/styles/test/css/justin.png differ
diff --git a/browserid/static/dialog/steal/build/styles/test/css2.css b/browserid/static/dialog/steal/build/styles/test/css2.css
new file mode 100644
index 0000000000000000000000000000000000000000..a0d19cc1d2eaec93825d7eaf3f31053ab1bc5266
--- /dev/null
+++ b/browserid/static/dialog/steal/build/styles/test/css2.css
@@ -0,0 +1,9 @@
+.background2 { background-image: url(upload.PNG) }
+
+.back {
+	width: 200px; height: 200px;
+}
+
+.background2b{
+	background-image : url(/foo/bar.PNG)
+}
diff --git a/browserid/static/dialog/steal/build/styles/test/page.html b/browserid/static/dialog/steal/build/styles/test/page.html
new file mode 100644
index 0000000000000000000000000000000000000000..6356e957b9b5be34a42a3f80b804cb727b73c23d
--- /dev/null
+++ b/browserid/static/dialog/steal/build/styles/test/page.html
@@ -0,0 +1,18 @@
+<html>
+	<head>
+		<link type="text/css" href="css/css1.css" rel="stylesheet" />
+		<link type="text/css" href="css2.css" rel="stylesheet" />    
+		<!-- <link type="text/css" href="production.css" rel="stylesheet" />
+			-->             
+	</head>
+	<body>
+		<h3>Picture of Justin</h3>
+		<div class='background1a back'></div>
+		<h3>Picture of Upload</h3>
+		<div class='background1b back'></div>
+		<h3>Picture of Upload</h3>
+		<div class='background2 back'></div>
+		<p>You can verify this by replacing the style sheet's above
+		with production.css</p>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/styles/test/production.css b/browserid/static/dialog/steal/build/styles/test/production.css
new file mode 100644
index 0000000000000000000000000000000000000000..a4b524ffbc612155811be8562fb303b3e556446f
--- /dev/null
+++ b/browserid/static/dialog/steal/build/styles/test/production.css
@@ -0,0 +1,2 @@
+.background1a{background-image:url(css/justin.png)}.background1b{background-image:url(upload.png)}.background1c{background-image:url(css/justin.png)}.background1d{background-image:url(upload.png)}

+.background2{background-image:url(upload.PNG)}.back{width:200px;height:200px}.background2b{background-image:url(/foo/bar.PNG)}
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/styles/test/productionCompare.css b/browserid/static/dialog/steal/build/styles/test/productionCompare.css
new file mode 100644
index 0000000000000000000000000000000000000000..d464338f07c2f883aeda65da182615a5006068be
--- /dev/null
+++ b/browserid/static/dialog/steal/build/styles/test/productionCompare.css
@@ -0,0 +1,3 @@
+.background1a{background-image:url(css/justin.png)}.background1b{background-image:url(upload.png)}.background1c{background-image:url(css/justin.png)}.background1d{background-image:url(upload.png)}
+
+.background2{background-image:url(upload.PNG)}.back{width:200px;height:200px}.background2b{background-image:url(/foo/bar.PNG)}
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/styles/test/styles_test.js b/browserid/static/dialog/steal/build/styles/test/styles_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..2bd47250e5c9d455fd650bde5a6d6b64f3fe827c
--- /dev/null
+++ b/browserid/static/dialog/steal/build/styles/test/styles_test.js
@@ -0,0 +1,34 @@
+// load('steal/compress/test/run.js')
+/**
+ * Tests compressing a very basic page and one that is using steal
+ */
+load('steal/rhino/steal.js')
+steal('//steal/test/test', function( s ) {
+	//STEALPRINT = false;
+	s.test.module("steal/build/styles")
+	
+	STEALPRINT = false;
+
+	s.test.test("css", function(){
+		load('steal/rhino/steal.js');
+		steal.plugins(
+			'steal/build',
+			'steal/build/scripts',
+			'steal/build/styles',
+			function(){
+				steal.build('steal/build/styles/test/page.html',
+					{to: 'steal/build/styles/test'});
+			});
+		
+		var prod = readFile('steal/build/styles/test/production.css').replace(/\r|\n|\s/g,""),
+			expected = readFile('steal/build/styles/test/productionCompare.css').replace(/\r|\n|\s/g,"");
+		
+		s.test.equals(
+			prod,
+			expected,
+			"css out right");
+			
+		s.test.clear();
+	})
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/styles/test/upload.PNG b/browserid/static/dialog/steal/build/styles/test/upload.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..f5bc25db357baa42da2f305ee8c2ca79d70ad9ac
Binary files /dev/null and b/browserid/static/dialog/steal/build/styles/test/upload.PNG differ
diff --git a/browserid/static/dialog/steal/build/test/basicpage.html b/browserid/static/dialog/steal/build/test/basicpage.html
new file mode 100644
index 0000000000000000000000000000000000000000..19ce164aab7992044e80544979a83eb5a78954b5
--- /dev/null
+++ b/browserid/static/dialog/steal/build/test/basicpage.html
@@ -0,0 +1,6 @@
+<html>
+	<head></head>
+	<body>
+		<script type='text/javascript' src='basicsource.js' package='basicproduction.js' compress='true'></script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/test/basicsource.js b/browserid/static/dialog/steal/build/test/basicsource.js
new file mode 100644
index 0000000000000000000000000000000000000000..d6f4d2c806b8809a96ca7619e73c9b2c454aa01f
--- /dev/null
+++ b/browserid/static/dialog/steal/build/test/basicsource.js
@@ -0,0 +1,5 @@
+BasicSource = 5;
+(function( hereIsAVeryLongName ) {
+	hereIsAVeryLongName++;
+	BasicSource = hereIsAVeryLongName;
+})(BasicSource)
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/test/foreign.html b/browserid/static/dialog/steal/build/test/foreign.html
new file mode 100644
index 0000000000000000000000000000000000000000..99606b0b3885e36d5ac06ebd6f588b3f3214c2f7
--- /dev/null
+++ b/browserid/static/dialog/steal/build/test/foreign.html
@@ -0,0 +1,6 @@
+<html>
+	<head></head>
+	<body>
+		<script type='text/javascript' src='foreign.js' package='foreignproduction.js' compress='true'></script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/test/foreign.js b/browserid/static/dialog/steal/build/test/foreign.js
new file mode 100644
index 0000000000000000000000000000000000000000..2059dea23880f9d7589db57e89e393fe9c13ce6d
--- /dev/null
+++ b/browserid/static/dialog/steal/build/test/foreign.js
@@ -0,0 +1,2 @@
+a = "Miércoles";
+b = "Atenção";
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/test/removecode.js b/browserid/static/dialog/steal/build/test/removecode.js
new file mode 100644
index 0000000000000000000000000000000000000000..66c418a357407b31bdc60701498d64fd8b3cc271
--- /dev/null
+++ b/browserid/static/dialog/steal/build/test/removecode.js
@@ -0,0 +1,14 @@
+removeRemoveSteal = function( text ) {
+	return String(java.lang.String(text).replaceAll("(?s)\/\/@steal-remove-start(.*?)\/\/@steal-remove-end", "").replaceAll("steal[\n\s\r]*\.[\n\s\r]*dev[\n\s\r]*\.[\n\s\r]*(\w+)[\n\s\r]*\([^\)]*\)", ""))
+}
+//@steal-remove-start
+print(removeRemoveSteal(readFile("steal/compress/test/removecode.js")))
+//@steal-remove-end
+steal = {
+	dev: {
+		log: function() {},
+		isHappyName: function() {}
+	}
+}
+steal.dev.log()
+var foo = bar;
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/test/run.js b/browserid/static/dialog/steal/build/test/run.js
new file mode 100644
index 0000000000000000000000000000000000000000..28264b46b40bf20f66afcb8c6eea3a80ec037958
--- /dev/null
+++ b/browserid/static/dialog/steal/build/test/run.js
@@ -0,0 +1,70 @@
+// load('steal/compress/test/run.js')
+/**
+ * Tests compressing a very basic page and one that is using steal
+ */
+load('steal/rhino/steal.js')
+steal('//steal/test/test', function( s ) {
+	STEALPRINT = false;
+	s.test.module("steal/build")
+	
+	s.test.test("basicpage", function(){
+		
+		//lets see if we can clear everything
+		s.test.clear();
+	
+		load('steal/rhino/steal.js')
+		steal("//steal/build/build")
+		steal("//steal/build/scripts/scripts")
+	
+		steal.build("steal/build/test/basicpage.html", {
+			to: 'steal/build/test'
+		})
+		s.test.clear();
+	
+		load("steal/build/test/basicproduction.js")
+		s.test.equals(BasicSource, 6, "Basic source not right number")
+	
+	
+		s.test.clear();
+		s.test.remove('steal/build/test/basicproduction.js')
+		
+	})
+	
+	s.test.test("using stealjs", function(){
+		load('steal/rhino/steal.js')
+		steal("//steal/build/build")
+		steal("//steal/build/scripts/scripts")
+		steal.build("steal/build/test/stealpage.html", {
+			to: 'steal/build/test'
+		})
+		s.test.clear();
+	
+		s.test.open('steal/build/test/stealprodpage.html')
+		s.test.equals(BasicSource, 7, "Basic source not right number")
+		s.test.clear();
+	
+		s.test.remove('steal/build/test/production.js')
+		
+	});
+	
+	
+	s.test.test("foreign characters", function(){
+		load('steal/rhino/steal.js')
+		steal("//steal/build/build")
+		steal("//steal/build/scripts/scripts")
+		steal.build("steal/build/test/foreign.html", {
+			to: 'steal/build/test'
+		})
+		s.test.clear();
+	
+		//check that srcs are equal
+		f1 = readFile('foreign.js').replace(/\r/,"");
+		f2 = readFile('foreignproduction.js');
+		s.test.equals(f1, f2, "Foreign Characters")
+	
+		s.test.clear();
+		s.test.remove('steal/build/test/foreignproduction.js')
+	});
+
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/build/test/stealpage.html b/browserid/static/dialog/steal/build/test/stealpage.html
new file mode 100644
index 0000000000000000000000000000000000000000..69fb22e967469d84f4e78d31ce2f6ca01564fe3f
--- /dev/null
+++ b/browserid/static/dialog/steal/build/test/stealpage.html
@@ -0,0 +1,10 @@
+<html>
+	<head></head>
+	<body>
+		<script type='text/javascript' 
+                src='../../steal.js?steal[app]=steal/build/test&steal[env]=development'
+                compress='false'>   
+        </script>
+	</body>
+</html>
+
diff --git a/browserid/static/dialog/steal/build/test/stealprodpage.html b/browserid/static/dialog/steal/build/test/stealprodpage.html
new file mode 100644
index 0000000000000000000000000000000000000000..379f89ffc421a74bc8276ab9bb0f973aec71be3b
--- /dev/null
+++ b/browserid/static/dialog/steal/build/test/stealprodpage.html
@@ -0,0 +1,10 @@
+<html>
+	<head></head>
+	<body>
+		<script type='text/javascript' 
+                src='../../steal.js?steal[app]=steal/build/test&steal[env]=production'
+                compress='false'>   
+        </script>
+	</body>
+</html>
+
diff --git a/browserid/static/dialog/steal/build/test/test.js b/browserid/static/dialog/steal/build/test/test.js
new file mode 100644
index 0000000000000000000000000000000000000000..31c785f5925929275cb8c86070a71f9b2986d442
--- /dev/null
+++ b/browserid/static/dialog/steal/build/test/test.js
@@ -0,0 +1,3 @@
+steal('basicsource').then(function() {
+	BasicSource++;
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/buildjs b/browserid/static/dialog/steal/buildjs
new file mode 100644
index 0000000000000000000000000000000000000000..eea140cda161f2210f78cc03e70e9780543379e5
--- /dev/null
+++ b/browserid/static/dialog/steal/buildjs
@@ -0,0 +1,19 @@
+load("steal/rhino/steal.js");
+steal.plugins('steal/build', 'steal/build/scripts', 'steal/build/styles', 'steal/build/apps', function () {
+    //check if args
+    var urls = [];
+    while (_args.length) {
+        if (_args[0].indexOf('-') !== 0) {
+            urls.push(_args.shift());
+        } else {
+            break;
+        }
+    }
+
+    if (urls.length > 1) {
+        steal.build.apps(urls);
+    } else {
+        steal.build(urls[0], _args);
+    }
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/clean/beautify.js b/browserid/static/dialog/steal/clean/beautify.js
new file mode 100644
index 0000000000000000000000000000000000000000..fe925cfb2a59358cbf4deb2a5a854e52c813059d
--- /dev/null
+++ b/browserid/static/dialog/steal/clean/beautify.js
@@ -0,0 +1,1116 @@
+/*jslint onevar: false, plusplus: false */
+/*
+
+ JS Beautifier
+---------------
+
+
+  Written by Einar Lielmanis, <einar@jsbeautifier.org>
+      http://jsbeautifier.org/
+
+  Originally converted to javascript by Vital, <vital76@gmail.com>
+
+  You are free to use this in any way you want, in case you find this useful or working for you.
+
+  Usage:
+    js_beautify(js_source_text);
+    js_beautify(js_source_text, options);
+
+  The options are:
+    indent_size (default 4)          — indentation size,
+    indent_char (default space)      — character to indent with,
+    preserve_newlines (default true) — whether existing line breaks should be preserved,
+    indent_level (default 0)         — initial indentation level, you probably won't need this ever,
+
+    space_after_anon_function (default false) — if true, then space is added between "function ()"
+            (jslint is happy about this); if false, then the common "function()" output is used.
+    braces_on_own_line (default false) - ANSI / Allman brace style, each opening/closing brace gets its own line.
+
+    e.g
+
+    js_beautify(js_source_text, {indent_size: 1, indent_char: '\t'});
+
+
+*/
+
+
+
+js_beautify = function(js_source_text, options) {
+    var input, output, token_text, last_type, last_text, last_last_text, last_word, flags, flag_store, indent_string;
+    var whitespace, wordchar, punct, parser_pos, line_starters, digits;
+    var prefix, token_type, do_block_just_closed, in_statement_expression = false, expression_has_word = false;
+    var wanted_newline, just_added_newline, n_newlines;
+	var paren_count = 0, paren_spots = {};
+
+
+    // Some interpreters have unexpected results with foo = baz || bar;
+    options = options ? options : {};
+    var opt_braces_on_own_line = options.braces_on_own_line ? options.braces_on_own_line : false;
+    var opt_indent_size = options.indent_size ? options.indent_size : 4;
+    var opt_indent_char = options.indent_char ? options.indent_char : ' ';
+    var opt_preserve_newlines = typeof options.preserve_newlines === 'undefined' ? true : options.preserve_newlines;
+    var opt_indent_level = options.indent_level ? options.indent_level : 0; // starting indentation
+    var opt_space_after_anon_function = options.space_after_anon_function === 'undefined' ? false : options.space_after_anon_function;
+    var opt_keep_array_indentation = typeof options.keep_array_indentation === 'undefined' ? false : options.keep_array_indentation;
+	var opt_space_statement_expression = typeof options.space_statement_expression === 'undefined' ? false : options.space_statement_expression;
+	
+    just_added_newline = false;
+
+    // cache the source's length.
+    var input_length = js_source_text.length;
+
+    function trim_output() {
+        while (output.length && (output[output.length - 1] === ' ' || output[output.length - 1] === indent_string)) {
+            output.pop();
+        }
+    }
+
+    function is_array(mode) {
+        return mode === '[EXPRESSION]' || mode === '[INDENTED-EXPRESSION]';
+    }
+
+
+    function print_newline(ignore_repeated) {
+
+        flags.eat_next_space = false;
+        if (opt_keep_array_indentation && is_array(flags.mode)) {
+            return;
+        }
+
+        ignore_repeated = typeof ignore_repeated === 'undefined' ? true : ignore_repeated;
+
+        flags.if_line = false;
+        trim_output();
+
+        if (!output.length) {
+            return; // no newline on start of file
+        }
+
+        if (output[output.length - 1] !== "\n" || !ignore_repeated) {
+            just_added_newline = true;
+            output.push("\n");
+        }
+        for (var i = 0; i < flags.indentation_level; i += 1) {
+            output.push(indent_string);
+        }
+        if (flags.var_line && flags.var_line_reindented) {
+            if (opt_indent_char === ' ') {
+                output.push('    '); // var_line always pushes 4 spaces, so that the variables would be one under another
+            } else {
+                output.push(indent_string); // skip space-stuffing, if indenting with a tab
+            }
+        }
+    }
+
+
+
+    function print_single_space() {
+        if (flags.eat_next_space) {
+            flags.eat_next_space = false;
+            return;
+        }
+        var last_output = ' ';
+        if (output.length) {
+            last_output = output[output.length - 1];
+        }
+        if (last_output !== ' ' && last_output !== '\n' && last_output !== indent_string) { // prevent occassional duplicate space
+            output.push(' ');
+        }
+    }
+
+
+    function print_token() {
+        just_added_newline = false;
+        flags.eat_next_space = false;
+        output.push(token_text);
+    }
+
+    function indent() {
+        flags.indentation_level += 1;
+    }
+
+
+    function remove_indent() {
+        if (output.length && output[output.length - 1] === indent_string) {
+            output.pop();
+        }
+    }
+
+    function set_mode(mode) {
+        if (flags) {
+            flag_store.push(flags);
+        }
+        flags = {
+            previous_mode: flags ? flags.mode : 'BLOCK',
+            mode: mode,
+            var_line: false,
+            var_line_tainted: false,
+            var_line_reindented: false,
+            in_html_comment: false,
+            if_line: false,
+            in_case: false,
+            eat_next_space: false,
+            indentation_baseline: -1,
+            indentation_level: (flags ? flags.indentation_level + ((flags.var_line && flags.var_line_reindented) ? 1 : 0) : opt_indent_level)
+        };
+    }
+
+    function is_array(mode) {
+        return mode === '[EXPRESSION]' || mode === '[INDENTED-EXPRESSION]';
+    }
+
+    function is_expression(mode) {
+        return mode === '[EXPRESSION]' || mode === '[INDENTED-EXPRESSION]' || mode === '(EXPRESSION)';
+    }
+
+    function restore_mode() {
+        do_block_just_closed = flags.mode === 'DO_BLOCK';
+        if (flag_store.length > 0) {
+            flags = flag_store.pop();
+        }
+    }
+
+
+    function in_array(what, arr) {
+        for (var i = 0; i < arr.length; i += 1) {
+            if (arr[i] === what) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // Walk backwards from the colon to find a '?' (colon is part of a ternary op)
+    // or a '{' (colon is part of a class literal).  Along the way, keep track of
+    // the blocks and expressions we pass so we only trigger on those chars in our
+    // own level, and keep track of the colons so we only trigger on the matching '?'.
+
+
+    function is_ternary_op() {
+        var level = 0,
+            colon_count = 0;
+        for (var i = output.length - 1; i >= 0; i--) {
+            switch (output[i]) {
+            case ':':
+                if (level === 0) {
+                    colon_count++;
+                }
+                break;
+            case '?':
+                if (level === 0) {
+                    if (colon_count === 0) {
+                        return true;
+                    } else {
+                        colon_count--;
+                    }
+                }
+                break;
+            case '{':
+                if (level === 0) {
+                    return false;
+                }
+                level--;
+                break;
+            case '(':
+            case '[':
+                level--;
+                break;
+            case ')':
+            case ']':
+            case '}':
+                level++;
+                break;
+            }
+        }
+    }
+
+    function get_next_token() {
+        n_newlines = 0;
+
+        if (parser_pos >= input_length) {
+            return ['', 'TK_EOF'];
+        }
+
+        wanted_newline = false;
+
+        var c = input.charAt(parser_pos);
+        parser_pos += 1;
+
+
+        var keep_whitespace = opt_keep_array_indentation && is_array(flags.mode);
+
+        if (keep_whitespace) {
+
+            //
+            // slight mess to allow nice preservation of array indentation and reindent that correctly
+            // first time when we get to the arrays:
+            // var a = [
+            // ....'something'
+            // we make note of whitespace_count = 4 into flags.indentation_baseline
+            // so we know that 4 whitespaces in original source match indent_level of reindented source
+            //
+            // and afterwards, when we get to
+            //    'something,
+            // .......'something else'
+            // we know that this should be indented to indent_level + (7 - indentation_baseline) spaces
+            //
+            var whitespace_count = 0;
+
+            while (in_array(c, whitespace)) {
+
+                if (c === "\n") {
+                    trim_output();
+                    output.push("\n");
+                    just_added_newline = true;
+                    whitespace_count = 0;
+                } else {
+                    if (c === '\t') {
+                        whitespace_count += 4;
+                    } else {
+                        whitespace_count += 1;
+                    }
+                }
+
+                if (parser_pos >= input_length) {
+                    return ['', 'TK_EOF'];
+                }
+
+                c = input.charAt(parser_pos);
+                parser_pos += 1;
+
+            }
+            if (flags.indentation_baseline === -1) {
+                flags.indentation_baseline = whitespace_count;
+            }
+
+            if (just_added_newline) {
+                var i;
+                for (i = 0; i < flags.indentation_level + 1; i += 1) {
+                    output.push(indent_string);
+                }
+                if (flags.indentation_baseline !== -1) {
+                    for (i = 0; i < whitespace_count - flags.indentation_baseline; i++) {
+                        output.push(' ');
+                    }
+                }
+            }
+
+        } else {
+            while (in_array(c, whitespace)) {
+
+                if (c === "\n") {
+                    n_newlines += 1;
+                }
+
+
+                if (parser_pos >= input_length) {
+                    return ['', 'TK_EOF'];
+                }
+
+                c = input.charAt(parser_pos);
+                parser_pos += 1;
+
+            }
+
+            if (opt_preserve_newlines) {
+                if (n_newlines > 1) {
+                    for (i = 0; i < n_newlines; i += 1) {
+                        print_newline(i === 0);
+                        just_added_newline = true;
+                    }
+                }
+            }
+            wanted_newline = n_newlines > 0;
+        }
+
+
+        if (in_array(c, wordchar)) {
+            if (parser_pos < input_length) {
+                while (in_array(input.charAt(parser_pos), wordchar)) {
+                    c += input.charAt(parser_pos);
+                    parser_pos += 1;
+                    if (parser_pos === input_length) {
+                        break;
+                    }
+                }
+            }
+
+            // small and surprisingly unugly hack for 1E-10 representation
+            if (parser_pos !== input_length && c.match(/^[0-9]+[Ee]$/) && (input.charAt(parser_pos) === '-' || input.charAt(parser_pos) === '+')) {
+
+                var sign = input.charAt(parser_pos);
+                parser_pos += 1;
+
+                var t = get_next_token(parser_pos);
+                c += sign + t[0];
+                return [c, 'TK_WORD'];
+            }
+
+            if (c === 'in') { // hack for 'in' operator
+                return [c, 'TK_OPERATOR'];
+            }
+            if (wanted_newline && last_type !== 'TK_OPERATOR' && !flags.if_line && (opt_preserve_newlines || last_text !== 'var')) {
+                print_newline();
+            }
+            return [c, 'TK_WORD'];
+        }
+
+        if (c === '(' || c === '[') {
+            return [c, 'TK_START_EXPR'];
+        }
+
+        if (c === ')' || c === ']') {
+            return [c, 'TK_END_EXPR'];
+        }
+
+        if (c === '{') {
+            return [c, 'TK_START_BLOCK'];
+        }
+
+        if (c === '}') {
+            return [c, 'TK_END_BLOCK'];
+        }
+
+        if (c === ';') {
+            return [c, 'TK_SEMICOLON'];
+        }
+
+        if (c === '/') {
+            var comment = '';
+            // peek for comment /* ... */
+            var inline_comment = true;
+            if (input.charAt(parser_pos) === '*') {
+                parser_pos += 1;
+                if (parser_pos < input_length) {
+                    while (! (input.charAt(parser_pos) === '*' && input.charAt(parser_pos + 1) && input.charAt(parser_pos + 1) === '/') && parser_pos < input_length) {
+                        c = input.charAt(parser_pos);
+                        comment += c;
+                        if (c === '\x0d' || c === '\x0a') {
+                            inline_comment = false;
+                        }
+                        parser_pos += 1;
+                        if (parser_pos >= input_length) {
+                            break;
+                        }
+                    }
+                }
+                parser_pos += 2;
+                if (inline_comment) {
+                    return ['/*' + comment + '*/', 'TK_INLINE_COMMENT'];
+                } else {
+                    return ['/*' + comment + '*/', 'TK_BLOCK_COMMENT'];
+                }
+            }
+            // peek for comment // ...
+            if (input.charAt(parser_pos) === '/') {
+                comment = c;
+                while (input.charAt(parser_pos) !== "\x0d" && input.charAt(parser_pos) !== "\x0a") {
+                    comment += input.charAt(parser_pos);
+                    parser_pos += 1;
+                    if (parser_pos >= input_length) {
+                        break;
+                    }
+                }
+                parser_pos += 1;
+                if (wanted_newline) {
+                    print_newline();
+                }
+                return [comment, 'TK_COMMENT'];
+            }
+
+        }
+
+        if (c === "'" || // string
+        c === '"' || // string
+        (c === '/' && ((last_type === 'TK_WORD' && in_array(last_text, ['return', 'do'])) || (last_type === 'TK_START_EXPR' || last_type === 'TK_START_BLOCK' || last_type === 'TK_END_BLOCK' || last_type === 'TK_OPERATOR' || last_type === 'TK_EQUALS' || last_type === 'TK_EOF' || last_type === 'TK_SEMICOLON')))) { // regexp
+            var sep = c;
+            var esc = false;
+            var resulting_string = c;
+
+            if (parser_pos < input_length) {
+                if (sep === '/') {
+                    //
+                    // handle regexp separately...
+                    //
+                    var in_char_class = false;
+                    while (esc || in_char_class || input.charAt(parser_pos) !== sep) {
+                        resulting_string += input.charAt(parser_pos);
+                        if (!esc) {
+                            esc = input.charAt(parser_pos) === '\\';
+                            if (input.charAt(parser_pos) === '[') {
+                                in_char_class = true;
+                            } else if (input.charAt(parser_pos) === ']') {
+                                in_char_class = false;
+                            }
+                        } else {
+                            esc = false;
+                        }
+                        parser_pos += 1;
+                        if (parser_pos >= input_length) {
+                            // incomplete string/rexp when end-of-file reached.
+                            // bail out with what had been received so far.
+                            return [resulting_string, 'TK_STRING'];
+                        }
+                    }
+
+                } else {
+                    //
+                    // and handle string also separately
+                    //
+                    while (esc || input.charAt(parser_pos) !== sep) {
+                        resulting_string += input.charAt(parser_pos);
+                        if (!esc) {
+                            esc = input.charAt(parser_pos) === '\\';
+                        } else {
+                            esc = false;
+                        }
+                        parser_pos += 1;
+                        if (parser_pos >= input_length) {
+                            // incomplete string/rexp when end-of-file reached.
+                            // bail out with what had been received so far.
+                            return [resulting_string, 'TK_STRING'];
+                        }
+                    }
+                }
+
+
+
+            }
+
+            parser_pos += 1;
+
+            resulting_string += sep;
+
+            if (sep === '/') {
+                // regexps may have modifiers /regexp/MOD , so fetch those, too
+                while (parser_pos < input_length && in_array(input.charAt(parser_pos), wordchar)) {
+                    resulting_string += input.charAt(parser_pos);
+                    parser_pos += 1;
+                }
+            }
+            return [resulting_string, 'TK_STRING'];
+        }
+
+        if (c === '#') {
+            // Spidermonkey-specific sharp variables for circular references
+            // https://developer.mozilla.org/En/Sharp_variables_in_JavaScript
+            // http://mxr.mozilla.org/mozilla-central/source/js/src/jsscan.cpp around line 1935
+            var sharp = '#';
+            if (parser_pos < input_length && in_array(input.charAt(parser_pos), digits)) {
+                do {
+                    c = input.charAt(parser_pos);
+                    sharp += c;
+                    parser_pos += 1;
+                } while (parser_pos < input_length && c !== '#' && c !== '=');
+                if (c === '#') {
+                    //
+                } else if (input.charAt(parser_pos) === '[' && input.charAt(parser_pos + 1) === ']') {
+                    sharp += '[]';
+                    parser_pos += 2;
+                } else if (input.charAt(parser_pos) === '{' && input.charAt(parser_pos + 1) === '}') {
+                    sharp += '{}';
+                    parser_pos += 2;
+                }
+                return [sharp, 'TK_WORD'];
+            }
+        }
+
+        if (c === '<' && input.substring(parser_pos - 1, parser_pos + 3) === '<!--') {
+            parser_pos += 3;
+            flags.in_html_comment = true;
+            return ['<!--', 'TK_COMMENT'];
+        }
+
+        if (c === '-' && flags.in_html_comment && input.substring(parser_pos - 1, parser_pos + 2) === '-->') {
+            flags.in_html_comment = false;
+            parser_pos += 2;
+            if (wanted_newline) {
+                print_newline();
+            }
+            return ['-->', 'TK_COMMENT'];
+        }
+
+        if (in_array(c, punct)) {
+            while (parser_pos < input_length && in_array(c + input.charAt(parser_pos), punct)) {
+                c += input.charAt(parser_pos);
+                parser_pos += 1;
+                if (parser_pos >= input_length) {
+                    break;
+                }
+            }
+
+            if (c === '=') {
+                return [c, 'TK_EQUALS'];
+            } else {
+                return [c, 'TK_OPERATOR'];
+            }
+        }
+
+        return [c, 'TK_UNKNOWN'];
+    }
+
+    //----------------------------------
+    indent_string = '';
+    while (opt_indent_size > 0) {
+        indent_string += opt_indent_char;
+        opt_indent_size -= 1;
+    }
+
+    input = js_source_text;
+
+    last_word = ''; // last 'TK_WORD' passed
+    last_type = 'TK_START_EXPR'; // last token type
+    last_text = ''; // last token text
+    last_last_text = ''; // pre-last token text
+    output = [];
+
+    do_block_just_closed = false;
+
+    whitespace = "\n\r\t ".split('');
+    wordchar = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$'.split('');
+    digits = '0123456789'.split('');
+
+    punct = '+ - * / % & ++ -- = += -= *= /= %= == === != !== > < >= <= >> << >>> >>>= >>= <<= && &= | || ! !! , : ? ^ ^= |= ::'.split(' ');
+
+    // words which should always start on new line.
+    line_starters = 'continue,try,throw,return,var,if,switch,case,default,for,while,break,function'.split(',');
+
+    // states showing if we are currently in expression (i.e. "if" case) - 'EXPRESSION', or in usual block (like, procedure), 'BLOCK'.
+    // some formatting depends on that.
+    flag_store = [];
+    set_mode('BLOCK');
+
+    parser_pos = 0;
+    while (true) {
+        var t = get_next_token(parser_pos);
+        token_text = t[0];
+        token_type = t[1];
+        if (token_type === 'TK_EOF') {
+            break;
+        }
+
+		//print(token_text+" = "+token_type);
+        switch (token_type) {
+
+        case 'TK_START_EXPR':
+
+            if (token_text === '[') {
+
+                if (last_type === 'TK_WORD' || last_text === ')') {
+                    // this is array index specifier, break immediately
+                    // a[x], fn()[x]
+                    if (in_array(last_text, line_starters)) {
+                        print_single_space();
+                    }
+                    set_mode('(EXPRESSION)');
+                    print_token();
+                    break;
+                }
+
+                if (flags.mode === '[EXPRESSION]' || flags.mode === '[INDENTED-EXPRESSION]') {
+                    if (last_last_text === ']' && last_text === ',') {
+                        // ], [ goes to new line
+                        if (flags.mode === '[EXPRESSION]') {
+                            flags.mode = '[INDENTED-EXPRESSION]';
+                            if (!opt_keep_array_indentation) {
+                                indent();
+                            }
+                        }
+                        set_mode('[EXPRESSION]');
+                        if (!opt_keep_array_indentation) {
+                            print_newline();
+                        }
+                    } else if (last_text === '[') {
+                        if (flags.mode === '[EXPRESSION]') {
+                            flags.mode = '[INDENTED-EXPRESSION]';
+                            if (!opt_keep_array_indentation) {
+                                indent();
+                            }
+                        }
+                        set_mode('[EXPRESSION]');
+
+                        if (!opt_keep_array_indentation) {
+                            print_newline();
+                        }
+                    } else {
+                        set_mode('[EXPRESSION]');
+                    }
+                } else {
+                    set_mode('[EXPRESSION]');
+                }
+
+
+
+            } else {
+                set_mode('(EXPRESSION)');
+            }
+			if(token_text == "("){
+				paren_count++;
+			}
+            if (last_text === ';' || last_type === 'TK_START_BLOCK') {
+                print_newline();
+            } else if (last_type === 'TK_END_EXPR' || last_type === 'TK_START_EXPR' || last_type === 'TK_END_BLOCK' || last_text === '.') {
+                // do nothing on (( and )( and ][ and ]( and .(
+            } else if (last_type !== 'TK_WORD' && last_type !== 'TK_OPERATOR') {
+                print_single_space();
+            } else if (last_word === 'function') {
+                // function() vs function ()
+                if (opt_space_after_anon_function) {
+                    print_single_space();
+                }
+				paren_spots[paren_count] = false;
+				//in_statement_expression = true;
+				
+            } else if (in_array(last_text, line_starters) || last_text === 'catch') {
+                print_single_space();
+            }
+			if(last_text === 'for' || last_text === 'if' || last_text === 'while' || last_text === 'switch' || last_text === 'with'){
+				paren_spots[paren_count] = false;
+				//in_statement_expression = true;
+			}
+			
+            print_token();
+            break;
+
+        case 'TK_END_EXPR':
+            
+			if(token_text == ")"){
+				//is there someone waiting
+				var ps = paren_spots[paren_count];
+				if(ps && opt_space_statement_expression){
+					print_single_space();
+				}
+				delete paren_spots[paren_count];
+				paren_count--;
+			}
+			if (token_text === ']') {
+                if (opt_keep_array_indentation) {
+                    if (last_text === '}') {
+                        // trim_output();
+                        // print_newline(true);
+                        remove_indent();
+                        print_token();
+                        restore_mode();
+                        break;
+                    }
+                } else {
+                    if (flags.mode === '[INDENTED-EXPRESSION]') {
+                        if (last_text === ']') {
+                            restore_mode();
+                            print_newline();
+                            print_token();
+                            break;
+                        }
+                    }
+                }
+            }
+            restore_mode();
+            print_token();
+            break;
+
+        case 'TK_START_BLOCK':
+
+            if (last_word === 'do') {
+                set_mode('DO_BLOCK');
+            } else {
+                set_mode('BLOCK');
+            }
+            if (opt_braces_on_own_line) {
+                if (last_type !== 'TK_OPERATOR') {
+                    if (last_text == 'return') {
+                        print_single_space();
+                    } else {
+                        print_newline(true);
+                    }
+                }
+                print_token();
+                indent();
+            } else {
+                if (last_type !== 'TK_OPERATOR' && last_type !== 'TK_START_EXPR') {
+                    if (last_type === 'TK_START_BLOCK') {
+                        print_newline();
+                    } else {
+                        print_single_space();
+                    }
+                } else {
+                    // if TK_OPERATOR or TK_START_EXPR
+                    if (is_array(flags.previous_mode) && last_text === ',') {
+                        print_newline(); // [a, b, c, {
+                    }
+                }
+                indent();
+                print_token();
+            }
+
+            break;
+
+        case 'TK_END_BLOCK':
+            restore_mode();
+            if (opt_braces_on_own_line) {
+                print_newline();
+                print_token();
+            } else {
+                if (last_type === 'TK_START_BLOCK') {
+                    // nothing
+                    if (just_added_newline) {
+                        remove_indent();
+                    } else {
+                        // {}
+                        trim_output();
+                    }
+                } else {
+                    print_newline();
+                }
+                print_token();
+            }
+            break;
+
+        case 'TK_WORD':
+			if(typeof paren_spots[paren_count] == 'boolean'){
+
+				if(opt_space_statement_expression && ( last_text === "," || last_text == "(" )){
+					print_single_space();
+				}
+				paren_spots[paren_count] = true;
+			}
+            // no, it's not you. even I have problems understanding how this works
+            // and what does what.
+            if (do_block_just_closed) {
+                // do {} ## while ()
+                print_single_space();
+                print_token();
+                print_single_space();
+                do_block_just_closed = false;
+                break;
+            }
+
+            if (token_text === 'function') {
+                if ((just_added_newline || last_text === ';') && last_text !== '{') {
+                    // make sure there is a nice clean space of at least one blank line
+                    // before a new function definition
+                    n_newlines = just_added_newline ? n_newlines : 0;
+
+                    for (var i = 0; i < 2 - n_newlines; i++) {
+                        print_newline(false);
+                    }
+
+                }
+            }
+
+            if (token_text === 'case' || token_text === 'default') {
+                if (last_text === ':') {
+                    // switch cases following one another
+                    remove_indent();
+                } else {
+                    // case statement starts in the same line where switch
+                    flags.indentation_level--;
+                    print_newline();
+                    flags.indentation_level++;
+                }
+                print_token();
+                flags.in_case = true;
+                break;
+            }
+
+            prefix = 'NONE';
+
+            if (last_type === 'TK_END_BLOCK') {
+                if (!in_array(token_text.toLowerCase(), ['else', 'catch', 'finally'])) {
+                    prefix = 'NEWLINE';
+                } else {
+                    if (opt_braces_on_own_line) {
+                        prefix = 'NEWLINE';
+                    } else {
+                        prefix = 'SPACE';
+                        print_single_space();
+                    }
+                }
+            } else if (last_type === 'TK_SEMICOLON' && (flags.mode === 'BLOCK' || flags.mode === 'DO_BLOCK')) {
+                prefix = 'NEWLINE';
+            } else if (last_type === 'TK_SEMICOLON' && is_expression(flags.mode)) {
+                prefix = 'SPACE';
+            } else if (last_type === 'TK_STRING') {
+                prefix = 'NEWLINE';
+            } else if (last_type === 'TK_WORD') {
+                prefix = 'SPACE';
+            } else if (last_type === 'TK_START_BLOCK') {
+                prefix = 'NEWLINE';
+            } else if (last_type === 'TK_END_EXPR') {
+                print_single_space();
+                prefix = 'NEWLINE';
+            }
+
+            if (last_type !== 'TK_END_BLOCK' && in_array(token_text.toLowerCase(), ['else', 'catch', 'finally'])) {
+                print_newline();
+            } else if (in_array(token_text, line_starters) || prefix === 'NEWLINE') {
+                if (last_text === 'else') {
+                    // no need to force newline on else break
+                    print_single_space();
+                } else if ((last_type === 'TK_START_EXPR' || last_text === '=' || last_text === ',') && token_text === 'function') {
+                    // no need to force newline on 'function': (function
+                    // DONOTHING
+                } else if (last_text === 'return' || last_text === 'throw') {
+                    // no newline between 'return nnn'
+                    print_single_space();
+                } else if (last_type !== 'TK_END_EXPR') {
+                    if ((last_type !== 'TK_START_EXPR' || token_text !== 'var') && last_text !== ':') {
+                        // no need to force newline on 'var': for (var x = 0...)
+                        if (token_text === 'if' && last_word === 'else' && last_text !== '{') {
+                            // no newline for } else if {
+                            print_single_space();
+                        } else {
+                            print_newline();
+                        }
+                    }
+                } else {
+                    if (in_array(token_text, line_starters) && last_text !== ')') {
+                        print_newline();
+                    }
+                }
+            } else if (is_array(flags.mode) && last_text === ',' && last_last_text === '}') {
+                print_newline(); // }, in lists get a newline treatment
+            } else if (prefix === 'SPACE') {
+                print_single_space();
+            }
+            print_token();
+            last_word = token_text;
+
+            if (token_text === 'var') {
+                flags.var_line = true;
+                flags.var_line_reindented = false;
+                flags.var_line_tainted = false;
+            }
+
+            if (token_text === 'if' || token_text === 'else') {
+                flags.if_line = true;
+            }
+
+            break;
+
+        case 'TK_SEMICOLON':
+
+            print_token();
+            flags.var_line = false;
+            flags.var_line_reindented = false;
+            break;
+
+        case 'TK_STRING':
+
+            if (last_type === 'TK_START_BLOCK' || last_type === 'TK_END_BLOCK' || last_type === 'TK_SEMICOLON') {
+                print_newline();
+            } else if (last_type === 'TK_WORD') {
+                print_single_space();
+            }
+            print_token();
+            break;
+
+        case 'TK_EQUALS':
+            if (flags.var_line) {
+                // just got an '=' in a var-line, different formatting/line-breaking, etc will now be done
+                flags.var_line_tainted = true;
+            }
+            print_single_space();
+            print_token();
+            print_single_space();
+            break;
+
+        case 'TK_OPERATOR':
+
+            var space_before = true;
+            var space_after = true;
+
+            if (flags.var_line && token_text === ',' && (is_expression(flags.mode))) {
+                // do not break on comma, for(var a = 1, b = 2)
+                flags.var_line_tainted = false;
+            }
+
+            if (flags.var_line) {
+                if (token_text === ',') {
+                    if (flags.var_line_tainted) {
+                        print_token();
+                        flags.var_line_reindented = true;
+                        flags.var_line_tainted = false;
+                        print_newline();
+                        break;
+                    } else {
+                        flags.var_line_tainted = false;
+                    }
+                // } else if (token_text === ':') {
+                    // hmm, when does this happen? tests don't catch this
+                    // flags.var_line = false;
+                }
+            }
+
+            if (last_text === 'return' || last_text === 'throw') {
+                // "return" had a special handling in TK_WORD. Now we need to return the favor
+                print_single_space();
+                print_token();
+                break;
+            }
+
+            if (token_text === ':' && flags.in_case) {
+                print_token(); // colon really asks for separate treatment
+                print_newline();
+                flags.in_case = false;
+                break;
+            }
+
+            if (token_text === '::') {
+                // no spaces around exotic namespacing syntax operator
+                print_token();
+                break;
+            }
+
+            if (token_text === ',') {
+                if (flags.var_line) {
+                    if (flags.var_line_tainted) {
+                        print_token();
+                        print_newline();
+                        flags.var_line_tainted = false;
+                    } else {
+                        print_token();
+                        print_single_space();
+                    }
+                } else if (last_type === 'TK_END_BLOCK' && flags.mode !== "(EXPRESSION)") {
+                    print_token();
+                    if (flags.mode === 'OBJECT' && last_text === '}') {
+                        print_newline();
+                    } else {
+                        print_single_space();
+                    }
+                } else {
+                    if (flags.mode === 'OBJECT') {
+                        print_token();
+                        print_newline();
+                    } else {
+                        // EXPR or DO_BLOCK
+                        print_token();
+                        print_single_space();
+                    }
+                }
+                break;
+            // } else if (in_array(token_text, ['--', '++', '!']) || (in_array(token_text, ['-', '+']) && (in_array(last_type, ['TK_START_BLOCK', 'TK_START_EXPR', 'TK_EQUALS']) || in_array(last_text, line_starters) || in_array(last_text, ['==', '!=', '+=', '-=', '*=', '/=', '+', '-'])))) {
+            } else if (in_array(token_text, ['--', '++', '!']) || (in_array(token_text, ['-', '+']) && (in_array(last_type, ['TK_START_BLOCK', 'TK_START_EXPR', 'TK_EQUALS', 'TK_OPERATOR']) || in_array(last_text, line_starters)))) {
+                // unary operators (and binary +/- pretending to be unary) special cases
+
+                space_before = false;
+                space_after = false;
+
+                if (last_text === ';' && is_expression(flags.mode)) {
+                    // for (;; ++i)
+                    //        ^^^
+                    space_before = true;
+                }
+                if (last_type === 'TK_WORD' && in_array(last_text, line_starters)) {
+                    space_before = true;
+                }
+
+                if (flags.mode === 'BLOCK' && (last_text === '{' || last_text === ';')) {
+                    // { foo; --i }
+                    // foo(); --bar;
+                    print_newline();
+                }
+            } else if (token_text === '.') {
+                // decimal digits or object.property
+                space_before = false;
+
+            } else if (token_text === ':') {
+                if (!is_ternary_op()) {
+                    flags.mode = 'OBJECT';
+                    space_before = false;
+                }
+            }
+            if (space_before) {
+                print_single_space();
+            }
+
+            print_token();
+
+            if (space_after) {
+                print_single_space();
+            }
+
+            if (token_text === '!') {
+                // flags.eat_next_space = true;
+            }
+
+            break;
+
+        case 'TK_BLOCK_COMMENT':
+
+            var lines = token_text.split(/\x0a|\x0d\x0a/);
+
+            if (/^\/\*\*/.test(token_text)) {
+            	
+                // javadoc: reformat and reindent
+                print_newline();
+                output.push(lines[0]);
+                for (i = 1; i < lines.length; i++) {
+                    print_newline();
+                    output.push(' ');
+                    output.push(lines[i].replace(/^\s\s*|\s\s*$/, ''));
+                }
+                
+            } else {
+                // simple block comment: leave intact
+                if (lines.length > 1) {
+                    // multiline comment block starts with a new line
+                    print_newline();
+                    trim_output();
+                } else {
+                    // single-line /* comment */ stays where it is
+                	print_single_space();
+                }
+                for (i = 0; i < lines.length; i++) {
+                    output.push(lines[i]);
+                    output.push('\n');
+                }
+
+            }
+            print_newline();
+            break;
+
+        case 'TK_INLINE_COMMENT':
+        	// Slightly misleading name, this deals with this style comment:  /* foo */ - JCK  
+        	
+            print_single_space();
+            
+            // Give the comment its own line - JCK
+            print_newline();
+            print_token();
+            print_newline();
+            
+            
+            if (is_expression(flags.mode)) {
+                print_single_space();
+            } else {
+                print_newline();
+            }
+            break;
+
+        case 'TK_COMMENT':
+        	
+            //print_newline();
+            
+            if (wanted_newline) {
+                print_newline();
+            } else {
+                print_single_space();
+            }
+            print_token();
+            print_newline();
+            break;
+
+        case 'TK_UNKNOWN':
+            print_token();
+            break;
+        }
+
+        last_last_text = last_text;
+        last_type = token_type;
+        last_text = token_text;
+    }
+
+    return output.join('').replace(/[\n ]+$/, '');
+
+}
diff --git a/browserid/static/dialog/steal/clean/clean.js b/browserid/static/dialog/steal/clean/clean.js
new file mode 100644
index 0000000000000000000000000000000000000000..317ac03a55d65272b75d93012f2eb2f63c3e46d8
--- /dev/null
+++ b/browserid/static/dialog/steal/clean/clean.js
@@ -0,0 +1,181 @@
+// lets you know if your JS sucks and will try to clean it for you
+// using with jslint: js steal/cleanjs path/to/file -jslint
+
+steal.plugins('steal/build').then('//steal/clean/beautify','//steal/clean/jslint','//steal/rhino/prompt', function(steal){
+	var lintAndPrint = function(out, predefined){
+		
+
+		JSLINT(out,{devel: true, forin: true, browser: true, windows: true, rhino: true, predefined : predefined});
+		if(JSLINT.errors.length){
+			//var lines = out.split('\n'), line, error;
+			for(var i = 0; i < JSLINT.errors.length; i++){
+				error = JSLINT.errors[i];
+				if(!error.evidence){
+					break;
+				}
+				line = error.evidence.replace(/\t/g,"     ");
+
+				print("    "+error.line+":"+error.character+"  "+
+					line.substring(Math.max(error.character-25, 0), 
+					   Math.min(error.character+25, line.length)).replace(/^\s+/,"")
+					
+					)
+				print(" ")
+			}
+		}
+		
+		var data  = JSLINT.data();
+		//if(data.globals){
+		//	print("  GLOBALS \n    "+data.globals.join("\n    "))
+		//}
+		if(data.unused){
+			print("  UNUSED    ");
+			for(var i =0; i < data.unused.length; i++){
+				print("    "+data.unused[i].line+" : "+data.unused[i].name)
+			}
+		}
+		if(data.implieds){
+			print("  implied    ");
+			for(var i =0; i < data.implieds.length; i++){
+				print("    "+data.implieds[i].line+" : "+data.implieds[i].name)
+			}
+		}
+		return JSLINT.errors.length > 0 
+	}
+	
+	
+	/**
+	 * @parent stealjs
+	 * <p>Beautifies source code with [http://jsbeautifier.org/ JS Beautify]
+	 * and checks it for trouble spots with 
+	 * [http://www.jslint.com/ JSLint].
+	 * </p>
+	 * <p>The following cleans all scripts found in myapp/myapp.html.</p>
+	 * @codestart text
+	 * ./js steal/cleanjs myapp/myapp.html
+	 * @codeend
+	 * <h2>Use</h2>
+	 * <p>Typically, steal.clean is used from the command line
+	 * <code>steal/cleanjs</code> script.  It takes
+	 * a path to an html or js file on the filesystem and
+	 * a list of options.  It then
+	 * updates the file or files in place.</p>
+	 * <p><b>Using on a single file</b></p>
+	 * @codestart text
+	 * ./js steal/cleanjs myapp/myapp.js
+	 * @codeend
+	 * <p><b>Using on many files</b></p>
+	 * @codestart text
+	 * ./js steal/cleanjs myapp/myapp.html
+	 * @codeend
+	 * <h2>Turning on JSLint and other options</h2>
+	 * Turn on JSLint like:
+	 * @codestart text
+	 * ./js steal/cleanjs myapp/myapp.js -jslint true
+	 * @codeend
+	 * <p>You can pass other options in a similar way.</p>
+	 * <h2>The clean script</h2>
+	 * When you generate a JavaScriptMVC application, it comes with
+	 * a steal script.  You can modify the options in this file.</p>
+	 * <h2>Ignoring Files</h2>
+	 * To ignore a file from your application, mark it as clean with a comment like:
+	 * @codestart
+	 * //@steal-clean
+	 * @codeend
+	 * <h2>The steal.clean function</h2>
+	 * <p>Takes a relative path to a file on the filesystem;
+	 * checks if it is a html page or a single js file; runs 
+	 * beautify on it then optionally runs JSLint.</p>
+	 * @param {String} url the path to a page or a JS file
+	 * @param {Object} [options] an optional set of params.  If you
+	 * want to turn on steal, this should be true.
+	 * 
+	 */
+	steal.clean = function(url, options){
+		options = steal.extend(
+			{indent_size: 1, 
+			 indent_char: '\t', 
+			 space_statement_expression: true,
+			 jquery : false},
+			steal.opts(options || {}, {
+				//compress everything, regardless of what you find
+				all : 1,
+				//folder to build to, defaults to the folder the page is in
+				to: 1,
+				print : 1,
+				jslint :1,
+				predefined: 1
+			}) )
+		
+		//if it ends with js, just rewwrite
+		if(/\.js/.test(url)){
+			var text = readFile(url);
+			steal.print('Beautifying '+url)
+			var out = js_beautify(text, options);
+			if(options.print){
+				print(out)
+			}else{
+				steal.File(url).save( out  )
+			}
+			if(options.jslint){
+				var errors = lintAndPrint(out, options.predefined || {});
+				if(errors){
+					print("quiting because of JSLint Errors");
+					quit();
+				}
+			}
+		}else{
+			var folder = steal.File(url).dir(),
+				clean = /\/\/@steal-clean/
+			//folder
+			
+			steal.build.open(url).each(function(script, text, i){
+				if(!text || !script.src){
+					return;
+				}
+				var path = steal.File(script.src).joinFrom(folder).replace(/\?.*/,"")
+				if(clean.test(text) || (options.ignore && options.ignore.test(path) ) ){
+					print("I "+path)
+				}else{
+					var out = js_beautify(text, options);
+					if(out == text){
+						print("C "+path);
+						if(options.jslint){
+							var errors = lintAndPrint(out, options.predefined || {});
+							if(errors){
+								print("quiting because of JSLint Errors");
+								quit();
+							}
+						}
+						
+					}else{
+						if(steal.prompt.yesno("B "+path+" Overwrite? [Yn]")){
+							if(options.print){
+								print(out)
+							}else{
+								steal.File(path).save( out  )
+							}
+							
+							if(options.jslint){
+								var errors = lintAndPrint(out, options.predefined || {});
+								if(errors){
+									print("quiting because of JSLint Errors");
+									quit();
+								}
+							}
+						}
+	
+					}
+					
+				}
+			});
+		}
+		
+		
+		
+		
+	};
+	
+
+  
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/clean/jslint.js b/browserid/static/dialog/steal/clean/jslint.js
new file mode 100644
index 0000000000000000000000000000000000000000..156a9711f0475892023bc2aedf9b010eee72fef7
--- /dev/null
+++ b/browserid/static/dialog/steal/clean/jslint.js
@@ -0,0 +1,5665 @@
+// jslint.js
+// 2010-08-08
+
+/*
+Copyright (c) 2002 Douglas Crockford  (www.JSLint.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+The Software shall be used for Good, not Evil.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+/*
+    JSLINT is a global function. It takes two parameters.
+
+        var myResult = JSLINT(source, option);
+
+    The first parameter is either a string or an array of strings. If it is a
+    string, it will be split on '\n' or '\r'. If it is an array of strings, it
+    is assumed that each string represents one line. The source can be a
+    JavaScript text, or HTML text, or a Konfabulator text.
+
+    The second parameter is an optional object of options which control the
+    operation of JSLINT. Most of the options are booleans: They are all are
+    optional and have a default value of false.
+
+    If it checks out, JSLINT returns true. Otherwise, it returns false.
+
+    If false, you can inspect JSLINT.errors to find out the problems.
+    JSLINT.errors is an array of objects containing these members:
+
+    {
+        line      : The line (relative to 0) at which the lint was found
+        character : The character (relative to 0) at which the lint was found
+        reason    : The problem
+        evidence  : The text line in which the problem occurred
+        raw       : The raw message before the details were inserted
+        a         : The first detail
+        b         : The second detail
+        c         : The third detail
+        d         : The fourth detail
+    }
+
+    If a fatal error was found, a null will be the last element of the
+    JSLINT.errors array.
+
+    You can request a Function Report, which shows all of the functions
+    and the parameters and vars that they use. This can be used to find
+    implied global variables and other problems. The report is in HTML and
+    can be inserted in an HTML <body>.
+
+        var myReport = JSLINT.report(limited);
+
+    If limited is true, then the report will be limited to only errors.
+
+    You can request a data structure which contains JSLint's results.
+
+        var myData = JSLINT.data();
+
+    It returns a structure with this form:
+
+    {
+        errors: [
+            {
+                line: NUMBER,
+                character: NUMBER,
+                reason: STRING,
+                evidence: STRING
+            }
+        ],
+        functions: [
+            name: STRING,
+            line: NUMBER,
+            last: NUMBER,
+            param: [
+                STRING
+            ],
+            closure: [
+                STRING
+            ],
+            var: [
+                STRING
+            ],
+            exception: [
+                STRING
+            ],
+            outer: [
+                STRING
+            ],
+            unused: [
+                STRING
+            ],
+            global: [
+                STRING
+            ],
+            label: [
+                STRING
+            ]
+        ],
+        globals: [
+            STRING
+        ],
+        member: {
+            STRING: NUMBER
+        },
+        unuseds: [
+            {
+                name: STRING,
+                line: NUMBER
+            }
+        ],
+        implieds: [
+            {
+                name: STRING,
+                line: NUMBER
+            }
+        ],
+        urls: [
+            STRING
+        ],
+        json: BOOLEAN
+    }
+
+    Empty arrays will not be included.
+
+*/
+
+/*jslint
+    evil: true, nomen: false, onevar: false, regexp: false, strict: true
+*/
+
+/*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%",
+    "(begin)", "(breakage)", "(context)", "(error)", "(global)",
+    "(identifier)", "(last)", "(line)", "(loopage)", "(name)", "(onevar)",
+    "(params)", "(scope)", "(verb)", "*", "+", "++", "-", "--", "\/",
+    "<", "<=", "==", "===", ">", ">=", ADSAFE, ActiveXObject,
+    Array, Boolean, COM, CScript, Canvas, CustomAnimation, Date, Debug, E,
+    Enumerator, Error, EvalError, FadeAnimation, Flash, FormField, Frame,
+    Function, HotKey, Image, JSON, LN10, LN2, LOG10E, LOG2E, MAX_VALUE,
+    MIN_VALUE, Math, MenuItem, MoveAnimation, NEGATIVE_INFINITY, Number,
+    Object, Option, PI, POSITIVE_INFINITY, Point, RangeError, Rectangle,
+    ReferenceError, RegExp, ResizeAnimation, RotateAnimation, SQRT1_2,
+    SQRT2, ScrollBar, String, Style, SyntaxError, System, Text, TextArea,
+    Timer, TypeError, URIError, URL, VBArray, WScript, Web, Window, XMLDOM,
+    XMLHttpRequest, "\\", a, abbr, acronym, addEventListener, address,
+    adsafe, alert, aliceblue, animator, antiquewhite, appleScript, applet,
+    apply, approved, aqua, aquamarine, area, arguments, arity, article,
+    aside, audio, autocomplete, azure, b, background,
+    "background-attachment", "background-color", "background-image",
+    "background-position", "background-repeat", base, bdo, beep, beige, big,
+    bisque, bitwise, black, blanchedalmond, block, blockquote, blue,
+    blueviolet, blur, body, border, "border-bottom", "border-bottom-color",
+    "border-bottom-style", "border-bottom-width", "border-collapse",
+    "border-color", "border-left", "border-left-color", "border-left-style",
+    "border-left-width", "border-right", "border-right-color",
+    "border-right-style", "border-right-width", "border-spacing",
+    "border-style", "border-top", "border-top-color", "border-top-style",
+    "border-top-width", "border-width", bottom, br, brown, browser,
+    burlywood, button, bytesToUIString, c, cadetblue, call, callee, caller,
+    canvas, cap, caption, "caption-side", cases, center, charAt, charCodeAt,
+    character, chartreuse, chocolate, chooseColor, chooseFile, chooseFolder,
+    cite, clear, clearInterval, clearTimeout, clip, close, closeWidget,
+    closed, closure, cm, code, col, colgroup, color, command, comment,
+    condition, confirm, console, constructor, content, convertPathToHFS,
+    convertPathToPlatform, coral, cornflowerblue, cornsilk,
+    "counter-increment", "counter-reset", create, crimson, css, cursor,
+    cyan, d, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen,
+    darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, darkred,
+    darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise,
+    darkviolet, data, datalist, dd, debug, decodeURI, decodeURIComponent,
+    deeppink, deepskyblue, defaultStatus, defineClass, del, deserialize,
+    details, devel, dfn, dialog, dimension, dimgray, dir, direction,
+    display, div, dl, document, dodgerblue, dt, edition, else, em, embed,
+    empty, "empty-cells", encodeURI, encodeURIComponent, entityify, eqeqeq,
+    errors, es5, escape, eval, event, evidence, evil, ex, exception, exec, exps,
+    fieldset, figure, filesystem, firebrick, first, float, floor,
+    floralwhite, focus, focusWidget, font, "font-face", "font-family",
+    "font-size", "font-size-adjust", "font-stretch", "font-style",
+    "font-variant", "font-weight", footer, forestgreen, forin, form,
+    fragment, frame, frames, frameset, from, fromCharCode, fuchsia, fud,
+    funct, function, functions, g, gainsboro, gc, getComputedStyle,
+    ghostwhite, global, globals, gold, goldenrod, gray, green, greenyellow,
+    h1, h2, h3, h4, h5, h6, hasOwnProperty, head, header, height, help,
+    hgroup, history, honeydew, hotpink, hr, 'hta:application', html,
+    i, iTunes, id, identifier,
+    iframe, img, immed, implieds, in, include, indent, indexOf, indianred,
+    indigo, init, input, ins, isAlpha, isApplicationRunning, isDigit,
+    isFinite, isNaN, ivory, join, jslint, json, kbd, keygen, khaki,
+    konfabulatorVersion, label, labelled, lang, last, lavender,
+    lavenderblush, lawngreen, laxbreak, lbp, led, left, legend,
+    lemonchiffon, length, "letter-spacing", li, lib, lightblue, lightcoral,
+    lightcyan, lightgoldenrodyellow, lightgreen, lightpink, lightsalmon,
+    lightseagreen, lightskyblue, lightslategray, lightsteelblue,
+    lightyellow, lime, limegreen, line, "line-height", linen, link,
+    "list-style", "list-style-image", "list-style-position",
+    "list-style-type", load, loadClass, location, log, m, magenta, map,
+    margin, "margin-bottom", "margin-left", "margin-right", "margin-top",
+    mark, "marker-offset", maroon, match, "max-height", "max-width", maxerr,
+    maxlen, md5, media, mediumaquamarine, mediumblue, mediumorchid,
+    mediumpurple, mediumseagreen, mediumslateblue, mediumspringgreen,
+    mediumturquoise, mediumvioletred, member, menu, message, meta, meter,
+    midnightblue, "min-height", "min-width", mintcream, mistyrose, mm,
+    moccasin, moveBy, moveTo, name, nav, navajowhite, navigator, navy, new,
+    newcap, noframes, nomen, noscript, nud, object, ol, oldlace, olive,
+    olivedrab, on, onbeforeunload, onblur, onerror, onevar, onfocus, onload,
+    onresize, onunload, opacity, open, openURL, opener, opera, optgroup,
+    option, orange, orangered, orchid, outer, outline, "outline-color",
+    "outline-style", "outline-width", output, overflow, "overflow-x",
+    "overflow-y", p, padding, "padding-bottom", "padding-left",
+    "padding-right", "padding-top", page, "page-break-after",
+    "page-break-before", palegoldenrod, palegreen, paleturquoise,
+    palevioletred, papayawhip, param, parent, parseFloat, parseInt,
+    passfail, pc, peachpuff, peru, pink, play, plum, plusplus, pop,
+    popupMenu, position, powderblue, pre, predef, preferenceGroups,
+    preferences, print, progress, prompt, prototype, pt, purple, push, px,
+    q, quit, quotes, random, range, raw, reach, readFile, readUrl, reason,
+    red, regexp, reloadWidget, removeEventListener, replace, report,
+    reserved, resizeBy, resizeTo, resolvePath, resumeUpdates, rhino, right,
+    rosybrown, royalblue, rp, rt, ruby, runCommand, runCommandInBg,
+    saddlebrown, safe, salmon, samp, sandybrown, saveAs, savePreferences,
+    screen, script, scroll, scrollBy, scrollTo, seagreen, seal, search,
+    seashell, section, select, serialize, setInterval, setTimeout, shift,
+    showWidgetPreferences, sienna, silver, skyblue, slateblue, slategray,
+    sleep, slice, small, snow, sort, source, span, spawn, speak, split,
+    springgreen, src, stack, status, steelblue, strict, strong, style,
+    styleproperty, sub, substr, sup, supplant, suppressUpdates, sync,
+    system, table, "table-layout", tan, tbody, td, teal, tellWidget, test,
+    "text-align", "text-decoration", "text-indent", "text-shadow",
+    "text-transform", textarea, tfoot, th, thead, thistle, time, title,
+    toLowerCase, toString, toUpperCase, toint32, token, tomato, top, tr, tt,
+    turquoise, type, u, ul, undef, unescape, "unicode-bidi", unused,
+    unwatch, updateNow, urls, value, valueOf, var, version,
+    "vertical-align", video, violet, visibility, watch, wheat, white,
+    "white-space", whitesmoke, widget, width, windows, "word-spacing",
+    "word-wrap", yahooCheckLogin, yahooLogin, yahooLogout, yellow,
+    yellowgreen, "z-index"
+*/
+
+// We build the application inside a function so that we produce only a single
+// global variable. The function will be invoked, its return value is the JSLINT
+// application itself.
+
+"use strict";
+
+JSLINT = (function () {
+    var adsafe_id,      // The widget's ADsafe id.
+        adsafe_may,     // The widget may load approved scripts.
+        adsafe_went,    // ADSAFE.go has been called.
+        anonname,       // The guessed name for anonymous functions.
+        approved,       // ADsafe approved urls.
+
+        atrule = {
+            media      : true,
+            'font-face': true,
+            page       : true
+        },
+
+// These are operators that should not be used with the ! operator.
+
+        bang = {
+            '<': true,
+            '<=': true,
+            '==': true,
+            '===': true,
+            '!==': true,
+            '!=': true,
+            '>': true,
+            '>=': true,
+            '+': true,
+            '-': true,
+            '*': true,
+            '/': true,
+            '%': true
+        },
+
+// These are members that should not be permitted in the safe subset.
+
+        banned = {              // the member names that ADsafe prohibits.
+            'arguments'     : true,
+            callee          : true,
+            caller          : true,
+            constructor     : true,
+            'eval'          : true,
+            prototype       : true,
+            stack           : true,
+            unwatch         : true,
+            valueOf         : true,
+            watch           : true
+        },
+
+
+// These are the JSLint boolean options.
+
+        boolOptions = {
+            adsafe     : true, // if ADsafe should be enforced
+            bitwise    : true, // if bitwise operators should not be allowed
+            browser    : true, // if the standard browser globals should be predefined
+            cap        : true, // if upper case HTML should be allowed
+            css        : true, // if CSS workarounds should be tolerated
+            debug      : true, // if debugger statements should be allowed
+            devel      : true, // if logging should be allowed (console, alert, etc.)
+            eqeqeq     : true, // if === should be required
+            es5        : true, // if ES5 syntax should be allowed
+            evil       : true, // if eval should be allowed
+            forin      : true, // if for in statements must filter
+            fragment   : true, // if HTML fragments should be allowed
+            immed      : true, // if immediate invocations must be wrapped in parens
+            laxbreak   : true, // if line breaks should not be checked
+            newcap     : true, // if constructor names must be capitalized
+            nomen      : true, // if names should be checked
+            on         : true, // if HTML event handlers should be allowed
+            onevar     : true, // if only one var statement per function should be allowed
+            passfail   : true, // if the scan should stop on first error
+            plusplus   : true, // if increment/decrement should not be allowed
+            regexp     : true, // if the . should not be allowed in regexp literals
+            rhino      : true, // if the Rhino environment globals should be predefined
+            undef      : true, // if variables should be declared before used
+            safe       : true, // if use of some browser features should be restricted
+            windows    : true, // if MS Windows-specigic globals should be predefined
+            strict     : true, // require the "use strict"; pragma
+            sub        : true, // if all forms of subscript notation are tolerated
+            white      : true, // if strict whitespace rules apply
+            widget     : true  // if the Yahoo Widgets globals should be predefined
+        },
+
+// browser contains a set of global names which are commonly provided by a
+// web browser environment.
+
+        browser = {
+            addEventListener: false,
+            blur            : false,
+            clearInterval   : false,
+            clearTimeout    : false,
+            close           : false,
+            closed          : false,
+            defaultStatus   : false,
+            document        : false,
+            event           : false,
+            focus           : false,
+            frames          : false,
+            getComputedStyle: false,
+            history         : false,
+            Image           : false,
+            length          : false,
+            location        : false,
+            moveBy          : false,
+            moveTo          : false,
+            name            : false,
+            navigator       : false,
+            onbeforeunload  : true,
+            onblur          : true,
+            onerror         : true,
+            onfocus         : true,
+            onload          : true,
+            onresize        : true,
+            onunload        : true,
+            open            : false,
+            opener          : false,
+            Option          : false,
+            parent          : false,
+            print           : false,
+            removeEventListener: false,
+            resizeBy        : false,
+            resizeTo        : false,
+            screen          : false,
+            scroll          : false,
+            scrollBy        : false,
+            scrollTo        : false,
+            setInterval     : false,
+            setTimeout      : false,
+            status          : false,
+            top             : false,
+            XMLHttpRequest  : false
+        },
+
+        cssAttributeData,
+        cssAny,
+
+        cssColorData = {
+            "aliceblue"             : true,
+            "antiquewhite"          : true,
+            "aqua"                  : true,
+            "aquamarine"            : true,
+            "azure"                 : true,
+            "beige"                 : true,
+            "bisque"                : true,
+            "black"                 : true,
+            "blanchedalmond"        : true,
+            "blue"                  : true,
+            "blueviolet"            : true,
+            "brown"                 : true,
+            "burlywood"             : true,
+            "cadetblue"             : true,
+            "chartreuse"            : true,
+            "chocolate"             : true,
+            "coral"                 : true,
+            "cornflowerblue"        : true,
+            "cornsilk"              : true,
+            "crimson"               : true,
+            "cyan"                  : true,
+            "darkblue"              : true,
+            "darkcyan"              : true,
+            "darkgoldenrod"         : true,
+            "darkgray"              : true,
+            "darkgreen"             : true,
+            "darkkhaki"             : true,
+            "darkmagenta"           : true,
+            "darkolivegreen"        : true,
+            "darkorange"            : true,
+            "darkorchid"            : true,
+            "darkred"               : true,
+            "darksalmon"            : true,
+            "darkseagreen"          : true,
+            "darkslateblue"         : true,
+            "darkslategray"         : true,
+            "darkturquoise"         : true,
+            "darkviolet"            : true,
+            "deeppink"              : true,
+            "deepskyblue"           : true,
+            "dimgray"               : true,
+            "dodgerblue"            : true,
+            "firebrick"             : true,
+            "floralwhite"           : true,
+            "forestgreen"           : true,
+            "fuchsia"               : true,
+            "gainsboro"             : true,
+            "ghostwhite"            : true,
+            "gold"                  : true,
+            "goldenrod"             : true,
+            "gray"                  : true,
+            "green"                 : true,
+            "greenyellow"           : true,
+            "honeydew"              : true,
+            "hotpink"               : true,
+            "indianred"             : true,
+            "indigo"                : true,
+            "ivory"                 : true,
+            "khaki"                 : true,
+            "lavender"              : true,
+            "lavenderblush"         : true,
+            "lawngreen"             : true,
+            "lemonchiffon"          : true,
+            "lightblue"             : true,
+            "lightcoral"            : true,
+            "lightcyan"             : true,
+            "lightgoldenrodyellow"  : true,
+            "lightgreen"            : true,
+            "lightpink"             : true,
+            "lightsalmon"           : true,
+            "lightseagreen"         : true,
+            "lightskyblue"          : true,
+            "lightslategray"        : true,
+            "lightsteelblue"        : true,
+            "lightyellow"           : true,
+            "lime"                  : true,
+            "limegreen"             : true,
+            "linen"                 : true,
+            "magenta"               : true,
+            "maroon"                : true,
+            "mediumaquamarine"      : true,
+            "mediumblue"            : true,
+            "mediumorchid"          : true,
+            "mediumpurple"          : true,
+            "mediumseagreen"        : true,
+            "mediumslateblue"       : true,
+            "mediumspringgreen"     : true,
+            "mediumturquoise"       : true,
+            "mediumvioletred"       : true,
+            "midnightblue"          : true,
+            "mintcream"             : true,
+            "mistyrose"             : true,
+            "moccasin"              : true,
+            "navajowhite"           : true,
+            "navy"                  : true,
+            "oldlace"               : true,
+            "olive"                 : true,
+            "olivedrab"             : true,
+            "orange"                : true,
+            "orangered"             : true,
+            "orchid"                : true,
+            "palegoldenrod"         : true,
+            "palegreen"             : true,
+            "paleturquoise"         : true,
+            "palevioletred"         : true,
+            "papayawhip"            : true,
+            "peachpuff"             : true,
+            "peru"                  : true,
+            "pink"                  : true,
+            "plum"                  : true,
+            "powderblue"            : true,
+            "purple"                : true,
+            "red"                   : true,
+            "rosybrown"             : true,
+            "royalblue"             : true,
+            "saddlebrown"           : true,
+            "salmon"                : true,
+            "sandybrown"            : true,
+            "seagreen"              : true,
+            "seashell"              : true,
+            "sienna"                : true,
+            "silver"                : true,
+            "skyblue"               : true,
+            "slateblue"             : true,
+            "slategray"             : true,
+            "snow"                  : true,
+            "springgreen"           : true,
+            "steelblue"             : true,
+            "tan"                   : true,
+            "teal"                  : true,
+            "thistle"               : true,
+            "tomato"                : true,
+            "turquoise"             : true,
+            "violet"                : true,
+            "wheat"                 : true,
+            "white"                 : true,
+            "whitesmoke"            : true,
+            "yellow"                : true,
+            "yellowgreen"           : true
+        },
+
+        cssBorderStyle,
+        cssBreak,
+
+        cssLengthData = {
+            '%': true,
+            'cm': true,
+            'em': true,
+            'ex': true,
+            'in': true,
+            'mm': true,
+            'pc': true,
+            'pt': true,
+            'px': true
+        },
+
+        cssOverflow,
+
+        devel = {
+            alert           : false,
+            confirm         : false,
+            console         : false,
+            Debug           : false,
+            opera           : false,
+            prompt          : false
+        },
+
+        escapes = {
+            '\b': '\\b',
+            '\t': '\\t',
+            '\n': '\\n',
+            '\f': '\\f',
+            '\r': '\\r',
+            '"' : '\\"',
+            '/' : '\\/',
+            '\\': '\\\\'
+        },
+
+        funct,          // The current function
+
+        functionicity = [
+            'closure', 'exception', 'global', 'label',
+            'outer', 'unused', 'var'
+        ],
+
+        functions,      // All of the functions
+
+        global,         // The global scope
+        htmltag = {
+            a:        {},
+            abbr:     {},
+            acronym:  {},
+            address:  {},
+            applet:   {},
+            area:     {empty: true, parent: ' map '},
+            article:  {},
+            aside:    {},
+            audio:    {},
+            b:        {},
+            base:     {empty: true, parent: ' head '},
+            bdo:      {},
+            big:      {},
+            blockquote: {},
+            body:     {parent: ' html noframes '},
+            br:       {empty: true},
+            button:   {},
+            canvas:   {parent: ' body p div th td '},
+            caption:  {parent: ' table '},
+            center:   {},
+            cite:     {},
+            code:     {},
+            col:      {empty: true, parent: ' table colgroup '},
+            colgroup: {parent: ' table '},
+            command:  {parent: ' menu '},
+            datalist: {},
+            dd:       {parent: ' dl '},
+            del:      {},
+            details:  {},
+            dialog:   {},
+            dfn:      {},
+            dir:      {},
+            div:      {},
+            dl:       {},
+            dt:       {parent: ' dl '},
+            em:       {},
+            embed:    {},
+            fieldset: {},
+            figure:   {},
+            font:     {},
+            footer:   {},
+            form:     {},
+            frame:    {empty: true, parent: ' frameset '},
+            frameset: {parent: ' html frameset '},
+            h1:       {},
+            h2:       {},
+            h3:       {},
+            h4:       {},
+            h5:       {},
+            h6:       {},
+            head:     {parent: ' html '},
+            header:   {},
+            hgroup:   {},
+            hr:       {empty: true},
+            'hta:application':
+                      {empty: true, parent: ' head '},
+            html:     {parent: '*'},
+            i:        {},
+            iframe:   {},
+            img:      {empty: true},
+            input:    {empty: true},
+            ins:      {},
+            kbd:      {},
+            keygen:   {},
+            label:    {},
+            legend:   {parent: ' details fieldset figure '},
+            li:       {parent: ' dir menu ol ul '},
+            link:     {empty: true, parent: ' head '},
+            map:      {},
+            mark:     {},
+            menu:     {},
+            meta:     {empty: true, parent: ' head noframes noscript '},
+            meter:    {},
+            nav:      {},
+            noframes: {parent: ' html body '},
+            noscript: {parent: ' body head noframes '},
+            object:   {},
+            ol:       {},
+            optgroup: {parent: ' select '},
+            option:   {parent: ' optgroup select '},
+            output:   {},
+            p:        {},
+            param:    {empty: true, parent: ' applet object '},
+            pre:      {},
+            progress: {},
+            q:        {},
+            rp:       {},
+            rt:       {},
+            ruby:     {},
+            samp:     {},
+            script:   {empty: true, parent: ' body div frame head iframe p pre span '},
+            section:  {},
+            select:   {},
+            small:    {},
+            span:     {},
+            source:   {},
+            strong:   {},
+            style:    {parent: ' head ', empty: true},
+            sub:      {},
+            sup:      {},
+            table:    {},
+            tbody:    {parent: ' table '},
+            td:       {parent: ' tr '},
+            textarea: {},
+            tfoot:    {parent: ' table '},
+            th:       {parent: ' tr '},
+            thead:    {parent: ' table '},
+            time:     {},
+            title:    {parent: ' head '},
+            tr:       {parent: ' table tbody thead tfoot '},
+            tt:       {},
+            u:        {},
+            ul:       {},
+            'var':    {},
+            video:    {}
+        },
+
+        ids,            // HTML ids
+        implied,        // Implied globals
+        inblock,
+        indent,
+        jsonmode,
+        lines,
+        lookahead,
+        member,
+        membersOnly,
+        nexttoken,
+        noreach,
+        option,
+        predefined,     // Global variables defined by option
+        prereg,
+        prevtoken,
+
+        rhino = {
+            defineClass : false,
+            deserialize : false,
+            gc          : false,
+            help        : false,
+            load        : false,
+            loadClass   : false,
+            print       : false,
+            quit        : false,
+            readFile    : false,
+            readUrl     : false,
+            runCommand  : false,
+            seal        : false,
+            serialize   : false,
+            spawn       : false,
+            sync        : false,
+            toint32     : false,
+            version     : false
+        },
+
+        scope,      // The current scope
+
+        windows = {
+            ActiveXObject: false,
+            CScript      : false,
+            Debug        : false,
+            Enumerator   : false,
+            System       : false,
+            VBArray      : false,
+            WScript      : false
+        },
+
+        src,
+        stack,
+
+// standard contains the global names that are provided by the
+// ECMAScript standard.
+
+        standard = {
+            Array               : false,
+            Boolean             : false,
+            Date                : false,
+            decodeURI           : false,
+            decodeURIComponent  : false,
+            encodeURI           : false,
+            encodeURIComponent  : false,
+            Error               : false,
+            'eval'              : false,
+            EvalError           : false,
+            Function            : false,
+            hasOwnProperty      : false,
+            isFinite            : false,
+            isNaN               : false,
+            JSON                : false,
+            Math                : false,
+            Number              : false,
+            Object              : false,
+            parseInt            : false,
+            parseFloat          : false,
+            RangeError          : false,
+            ReferenceError      : false,
+            RegExp              : false,
+            String              : false,
+            SyntaxError         : false,
+            TypeError           : false,
+            URIError            : false
+        },
+
+        standard_member = {
+            E                   : true,
+            LN2                 : true,
+            LN10                : true,
+            LOG2E               : true,
+            LOG10E              : true,
+            PI                  : true,
+            SQRT1_2             : true,
+            SQRT2               : true,
+            MAX_VALUE           : true,
+            MIN_VALUE           : true,
+            NEGATIVE_INFINITY   : true,
+            POSITIVE_INFINITY   : true
+        },
+
+        strict_mode,
+        syntax = {},
+        tab,
+        token,
+        urls,
+        warnings,
+
+// widget contains the global names which are provided to a Yahoo
+// (fna Konfabulator) widget.
+
+        widget = {
+            alert                   : true,
+            animator                : true,
+            appleScript             : true,
+            beep                    : true,
+            bytesToUIString         : true,
+            Canvas                  : true,
+            chooseColor             : true,
+            chooseFile              : true,
+            chooseFolder            : true,
+            closeWidget             : true,
+            COM                     : true,
+            convertPathToHFS        : true,
+            convertPathToPlatform   : true,
+            CustomAnimation         : true,
+            escape                  : true,
+            FadeAnimation           : true,
+            filesystem              : true,
+            Flash                   : true,
+            focusWidget             : true,
+            form                    : true,
+            FormField               : true,
+            Frame                   : true,
+            HotKey                  : true,
+            Image                   : true,
+            include                 : true,
+            isApplicationRunning    : true,
+            iTunes                  : true,
+            konfabulatorVersion     : true,
+            log                     : true,
+            md5                     : true,
+            MenuItem                : true,
+            MoveAnimation           : true,
+            openURL                 : true,
+            play                    : true,
+            Point                   : true,
+            popupMenu               : true,
+            preferenceGroups        : true,
+            preferences             : true,
+            print                   : true,
+            prompt                  : true,
+            random                  : true,
+            Rectangle               : true,
+            reloadWidget            : true,
+            ResizeAnimation         : true,
+            resolvePath             : true,
+            resumeUpdates           : true,
+            RotateAnimation         : true,
+            runCommand              : true,
+            runCommandInBg          : true,
+            saveAs                  : true,
+            savePreferences         : true,
+            screen                  : true,
+            ScrollBar               : true,
+            showWidgetPreferences   : true,
+            sleep                   : true,
+            speak                   : true,
+            Style                   : true,
+            suppressUpdates         : true,
+            system                  : true,
+            tellWidget              : true,
+            Text                    : true,
+            TextArea                : true,
+            Timer                   : true,
+            unescape                : true,
+            updateNow               : true,
+            URL                     : true,
+            Web                     : true,
+            widget                  : true,
+            Window                  : true,
+            XMLDOM                  : true,
+            XMLHttpRequest          : true,
+            yahooCheckLogin         : true,
+            yahooLogin              : true,
+            yahooLogout             : true
+        },
+
+//  xmode is used to adapt to the exceptions in html parsing.
+//  It can have these states:
+//      false   .js script file
+//      html
+//      outer
+//      script
+//      style
+//      scriptstring
+//      styleproperty
+
+        xmode,
+        xquote,
+
+// unsafe comment or string
+        ax = /@cc|<\/?|script|\]*s\]|<\s*!|&lt/i,
+// unsafe characters that are silently deleted by one or more browsers
+        cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,
+// token
+        tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jslint|members?|global)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,
+// html token
+        hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-:]*|[0-9]+|--)/,
+// characters in strings that need escapement
+        nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,
+        nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+// outer html token
+        ox = /[>&]|<[\/!]?|--/,
+// star slash
+        lx = /\*\/|\/\*/,
+// identifier
+        ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,
+// javascript url
+        jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i,
+// url badness
+        ux = /&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i,
+// style
+        sx = /^\s*([{:#%.=,>+\[\]@()"';]|\*=?|\$=|\|=|\^=|~=|[a-zA-Z_][a-zA-Z0-9_\-]*|[0-9]+|<\/|\/\*)/,
+        ssx = /^\s*([@#!"'};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|\d+(?:\.\d+)?|<\/)/,
+// attributes characters
+        qx = /[^a-zA-Z0-9+\-_\/ ]/,
+// query characters for ids
+        dx = /[\[\]\/\\"'*<>.&:(){}+=#]/,
+
+        rx = {
+            outer: hx,
+            html: hx,
+            style: sx,
+            styleproperty: ssx
+        };
+
+    function F() {}
+
+    if (typeof Object.create !== 'function') {
+        Object.create = function (o) {
+            F.prototype = o;
+            return new F();
+        };
+    }
+
+
+    function is_own(object, name) {
+        return Object.prototype.hasOwnProperty.call(object, name);
+    }
+
+
+    function combine(t, o) {
+        var n;
+        for (n in o) {
+            if (is_own(o, n)) {
+                t[n] = o[n];
+            }
+        }
+    }
+
+    String.prototype.entityify = function () {
+        return this.
+            replace(/&/g, '&amp;').
+            replace(/</g, '&lt;').
+            replace(/>/g, '&gt;');
+    };
+
+    String.prototype.isAlpha = function () {
+        return (this >= 'a' && this <= 'z\uffff') ||
+            (this >= 'A' && this <= 'Z\uffff');
+    };
+
+
+    String.prototype.isDigit = function () {
+        return (this >= '0' && this <= '9');
+    };
+
+
+    String.prototype.supplant = function (o) {
+        return this.replace(/\{([^{}]*)\}/g, function (a, b) {
+            var r = o[b];
+            return typeof r === 'string' || typeof r === 'number' ? r : a;
+        });
+    };
+
+    String.prototype.name = function () {
+
+// If the string looks like an identifier, then we can return it as is.
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can simply slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe
+// sequences.
+
+        if (ix.test(this)) {
+            return this;
+        }
+        if (nx.test(this)) {
+            return '"' + this.replace(nxg, function (a) {
+                var c = escapes[a];
+                if (c) {
+                    return c;
+                }
+                return '\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4);
+            }) + '"';
+        }
+        return '"' + this + '"';
+    };
+
+
+    function assume() {
+        if (!option.safe) {
+            if (option.rhino) {
+                combine(predefined, rhino);
+            }
+            if (option.devel) {
+                combine(predefined, devel);
+            }
+            if (option.browser) {
+                combine(predefined, browser);
+            }
+            if (option.windows) {
+                combine(predefined, windows);
+            }
+            if (option.widget) {
+                combine(predefined, widget);
+            }
+			if(option.predefined){
+				combine(predefined, option.predefined);
+			}
+        }
+    }
+
+
+// Produce an error warning.
+
+    function quit(m, l, ch) {
+        throw {
+            name: 'JSLintError',
+            line: l,
+            character: ch,
+            message: m + " (" + Math.floor((l / lines.length) * 100) +
+                    "% scanned)."
+        };
+    }
+
+    function warning(m, t, a, b, c, d) {
+        var ch, l, w;
+        t = t || nexttoken;
+        if (t.id === '(end)') {  // `~
+            t = token;
+        }
+        l = t.line || 0;
+        ch = t.from || 0;
+        w = {
+            id: '(error)',
+            raw: m,
+            evidence: lines[l - 1] || '',
+            line: l,
+            character: ch,
+            a: a,
+            b: b,
+            c: c,
+            d: d
+        };
+        w.reason = m.supplant(w);
+        JSLINT.errors.push(w);
+        if (option.passfail) {
+            quit('Stopping. ', l, ch);
+        }
+        warnings += 1;
+        if (warnings >= option.maxerr) {
+            quit("Too many errors.", l, ch);
+        }
+        return w;
+    }
+
+    function warningAt(m, l, ch, a, b, c, d) {
+        return warning(m, {
+            line: l,
+            from: ch
+        }, a, b, c, d);
+    }
+
+    function error(m, t, a, b, c, d) {
+        var w = warning(m, t, a, b, c, d);
+        quit("Stopping, unable to continue.", w.line, w.character);
+    }
+
+    function errorAt(m, l, ch, a, b, c, d) {
+        return error(m, {
+            line: l,
+            from: ch
+        }, a, b, c, d);
+    }
+
+
+
+// lexical analysis
+
+    var lex = (function lex() {
+        var character, from, line, s;
+
+// Private lex methods
+
+        function nextLine() {
+            var at;
+            if (line >= lines.length) {
+                return false;
+            }
+            character = 1;
+            s = lines[line];
+            line += 1;
+            at = s.search(/ \t/);
+            if (at >= 0) {
+                warningAt("Mixed spaces and tabs.", line, at + 1);
+            }
+            s = s.replace(/\t/g, tab);
+            at = s.search(cx);
+            if (at >= 0) {
+                warningAt("Unsafe character.", line, at);
+            }
+            if (option.maxlen && option.maxlen < s.length) {
+                warningAt("Line too long.", line, s.length);
+            }
+            return true;
+        }
+
+// Produce a token object.  The token inherits from a syntax symbol.
+
+        function it(type, value) {
+            var i, t;
+            if (type === '(color)') {
+                t = {type: type};
+            } else if (type === '(punctuator)' ||
+                    (type === '(identifier)' && is_own(syntax, value))) {
+                t = syntax[value] || syntax['(error)'];
+            } else {
+                t = syntax[type];
+            }
+            t = Object.create(t);
+            if (type === '(string)' || type === '(range)') {
+                if (jx.test(value)) {
+                    warningAt("Script URL.", line, from);
+                }
+            }
+            if (type === '(identifier)') {
+                t.identifier = true;
+                if (value === '__iterator__' || value === '__proto__') {
+                    errorAt("Reserved name '{a}'.",
+                        line, from, value);
+                } else if (option.nomen &&
+                        (value.charAt(0) === '_' ||
+                         value.charAt(value.length - 1) === '_')) {
+                    warningAt("Unexpected {a} in '{b}'.", line, from,
+                        "dangling '_'", value);
+                }
+            }
+            t.value = value;
+            t.line = line;
+            t.character = character;
+            t.from = from;
+            i = t.id;
+            if (i !== '(endline)') {
+                prereg = i &&
+                    (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) ||
+                    i === 'return');
+            }
+            return t;
+        }
+
+// Public lex methods
+
+        return {
+            init: function (source) {
+                if (typeof source === 'string') {
+                    lines = source.
+                        replace(/\r\n/g, '\n').
+                        replace(/\r/g, '\n').
+                        split('\n');
+                } else {
+                    lines = source;
+                }
+                line = 0;
+                nextLine();
+                from = 1;
+            },
+
+            range: function (begin, end) {
+                var c, value = '';
+                from = character;
+                if (s.charAt(0) !== begin) {
+                    errorAt("Expected '{a}' and instead saw '{b}'.",
+                            line, character, begin, s.charAt(0));
+                }
+                for (;;) {
+                    s = s.slice(1);
+                    character += 1;
+                    c = s.charAt(0);
+                    switch (c) {
+                    case '':
+                        errorAt("Missing '{a}'.", line, character, c);
+                        break;
+                    case end:
+                        s = s.slice(1);
+                        character += 1;
+                        return it('(range)', value);
+                    case xquote:
+                    case '\\':
+                        warningAt("Unexpected '{a}'.", line, character, c);
+                    }
+                    value += c;
+                }
+
+            },
+
+// token -- this is called by advance to get the next token.
+
+            token: function () {
+                var b, c, captures, d, depth, high, i, l, low, q, t;
+
+                function match(x) {
+                    var r = x.exec(s), r1;
+                    if (r) {
+                        l = r[0].length;
+                        r1 = r[1];
+                        c = r1.charAt(0);
+                        s = s.substr(l);
+                        from = character + l - r1.length;
+                        character += l;
+                        return r1;
+                    }
+                }
+
+                function string(x) {
+                    var c, j, r = '';
+
+                    if (jsonmode && x !== '"') {
+                        warningAt("Strings must use doublequote.",
+                                line, character);
+                    }
+
+                    if (xquote === x || (xmode === 'scriptstring' && !xquote)) {
+                        return it('(punctuator)', x);
+                    }
+
+                    function esc(n) {
+                        var i = parseInt(s.substr(j + 1, n), 16);
+                        j += n;
+                        if (i >= 32 && i <= 126 &&
+                                i !== 34 && i !== 92 && i !== 39) {
+                            warningAt("Unnecessary escapement.", line, character);
+                        }
+                        character += n;
+                        c = String.fromCharCode(i);
+                    }
+                    j = 0;
+                    for (;;) {
+                        while (j >= s.length) {
+                            j = 0;
+                            if (xmode !== 'html' || !nextLine()) {
+                                errorAt("Unclosed string.", line, from);
+                            }
+                        }
+                        c = s.charAt(j);
+                        if (c === x) {
+                            character += 1;
+                            s = s.substr(j + 1);
+                            return it('(string)', r, x);
+                        }
+                        if (c < ' ') {
+                            if (c === '\n' || c === '\r') {
+                                break;
+                            }
+                            warningAt("Control character in string: {a}.",
+                                    line, character + j, s.slice(0, j));
+                        } else if (c === xquote) {
+                            warningAt("Bad HTML string", line, character + j);
+                        } else if (c === '<') {
+                            if (option.safe && xmode === 'html') {
+                                warningAt("ADsafe string violation.",
+                                        line, character + j);
+                            } else if (s.charAt(j + 1) === '/' && (xmode || option.safe)) {
+                                warningAt("Expected '<\\/' and instead saw '</'.", line, character);
+                            } else if (s.charAt(j + 1) === '!' && (xmode || option.safe)) {
+                                warningAt("Unexpected '<!' in a string.", line, character);
+                            }
+                        } else if (c === '\\') {
+                            if (xmode === 'html') {
+                                if (option.safe) {
+                                    warningAt("ADsafe string violation.",
+                                            line, character + j);
+                                }
+                            } else if (xmode === 'styleproperty') {
+                                j += 1;
+                                character += 1;
+                                c = s.charAt(j);
+                                if (c !== x) {
+                                    warningAt("Escapement in style string.",
+                                            line, character + j);
+                                }
+                            } else {
+                                j += 1;
+                                character += 1;
+                                c = s.charAt(j);
+                                switch (c) {
+                                case xquote:
+                                    warningAt("Bad HTML string", line,
+                                        character + j);
+                                    break;
+                                case '\\':
+                                case '\'':
+                                case '"':
+                                case '/':
+                                    break;
+                                case 'b':
+                                    c = '\b';
+                                    break;
+                                case 'f':
+                                    c = '\f';
+                                    break;
+                                case 'n':
+                                    c = '\n';
+                                    break;
+                                case 'r':
+                                    c = '\r';
+                                    break;
+                                case 't':
+                                    c = '\t';
+                                    break;
+                                case 'u':
+                                    esc(4);
+                                    break;
+                                case 'v':
+                                    c = '\v';
+                                    break;
+                                case 'x':
+                                    if (jsonmode) {
+                                        warningAt("Avoid \\x-.", line, character);
+                                    }
+                                    esc(2);
+                                    break;
+                                default:
+                                    warningAt("Bad escapement.", line, character);
+                                }
+                            }
+                        }
+                        r += c;
+                        character += 1;
+                        j += 1;
+                    }
+                }
+
+                for (;;) {
+                    if (!s) {
+                        return it(nextLine() ? '(endline)' : '(end)', '');
+                    }
+                    while (xmode === 'outer') {
+                        i = s.search(ox);
+                        if (i === 0) {
+                            break;
+                        } else if (i > 0) {
+                            character += 1;
+                            s = s.slice(i);
+                            break;
+                        } else {
+                            if (!nextLine()) {
+                                return it('(end)', '');
+                            }
+                        }
+                    }
+//                     t = match(rx[xmode] || tx);
+//                     if (!t) {
+//                         if (xmode === 'html') {
+//                             return it('(error)', s.charAt(0));
+//                         } else {
+//                             t = '';
+//                             c = '';
+//                             while (s && s < '!') {
+//                                 s = s.substr(1);
+//                             }
+//                             if (s) {
+//                                 errorAt("Unexpected '{a}'.",
+//                                         line, character, s.substr(0, 1));
+//                             }
+//                         }
+                    t = match(rx[xmode] || tx);
+                    if (!t) {
+                        t = '';
+                        c = '';
+                        while (s && s < '!') {
+                            s = s.substr(1);
+                        }
+                        if (s) {
+                            if (xmode === 'html') {
+                                return it('(error)', s.charAt(0));
+                            } else {
+                                errorAt("Unexpected '{a}'.",
+                                        line, character, s.substr(0, 1));
+                            }
+                        }
+                    } else {
+
+    //      identifier
+
+                        if (c.isAlpha() || c === '_' || c === '$') {
+                            return it('(identifier)', t);
+                        }
+
+    //      number
+
+                        if (c.isDigit()) {
+                            if (xmode !== 'style' && !isFinite(Number(t))) {
+                                warningAt("Bad number '{a}'.",
+                                    line, character, t);
+                            }
+                            if (xmode !== 'style' &&
+                                     xmode !== 'styleproperty' &&
+                                     s.substr(0, 1).isAlpha()) {
+                                warningAt("Missing space after '{a}'.",
+                                        line, character, t);
+                            }
+                            if (c === '0') {
+                                d = t.substr(1, 1);
+                                if (d.isDigit()) {
+                                    if (token.id !== '.' && xmode !== 'styleproperty') {
+                                        warningAt("Don't use extra leading zeros '{a}'.",
+                                            line, character, t);
+                                    }
+                                } else if (jsonmode && (d === 'x' || d === 'X')) {
+                                    warningAt("Avoid 0x-. '{a}'.",
+                                            line, character, t);
+                                }
+                            }
+                            if (t.substr(t.length - 1) === '.') {
+                                warningAt(
+        "A trailing decimal point can be confused with a dot '{a}'.",
+                                        line, character, t);
+                            }
+                            return it('(number)', t);
+                        }
+                        switch (t) {
+
+    //      string
+
+                        case '"':
+                        case "'":
+                            return string(t);
+
+    //      // comment
+
+                        case '//':
+                            if (src || (xmode && xmode !== 'script')) {
+                                warningAt("Unexpected comment.", line, character);
+                            } else if (xmode === 'script' && /<\s*\//i.test(s)) {
+                                warningAt("Unexpected <\/ in comment.", line, character);
+                            } else if ((option.safe || xmode === 'script') && ax.test(s)) {
+                                warningAt("Dangerous comment.", line, character);
+                            }
+                            s = '';
+                            token.comment = true;
+                            break;
+
+    //      /* comment
+
+                        case '/*':
+                            if (src || (xmode && xmode !== 'script' && xmode !== 'style' && xmode !== 'styleproperty')) {
+                                warningAt("Unexpected comment.", line, character);
+                            }
+                            if (option.safe && ax.test(s)) {
+                                warningAt("ADsafe comment violation.", line, character);
+                            }
+                            for (;;) {
+                                i = s.search(lx);
+                                if (i >= 0) {
+                                    break;
+                                }
+                                if (!nextLine()) {
+                                    errorAt("Unclosed comment.", line, character);
+                                } else {
+                                    if (option.safe && ax.test(s)) {
+                                        warningAt("ADsafe comment violation.",
+                                                line, character);
+                                    }
+                                }
+                            }
+                            character += i + 2;
+                            if (s.substr(i, 1) === '/') {
+                                errorAt("Nested comment.", line, character);
+                            }
+                            s = s.substr(i + 2);
+                            token.comment = true;
+                            break;
+
+    //      /*members /*jslint /*global
+
+                        case '/*members':
+                        case '/*member':
+                        case '/*jslint':
+                        case '/*global':
+                        case '*/':
+                            return {
+                                value: t,
+                                type: 'special',
+                                line: line,
+                                character: character,
+                                from: from
+                            };
+
+                        case '':
+                            break;
+    //      /
+                        case '/':
+                            if (token.id === '/=') {
+                                errorAt(
+"A regular expression literal can be confused with '/='.", line, from);
+                            }
+                            if (prereg) {
+                                depth = 0;
+                                captures = 0;
+                                l = 0;
+                                for (;;) {
+                                    b = true;
+                                    c = s.charAt(l);
+                                    l += 1;
+                                    switch (c) {
+                                    case '':
+                                        errorAt("Unclosed regular expression.",
+                                                line, from);
+                                        return;
+                                    case '/':
+                                        if (depth > 0) {
+                                            warningAt("Unescaped '{a}'.",
+                                                    line, from + l, '/');
+                                        }
+                                        c = s.substr(0, l - 1);
+                                        q = {
+                                            g: true,
+                                            i: true,
+                                            m: true
+                                        };
+                                        while (q[s.charAt(l)] === true) {
+                                            q[s.charAt(l)] = false;
+                                            l += 1;
+                                        }
+                                        character += l;
+                                        s = s.substr(l);
+                                        q = s.charAt(0);
+                                        if (q === '/' || q === '*') {
+                                            errorAt("Confusing regular expression.",
+                                                    line, from);
+                                        }
+                                        return it('(regexp)', c);
+                                    case '\\':
+                                        c = s.charAt(l);
+                                        if (c < ' ') {
+                                            warningAt(
+"Unexpected control character in regular expression.", line, from + l);
+                                        } else if (c === '<') {
+                                            warningAt(
+"Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
+                                        }
+                                        l += 1;
+                                        break;
+                                    case '(':
+                                        depth += 1;
+                                        b = false;
+                                        if (s.charAt(l) === '?') {
+                                            l += 1;
+                                            switch (s.charAt(l)) {
+                                            case ':':
+                                            case '=':
+                                            case '!':
+                                                l += 1;
+                                                break;
+                                            default:
+                                                warningAt(
+"Expected '{a}' and instead saw '{b}'.", line, from + l, ':', s.charAt(l));
+                                            }
+                                        } else {
+                                            captures += 1;
+                                        }
+                                        break;
+                                    case '|':
+                                        b = false;
+                                        break;
+                                    case ')':
+                                        if (depth === 0) {
+                                            warningAt("Unescaped '{a}'.",
+                                                    line, from + l, ')');
+                                        } else {
+                                            depth -= 1;
+                                        }
+                                        break;
+                                    case ' ':
+                                        q = 1;
+                                        while (s.charAt(l) === ' ') {
+                                            l += 1;
+                                            q += 1;
+                                        }
+                                        if (q > 1) {
+                                            warningAt(
+"Spaces are hard to count. Use {{a}}.", line, from + l, q);
+                                        }
+                                        break;
+                                    case '[':
+                                        c = s.charAt(l);
+                                        if (c === '^') {
+                                            l += 1;
+                                            if (option.regexp) {
+                                                warningAt("Insecure '{a}'.",
+                                                        line, from + l, c);
+                                            }
+                                        }
+                                        q = false;
+                                        if (c === ']') {
+                                            warningAt("Empty class.", line,
+                                                    from + l - 1);
+                                            q = true;
+                                        }
+klass:                                  do {
+                                            c = s.charAt(l);
+                                            l += 1;
+                                            switch (c) {
+                                            case '[':
+                                            case '^':
+                                                warningAt("Unescaped '{a}'.",
+                                                        line, from + l, c);
+                                                q = true;
+                                                break;
+                                            case '-':
+                                                if (q) {
+                                                    q = false;
+                                                } else {
+                                                    warningAt("Unescaped '{a}'.",
+                                                            line, from + l, '-');
+                                                    q = true;
+                                                }
+                                                break;
+                                            case ']':
+                                                if (!q) {
+                                                    warningAt("Unescaped '{a}'.",
+                                                            line, from + l - 1, '-');
+                                                }
+                                                break klass;
+                                            case '\\':
+                                                c = s.charAt(l);
+                                                if (c < ' ') {
+                                                    warningAt(
+"Unexpected control character in regular expression.", line, from + l);
+                                                } else if (c === '<') {
+                                                    warningAt(
+"Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
+                                                }
+                                                l += 1;
+                                                q = true;
+                                                break;
+                                            case '/':
+                                                warningAt("Unescaped '{a}'.",
+                                                        line, from + l - 1, '/');
+                                                q = true;
+                                                break;
+                                            case '<':
+                                                if (xmode === 'script') {
+                                                    c = s.charAt(l);
+                                                    if (c === '!' || c === '/') {
+                                                        warningAt(
+"HTML confusion in regular expression '<{a}'.", line, from + l, c);
+                                                    }
+                                                }
+                                                q = true;
+                                                break;
+                                            default:
+                                                q = true;
+                                            }
+                                        } while (c);
+                                        break;
+                                    case '.':
+                                        if (option.regexp) {
+                                            warningAt("Insecure '{a}'.", line,
+                                                    from + l, c);
+                                        }
+                                        break;
+                                    case ']':
+                                    case '?':
+                                    case '{':
+                                    case '}':
+                                    case '+':
+                                    case '*':
+                                        warningAt("Unescaped '{a}'.", line,
+                                                from + l, c);
+                                        break;
+                                    case '<':
+                                        if (xmode === 'script') {
+                                            c = s.charAt(l);
+                                            if (c === '!' || c === '/') {
+                                                warningAt(
+"HTML confusion in regular expression '<{a}'.", line, from + l, c);
+                                            }
+                                        }
+                                    }
+                                    if (b) {
+                                        switch (s.charAt(l)) {
+                                        case '?':
+                                        case '+':
+                                        case '*':
+                                            l += 1;
+                                            if (s.charAt(l) === '?') {
+                                                l += 1;
+                                            }
+                                            break;
+                                        case '{':
+                                            l += 1;
+                                            c = s.charAt(l);
+                                            if (c < '0' || c > '9') {
+                                                warningAt(
+"Expected a number and instead saw '{a}'.", line, from + l, c);
+                                            }
+                                            l += 1;
+                                            low = +c;
+                                            for (;;) {
+                                                c = s.charAt(l);
+                                                if (c < '0' || c > '9') {
+                                                    break;
+                                                }
+                                                l += 1;
+                                                low = +c + (low * 10);
+                                            }
+                                            high = low;
+                                            if (c === ',') {
+                                                l += 1;
+                                                high = Infinity;
+                                                c = s.charAt(l);
+                                                if (c >= '0' && c <= '9') {
+                                                    l += 1;
+                                                    high = +c;
+                                                    for (;;) {
+                                                        c = s.charAt(l);
+                                                        if (c < '0' || c > '9') {
+                                                            break;
+                                                        }
+                                                        l += 1;
+                                                        high = +c + (high * 10);
+                                                    }
+                                                }
+                                            }
+                                            if (s.charAt(l) !== '}') {
+                                                warningAt(
+"Expected '{a}' and instead saw '{b}'.", line, from + l, '}', c);
+                                            } else {
+                                                l += 1;
+                                            }
+                                            if (s.charAt(l) === '?') {
+                                                l += 1;
+                                            }
+                                            if (low > high) {
+                                                warningAt(
+"'{a}' should not be greater than '{b}'.", line, from + l, low, high);
+                                            }
+                                        }
+                                    }
+                                }
+                                c = s.substr(0, l - 1);
+                                character += l;
+                                s = s.substr(l);
+                                return it('(regexp)', c);
+                            }
+                            return it('(punctuator)', t);
+
+    //      punctuator
+
+                        case '<!--':
+                            l = line;
+                            c = character;
+                            for (;;) {
+                                i = s.indexOf('--');
+                                if (i >= 0) {
+                                    break;
+                                }
+                                i = s.indexOf('<!');
+                                if (i >= 0) {
+                                    errorAt("Nested HTML comment.",
+                                        line, character + i);
+                                }
+                                if (!nextLine()) {
+                                    errorAt("Unclosed HTML comment.", l, c);
+                                }
+                            }
+                            l = s.indexOf('<!');
+                            if (l >= 0 && l < i) {
+                                errorAt("Nested HTML comment.",
+                                    line, character + l);
+                            }
+                            character += i;
+                            if (s[i + 2] !== '>') {
+                                errorAt("Expected -->.", line, character);
+                            }
+                            character += 3;
+                            s = s.slice(i + 3);
+                            break;
+                        case '#':
+                            if (xmode === 'html' || xmode === 'styleproperty') {
+                                for (;;) {
+                                    c = s.charAt(0);
+                                    if ((c < '0' || c > '9') &&
+                                            (c < 'a' || c > 'f') &&
+                                            (c < 'A' || c > 'F')) {
+                                        break;
+                                    }
+                                    character += 1;
+                                    s = s.substr(1);
+                                    t += c;
+                                }
+                                if (t.length !== 4 && t.length !== 7) {
+                                    warningAt("Bad hex color '{a}'.", line,
+                                        from + l, t);
+                                }
+                                return it('(color)', t);
+                            }
+                            return it('(punctuator)', t);
+                        default:
+                            if (xmode === 'outer' && c === '&') {
+                                character += 1;
+                                s = s.substr(1);
+                                for (;;) {
+                                    c = s.charAt(0);
+                                    character += 1;
+                                    s = s.substr(1);
+                                    if (c === ';') {
+                                        break;
+                                    }
+                                    if (!((c >= '0' && c <= '9') ||
+                                            (c >= 'a' && c <= 'z') ||
+                                            c === '#')) {
+                                        errorAt("Bad entity", line, from + l,
+                                        character);
+                                    }
+                                }
+                                break;
+                            }
+                            return it('(punctuator)', t);
+                        }
+                    }
+                }
+            }
+        };
+    }());
+
+
+    function addlabel(t, type) {
+
+        if (option.safe && funct['(global)'] &&
+                typeof predefined[t] !== 'boolean') {
+            warning('ADsafe global: ' + t + '.', token);
+        } else if (t === 'hasOwnProperty') {
+            warning("'hasOwnProperty' is a really bad name.");
+        }
+
+// Define t in the current function in the current scope.
+
+        if (is_own(funct, t) && !funct['(global)']) {
+            warning(funct[t] === true ?
+                "'{a}' was used before it was defined." :
+                "'{a}' is already defined.",
+                nexttoken, t);
+        }
+        funct[t] = type;
+        if (funct['(global)']) {
+            global[t] = funct;
+            if (is_own(implied, t)) {
+                warning("'{a}' was used before it was defined.", nexttoken, t);
+                delete implied[t];
+            }
+        } else {
+            scope[t] = funct;
+        }
+    }
+
+
+    function doOption() {
+        var b, obj, filter, o = nexttoken.value, t, v;
+        switch (o) {
+        case '*/':
+            error("Unbegun comment.");
+            break;
+        case '/*members':
+        case '/*member':
+            o = '/*members';
+            if (!membersOnly) {
+                membersOnly = {};
+            }
+            obj = membersOnly;
+            break;
+        case '/*jslint':
+            if (option.safe) {
+                warning("ADsafe restriction.");
+            }
+            obj = option;
+            filter = boolOptions;
+            break;
+        case '/*global':
+            if (option.safe) {
+                warning("ADsafe restriction.");
+            }
+            obj = predefined;
+            break;
+        default:
+        }
+        t = lex.token();
+loop:   for (;;) {
+            for (;;) {
+                if (t.type === 'special' && t.value === '*/') {
+                    break loop;
+                }
+                if (t.id !== '(endline)' && t.id !== ',') {
+                    break;
+                }
+                t = lex.token();
+            }
+            if (t.type !== '(string)' && t.type !== '(identifier)' &&
+                    o !== '/*members') {
+                error("Bad option.", t);
+            }
+            v = lex.token();
+            if (v.id === ':') {
+                v = lex.token();
+                if (obj === membersOnly) {
+                    error("Expected '{a}' and instead saw '{b}'.",
+                            t, '*/', ':');
+                }
+                if (t.value === 'indent' && o === '/*jslint') {
+                    b = +v.value;
+                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
+                            Math.floor(b) !== b) {
+                        error("Expected a small integer and instead saw '{a}'.",
+                                v, v.value);
+                    }
+                    obj.white = true;
+                    obj.indent = b;
+                } else if (t.value === 'maxerr' && o === '/*jslint') {
+                    b = +v.value;
+                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
+                            Math.floor(b) !== b) {
+                        error("Expected a small integer and instead saw '{a}'.",
+                                v, v.value);
+                    }
+                    obj.maxerr = b;
+                } else if (t.value === 'maxlen' && o === '/*jslint') {
+                    b = +v.value;
+                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
+                            Math.floor(b) !== b) {
+                        error("Expected a small integer and instead saw '{a}'.",
+                                v, v.value);
+                    }
+                    obj.maxlen = b;
+                } else if (v.value === 'true') {
+                    obj[t.value] = true;
+                } else if (v.value === 'false') {
+                    obj[t.value] = false;
+                } else {
+                    error("Bad option value.", v);
+                }
+                t = lex.token();
+            } else {
+                if (o === '/*jslint') {
+                    error("Missing option value.", t);
+                }
+                obj[t.value] = false;
+                t = v;
+            }
+        }
+        if (filter) {
+            assume();
+        }
+    }
+
+
+// We need a peek function. If it has an argument, it peeks that much farther
+// ahead. It is used to distinguish
+//     for ( var i in ...
+// from
+//     for ( var i = ...
+
+    function peek(p) {
+        var i = p || 0, j = 0, t;
+
+        while (j <= i) {
+            t = lookahead[j];
+            if (!t) {
+                t = lookahead[j] = lex.token();
+            }
+            j += 1;
+        }
+        return t;
+    }
+
+
+
+// Produce the next token. It looks for programming errors.
+
+    function advance(id, t) {
+        switch (token.id) {
+        case '(number)':
+            if (nexttoken.id === '.') {
+                warning(
+"A dot following a number can be confused with a decimal point.", token);
+            }
+            break;
+        case '-':
+            if (nexttoken.id === '-' || nexttoken.id === '--') {
+                warning("Confusing minusses.");
+            }
+            break;
+        case '+':
+            if (nexttoken.id === '+' || nexttoken.id === '++') {
+                warning("Confusing plusses.");
+            }
+            break;
+        }
+        if (token.type === '(string)' || token.identifier) {
+            anonname = token.value;
+        }
+
+        if (id && nexttoken.id !== id) {
+            if (t) {
+                if (nexttoken.id === '(end)') {
+                    warning("Unmatched '{a}'.", t, t.id);
+                } else {
+                    warning(
+"Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
+                            nexttoken, id, t.id, t.line, nexttoken.value);
+                }
+            } else if (nexttoken.type !== '(identifier)' ||
+                            nexttoken.value !== id) {
+                warning("Expected '{a}' and instead saw '{b}'.",
+                        nexttoken, id, nexttoken.value);
+            }
+        }
+        prevtoken = token;
+        token = nexttoken;
+        for (;;) {
+            nexttoken = lookahead.shift() || lex.token();
+            if (nexttoken.id === '(end)' || nexttoken.id === '(error)') {
+                return;
+            }
+            if (nexttoken.type === 'special') {
+                doOption();
+            } else {
+                if (nexttoken.id !== '(endline)') {
+                    break;
+                }
+            }
+        }
+    }
+
+
+// This is the heart of JSLINT, the Pratt parser. In addition to parsing, it
+// is looking for ad hoc lint patterns. We add to Pratt's model .fud, which is
+// like nud except that it is only used on the first token of a statement.
+// Having .fud makes it much easier to define JavaScript. I retained Pratt's
+// nomenclature.
+
+// .nud     Null denotation
+// .fud     First null denotation
+// .led     Left denotation
+//  lbp     Left binding power
+//  rbp     Right binding power
+
+// They are key to the parsing method called Top Down Operator Precedence.
+
+    function parse(rbp, initial) {
+        var left;
+        if (nexttoken.id === '(end)') {
+            error("Unexpected early end of program.", token);
+        }
+        advance();
+        if (option.safe && typeof predefined[token.value] === 'boolean' &&
+                (nexttoken.id !== '(' && nexttoken.id !== '.')) {
+            warning('ADsafe violation.', token);
+        }
+        if (initial) {
+            anonname = 'anonymous';
+            funct['(verb)'] = token.value;
+        }
+        if (initial === true && token.fud) {
+            left = token.fud();
+        } else {
+            if (token.nud) {
+                left = token.nud();
+            } else {
+                if (nexttoken.type === '(number)' && token.id === '.') {
+                    warning(
+"A leading decimal point can be confused with a dot: '.{a}'.",
+                            token, nexttoken.value);
+                    advance();
+                    return token;
+                } else {
+                    error("Expected an identifier and instead saw '{a}'.",
+                            token, token.id);
+                }
+            }
+            while (rbp < nexttoken.lbp) {
+                advance();
+                if (token.led) {
+                    left = token.led(left);
+                } else {
+                    error("Expected an operator and instead saw '{a}'.",
+                        token, token.id);
+                }
+            }
+        }
+        return left;
+    }
+
+
+// Functions for conformance of style.
+
+    function adjacent(left, right) {
+        left = left || token;
+        right = right || nexttoken;
+        if (option.white || xmode === 'styleproperty' || xmode === 'style') {
+            if (left.character !== right.from && left.line === right.line) {
+                warning("Unexpected space after '{a}'.", right, left.value);
+            }
+        }
+    }
+
+    function nospace(left, right) {
+        left = left || token;
+        right = right || nexttoken;
+        if (option.white && !left.comment) {
+            if (left.line === right.line) {
+                adjacent(left, right);
+            }
+        }
+    }
+
+
+    function nonadjacent(left, right) {
+        if (option.white) {
+            left = left || token;
+            right = right || nexttoken;
+            if (left.line === right.line && left.character === right.from) {
+                warning("Missing space after '{a}'.",
+                        nexttoken, left.value);
+            }
+        }
+    }
+
+    function nobreaknonadjacent(left, right) {
+        left = left || token;
+        right = right || nexttoken;
+        if (!option.laxbreak && left.line !== right.line) {
+            warning("Bad line breaking before '{a}'.", right, right.id);
+        } else if (option.white) {
+            left = left || token;
+            right = right || nexttoken;
+            if (left.character === right.from) {
+                warning("Missing space after '{a}'.",
+                        nexttoken, left.value);
+            }
+        }
+    }
+
+    function indentation(bias) {
+        var i;
+        if (option.white && nexttoken.id !== '(end)') {
+            i = indent + (bias || 0);
+            if (nexttoken.from !== i) {
+                warning(
+"Expected '{a}' to have an indentation at {b} instead at {c}.",
+                        nexttoken, nexttoken.value, i, nexttoken.from);
+            }
+        }
+    }
+
+    function nolinebreak(t) {
+        t = t || token;
+        if (t.line !== nexttoken.line) {
+            warning("Line breaking error '{a}'.", t, t.value);
+        }
+    }
+
+
+    function comma() {
+        if (token.line !== nexttoken.line) {
+            if (!option.laxbreak) {
+                warning("Bad line breaking before '{a}'.", token, nexttoken.id);
+            }
+        } else if (token.character !== nexttoken.from && option.white) {
+            warning("Unexpected space after '{a}'.", nexttoken, token.value);
+        }
+        advance(',');
+        nonadjacent(token, nexttoken);
+    }
+
+
+// Functional constructors for making the symbols that will be inherited by
+// tokens.
+
+    function symbol(s, p) {
+        var x = syntax[s];
+        if (!x || typeof x !== 'object') {
+            syntax[s] = x = {
+                id: s,
+                lbp: p,
+                value: s
+            };
+        }
+        return x;
+    }
+
+
+    function delim(s) {
+        return symbol(s, 0);
+    }
+
+
+    function stmt(s, f) {
+        var x = delim(s);
+        x.identifier = x.reserved = true;
+        x.fud = f;
+        return x;
+    }
+
+
+    function blockstmt(s, f) {
+        var x = stmt(s, f);
+        x.block = true;
+        return x;
+    }
+
+
+    function reserveName(x) {
+        var c = x.id.charAt(0);
+        if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
+            x.identifier = x.reserved = true;
+        }
+        return x;
+    }
+
+
+    function prefix(s, f) {
+        var x = symbol(s, 150);
+        reserveName(x);
+        x.nud = (typeof f === 'function') ? f : function () {
+            this.right = parse(150);
+            this.arity = 'unary';
+            if (this.id === '++' || this.id === '--') {
+                if (option.plusplus) {
+                    warning("Unexpected use of '{a}'.", this, this.id);
+                } else if ((!this.right.identifier || this.right.reserved) &&
+                        this.right.id !== '.' && this.right.id !== '[') {
+                    warning("Bad operand.", this);
+                }
+            }
+            return this;
+        };
+        return x;
+    }
+
+
+    function type(s, f) {
+        var x = delim(s);
+        x.type = s;
+        x.nud = f;
+        return x;
+    }
+
+
+    function reserve(s, f) {
+        var x = type(s, f);
+        x.identifier = x.reserved = true;
+        return x;
+    }
+
+
+    function reservevar(s, v) {
+        return reserve(s, function () {
+            if (this.id === 'this' || this.id === 'arguments' ||
+                    this.id === 'eval') {
+                if (strict_mode && funct['(global)']) {
+                    warning("Strict violation.", this);
+                } else if (option.safe) {
+                    warning("ADsafe violation.", this);
+                }
+            }
+            return this;
+        });
+    }
+
+
+    function infix(s, f, p, w) {
+        var x = symbol(s, p);
+        reserveName(x);
+        x.led = function (left) {
+            if (!w) {
+                nobreaknonadjacent(prevtoken, token);
+                nonadjacent(token, nexttoken);
+            }
+            if (typeof f === 'function') {
+                return f(left, this);
+            } else {
+                this.left = left;
+                this.right = parse(p);
+                return this;
+            }
+        };
+        return x;
+    }
+
+
+    function relation(s, f) {
+        var x = symbol(s, 100);
+        x.led = function (left) {
+            nobreaknonadjacent(prevtoken, token);
+            nonadjacent(token, nexttoken);
+            var right = parse(100);
+            if ((left && left.id === 'NaN') || (right && right.id === 'NaN')) {
+                warning("Use the isNaN function to compare with NaN.", this);
+            } else if (f) {
+                f.apply(this, [left, right]);
+            }
+            if (left.id === '!') {
+                warning("Confusing use of '{a}'.", left, '!');
+            }
+            if (right.id === '!') {
+                warning("Confusing use of '{a}'.", left, '!');
+            }
+            this.left = left;
+            this.right = right;
+            return this;
+        };
+        return x;
+    }
+
+
+    function isPoorRelation(node) {
+        return node &&
+              ((node.type === '(number)' && +node.value === 0) ||
+               (node.type === '(string)' && node.value === '') ||
+                node.type === 'true' ||
+                node.type === 'false' ||
+                node.type === 'undefined' ||
+                node.type === 'null');
+    }
+
+
+    function assignop(s, f) {
+        symbol(s, 20).exps = true;
+        return infix(s, function (left, that) {
+            var l;
+            that.left = left;
+            if (predefined[left.value] === false &&
+                    scope[left.value]['(global)'] === true) {
+                warning('Read only.', left);
+            }
+            if (option.safe) {
+                l = left;
+                do {
+                    if (typeof predefined[l.value] === 'boolean') {
+                        warning('ADsafe violation.', l);
+                    }
+                    l = l.left;
+                } while (l);
+            }
+            if (left) {
+                if (left.id === '.' || left.id === '[') {
+                    if (!left.left || left.left.value === 'arguments') {
+                        warning('Bad assignment.', that);
+                    }
+                    that.right = parse(19);
+                    return that;
+                } else if (left.identifier && !left.reserved) {
+                    if (funct[left.value] === 'exception') {
+                        warning("Do not assign to the exception parameter.", left);
+                    }
+                    that.right = parse(19);
+                    return that;
+                }
+                if (left === syntax['function']) {
+                    warning(
+"Expected an identifier in an assignment and instead saw a function invocation.",
+                                token);
+                }
+            }
+            error("Bad assignment.", that);
+        }, 20);
+    }
+
+    function bitwise(s, f, p) {
+        var x = symbol(s, p);
+        reserveName(x);
+        x.led = (typeof f === 'function') ? f : function (left) {
+            if (option.bitwise) {
+                warning("Unexpected use of '{a}'.", this, this.id);
+            }
+            this.left = left;
+            this.right = parse(p);
+            return this;
+        };
+        return x;
+    }
+
+    function bitwiseassignop(s) {
+        symbol(s, 20).exps = true;
+        return infix(s, function (left, that) {
+            if (option.bitwise) {
+                warning("Unexpected use of '{a}'.", that, that.id);
+            }
+            nonadjacent(prevtoken, token);
+            nonadjacent(token, nexttoken);
+            if (left) {
+                if (left.id === '.' || left.id === '[' ||
+                        (left.identifier && !left.reserved)) {
+                    parse(19);
+                    return that;
+                }
+                if (left === syntax['function']) {
+                    warning(
+"Expected an identifier in an assignment, and instead saw a function invocation.",
+                                token);
+                }
+                return that;
+            }
+            error("Bad assignment.", that);
+        }, 20);
+    }
+
+
+    function suffix(s, f) {
+        var x = symbol(s, 150);
+        x.led = function (left) {
+            if (option.plusplus) {
+                warning("Unexpected use of '{a}'.", this, this.id);
+            } else if ((!left.identifier || left.reserved) &&
+                    left.id !== '.' && left.id !== '[') {
+                warning("Bad operand.", this);
+            }
+            this.left = left;
+            return this;
+        };
+        return x;
+    }
+
+
+    function optionalidentifier() {
+        if (nexttoken.identifier) {
+            advance();
+            if (option.safe && banned[token.value]) {
+                warning("ADsafe violation: '{a}'.", token, token.value);
+            } else if (token.reserved && !option.es5) {
+                warning("Expected an identifier and instead saw '{a}' (a reserved word).",
+                        token, token.id);
+            }
+            return token.value;
+        }
+    }
+
+
+    function identifier() {
+        var i = optionalidentifier();
+        if (i) {
+            return i;
+        }
+        if (token.id === 'function' && nexttoken.id === '(') {
+            warning("Missing name in function statement.");
+        } else {
+            error("Expected an identifier and instead saw '{a}'.",
+                    nexttoken, nexttoken.value);
+        }
+    }
+
+    function reachable(s) {
+        var i = 0, t;
+        if (nexttoken.id !== ';' || noreach) {
+            return;
+        }
+        for (;;) {
+            t = peek(i);
+            if (t.reach) {
+                return;
+            }
+            if (t.id !== '(endline)') {
+                if (t.id === 'function') {
+                    warning(
+"Inner functions should be listed at the top of the outer function.", t);
+                    break;
+                }
+                warning("Unreachable '{a}' after '{b}'.", t, t.value, s);
+                break;
+            }
+            i += 1;
+        }
+    }
+
+
+    function statement(noindent) {
+        var i = indent, r, s = scope, t = nexttoken;
+
+// We don't like the empty statement.
+
+        if (t.id === ';') {
+            warning("Unnecessary semicolon.", t);
+            advance(';');
+            return;
+        }
+
+// Is this a labelled statement?
+
+        if (t.identifier && !t.reserved && peek().id === ':') {
+            advance();
+            advance(':');
+            scope = Object.create(s);
+            addlabel(t.value, 'label');
+            if (!nexttoken.labelled) {
+                warning("Label '{a}' on {b} statement.",
+                        nexttoken, t.value, nexttoken.value);
+            }
+            if (jx.test(t.value + ':')) {
+                warning("Label '{a}' looks like a javascript url.",
+                        t, t.value);
+            }
+            nexttoken.label = t.value;
+            t = nexttoken;
+        }
+
+// Parse the statement.
+
+        if (!noindent) {
+            indentation();
+        }
+        r = parse(0, true);
+
+// Look for the final semicolon.
+
+        if (!t.block) {
+            if (!r || !r.exps) {
+                warning(
+"Expected an assignment or function call and instead saw an expression.",
+                        token);
+            } else if (r.id === '(' && r.left.id === 'new') {
+                warning("Do not use 'new' for side effects.");
+            }
+            if (nexttoken.id !== ';') {
+                warningAt("Missing semicolon.", token.line,
+                        token.from + token.value.length);
+            } else {
+                adjacent(token, nexttoken);
+                advance(';');
+                nonadjacent(token, nexttoken);
+            }
+        }
+
+// Restore the indentation.
+
+        indent = i;
+        scope = s;
+        return r;
+    }
+
+
+    function use_strict() {
+        if (nexttoken.value === 'use strict') {
+            advance();
+            advance(';');
+            strict_mode = true;
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+
+    function statements(begin) {
+        var a = [], f, p;
+        if (begin && !use_strict() && option.strict) {
+            warning('Missing "use strict" statement.', nexttoken);
+        }
+        if (option.adsafe) {
+            switch (begin) {
+            case 'script':
+                if (!adsafe_may) {
+                    if (nexttoken.value !== 'ADSAFE' ||
+                            peek(0).id !== '.' ||
+                            (peek(1).value !== 'id' &&
+                            peek(1).value !== 'go')) {
+                        error('ADsafe violation: Missing ADSAFE.id or ADSAFE.go.',
+                            nexttoken);
+                    }
+                }
+                if (nexttoken.value === 'ADSAFE' &&
+                        peek(0).id === '.' &&
+                        peek(1).value === 'id') {
+                    if (adsafe_may) {
+                        error('ADsafe violation.', nexttoken);
+                    }
+                    advance('ADSAFE');
+                    advance('.');
+                    advance('id');
+                    advance('(');
+                    if (nexttoken.value !== adsafe_id) {
+                        error('ADsafe violation: id does not match.', nexttoken);
+                    }
+                    advance('(string)');
+                    advance(')');
+                    advance(';');
+                    adsafe_may = true;
+                }
+                break;
+            case 'lib':
+                if (nexttoken.value === 'ADSAFE') {
+                    advance('ADSAFE');
+                    advance('.');
+                    advance('lib');
+                    advance('(');
+                    advance('(string)');
+                    comma();
+                    f = parse(0);
+                    if (f.id !== 'function') {
+                        error('The second argument to lib must be a function.', f);
+                    }
+                    p = f.funct['(params)'];
+                    p = p && p.join(', ');
+                    if (p && p !== 'lib') {
+                        error("Expected '{a}' and instead saw '{b}'.",
+                            f, '(lib)', '(' + p + ')');
+                    }
+                    advance(')');
+                    advance(';');
+                    return a;
+                } else {
+                    error("ADsafe lib violation.");
+                }
+            }
+        }
+        while (!nexttoken.reach && nexttoken.id !== '(end)') {
+            if (nexttoken.id === ';') {
+                warning("Unnecessary semicolon.");
+                advance(';');
+            } else {
+                a.push(statement());
+            }
+        }
+        return a;
+    }
+
+
+    function block(f) {
+        var a, b = inblock, old_indent = indent, s = scope, t;
+        inblock = f;
+        scope = Object.create(scope);
+        nonadjacent(token, nexttoken);
+        t = nexttoken;
+        if (nexttoken.id === '{') {
+            advance('{');
+            if (nexttoken.id !== '}' || token.line !== nexttoken.line) {
+                indent += option.indent;
+                while (!f && nexttoken.from > indent) {
+                    indent += option.indent;
+                }
+                if (!f) {
+                    use_strict();
+                }
+                a = statements();
+                indent -= option.indent;
+                indentation();
+            }
+            advance('}', t);
+            indent = old_indent;
+        } else {
+            warning("Expected '{a}' and instead saw '{b}'.",
+                    nexttoken, '{', nexttoken.value);
+            noreach = true;
+            a = [statement()];
+            noreach = false;
+        }
+        funct['(verb)'] = null;
+        scope = s;
+        inblock = b;
+        return a;
+    }
+
+
+// An identity function, used by string and number tokens.
+
+    function idValue() {
+        return this;
+    }
+
+
+    function countMember(m) {
+        if (membersOnly && typeof membersOnly[m] !== 'boolean') {
+            warning("Unexpected /*member '{a}'.", token, m);
+        }
+        if (typeof member[m] === 'number') {
+            member[m] += 1;
+        } else {
+            member[m] = 1;
+        }
+    }
+
+
+    function note_implied(token) {
+        var name = token.value, line = token.line, a = implied[name];
+        if (typeof a === 'function') {
+            a = false;
+        }
+        if (!a) {
+            a = [line];
+            implied[name] = a;
+        } else if (a[a.length - 1] !== line) {
+            a.push(line);
+        }
+    }
+
+// CSS parsing.
+
+
+    function cssName() {
+        if (nexttoken.identifier) {
+            advance();
+            return true;
+        }
+    }
+
+    function cssNumber() {
+        if (nexttoken.id === '-') {
+            advance('-');
+            adjacent();
+            nolinebreak();
+        }
+        if (nexttoken.type === '(number)') {
+            advance('(number)');
+            return true;
+        }
+    }
+
+    function cssString() {
+        if (nexttoken.type === '(string)') {
+            advance();
+            return true;
+        }
+    }
+
+    function cssColor() {
+        var i, number, value;
+        if (nexttoken.identifier) {
+            value = nexttoken.value;
+            if (value === 'rgb' || value === 'rgba') {
+                advance();
+                advance('(');
+                for (i = 0; i < 3; i += 1) {
+                    if (i) {
+                        advance(',');
+                    }
+                    number = nexttoken.value;
+                    if (nexttoken.type !== '(number)' || number < 0) {
+                        warning("Expected a positive number and instead saw '{a}'",
+                            nexttoken, number);
+                        advance();
+                    } else {
+                        advance();
+                        if (nexttoken.id === '%') {
+                            advance('%');
+                            if (number > 100) {
+                                warning("Expected a percentage and instead saw '{a}'",
+                                    token, number);
+                            }
+                        } else {
+                            if (number > 255) {
+                                warning("Expected a small number and instead saw '{a}'",
+                                    token, number);
+                            }
+                        }
+                    }
+                }
+                if (value === 'rgba') {
+                    advance(',');
+                    number = +nexttoken.value;
+                    if (nexttoken.type !== '(number)' || number < 0 || number > 1) {
+                        warning("Expected a number between 0 and 1 and instead saw '{a}'",
+                            nexttoken, number);
+                    }
+                    advance();
+                    if (nexttoken.id === '%') {
+                        warning("Unexpected '%'.");
+                        advance('%');
+                    }
+                }
+                advance(')');
+                return true;
+            } else if (cssColorData[nexttoken.value] === true) {
+                advance();
+                return true;
+            }
+        } else if (nexttoken.type === '(color)') {
+            advance();
+            return true;
+        }
+        return false;
+    }
+
+    function cssLength() {
+        if (nexttoken.id === '-') {
+            advance('-');
+            adjacent();
+            nolinebreak();
+        }
+        if (nexttoken.type === '(number)') {
+            advance();
+            if (nexttoken.type !== '(string)' &&
+                    cssLengthData[nexttoken.value] === true) {
+                adjacent();
+                advance();
+            } else if (+token.value !== 0) {
+                warning("Expected a linear unit and instead saw '{a}'.",
+                    nexttoken, nexttoken.value);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    function cssLineHeight() {
+        if (nexttoken.id === '-') {
+            advance('-');
+            adjacent();
+        }
+        if (nexttoken.type === '(number)') {
+            advance();
+            if (nexttoken.type !== '(string)' &&
+                    cssLengthData[nexttoken.value] === true) {
+                adjacent();
+                advance();
+            }
+            return true;
+        }
+        return false;
+    }
+
+    function cssWidth() {
+        if (nexttoken.identifier) {
+            switch (nexttoken.value) {
+            case 'thin':
+            case 'medium':
+            case 'thick':
+                advance();
+                return true;
+            }
+        } else {
+            return cssLength();
+        }
+    }
+
+    function cssMargin() {
+        if (nexttoken.identifier) {
+            if (nexttoken.value === 'auto') {
+                advance();
+                return true;
+            }
+        } else {
+            return cssLength();
+        }
+    }
+
+    function cssAttr() {
+        if (nexttoken.identifier && nexttoken.value === 'attr') {
+            advance();
+            advance('(');
+            if (!nexttoken.identifier) {
+                warning("Expected a name and instead saw '{a}'.",
+                        nexttoken, nexttoken.value);
+            }
+            advance();
+            advance(')');
+            return true;
+        }
+        return false;
+    }
+
+    function cssCommaList() {
+        while (nexttoken.id !== ';') {
+            if (!cssName() && !cssString()) {
+                warning("Expected a name and instead saw '{a}'.",
+                        nexttoken, nexttoken.value);
+            }
+            if (nexttoken.id !== ',') {
+                return true;
+            }
+            comma();
+        }
+    }
+
+    function cssCounter() {
+        if (nexttoken.identifier && nexttoken.value === 'counter') {
+            advance();
+            advance('(');
+            if (!nexttoken.identifier) {
+            }
+            advance();
+            if (nexttoken.id === ',') {
+                comma();
+                if (nexttoken.type !== '(string)') {
+                    warning("Expected a string and instead saw '{a}'.",
+                        nexttoken, nexttoken.value);
+                }
+                advance();
+            }
+            advance(')');
+            return true;
+        }
+        if (nexttoken.identifier && nexttoken.value === 'counters') {
+            advance();
+            advance('(');
+            if (!nexttoken.identifier) {
+                warning("Expected a name and instead saw '{a}'.",
+                        nexttoken, nexttoken.value);
+            }
+            advance();
+            if (nexttoken.id === ',') {
+                comma();
+                if (nexttoken.type !== '(string)') {
+                    warning("Expected a string and instead saw '{a}'.",
+                        nexttoken, nexttoken.value);
+                }
+                advance();
+            }
+            if (nexttoken.id === ',') {
+                comma();
+                if (nexttoken.type !== '(string)') {
+                    warning("Expected a string and instead saw '{a}'.",
+                        nexttoken, nexttoken.value);
+                }
+                advance();
+            }
+            advance(')');
+            return true;
+        }
+        return false;
+    }
+
+
+    function cssShape() {
+        var i;
+        if (nexttoken.identifier && nexttoken.value === 'rect') {
+            advance();
+            advance('(');
+            for (i = 0; i < 4; i += 1) {
+                if (!cssLength()) {
+                    warning("Expected a number and instead saw '{a}'.",
+                        nexttoken, nexttoken.value);
+                    break;
+                }
+            }
+            advance(')');
+            return true;
+        }
+        return false;
+    }
+
+    function cssUrl() {
+        var c, url;
+        if (nexttoken.identifier && nexttoken.value === 'url') {
+            nexttoken = lex.range('(', ')');
+            url = nexttoken.value;
+            c = url.charAt(0);
+            if (c === '"' || c === '\'') {
+                if (url.slice(-1) !== c) {
+                    warning("Bad url string.");
+                } else {
+                    url = url.slice(1, -1);
+                    if (url.indexOf(c) >= 0) {
+                        warning("Bad url string.");
+                    }
+                }
+            }
+            if (!url) {
+                warning("Missing url.");
+            }
+            advance();
+            if (option.safe && ux.test(url)) {
+                error("ADsafe URL violation.");
+            }
+            urls.push(url);
+            return true;
+        }
+        return false;
+    }
+
+    cssAny = [cssUrl, function () {
+        for (;;) {
+            if (nexttoken.identifier) {
+                switch (nexttoken.value.toLowerCase()) {
+                case 'url':
+                    cssUrl();
+                    break;
+                case 'expression':
+                    warning("Unexpected expression '{a}'.",
+                        nexttoken, nexttoken.value);
+                    advance();
+                    break;
+                default:
+                    advance();
+                }
+            } else {
+                if (nexttoken.id === ';' || nexttoken.id === '!'  ||
+                        nexttoken.id === '(end)' || nexttoken.id === '}') {
+                    return true;
+                }
+                advance();
+            }
+        }
+    }];
+
+    cssBorderStyle = [
+        'none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'ridge',
+        'inset', 'outset'
+    ];
+
+    cssBreak = [
+        'auto', 'always', 'avoid', 'left', 'right'
+    ];
+
+    cssOverflow = [
+        'auto', 'hidden', 'scroll', 'visible'
+    ];
+
+    cssAttributeData = {
+        background: [
+            true, 'background-attachment', 'background-color',
+            'background-image', 'background-position', 'background-repeat'
+        ],
+        'background-attachment': ['scroll', 'fixed'],
+        'background-color': ['transparent', cssColor],
+        'background-image': ['none', cssUrl],
+        'background-position': [
+            2, [cssLength, 'top', 'bottom', 'left', 'right', 'center']
+        ],
+        'background-repeat': [
+            'repeat', 'repeat-x', 'repeat-y', 'no-repeat'
+        ],
+        'border': [true, 'border-color', 'border-style', 'border-width'],
+        'border-bottom': [
+            true, 'border-bottom-color', 'border-bottom-style',
+            'border-bottom-width'
+        ],
+        'border-bottom-color': cssColor,
+        'border-bottom-style': cssBorderStyle,
+        'border-bottom-width': cssWidth,
+        'border-collapse': ['collapse', 'separate'],
+        'border-color': ['transparent', 4, cssColor],
+        'border-left': [
+            true, 'border-left-color', 'border-left-style', 'border-left-width'
+        ],
+        'border-left-color': cssColor,
+        'border-left-style': cssBorderStyle,
+        'border-left-width': cssWidth,
+        'border-right': [
+            true, 'border-right-color', 'border-right-style',
+            'border-right-width'
+        ],
+        'border-right-color': cssColor,
+        'border-right-style': cssBorderStyle,
+        'border-right-width': cssWidth,
+        'border-spacing': [2, cssLength],
+        'border-style': [4, cssBorderStyle],
+        'border-top': [
+            true, 'border-top-color', 'border-top-style', 'border-top-width'
+        ],
+        'border-top-color': cssColor,
+        'border-top-style': cssBorderStyle,
+        'border-top-width': cssWidth,
+        'border-width': [4, cssWidth],
+        bottom: [cssLength, 'auto'],
+        'caption-side' : ['bottom', 'left', 'right', 'top'],
+        clear: ['both', 'left', 'none', 'right'],
+        clip: [cssShape, 'auto'],
+        color: cssColor,
+        content: [
+            'open-quote', 'close-quote', 'no-open-quote', 'no-close-quote',
+            cssString, cssUrl, cssCounter, cssAttr
+        ],
+        'counter-increment': [
+            cssName, 'none'
+        ],
+        'counter-reset': [
+            cssName, 'none'
+        ],
+        cursor: [
+            cssUrl, 'auto', 'crosshair', 'default', 'e-resize', 'help', 'move',
+            'n-resize', 'ne-resize', 'nw-resize', 'pointer', 's-resize',
+            'se-resize', 'sw-resize', 'w-resize', 'text', 'wait'
+        ],
+        direction: ['ltr', 'rtl'],
+        display: [
+            'block', 'compact', 'inline', 'inline-block', 'inline-table',
+            'list-item', 'marker', 'none', 'run-in', 'table', 'table-caption',
+            'table-cell', 'table-column', 'table-column-group',
+            'table-footer-group', 'table-header-group', 'table-row',
+            'table-row-group'
+        ],
+        'empty-cells': ['show', 'hide'],
+        'float': ['left', 'none', 'right'],
+        font: [
+            'caption', 'icon', 'menu', 'message-box', 'small-caption',
+            'status-bar', true, 'font-size', 'font-style', 'font-weight',
+            'font-family'
+        ],
+        'font-family': cssCommaList,
+        'font-size': [
+            'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large',
+            'xx-large', 'larger', 'smaller', cssLength
+        ],
+        'font-size-adjust': ['none', cssNumber],
+        'font-stretch': [
+            'normal', 'wider', 'narrower', 'ultra-condensed',
+            'extra-condensed', 'condensed', 'semi-condensed',
+            'semi-expanded', 'expanded', 'extra-expanded'
+        ],
+        'font-style': [
+            'normal', 'italic', 'oblique'
+        ],
+        'font-variant': [
+            'normal', 'small-caps'
+        ],
+        'font-weight': [
+            'normal', 'bold', 'bolder', 'lighter', cssNumber
+        ],
+        height: [cssLength, 'auto'],
+        left: [cssLength, 'auto'],
+        'letter-spacing': ['normal', cssLength],
+        'line-height': ['normal', cssLineHeight],
+        'list-style': [
+            true, 'list-style-image', 'list-style-position', 'list-style-type'
+        ],
+        'list-style-image': ['none', cssUrl],
+        'list-style-position': ['inside', 'outside'],
+        'list-style-type': [
+            'circle', 'disc', 'square', 'decimal', 'decimal-leading-zero',
+            'lower-roman', 'upper-roman', 'lower-greek', 'lower-alpha',
+            'lower-latin', 'upper-alpha', 'upper-latin', 'hebrew', 'katakana',
+            'hiragana-iroha', 'katakana-oroha', 'none'
+        ],
+        margin: [4, cssMargin],
+        'margin-bottom': cssMargin,
+        'margin-left': cssMargin,
+        'margin-right': cssMargin,
+        'margin-top': cssMargin,
+        'marker-offset': [cssLength, 'auto'],
+        'max-height': [cssLength, 'none'],
+        'max-width': [cssLength, 'none'],
+        'min-height': cssLength,
+        'min-width': cssLength,
+        opacity: cssNumber,
+        outline: [true, 'outline-color', 'outline-style', 'outline-width'],
+        'outline-color': ['invert', cssColor],
+        'outline-style': [
+            'dashed', 'dotted', 'double', 'groove', 'inset', 'none',
+            'outset', 'ridge', 'solid'
+        ],
+        'outline-width': cssWidth,
+        overflow: cssOverflow,
+        'overflow-x': cssOverflow,
+        'overflow-y': cssOverflow,
+        padding: [4, cssLength],
+        'padding-bottom': cssLength,
+        'padding-left': cssLength,
+        'padding-right': cssLength,
+        'padding-top': cssLength,
+        'page-break-after': cssBreak,
+        'page-break-before': cssBreak,
+        position: ['absolute', 'fixed', 'relative', 'static'],
+        quotes: [8, cssString],
+        right: [cssLength, 'auto'],
+        'table-layout': ['auto', 'fixed'],
+        'text-align': ['center', 'justify', 'left', 'right'],
+        'text-decoration': [
+            'none', 'underline', 'overline', 'line-through', 'blink'
+        ],
+        'text-indent': cssLength,
+        'text-shadow': ['none', 4, [cssColor, cssLength]],
+        'text-transform': ['capitalize', 'uppercase', 'lowercase', 'none'],
+        top: [cssLength, 'auto'],
+        'unicode-bidi': ['normal', 'embed', 'bidi-override'],
+        'vertical-align': [
+            'baseline', 'bottom', 'sub', 'super', 'top', 'text-top', 'middle',
+            'text-bottom', cssLength
+        ],
+        visibility: ['visible', 'hidden', 'collapse'],
+        'white-space': [
+            'normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap', 'inherit'
+        ],
+        width: [cssLength, 'auto'],
+        'word-spacing': ['normal', cssLength],
+        'word-wrap': ['break-word', 'normal'],
+        'z-index': ['auto', cssNumber]
+    };
+
+    function styleAttribute() {
+        var v;
+        while (nexttoken.id === '*' || nexttoken.id === '#' ||
+                nexttoken.value === '_') {
+            if (!option.css) {
+                warning("Unexpected '{a}'.", nexttoken, nexttoken.value);
+            }
+            advance();
+        }
+        if (nexttoken.id === '-') {
+            if (!option.css) {
+                warning("Unexpected '{a}'.", nexttoken, nexttoken.value);
+            }
+            advance('-');
+            if (!nexttoken.identifier) {
+                warning(
+"Expected a non-standard style attribute and instead saw '{a}'.",
+                    nexttoken, nexttoken.value);
+            }
+            advance();
+            return cssAny;
+        } else {
+            if (!nexttoken.identifier) {
+                warning("Excepted a style attribute, and instead saw '{a}'.",
+                    nexttoken, nexttoken.value);
+            } else {
+                if (is_own(cssAttributeData, nexttoken.value)) {
+                    v = cssAttributeData[nexttoken.value];
+                } else {
+                    v = cssAny;
+                    if (!option.css) {
+                        warning("Unrecognized style attribute '{a}'.",
+                                nexttoken, nexttoken.value);
+                    }
+                }
+            }
+            advance();
+            return v;
+        }
+    }
+
+    function styleValue(v) {
+        var i = 0,
+            n,
+            once,
+            match,
+            round,
+            start = 0,
+            vi;
+        switch (typeof v) {
+        case 'function':
+            return v();
+        case 'string':
+            if (nexttoken.identifier && nexttoken.value === v) {
+                advance();
+                return true;
+            }
+            return false;
+        }
+        for (;;) {
+            if (i >= v.length) {
+                return false;
+            }
+            vi = v[i];
+            i += 1;
+            if (vi === true) {
+                break;
+            } else if (typeof vi === 'number') {
+                n = vi;
+                vi = v[i];
+                i += 1;
+            } else {
+                n = 1;
+            }
+            match = false;
+            while (n > 0) {
+                if (styleValue(vi)) {
+                    match = true;
+                    n -= 1;
+                } else {
+                    break;
+                }
+            }
+            if (match) {
+                return true;
+            }
+        }
+        start = i;
+        once = [];
+        for (;;) {
+            round = false;
+            for (i = start; i < v.length; i += 1) {
+                if (!once[i]) {
+                    if (styleValue(cssAttributeData[v[i]])) {
+                        match = true;
+                        round = true;
+                        once[i] = true;
+                        break;
+                    }
+                }
+            }
+            if (!round) {
+                return match;
+            }
+        }
+    }
+
+    function styleChild() {
+        if (nexttoken.id === '(number)') {
+            advance();
+            if (nexttoken.value === 'n' && nexttoken.identifier) {
+                adjacent();
+                advance();
+                if (nexttoken.id === '+') {
+                    adjacent();
+                    advance('+');
+                    adjacent();
+                    advance('(number)');
+                }
+            }
+            return;
+        } else {
+            switch (nexttoken.value) {
+            case 'odd':
+            case 'even':
+                if (nexttoken.identifier) {
+                    advance();
+                    return;
+                }
+            }
+        }
+        warning("Unexpected token '{a}'.", nexttoken, nexttoken.value);
+    }
+
+    function substyle() {
+        var v;
+        for (;;) {
+            if (nexttoken.id === '}' || nexttoken.id === '(end)' ||
+                    xquote && nexttoken.id === xquote) {
+                return;
+            }
+            while (nexttoken.id === ';') {
+                warning("Misplaced ';'.");
+                advance(';');
+            }
+            v = styleAttribute();
+            advance(':');
+            if (nexttoken.identifier && nexttoken.value === 'inherit') {
+                advance();
+            } else {
+                if (!styleValue(v)) {
+                    warning("Unexpected token '{a}'.", nexttoken,
+                        nexttoken.value);
+                    advance();
+                }
+            }
+            if (nexttoken.id === '!') {
+                advance('!');
+                adjacent();
+                if (nexttoken.identifier && nexttoken.value === 'important') {
+                    advance();
+                } else {
+                    warning("Expected '{a}' and instead saw '{b}'.",
+                        nexttoken, 'important', nexttoken.value);
+                }
+            }
+            if (nexttoken.id === '}' || nexttoken.id === xquote) {
+                warning("Missing '{a}'.", nexttoken, ';');
+            } else {
+                advance(';');
+            }
+        }
+    }
+
+    function styleSelector() {
+        if (nexttoken.identifier) {
+            if (!is_own(htmltag, nexttoken.value)) {
+                warning("Expected a tagName, and instead saw {a}.",
+                    nexttoken, nexttoken.value);
+            }
+            advance();
+        } else {
+            switch (nexttoken.id) {
+            case '>':
+            case '+':
+                advance();
+                styleSelector();
+                break;
+            case ':':
+                advance(':');
+                switch (nexttoken.value) {
+                case 'active':
+                case 'after':
+                case 'before':
+                case 'checked':
+                case 'disabled':
+                case 'empty':
+                case 'enabled':
+                case 'first-child':
+                case 'first-letter':
+                case 'first-line':
+                case 'first-of-type':
+                case 'focus':
+                case 'hover':
+                case 'last-of-type':
+                case 'link':
+                case 'only-of-type':
+                case 'root':
+                case 'target':
+                case 'visited':
+                    advance();
+                    break;
+                case 'lang':
+                    advance();
+                    advance('(');
+                    if (!nexttoken.identifier) {
+                        warning("Expected a lang code, and instead saw :{a}.",
+                            nexttoken, nexttoken.value);
+                    }
+                    advance(')');
+                    break;
+                case 'nth-child':
+                case 'nth-last-child':
+                case 'nth-last-of-type':
+                case 'nth-of-type':
+                    advance();
+                    advance('(');
+                    styleChild();
+                    advance(')');
+                    break;
+                case 'not':
+                    advance();
+                    advance('(');
+                    if (nexttoken.id === ':' && peek(0).value === 'not') {
+                        warning("Nested not.");
+                    }
+                    styleSelector();
+                    advance(')');
+                    break;
+                default:
+                    warning("Expected a pseudo, and instead saw :{a}.",
+                        nexttoken, nexttoken.value);
+                }
+                break;
+            case '#':
+                advance('#');
+                if (!nexttoken.identifier) {
+                    warning("Expected an id, and instead saw #{a}.",
+                        nexttoken, nexttoken.value);
+                }
+                advance();
+                break;
+            case '*':
+                advance('*');
+                break;
+            case '.':
+                advance('.');
+                if (!nexttoken.identifier) {
+                    warning("Expected a class, and instead saw #.{a}.",
+                        nexttoken, nexttoken.value);
+                }
+                advance();
+                break;
+            case '[':
+                advance('[');
+                if (!nexttoken.identifier) {
+                    warning("Expected an attribute, and instead saw [{a}].",
+                        nexttoken, nexttoken.value);
+                }
+                advance();
+                if (nexttoken.id === '=' || nexttoken.value === '~=' ||
+                        nexttoken.value === '$=' ||
+                        nexttoken.value === '|=' ||
+                        nexttoken.id === '*=' ||
+                        nexttoken.id === '^=') {
+                    advance();
+                    if (nexttoken.type !== '(string)') {
+                        warning("Expected a string, and instead saw {a}.",
+                            nexttoken, nexttoken.value);
+                    }
+                    advance();
+                }
+                advance(']');
+                break;
+            default:
+                error("Expected a CSS selector, and instead saw {a}.",
+                    nexttoken, nexttoken.value);
+            }
+        }
+    }
+
+    function stylePattern() {
+        var name;
+        if (nexttoken.id === '{') {
+            warning("Expected a style pattern, and instead saw '{a}'.", nexttoken,
+                nexttoken.id);
+        } else if (nexttoken.id === '@') {
+            advance('@');
+            name = nexttoken.value;
+            if (nexttoken.identifier && atrule[name] === true) {
+                advance();
+                return name;
+            }
+            warning("Expected an at-rule, and instead saw @{a}.", nexttoken, name);
+        }
+        for (;;) {
+            styleSelector();
+            if (nexttoken.id === '</' || nexttoken.id === '{' ||
+                    nexttoken.id === '(end)') {
+                return '';
+            }
+            if (nexttoken.id === ',') {
+                comma();
+            }
+        }
+    }
+
+    function styles() {
+        var i;
+        while (nexttoken.id === '@') {
+            i = peek();
+            if (i.identifier && i.value === 'import') {
+                advance('@');
+                advance();
+                if (!cssUrl()) {
+                    warning("Expected '{a}' and instead saw '{b}'.", nexttoken,
+                        'url', nexttoken.value);
+                    advance();
+                }
+                advance(';');
+            } else {
+                break;
+            }
+        }
+        while (nexttoken.id !== '</' && nexttoken.id !== '(end)') {
+            stylePattern();
+            xmode = 'styleproperty';
+            if (nexttoken.id === ';') {
+                advance(';');
+            } else {
+                advance('{');
+                substyle();
+                xmode = 'style';
+                advance('}');
+            }
+        }
+    }
+
+
+// HTML parsing.
+
+    function doBegin(n) {
+        if (n !== 'html' && !option.fragment) {
+            if (n === 'div' && option.adsafe) {
+                error("ADSAFE: Use the fragment option.");
+            } else {
+                error("Expected '{a}' and instead saw '{b}'.",
+                    token, 'html', n);
+            }
+        }
+        if (option.adsafe) {
+            if (n === 'html') {
+                error(
+"Currently, ADsafe does not operate on whole HTML documents. It operates on <div> fragments and .js files.", token);
+            }
+            if (option.fragment) {
+                if (n !== 'div') {
+                    error("ADsafe violation: Wrap the widget in a div.", token);
+                }
+            } else {
+                error("Use the fragment option.", token);
+            }
+        }
+        option.browser = true;
+        assume();
+    }
+
+    function doAttribute(n, a, v) {
+        var u, x;
+        if (a === 'id') {
+            u = typeof v === 'string' ? v.toUpperCase() : '';
+            if (ids[u] === true) {
+                warning("Duplicate id='{a}'.", nexttoken, v);
+            }
+            if (!/^[A-Za-z][A-Za-z0-9._:\-]*$/.test(v)) {
+                warning("Bad id: '{a}'.", nexttoken, v);
+            } else if (option.adsafe) {
+                if (adsafe_id) {
+                    if (v.slice(0, adsafe_id.length) !== adsafe_id) {
+                        warning("ADsafe violation: An id must have a '{a}' prefix",
+                                nexttoken, adsafe_id);
+                    } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) {
+                        warning("ADSAFE violation: bad id.");
+                    }
+                } else {
+                    adsafe_id = v;
+                    if (!/^[A-Z]+_$/.test(v)) {
+                        warning("ADSAFE violation: bad id.");
+                    }
+                }
+            }
+            x = v.search(dx);
+            if (x >= 0) {
+                warning("Unexpected character '{a}' in {b}.", token, v.charAt(x), a);
+            }
+            ids[u] = true;
+        } else if (a === 'class' || a === 'type' || a === 'name') {
+            x = v.search(qx);
+            if (x >= 0) {
+                warning("Unexpected character '{a}' in {b}.", token, v.charAt(x), a);
+            }
+            ids[u] = true;
+        } else if (a === 'href' || a === 'background' ||
+                a === 'content' || a === 'data' ||
+                a.indexOf('src') >= 0 || a.indexOf('url') >= 0) {
+            if (option.safe && ux.test(v)) {
+                error("ADsafe URL violation.");
+            }
+            urls.push(v);
+        } else if (a === 'for') {
+            if (option.adsafe) {
+                if (adsafe_id) {
+                    if (v.slice(0, adsafe_id.length) !== adsafe_id) {
+                        warning("ADsafe violation: An id must have a '{a}' prefix",
+                                nexttoken, adsafe_id);
+                    } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) {
+                        warning("ADSAFE violation: bad id.");
+                    }
+                } else {
+                    warning("ADSAFE violation: bad id.");
+                }
+            }
+        } else if (a === 'name') {
+            if (option.adsafe && v.indexOf('_') >= 0) {
+                warning("ADsafe name violation.");
+            }
+        }
+    }
+
+    function doTag(n, a) {
+        var i, t = htmltag[n], x;
+        src = false;
+        if (!t) {
+            error("Unrecognized tag '<{a}>'.",
+                    nexttoken,
+                    n === n.toLowerCase() ? n :
+                        n + ' (capitalization error)');
+        }
+        if (stack.length > 0) {
+            if (n === 'html') {
+                error("Too many <html> tags.", token);
+            }
+            x = t.parent;
+            if (x) {
+                if (x.indexOf(' ' + stack[stack.length - 1].name + ' ') < 0) {
+                    error("A '<{a}>' must be within '<{b}>'.",
+                            token, n, x);
+                }
+            } else if (!option.adsafe && !option.fragment) {
+                i = stack.length;
+                do {
+                    if (i <= 0) {
+                        error("A '<{a}>' must be within '<{b}>'.",
+                                token, n, 'body');
+                    }
+                    i -= 1;
+                } while (stack[i].name !== 'body');
+            }
+        }
+        switch (n) {
+        case 'div':
+            if (option.adsafe && stack.length === 1 && !adsafe_id) {
+                warning("ADSAFE violation: missing ID_.");
+            }
+            break;
+        case 'script':
+            xmode = 'script';
+            advance('>');
+            indent = nexttoken.from;
+            if (a.lang) {
+                warning("lang is deprecated.", token);
+            }
+            if (option.adsafe && stack.length !== 1) {
+                warning("ADsafe script placement violation.", token);
+            }
+            if (a.src) {
+                if (option.adsafe && (!adsafe_may || !approved[a.src])) {
+                    warning("ADsafe unapproved script source.", token);
+                }
+                if (a.type) {
+                    warning("type is unnecessary.", token);
+                }
+            } else {
+                if (adsafe_went) {
+                    error("ADsafe script violation.", token);
+                }
+                statements('script');
+            }
+            xmode = 'html';
+            advance('</');
+            if (!nexttoken.identifier && nexttoken.value !== 'script') {
+                warning("Expected '{a}' and instead saw '{b}'.",
+                        nexttoken, 'script', nexttoken.value);
+            }
+            advance();
+            xmode = 'outer';
+            break;
+        case 'style':
+            xmode = 'style';
+            advance('>');
+            styles();
+            xmode = 'html';
+            advance('</');
+            if (!nexttoken.identifier && nexttoken.value !== 'style') {
+                warning("Expected '{a}' and instead saw '{b}'.",
+                        nexttoken, 'style', nexttoken.value);
+            }
+            advance();
+            xmode = 'outer';
+            break;
+        case 'input':
+            switch (a.type) {
+            case 'radio':
+            case 'checkbox':
+            case 'button':
+            case 'reset':
+            case 'submit':
+                break;
+            case 'text':
+            case 'file':
+            case 'password':
+            case 'file':
+            case 'hidden':
+            case 'image':
+                if (option.adsafe && a.autocomplete !== 'off') {
+                    warning("ADsafe autocomplete violation.");
+                }
+                break;
+            default:
+                warning("Bad input type.");
+            }
+            break;
+        case 'applet':
+        case 'body':
+        case 'embed':
+        case 'frame':
+        case 'frameset':
+        case 'head':
+        case 'iframe':
+        case 'noembed':
+        case 'noframes':
+        case 'object':
+        case 'param':
+            if (option.adsafe) {
+                warning("ADsafe violation: Disallowed tag: " + n);
+            }
+            break;
+        }
+    }
+
+
+    function closetag(n) {
+        return '</' + n + '>';
+    }
+
+    function html() {
+        var a, attributes, e, n, q, t, v, w = option.white, wmode;
+        xmode = 'html';
+        xquote = '';
+        stack = null;
+        for (;;) {
+            switch (nexttoken.value) {
+            case '<':
+                xmode = 'html';
+                advance('<');
+                attributes = {};
+                t = nexttoken;
+                if (!t.identifier) {
+                    warning("Bad identifier {a}.", t, t.value);
+                }
+                n = t.value;
+                if (option.cap) {
+                    n = n.toLowerCase();
+                }
+                t.name = n;
+                advance();
+                if (!stack) {
+                    stack = [];
+                    doBegin(n);
+                }
+                v = htmltag[n];
+                if (typeof v !== 'object') {
+                    error("Unrecognized tag '<{a}>'.", t, n);
+                }
+                e = v.empty;
+                t.type = n;
+                for (;;) {
+                    if (nexttoken.id === '/') {
+                        advance('/');
+                        if (nexttoken.id !== '>') {
+                            warning("Expected '{a}' and instead saw '{b}'.",
+                                    nexttoken, '>', nexttoken.value);
+                        }
+                        break;
+                    }
+                    if (nexttoken.id && nexttoken.id.substr(0, 1) === '>') {
+                        break;
+                    }
+                    if (!nexttoken.identifier) {
+                        if (nexttoken.id === '(end)' || nexttoken.id === '(error)') {
+                            error("Missing '>'.", nexttoken);
+                        }
+                        warning("Bad identifier.");
+                    }
+                    option.white = true;
+                    nonadjacent(token, nexttoken);
+                    a = nexttoken.value;
+                    option.white = w;
+                    advance();
+                    if (!option.cap && a !== a.toLowerCase()) {
+                        warning("Attribute '{a}' not all lower case.", nexttoken, a);
+                    }
+                    a = a.toLowerCase();
+                    xquote = '';
+                    if (is_own(attributes, a)) {
+                        warning("Attribute '{a}' repeated.", nexttoken, a);
+                    }
+                    if (a.slice(0, 2) === 'on') {
+                        if (!option.on) {
+                            warning("Avoid HTML event handlers.");
+                        }
+                        xmode = 'scriptstring';
+                        advance('=');
+                        q = nexttoken.id;
+                        if (q !== '"' && q !== "'") {
+                            error("Missing quote.");
+                        }
+                        xquote = q;
+                        wmode = option.white;
+                        option.white = false;
+                        advance(q);
+                        statements('on');
+                        option.white = wmode;
+                        if (nexttoken.id !== q) {
+                            error("Missing close quote on script attribute.");
+                        }
+                        xmode = 'html';
+                        xquote = '';
+                        advance(q);
+                        v = false;
+                    } else if (a === 'style') {
+                        xmode = 'scriptstring';
+                        advance('=');
+                        q = nexttoken.id;
+                        if (q !== '"' && q !== "'") {
+                            error("Missing quote.");
+                        }
+                        xmode = 'styleproperty';
+                        xquote = q;
+                        advance(q);
+                        substyle();
+                        xmode = 'html';
+                        xquote = '';
+                        advance(q);
+                        v = false;
+                    } else {
+                        if (nexttoken.id === '=') {
+                            advance('=');
+                            v = nexttoken.value;
+                            if (!nexttoken.identifier &&
+                                    nexttoken.id !== '"' &&
+                                    nexttoken.id !== '\'' &&
+                                    nexttoken.type !== '(string)' &&
+                                    nexttoken.type !== '(number)' &&
+                                    nexttoken.type !== '(color)') {
+                                warning("Expected an attribute value and instead saw '{a}'.", token, a);
+                            }
+                            advance();
+                        } else {
+                            v = true;
+                        }
+                    }
+                    attributes[a] = v;
+                    doAttribute(n, a, v);
+                }
+                doTag(n, attributes);
+                if (!e) {
+                    stack.push(t);
+                }
+                xmode = 'outer';
+                advance('>');
+                break;
+            case '</':
+                xmode = 'html';
+                advance('</');
+                if (!nexttoken.identifier) {
+                    warning("Bad identifier.");
+                }
+                n = nexttoken.value;
+                if (option.cap) {
+                    n = n.toLowerCase();
+                }
+                advance();
+                if (!stack) {
+                    error("Unexpected '{a}'.", nexttoken, closetag(n));
+                }
+                t = stack.pop();
+                if (!t) {
+                    error("Unexpected '{a}'.", nexttoken, closetag(n));
+                }
+                if (t.name !== n) {
+                    error("Expected '{a}' and instead saw '{b}'.",
+                            nexttoken, closetag(t.name), closetag(n));
+                }
+                if (nexttoken.id !== '>') {
+                    error("Missing '{a}'.", nexttoken, '>');
+                }
+                xmode = 'outer';
+                advance('>');
+                break;
+            case '<!':
+                if (option.safe) {
+                    warning("ADsafe HTML violation.");
+                }
+                xmode = 'html';
+                for (;;) {
+                    advance();
+                    if (nexttoken.id === '>' || nexttoken.id === '(end)') {
+                        break;
+                    }
+                    if (nexttoken.value.indexOf('--') >= 0) {
+                        error("Unexpected --.");
+                    }
+                    if (nexttoken.value.indexOf('<') >= 0) {
+                        error("Unexpected <.");
+                    }
+                    if (nexttoken.value.indexOf('>') >= 0) {
+                        error("Unexpected >.");
+                    }
+                }
+                xmode = 'outer';
+                advance('>');
+                break;
+            case '(end)':
+                return;
+            default:
+                if (nexttoken.id === '(end)') {
+                    error("Missing '{a}'.", nexttoken,
+                            '</' + stack[stack.length - 1].value + '>');
+                } else {
+                    advance();
+                }
+            }
+            if (stack && stack.length === 0 && (option.adsafe ||
+                    !option.fragment || nexttoken.id === '(end)')) {
+                break;
+            }
+        }
+        if (nexttoken.id !== '(end)') {
+            error("Unexpected material after the end.");
+        }
+    }
+
+
+// Build the syntax table by declaring the syntactic elements of the language.
+
+    type('(number)', idValue);
+    type('(string)', idValue);
+
+    syntax['(identifier)'] = {
+        type: '(identifier)',
+        lbp: 0,
+        identifier: true,
+        nud: function () {
+            var v = this.value,
+                s = scope[v],
+                f;
+            if (typeof s === 'function') {
+                s = undefined;
+            } else if (typeof s === 'boolean') {
+                f = funct;
+                funct = functions[0];
+                addlabel(v, 'var');
+                s = funct;
+                funct = f;
+            }
+
+// The name is in scope and defined in the current function.
+
+            if (funct === s) {
+
+//      Change 'unused' to 'var', and reject labels.
+
+                switch (funct[v]) {
+                case 'unused':
+                    funct[v] = 'var';
+                    break;
+                case 'label':
+                    warning("'{a}' is a statement label.", token, v);
+                    break;
+                }
+
+// The name is not defined in the function.  If we are in the global scope,
+// then we have an undefined variable.
+
+            } else if (funct['(global)']) {
+                if (option.undef && predefined[v] !== 'boolean') {
+                    warning("'{a}' is not defined.", token, v);
+                }
+                note_implied(token);
+
+// If the name is already defined in the current
+// function, but not as outer, then there is a scope error.
+
+            } else {
+                switch (funct[v]) {
+                case 'closure':
+                case 'function':
+                case 'var':
+                case 'unused':
+                    warning("'{a}' used out of scope.", token, v);
+                    break;
+                case 'label':
+                    warning("'{a}' is a statement label.", token, v);
+                    break;
+                case 'outer':
+                case 'global':
+                    break;
+                default:
+
+// If the name is defined in an outer function, make an outer entry, and if
+// it was unused, make it var.
+
+                    if (s === true) {
+                        funct[v] = true;
+                    } else if (s === null) {
+                        warning("'{a}' is not allowed.", token, v);
+                        note_implied(token);
+                    } else if (typeof s !== 'object') {
+                        if (option.undef) {
+                            warning("'{a}' is not defined.", token, v);
+                        } else {
+                            funct[v] = true;
+                        }
+                        note_implied(token);
+                    } else {
+                        switch (s[v]) {
+                        case 'function':
+                        case 'var':
+                        case 'unused':
+                            s[v] = 'closure';
+                            funct[v] = s['(global)'] ? 'global' : 'outer';
+                            break;
+                        case 'closure':
+                        case 'parameter':
+                            funct[v] = s['(global)'] ? 'global' : 'outer';
+                            break;
+                        case 'label':
+                            warning("'{a}' is a statement label.", token, v);
+                        }
+                    }
+                }
+            }
+            return this;
+        },
+        led: function () {
+            error("Expected an operator and instead saw '{a}'.",
+                    nexttoken, nexttoken.value);
+        }
+    };
+
+    type('(regexp)', function () {
+        return this;
+    });
+
+
+// ECMAScript parser
+
+    delim('(endline)');
+    delim('(begin)');
+    delim('(end)').reach = true;
+    delim('</').reach = true;
+    delim('<!');
+    delim('<!--');
+    delim('-->');
+    delim('(error)').reach = true;
+    delim('}').reach = true;
+    delim(')');
+    delim(']');
+    delim('"').reach = true;
+    delim("'").reach = true;
+    delim(';');
+    delim(':').reach = true;
+    delim(',');
+    delim('#');
+    delim('@');
+    reserve('else');
+    reserve('case').reach = true;
+    reserve('catch');
+    reserve('default').reach = true;
+    reserve('finally');
+    reservevar('arguments');
+    reservevar('eval');
+    reservevar('false');
+    reservevar('Infinity');
+    reservevar('NaN');
+    reservevar('null');
+    reservevar('this');
+    reservevar('true');
+    reservevar('undefined');
+    assignop('=', 'assign', 20);
+    assignop('+=', 'assignadd', 20);
+    assignop('-=', 'assignsub', 20);
+    assignop('*=', 'assignmult', 20);
+    assignop('/=', 'assigndiv', 20).nud = function () {
+        error("A regular expression literal can be confused with '/='.");
+    };
+    assignop('%=', 'assignmod', 20);
+    bitwiseassignop('&=', 'assignbitand', 20);
+    bitwiseassignop('|=', 'assignbitor', 20);
+    bitwiseassignop('^=', 'assignbitxor', 20);
+    bitwiseassignop('<<=', 'assignshiftleft', 20);
+    bitwiseassignop('>>=', 'assignshiftright', 20);
+    bitwiseassignop('>>>=', 'assignshiftrightunsigned', 20);
+    infix('?', function (left, that) {
+        that.left = left;
+        that.right = parse(10);
+        advance(':');
+        that['else'] = parse(10);
+        return that;
+    }, 30);
+
+    infix('||', 'or', 40);
+    infix('&&', 'and', 50);
+    bitwise('|', 'bitor', 70);
+    bitwise('^', 'bitxor', 80);
+    bitwise('&', 'bitand', 90);
+    relation('==', function (left, right) {
+        if (option.eqeqeq) {
+            warning("Expected '{a}' and instead saw '{b}'.",
+                    this, '===', '==');
+        } else if (isPoorRelation(left)) {
+            warning("Use '{a}' to compare with '{b}'.",
+                this, '===', left.value);
+        } else if (isPoorRelation(right)) {
+            warning("Use '{a}' to compare with '{b}'.",
+                this, '===', right.value);
+        }
+        return this;
+    });
+    relation('===');
+    relation('!=', function (left, right) {
+        if (option.eqeqeq) {
+            warning("Expected '{a}' and instead saw '{b}'.",
+                    this, '!==', '!=');
+        } else if (isPoorRelation(left)) {
+            warning("Use '{a}' to compare with '{b}'.",
+                    this, '!==', left.value);
+        } else if (isPoorRelation(right)) {
+            warning("Use '{a}' to compare with '{b}'.",
+                    this, '!==', right.value);
+        }
+        return this;
+    });
+    relation('!==');
+    relation('<');
+    relation('>');
+    relation('<=');
+    relation('>=');
+    bitwise('<<', 'shiftleft', 120);
+    bitwise('>>', 'shiftright', 120);
+    bitwise('>>>', 'shiftrightunsigned', 120);
+    infix('in', 'in', 120);
+    infix('instanceof', 'instanceof', 120);
+    infix('+', function (left, that) {
+        var right = parse(130);
+        if (left && right && left.id === '(string)' && right.id === '(string)') {
+            left.value += right.value;
+            left.character = right.character;
+            if (jx.test(left.value)) {
+                warning("JavaScript URL.", left);
+            }
+            return left;
+        }
+        that.left = left;
+        that.right = right;
+        return that;
+    }, 130);
+    prefix('+', 'num');
+    prefix('+++', function () {
+        warning("Confusing pluses.");
+        this.right = parse(150);
+        this.arity = 'unary';
+        return this;
+    });
+    infix('+++', function (left) {
+        warning("Confusing pluses.");
+        this.left = left;
+        this.right = parse(130);
+        return this;
+    }, 130);
+    infix('-', 'sub', 130);
+    prefix('-', 'neg');
+    prefix('---', function () {
+        warning("Confusing minuses.");
+        this.right = parse(150);
+        this.arity = 'unary';
+        return this;
+    });
+    infix('---', function (left) {
+        warning("Confusing minuses.");
+        this.left = left;
+        this.right = parse(130);
+        return this;
+    }, 130);
+    infix('*', 'mult', 140);
+    infix('/', 'div', 140);
+    infix('%', 'mod', 140);
+
+    suffix('++', 'postinc');
+    prefix('++', 'preinc');
+    syntax['++'].exps = true;
+
+    suffix('--', 'postdec');
+    prefix('--', 'predec');
+    syntax['--'].exps = true;
+    prefix('delete', function () {
+        var p = parse(0);
+        if (!p || (p.id !== '.' && p.id !== '[')) {
+            warning("Expected '{a}' and instead saw '{b}'.",
+                    nexttoken, '.', nexttoken.value);
+        }
+        this.first = p;
+        return this;
+    }).exps = true;
+
+
+    prefix('~', function () {
+        if (option.bitwise) {
+            warning("Unexpected '{a}'.", this, '~');
+        }
+        parse(150);
+        return this;
+    });
+    prefix('!', function () {
+        this.right = parse(150);
+        this.arity = 'unary';
+        if (bang[this.right.id] === true) {
+            warning("Confusing use of '{a}'.", this, '!');
+        }
+        return this;
+    });
+    prefix('typeof', 'typeof');
+    prefix('new', function () {
+        var c = parse(155), i;
+        if (c && c.id !== 'function') {
+            if (c.identifier) {
+                c['new'] = true;
+                switch (c.value) {
+                case 'Object':
+                    warning("Use the object literal notation {}.", token);
+                    break;
+                case 'Array':
+                    if (nexttoken.id !== '(') {
+                        warning("Use the array literal notation [].", token);
+                    } else {
+                        advance('(');
+                        if (nexttoken.id === ')') {
+                            warning("Use the array literal notation [].", token);
+                        } else {
+                            i = parse(0);
+                            c.dimension = i;
+                            if ((i.id === '(number)' && /[.+\-Ee]/.test(i.value)) ||
+                                    (i.id === '-' && !i.right) ||
+                                    i.id === '(string)' || i.id === '[' ||
+                                    i.id === '{' || i.id === 'true' ||
+                                    i.id === 'false' ||
+                                    i.id === 'null' || i.id === 'undefined' ||
+                                    i.id === 'Infinity') {
+                                warning("Use the array literal notation [].", token);
+                            }
+                            if (nexttoken.id !== ')') {
+                                error("Use the array literal notation [].", token);
+                            }
+                        }
+                        advance(')');
+                    }
+                    this.first = c;
+                    return this;
+                case 'Number':
+                case 'String':
+                case 'Boolean':
+                case 'Math':
+                case 'JSON':
+                    warning("Do not use {a} as a constructor.", token, c.value);
+                    break;
+                case 'Function':
+                    if (!option.evil) {
+                        warning("The Function constructor is eval.");
+                    }
+                    break;
+                case 'Date':
+                case 'RegExp':
+                    break;
+                default:
+                    if (c.id !== 'function') {
+                        i = c.value.substr(0, 1);
+                        if (option.newcap && (i < 'A' || i > 'Z')) {
+                            warning(
+                    "A constructor name should start with an uppercase letter.",
+                                token);
+                        }
+                    }
+                }
+            } else {
+                if (c.id !== '.' && c.id !== '[' && c.id !== '(') {
+                    warning("Bad constructor.", token);
+                }
+            }
+        } else {
+            warning("Weird construction. Delete 'new'.", this);
+        }
+        adjacent(token, nexttoken);
+        if (nexttoken.id !== '(') {
+            warning("Missing '()' invoking a constructor.");
+        }
+        this.first = c;
+        return this;
+    });
+    syntax['new'].exps = true;
+
+    infix('.', function (left, that) {
+        adjacent(prevtoken, token);
+        var m = identifier();
+        if (typeof m === 'string') {
+            countMember(m);
+        }
+        that.left = left;
+        that.right = m;
+        if (!option.evil && left && left.value === 'document' &&
+                (m === 'write' || m === 'writeln')) {
+            warning("document.write can be a form of eval.", left);
+        } else if (option.adsafe) {
+            if (left && left.value === 'ADSAFE') {
+                if (m === 'id' || m === 'lib') {
+                    warning("ADsafe violation.", that);
+                } else if (m === 'go') {
+                    if (xmode !== 'script') {
+                        warning("ADsafe violation.", that);
+                    } else if (adsafe_went || nexttoken.id !== '(' ||
+                            peek(0).id !== '(string)' ||
+                            peek(0).value !== adsafe_id ||
+                            peek(1).id !== ',') {
+                        error("ADsafe violation: go.", that);
+                    }
+                    adsafe_went = true;
+                    adsafe_may = false;
+                }
+            }
+        }
+        if (!option.evil && (m === 'eval' || m === 'execScript')) {
+            warning('eval is evil.');
+        } else if (option.safe) {
+            for (;;) {
+                if (banned[m] === true) {
+                    warning("ADsafe restricted word '{a}'.", token, m);
+                }
+                if (typeof predefined[left.value] !== 'boolean' ||
+                        nexttoken.id === '(') {
+                    break;
+                }
+                if (standard_member[m] === true) {
+                    if (nexttoken.id === '.') {
+                        warning("ADsafe violation.", that);
+                    }
+                    break;
+                }
+                if (nexttoken.id !== '.') {
+                    warning("ADsafe violation.", that);
+                    break;
+                }
+                advance('.');
+                token.left = that;
+                token.right = m;
+                that = token;
+                m = identifier();
+                if (typeof m === 'string') {
+                    countMember(m);
+                }
+            }
+        }
+        return that;
+    }, 160, true);
+
+    infix('(', function (left, that) {
+        adjacent(prevtoken, token);
+        nospace();
+        var n = 0,
+            p = [];
+        if (left) {
+            if (left.type === '(identifier)') {
+                if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) {
+                    if (left.value !== 'Number' && left.value !== 'String' &&
+                            left.value !== 'Boolean' &&
+                            left.value !== 'Date') {
+                        if (left.value === 'Math') {
+                            warning("Math is not a function.", left);
+                        } else if (option.newcap) {
+                            warning(
+"Missing 'new' prefix when invoking a constructor.", left);
+                        }
+                    }
+                }
+            } else if (left.id === '.') {
+                if (option.safe && left.left.value === 'Math' &&
+                        left.right === 'random') {
+                    warning("ADsafe violation.", left);
+                }
+            }
+        }
+        if (nexttoken.id !== ')') {
+            for (;;) {
+                p[p.length] = parse(10);
+                n += 1;
+                if (nexttoken.id !== ',') {
+                    break;
+                }
+                comma();
+            }
+        }
+        advance(')');
+        if (option.immed && left.id === 'function' && nexttoken.id !== ')') {
+            warning("Wrap the entire immediate function invocation in parens.",
+                that);
+        }
+        nospace(prevtoken, token);
+        if (typeof left === 'object') {
+            if (left.value === 'parseInt' && n === 1) {
+                warning("Missing radix parameter.", left);
+            }
+            if (!option.evil) {
+                if (left.value === 'eval' || left.value === 'Function' ||
+                        left.value === 'execScript') {
+                    warning("eval is evil.", left);
+                } else if (p[0] && p[0].id === '(string)' &&
+                       (left.value === 'setTimeout' ||
+                        left.value === 'setInterval')) {
+                    warning(
+    "Implied eval is evil. Pass a function instead of a string.", left);
+                }
+            }
+            if (!left.identifier && left.id !== '.' && left.id !== '[' &&
+                    left.id !== '(' && left.id !== '&&' && left.id !== '||' &&
+                    left.id !== '?') {
+                warning("Bad invocation.", left);
+            }
+        }
+        that.left = left;
+        return that;
+    }, 155, true).exps = true;
+
+    prefix('(', function () {
+        nospace();
+        var v = parse(0);
+        advance(')', this);
+        nospace(prevtoken, token);
+        if (option.immed && v.id === 'function') {
+            if (nexttoken.id === '(') {
+                warning(
+"Move the invocation into the parens that contain the function.", nexttoken);
+            } else {
+                warning(
+"Do not wrap function literals in parens unless they are to be immediately invoked.",
+                        this);
+            }
+        }
+        return v;
+    });
+
+    infix('[', function (left, that) {
+        nospace();
+        var e = parse(0), s;
+        if (e && e.type === '(string)') {
+            if (option.safe && banned[e.value] === true) {
+                warning("ADsafe restricted word '{a}'.", that, e.value);
+            } else if (!option.evil &&
+                    (e.value === 'eval' || e.value === 'execScript')) {
+                warning("eval is evil.", that);
+            } else if (option.safe &&
+                    (e.value.charAt(0) === '_' || e.value.charAt(0) === '-')) {
+                warning("ADsafe restricted subscript '{a}'.", that, e.value);
+            }
+            countMember(e.value);
+            if (!option.sub && ix.test(e.value)) {
+                s = syntax[e.value];
+                if (!s || !s.reserved) {
+                    warning("['{a}'] is better written in dot notation.",
+                            e, e.value);
+                }
+            }
+        } else if (!e || e.type !== '(number)' || e.value < 0) {
+            if (option.safe) {
+                warning('ADsafe subscripting.');
+            }
+        }
+        advance(']', that);
+        nospace(prevtoken, token);
+        that.left = left;
+        that.right = e;
+        return that;
+    }, 160, true);
+
+    prefix('[', function () {
+        var b = token.line !== nexttoken.line;
+        this.first = [];
+        if (b) {
+            indent += option.indent;
+            if (nexttoken.from === indent + option.indent) {
+                indent += option.indent;
+            }
+        }
+        while (nexttoken.id !== '(end)') {
+            while (nexttoken.id === ',') {
+                warning("Extra comma.");
+                advance(',');
+            }
+            if (nexttoken.id === ']') {
+                break;
+            }
+            if (b && token.line !== nexttoken.line) {
+                indentation();
+            }
+            this.first.push(parse(10));
+            if (nexttoken.id === ',') {
+                comma();
+                if (nexttoken.id === ']' && !option.es5) {
+                    warning("Extra comma.", token);
+                    break;
+                }
+            } else {
+                break;
+            }
+        }
+        if (b) {
+            indent -= option.indent;
+            indentation();
+        }
+        advance(']', this);
+        return this;
+    }, 160);
+
+
+    function property_name() {
+        var id = optionalidentifier(true);
+        if (!id) {
+            if (nexttoken.id === '(string)') {
+                id = nexttoken.value;
+                if (option.adsafe &&
+                        (id.charAt(0) === '_' ||
+                         id.charAt(id.length - 1) === '_')) {
+                    warning("Unexpected {a} in '{b}'.", token,
+                        "dangling '_'", id);
+                }
+                advance();
+            } else if (nexttoken.id === '(number)') {
+                id = nexttoken.value.toString();
+                advance();
+            }
+        }
+        return id;
+    }
+
+
+    function functionparams() {
+        var i, t = nexttoken, p = [];
+        advance('(');
+        nospace();
+        if (nexttoken.id === ')') {
+            advance(')');
+            nospace(prevtoken, token);
+            return;
+        }
+        for (;;) {
+            i = identifier();
+            p.push(i);
+            addlabel(i, 'parameter');
+            if (nexttoken.id === ',') {
+                comma();
+            } else {
+                advance(')', t);
+                nospace(prevtoken, token);
+                return p;
+            }
+        }
+    }
+
+
+    function doFunction(i) {
+        var f, s = scope;
+        scope = Object.create(s);
+        funct = {
+            '(name)'    : i || '"' + anonname + '"',
+            '(line)'    : nexttoken.line,
+            '(context)' : funct,
+            '(breakage)': 0,
+            '(loopage)' : 0,
+            '(scope)'   : scope
+        };
+        f = funct;
+        token.funct = funct;
+        functions.push(funct);
+        if (i) {
+            addlabel(i, 'function');
+        }
+        funct['(params)'] = functionparams();
+
+        block(false);
+        scope = s;
+        funct['(last)'] = token.line;
+        funct = funct['(context)'];
+        return f;
+    }
+
+
+    (function (x) {
+        x.nud = function () {
+            var b, f, i, j, p, seen = {}, t;
+            b = token.line !== nexttoken.line;
+            if (b) {
+                indent += option.indent;
+                if (nexttoken.from === indent + option.indent) {
+                    indent += option.indent;
+                }
+            }
+            for (;;) {
+                if (nexttoken.id === '}') {
+                    break;
+                }
+                if (b) {
+                    indentation();
+                }
+                if (nexttoken.value === 'get' && peek().id !== ':') {
+                    advance('get');
+                    if (!option.es5) {
+                        error("get/set are ES5 features.");
+                    }
+                    i = property_name();
+                    if (!i) {
+                        error("Missing property name.");
+                    }
+                    t = nexttoken;
+                    adjacent(token, nexttoken);
+                    f = doFunction(i);
+                    if (funct['(loopage)']) {
+                        warning("Don't make functions within a loop.", t);
+                    }
+                    p = f['(params)'];
+                    if (p) {
+                        warning("Unexpected parameter '{a}' in get {b} function.", t, p[0], i);
+                    }
+                    adjacent(token, nexttoken);
+                    advance(',');
+                    indentation();
+                    advance('set');
+                    j = property_name();
+                    if (i !== j) {
+                        error("Expected {a} and instead saw {b}.", token, i, j);
+                    }
+                    t = nexttoken;
+                    adjacent(token, nexttoken);
+                    f = doFunction(i);
+                    p = f['(params)'];
+                    if (!p || p.length !== 1 || p[0] !== 'value') {
+                        warning("Expected (value) in set {a} function.", t, i);
+                    }
+                } else {
+                    i = property_name();
+                    if (typeof i !== 'string') {
+                        break;
+                    }
+                    advance(':');
+                    nonadjacent(token, nexttoken);
+                    parse(10);
+                }
+                if (seen[i] === true) {
+                    warning("Duplicate member '{a}'.", nexttoken, i);
+                }
+                seen[i] = true;
+                countMember(i);
+                if (nexttoken.id === ',') {
+                    comma();
+                    if (nexttoken.id === ',') {
+                        warning("Extra comma.", token);
+                    } else if (nexttoken.id === '}' && !option.es5) {
+                        warning("Extra comma.", token);
+                    }
+                } else {
+                    break;
+                }
+            }
+            if (b) {
+                indent -= option.indent;
+                indentation();
+            }
+            advance('}', this);
+            return this;
+        };
+        x.fud = function () {
+            error("Expected to see a statement and instead saw a block.", token);
+        };
+    }(delim('{')));
+
+
+    function varstatement(prefix) {
+
+// JavaScript does not have block scope. It only has function scope. So,
+// declaring a variable in a block can have unexpected consequences.
+
+        var id, name, value;
+
+        if (funct['(onevar)'] && option.onevar) {
+            warning("Too many var statements.");
+        } else if (!funct['(global)']) {
+            funct['(onevar)'] = true;
+        }
+        this.first = [];
+        for (;;) {
+            nonadjacent(token, nexttoken);
+            id = identifier();
+            if (funct['(global)'] && predefined[id] === false) {
+                warning("Redefinition of '{a}'.", token, id);
+            }
+            addlabel(id, 'unused');
+            if (prefix) {
+                break;
+            }
+            name = token;
+            this.first.push(token);
+            if (nexttoken.id === '=') {
+                nonadjacent(token, nexttoken);
+                advance('=');
+                nonadjacent(token, nexttoken);
+                if (nexttoken.id === 'undefined') {
+                    warning("It is not necessary to initialize '{a}' to 'undefined'.", token, id);
+                }
+                if (peek(0).id === '=' && nexttoken.identifier) {
+                    error("Variable {a} was not declared correctly.",
+                            nexttoken, nexttoken.value);
+                }
+                value = parse(0);
+                name.first = value;
+            }
+            if (nexttoken.id !== ',') {
+                break;
+            }
+            comma();
+        }
+        return this;
+    }
+
+
+    stmt('var', varstatement).exps = true;
+
+
+    blockstmt('function', function () {
+        if (inblock) {
+            warning(
+"Function statements cannot be placed in blocks. Use a function expression or move the statement to the top of the outer function.", token);
+
+        }
+        var i = identifier();
+        adjacent(token, nexttoken);
+        addlabel(i, 'unused');
+        doFunction(i);
+        if (nexttoken.id === '(' && nexttoken.line === token.line) {
+            error(
+"Function statements are not invocable. Wrap the whole function invocation in parens.");
+        }
+        return this;
+    });
+
+    prefix('function', function () {
+        var i = optionalidentifier();
+        if (i) {
+            adjacent(token, nexttoken);
+        } else {
+            nonadjacent(token, nexttoken);
+        }
+        doFunction(i);
+        if (funct['(loopage)']) {
+            warning("Don't make functions within a loop.");
+        }
+        return this;
+    });
+
+    blockstmt('if', function () {
+        var t = nexttoken;
+        advance('(');
+        nonadjacent(this, t);
+        nospace();
+        parse(20);
+        if (nexttoken.id === '=') {
+            warning("Expected a conditional expression and instead saw an assignment.");
+            advance('=');
+            parse(20);
+        }
+        advance(')', t);
+        nospace(prevtoken, token);
+        block(true);
+        if (nexttoken.id === 'else') {
+            nonadjacent(token, nexttoken);
+            advance('else');
+            if (nexttoken.id === 'if' || nexttoken.id === 'switch') {
+                statement(true);
+            } else {
+                block(true);
+            }
+        }
+        return this;
+    });
+
+    blockstmt('try', function () {
+        var b, e, s;
+        if (option.adsafe) {
+            warning("ADsafe try violation.", this);
+        }
+        block(false);
+        if (nexttoken.id === 'catch') {
+            advance('catch');
+            nonadjacent(token, nexttoken);
+            advance('(');
+            s = scope;
+            scope = Object.create(s);
+            e = nexttoken.value;
+            if (nexttoken.type !== '(identifier)') {
+                warning("Expected an identifier and instead saw '{a}'.",
+                    nexttoken, e);
+            } else {
+                addlabel(e, 'exception');
+            }
+            advance();
+            advance(')');
+            block(false);
+            b = true;
+            scope = s;
+        }
+        if (nexttoken.id === 'finally') {
+            advance('finally');
+            block(false);
+            return;
+        } else if (!b) {
+            error("Expected '{a}' and instead saw '{b}'.",
+                    nexttoken, 'catch', nexttoken.value);
+        }
+        return this;
+    });
+
+    blockstmt('while', function () {
+        var t = nexttoken;
+        funct['(breakage)'] += 1;
+        funct['(loopage)'] += 1;
+        advance('(');
+        nonadjacent(this, t);
+        nospace();
+        parse(20);
+        if (nexttoken.id === '=') {
+            warning("Expected a conditional expression and instead saw an assignment.");
+            advance('=');
+            parse(20);
+        }
+        advance(')', t);
+        nospace(prevtoken, token);
+        block(true);
+        funct['(breakage)'] -= 1;
+        funct['(loopage)'] -= 1;
+        return this;
+    }).labelled = true;
+
+    reserve('with');
+
+    blockstmt('switch', function () {
+        var t = nexttoken,
+            g = false;
+        funct['(breakage)'] += 1;
+        advance('(');
+        nonadjacent(this, t);
+        nospace();
+        this.condition = parse(20);
+        advance(')', t);
+        nospace(prevtoken, token);
+        nonadjacent(token, nexttoken);
+        t = nexttoken;
+        advance('{');
+        nonadjacent(token, nexttoken);
+        indent += option.indent;
+        this.cases = [];
+        for (;;) {
+            switch (nexttoken.id) {
+            case 'case':
+                switch (funct['(verb)']) {
+                case 'break':
+                case 'case':
+                case 'continue':
+                case 'return':
+                case 'switch':
+                case 'throw':
+                    break;
+                default:
+                    warning(
+                        "Expected a 'break' statement before 'case'.",
+                        token);
+                }
+                indentation(-option.indent);
+                advance('case');
+                this.cases.push(parse(20));
+                g = true;
+                advance(':');
+                funct['(verb)'] = 'case';
+                break;
+            case 'default':
+                switch (funct['(verb)']) {
+                case 'break':
+                case 'continue':
+                case 'return':
+                case 'throw':
+                    break;
+                default:
+                    warning(
+                        "Expected a 'break' statement before 'default'.",
+                        token);
+                }
+                indentation(-option.indent);
+                advance('default');
+                g = true;
+                advance(':');
+                break;
+            case '}':
+                indent -= option.indent;
+                indentation();
+                advance('}', t);
+                if (this.cases.length === 1 || this.condition.id === 'true' ||
+                        this.condition.id === 'false') {
+                    warning("This 'switch' should be an 'if'.", this);
+                }
+                funct['(breakage)'] -= 1;
+                funct['(verb)'] = undefined;
+                return;
+            case '(end)':
+                error("Missing '{a}'.", nexttoken, '}');
+                return;
+            default:
+                if (g) {
+                    switch (token.id) {
+                    case ',':
+                        error("Each value should have its own case label.");
+                        return;
+                    case ':':
+                        statements();
+                        break;
+                    default:
+                        error("Missing ':' on a case clause.", token);
+                    }
+                } else {
+                    error("Expected '{a}' and instead saw '{b}'.",
+                        nexttoken, 'case', nexttoken.value);
+                }
+            }
+        }
+    }).labelled = true;
+
+    stmt('debugger', function () {
+        if (!option.debug) {
+            warning("All 'debugger' statements should be removed.");
+        }
+        return this;
+    }).exps = true;
+
+    (function () {
+        var x = stmt('do', function () {
+            funct['(breakage)'] += 1;
+            funct['(loopage)'] += 1;
+            this.first = block(true);
+            advance('while');
+            var t = nexttoken;
+            nonadjacent(token, t);
+            advance('(');
+            nospace();
+            parse(20);
+            if (nexttoken.id === '=') {
+                warning("Expected a conditional expression and instead saw an assignment.");
+                advance('=');
+                parse(20);
+            }
+            advance(')', t);
+            nospace(prevtoken, token);
+            funct['(breakage)'] -= 1;
+            funct['(loopage)'] -= 1;
+            return this;
+        });
+        x.labelled = true;
+        x.exps = true;
+    }());
+
+    blockstmt('for', function () {
+        var f = option.forin, s, t = nexttoken;
+        funct['(breakage)'] += 1;
+        funct['(loopage)'] += 1;
+        advance('(');
+        nonadjacent(this, t);
+        nospace();
+        if (peek(nexttoken.id === 'var' ? 1 : 0).id === 'in') {
+            if (nexttoken.id === 'var') {
+                advance('var');
+                varstatement(true);
+            } else {
+                switch (funct[nexttoken.value]) {
+                case 'unused':
+                    funct[nexttoken.value] = 'var';
+                    break;
+                case 'var':
+                    break;
+                default:
+                    warning("Bad for in variable '{a}'.",
+                            nexttoken, nexttoken.value);
+                }
+                advance();
+            }
+            advance('in');
+            parse(20);
+            advance(')', t);
+            s = block(true);
+            if (!f && (s.length > 1 || typeof s[0] !== 'object' ||
+                    s[0].value !== 'if')) {
+                warning("The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.", this);
+            }
+            funct['(breakage)'] -= 1;
+            funct['(loopage)'] -= 1;
+            return this;
+        } else {
+            if (nexttoken.id !== ';') {
+                if (nexttoken.id === 'var') {
+                    advance('var');
+                    varstatement();
+                } else {
+                    for (;;) {
+                        parse(0, 'for');
+                        if (nexttoken.id !== ',') {
+                            break;
+                        }
+                        comma();
+                    }
+                }
+            }
+            nolinebreak(token);
+            advance(';');
+            if (nexttoken.id !== ';') {
+                parse(20);
+                if (nexttoken.id === '=') {
+                    warning("Expected a conditional expression and instead saw an assignment.");
+                    advance('=');
+                    parse(20);
+                }
+            }
+            nolinebreak(token);
+            advance(';');
+            if (nexttoken.id === ';') {
+                error("Expected '{a}' and instead saw '{b}'.",
+                        nexttoken, ')', ';');
+            }
+            if (nexttoken.id !== ')') {
+                for (;;) {
+                    parse(0, 'for');
+                    if (nexttoken.id !== ',') {
+                        break;
+                    }
+                    comma();
+                }
+            }
+            advance(')', t);
+            nospace(prevtoken, token);
+            block(true);
+            funct['(breakage)'] -= 1;
+            funct['(loopage)'] -= 1;
+            return this;
+        }
+    }).labelled = true;
+
+
+    stmt('break', function () {
+        var v = nexttoken.value;
+        if (funct['(breakage)'] === 0) {
+            warning("Unexpected '{a}'.", nexttoken, this.value);
+        }
+        nolinebreak(this);
+        if (nexttoken.id !== ';') {
+            if (token.line === nexttoken.line) {
+                if (funct[v] !== 'label') {
+                    warning("'{a}' is not a statement label.", nexttoken, v);
+                } else if (scope[v] !== funct) {
+                    warning("'{a}' is out of scope.", nexttoken, v);
+                }
+                this.first = nexttoken;
+                advance();
+            }
+        }
+        reachable('break');
+        return this;
+    }).exps = true;
+
+
+    stmt('continue', function () {
+        var v = nexttoken.value;
+        if (funct['(breakage)'] === 0) {
+            warning("Unexpected '{a}'.", nexttoken, this.value);
+        }
+        nolinebreak(this);
+        if (nexttoken.id !== ';') {
+            if (token.line === nexttoken.line) {
+                if (funct[v] !== 'label') {
+                    warning("'{a}' is not a statement label.", nexttoken, v);
+                } else if (scope[v] !== funct) {
+                    warning("'{a}' is out of scope.", nexttoken, v);
+                }
+                this.first = nexttoken;
+                advance();
+            }
+        } else if (!funct['(loopage)']) {
+            warning("Unexpected '{a}'.", nexttoken, this.value);
+        }
+        reachable('continue');
+        return this;
+    }).exps = true;
+
+
+    stmt('return', function () {
+        nolinebreak(this);
+        if (nexttoken.id === '(regexp)') {
+            warning("Wrap the /regexp/ literal in parens to disambiguate the slash operator.");
+        }
+        if (nexttoken.id !== ';' && !nexttoken.reach) {
+            nonadjacent(token, nexttoken);
+            this.first = parse(20);
+        }
+        reachable('return');
+        return this;
+    }).exps = true;
+
+
+    stmt('throw', function () {
+        nolinebreak(this);
+        nonadjacent(token, nexttoken);
+        this.first = parse(20);
+        reachable('throw');
+        return this;
+    }).exps = true;
+
+    reserve('void');
+
+//  Superfluous reserved words
+
+    reserve('class');
+    reserve('const');
+    reserve('enum');
+    reserve('export');
+    reserve('extends');
+    reserve('import');
+    reserve('super');
+
+    reserve('let');
+    reserve('yield');
+    reserve('implements');
+    reserve('interface');
+    reserve('package');
+    reserve('private');
+    reserve('protected');
+    reserve('public');
+    reserve('static');
+
+
+// Parse JSON
+
+    function jsonValue() {
+
+        function jsonObject() {
+            var o = {}, t = nexttoken;
+            advance('{');
+            if (nexttoken.id !== '}') {
+                for (;;) {
+                    if (nexttoken.id === '(end)') {
+                        error("Missing '}' to match '{' from line {a}.",
+                                nexttoken, t.line);
+                    } else if (nexttoken.id === '}') {
+                        warning("Unexpected comma.", token);
+                        break;
+                    } else if (nexttoken.id === ',') {
+                        error("Unexpected comma.", nexttoken);
+                    } else if (nexttoken.id !== '(string)') {
+                        warning("Expected a string and instead saw {a}.",
+                                nexttoken, nexttoken.value);
+                    }
+                    if (o[nexttoken.value] === true) {
+                        warning("Duplicate key '{a}'.",
+                                nexttoken, nexttoken.value);
+                    } else if (nexttoken.value === '__proto__') {
+                        warning("Stupid key '{a}'.",
+                                nexttoken, nexttoken.value);
+                    } else {
+                        o[nexttoken.value] = true;
+                    }
+                    advance();
+                    advance(':');
+                    jsonValue();
+                    if (nexttoken.id !== ',') {
+                        break;
+                    }
+                    advance(',');
+                }
+            }
+            advance('}');
+        }
+
+        function jsonArray() {
+            var t = nexttoken;
+            advance('[');
+            if (nexttoken.id !== ']') {
+                for (;;) {
+                    if (nexttoken.id === '(end)') {
+                        error("Missing ']' to match '[' from line {a}.",
+                                nexttoken, t.line);
+                    } else if (nexttoken.id === ']') {
+                        warning("Unexpected comma.", token);
+                        break;
+                    } else if (nexttoken.id === ',') {
+                        error("Unexpected comma.", nexttoken);
+                    }
+                    jsonValue();
+                    if (nexttoken.id !== ',') {
+                        break;
+                    }
+                    advance(',');
+                }
+            }
+            advance(']');
+        }
+
+        switch (nexttoken.id) {
+        case '{':
+            jsonObject();
+            break;
+        case '[':
+            jsonArray();
+            break;
+        case 'true':
+        case 'false':
+        case 'null':
+        case '(number)':
+        case '(string)':
+            advance();
+            break;
+        case '-':
+            advance('-');
+            if (token.character !== nexttoken.from) {
+                warning("Unexpected space after '-'.", token);
+            }
+            adjacent(token, nexttoken);
+            advance('(number)');
+            break;
+        default:
+            error("Expected a JSON value.", nexttoken);
+        }
+    }
+
+
+// The actual JSLINT function itself.
+
+    var itself = function (s, o) {
+        var a, i;
+        JSLINT.errors = [];
+        predefined = Object.create(standard);
+        if (o) {
+            a = o.predef;
+            if (a instanceof Array) {
+                for (i = 0; i < a.length; i += 1) {
+                    predefined[a[i]] = true;
+                }
+            }
+            if (o.adsafe) {
+                o.safe = true;
+            }
+            if (o.safe) {
+                o.browser =
+                o.css     =
+                o.debug   =
+                o.devel   =
+                o.evil    =
+                o.forin   =
+                o.on      =
+                o.rhino   =
+                o.windows =
+                o.sub     =
+                o.widget  = false;
+
+                o.eqeqeq  =
+                o.nomen   =
+                o.safe    =
+                o.strict  =
+                o.undef   = true;
+
+                predefined.Date =
+                predefined['eval'] =
+                predefined.Function =
+                predefined.Object = null;
+
+                predefined.ADSAFE =
+                predefined.lib = false;
+            }
+            option = o;
+        } else {
+            option = {};
+        }
+        option.indent = option.indent || 4;
+        option.maxerr = option.maxerr || 50;
+        adsafe_id = '';
+        adsafe_may = false;
+        adsafe_went = false;
+        approved = {};
+        if (option.approved) {
+            for (i = 0; i < option.approved.length; i += 1) {
+                approved[option.approved[i]] = option.approved[i];
+            }
+        } else {
+            approved.test = 'test';
+        }
+        tab = '';
+        for (i = 0; i < option.indent; i += 1) {
+            tab += ' ';
+        }
+        indent = 1;
+        global = Object.create(predefined);
+        scope = global;
+        funct = {
+            '(global)': true,
+            '(name)': '(global)',
+            '(scope)': scope,
+            '(breakage)': 0,
+            '(loopage)': 0
+        };
+        functions = [funct];
+        ids = {};
+        urls = [];
+        src = false;
+        xmode = false;
+        stack = null;
+        member = {};
+        membersOnly = null;
+        implied = {};
+        inblock = false;
+        lookahead = [];
+        jsonmode = false;
+        warnings = 0;
+        lex.init(s);
+        prereg = true;
+        strict_mode = false;
+
+        prevtoken = token = nexttoken = syntax['(begin)'];
+        assume();
+
+        try {
+            advance();
+            if (nexttoken.value.charAt(0) === '<') {
+                html();
+                if (option.adsafe && !adsafe_went) {
+                    warning("ADsafe violation: Missing ADSAFE.go.", this);
+                }
+            } else {
+                switch (nexttoken.id) {
+                case '{':
+                case '[':
+                    option.laxbreak = true;
+                    jsonmode = true;
+                    jsonValue();
+                    break;
+                case '@':
+                case '*':
+                case '#':
+                case '.':
+                case ':':
+                    xmode = 'style';
+                    advance();
+                    if (token.id !== '@' || !nexttoken.identifier ||
+                            nexttoken.value !== 'charset' || token.line !== 1 ||
+                            token.from !== 1) {
+                        error('A css file should begin with @charset "UTF-8";');
+                    }
+                    advance();
+                    if (nexttoken.type !== '(string)' &&
+                            nexttoken.value !== 'UTF-8') {
+                        error('A css file should begin with @charset "UTF-8";');
+                    }
+                    advance();
+                    advance(';');
+                    styles();
+                    break;
+
+                default:
+                    if (option.adsafe && option.fragment) {
+                        error("Expected '{a}' and instead saw '{b}'.",
+                            nexttoken, '<div>', nexttoken.value);
+                    }
+                    statements('lib');
+                }
+            }
+            advance('(end)');
+        } catch (e) {
+            if (e) {
+                JSLINT.errors.push({
+                    reason    : e.message,
+                    line      : e.line || nexttoken.line,
+                    character : e.character || nexttoken.from
+                }, null);
+            }
+        }
+        return JSLINT.errors.length === 0;
+    };
+
+    function is_array(o) {
+        return Object.prototype.toString.apply(o) === '[object Array]';
+    }
+
+    function to_array(o) {
+        var a = [], k;
+        for (k in o) {
+            if (is_own(o, k)) {
+                a.push(k);
+            }
+        }
+        return a;
+    }
+
+
+// Data summary.
+
+    itself.data = function () {
+
+        var data = {functions: []}, fu, globals, implieds = [], f, i, j,
+            members = [], n, unused = [], v;
+        if (itself.errors.length) {
+            data.errors = itself.errors;
+        }
+
+        if (jsonmode) {
+            data.json = true;
+        }
+
+        for (n in implied) {
+            if (is_own(implied, n)) {
+                implieds.push({
+                    name: n,
+                    line: implied[n]
+                });
+            }
+        }
+        if (implieds.length > 0) {
+            data.implieds = implieds;
+        }
+
+        if (urls.length > 0) {
+            data.urls = urls;
+        }
+
+        globals = to_array(scope);
+        if (globals.length > 0) {
+            data.globals = globals;
+        }
+
+        for (i = 1; i < functions.length; i += 1) {
+            f = functions[i];
+            fu = {};
+            for (j = 0; j < functionicity.length; j += 1) {
+                fu[functionicity[j]] = [];
+            }
+            for (n in f) {
+                if (is_own(f, n) && n.charAt(0) !== '(') {
+                    v = f[n];
+                    if (is_array(fu[v])) {
+                        fu[v].push(n);
+                        if (v === 'unused') {
+                            unused.push({
+                                name: n,
+                                line: f['(line)'],
+                                'function': f['(name)']
+                            });
+                        }
+                    }
+                }
+            }
+            for (j = 0; j < functionicity.length; j += 1) {
+                if (fu[functionicity[j]].length === 0) {
+                    delete fu[functionicity[j]];
+                }
+            }
+            fu.name = f['(name)'];
+            fu.param = f['(params)'];
+            fu.line = f['(line)'];
+            fu.last = f['(last)'];
+            data.functions.push(fu);
+        }
+
+        if (unused.length > 0) {
+            data.unused = unused;
+        }
+
+        members = [];
+        for (n in member) {
+            if (typeof member[n] === 'number') {
+                data.member = member;
+                break;
+            }
+        }
+
+        return data;
+    };
+
+    itself.report = function (option) {
+        var data = itself.data();
+
+        var a = [], c, e, err, f, i, k, l, m = '', n, o = [], s;
+
+        function detail(h, array) {
+            var b, i, singularity;
+            if (array) {
+                o.push('<div><i>' + h + '</i> ');
+                array = array.sort();
+                for (i = 0; i < array.length; i += 1) {
+                    if (array[i] !== singularity) {
+                        singularity = array[i];
+                        o.push((b ? ', ' : '') + singularity);
+                        b = true;
+                    }
+                }
+                o.push('</div>');
+            }
+        }
+
+
+        if (data.errors || data.implieds || data.unused) {
+            err = true;
+            o.push('<div id=errors><i>Error:</i>');
+            if (data.errors) {
+                for (i = 0; i < data.errors.length; i += 1) {
+                    c = data.errors[i];
+                    if (c) {
+                        e = c.evidence || '';
+                        o.push('<p>Problem' + (isFinite(c.line) ? ' at line ' +
+                                c.line + ' character ' + c.character : '') +
+                                ': ' + c.reason.entityify() +
+                                '</p><p class=evidence>' +
+                                (e && (e.length > 80 ? e.slice(0, 77) + '...' :
+                                e).entityify()) + '</p>');
+                    }
+                }
+            }
+
+            if (data.implieds) {
+                s = [];
+                for (i = 0; i < data.implieds.length; i += 1) {
+                    s[i] = '<code>' + data.implieds[i].name + '</code>&nbsp;<i>' +
+                        data.implieds[i].line + '</i>';
+                }
+                o.push('<p><i>Implied global:</i> ' + s.join(', ') + '</p>');
+            }
+
+            if (data.unused) {
+                s = [];
+                for (i = 0; i < data.unused.length; i += 1) {
+                    s[i] = '<code><u>' + data.unused[i].name + '</u></code>&nbsp;<i>' +
+                        data.unused[i].line + '</i> <code>' +
+                        data.unused[i]['function'] + '</code>';
+                }
+                o.push('<p><i>Unused variable:</i> ' + s.join(', ') + '</p>');
+            }
+            if (data.json) {
+                o.push('<p>JSON: bad.</p>');
+            }
+            o.push('</div>');
+        }
+
+        if (!option) {
+
+            o.push('<br><div id=functions>');
+
+            if (data.urls) {
+                detail("URLs<br>", data.urls, '<br>');
+            }
+
+            if (xmode === 'style') {
+                o.push('<p>CSS.</p>');
+            } else if (data.json && !err) {
+                o.push('<p>JSON: good.</p>');
+            } else if (data.globals) {
+                o.push('<div><i>Global</i> ' +
+                        data.globals.sort().join(', ') + '</div>');
+            } else {
+                o.push('<div><i>No new global variables introduced.</i></div>');
+            }
+
+            for (i = 0; i < data.functions.length; i += 1) {
+                f = data.functions[i];
+
+                o.push('<br><div class=function><i>' + f.line + '-' +
+                        f.last + '</i> ' + (f.name || '') + '(' +
+                        (f.param ? f.param.join(', ') : '') + ')</div>');
+                detail('<big><b>Unused</b></big>', f.unused);
+                detail('Closure', f.closure);
+                detail('Variable', f['var']);
+                detail('Exception', f.exception);
+                detail('Outer', f.outer);
+                detail('Global', f.global);
+                detail('Label', f.label);
+            }
+
+            if (data.member) {
+                a = to_array(data.member);
+                if (a.length) {
+                    a = a.sort();
+                    m = '<br><pre id=members>/*members ';
+                    l = 10;
+                    for (i = 0; i < a.length; i += 1) {
+                        k = a[i];
+                        n = k.name();
+                        if (l + n.length > 72) {
+                            o.push(m + '<br>');
+                            m = '    ';
+                            l = 1;
+                        }
+                        l += n.length + 2;
+                        if (data.member[k] === 1) {
+                            n = '<i>' + n + '</i>';
+                        }
+                        if (i < a.length - 1) {
+                            n += ', ';
+                        }
+                        m += n;
+                    }
+                    o.push(m + '<br>*/</pre>');
+                }
+                o.push('</div>');
+            }
+        }
+        return o.join('');
+    };
+    itself.jslint = itself;
+
+    itself.edition = '2010-08-08';
+
+    return itself;
+
+}());
+// wsh.js
+// 2009-09-11
+
+// This is the WSH companion to fulljslint.js.
+/*
+Copyright (c) 2002 Douglas Crockford  (www.JSLint.com) WSH Edition
+*/
+
+/*global JSLINT, WScript */
+
diff --git a/browserid/static/dialog/steal/clean/test/clean_test.js b/browserid/static/dialog/steal/clean/test/clean_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..23b616a792379581645ff52e4a3ee4c801646751
--- /dev/null
+++ b/browserid/static/dialog/steal/clean/test/clean_test.js
@@ -0,0 +1,27 @@
+// load('steal/compress/test/run.js')
+/**
+ * Tests compressing a very basic page and one that is using steal
+ */
+load('steal/rhino/steal.js')
+steal('//steal/test/test', function( s ) {
+	
+	s.test.module("steal/clean")
+	
+	s.test.test("basic formatting", function(t){
+		s.test.clear();
+		load('steal/rhino/steal.js');
+		steal.plugins('steal/clean');
+		
+		steal.File('steal/clean/test/test.js').copyTo('steal/clean/test/testStart.js')
+		
+		// clean this file and see if it looks like it should
+		steal.clean('steal/clean/test/testStart.js')
+		
+		
+		s.test.equals( readFile('steal/clean/test/testStart.js'), 
+				readFile('steal/clean/test/testEnd.js'), "docs are clean");
+		steal.File('steal/clean/test/testStart.js').remove();
+	})
+
+	
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/clean/test/test.js b/browserid/static/dialog/steal/clean/test/test.js
new file mode 100644
index 0000000000000000000000000000000000000000..c577a51c44d36525b75f97d4ff9b516c477f4a2e
--- /dev/null
+++ b/browserid/static/dialog/steal/clean/test/test.js
@@ -0,0 +1,7 @@
+function(one, two ){
+	if(this[i] == isNumber( value )){
+		while(a< b){
+		}
+	}
+}
+	
diff --git a/browserid/static/dialog/steal/clean/test/testEnd.js b/browserid/static/dialog/steal/clean/test/testEnd.js
new file mode 100644
index 0000000000000000000000000000000000000000..3f2634cd43da3be104319b1365b7608784e562f0
--- /dev/null
+++ b/browserid/static/dialog/steal/clean/test/testEnd.js
@@ -0,0 +1,5 @@
+function( one, two ) {
+	if ( this[i] == isNumber(value) ) {
+		while ( a < b ) {}
+	}
+}
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/cleanjs b/browserid/static/dialog/steal/cleanjs
new file mode 100644
index 0000000000000000000000000000000000000000..00e70690cc1bb970b4d3c85c66e807c3653bc596
--- /dev/null
+++ b/browserid/static/dialog/steal/cleanjs
@@ -0,0 +1,5 @@
+load("steal/rhino/steal.js");
+steal.plugins('steal/clean', function () {
+    var url = _args.shift();
+    steal.clean(url, _args);
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/coffee/coffee-script.js b/browserid/static/dialog/steal/coffee/coffee-script.js
new file mode 100644
index 0000000000000000000000000000000000000000..66e0ed0523fe4e492ead2e87c30a65049db75649
--- /dev/null
+++ b/browserid/static/dialog/steal/coffee/coffee-script.js
@@ -0,0 +1,9 @@
+//@steal-clean
+/**
+ * CoffeeScript Compiler v0.9.1
+ * http://coffeescript.org
+ *
+ * Copyright 2010, Jeremy Ashkenas
+ * Released under the MIT License
+ */
+(function(){var compact,count,del,ends,extend,flatten,helpers,include,indexOf,merge,starts;if(!((typeof process!=="undefined"&&process!==null))){this.exports=this}helpers=(exports.helpers={});helpers.indexOf=(indexOf=function(array,item,from){var _a,_b,index,other;if(array.indexOf){return array.indexOf(item,from)}_a=array;for(index=0,_b=_a.length;index<_b;index++){other=_a[index];if(other===item&&(!from||(from<=index))){return index}}return -1});helpers.include=(include=function(list,value){return indexOf(list,value)>=0});helpers.starts=(starts=function(string,literal,start){return string.substring(start,(start||0)+literal.length)===literal});helpers.ends=(ends=function(string,literal,back){var start;start=string.length-literal.length-((typeof back!=="undefined"&&back!==null)?back:0);return string.substring(start,start+literal.length)===literal});helpers.compact=(compact=function(array){var _a,_b,_c,_d,item;_a=[];_c=array;for(_b=0,_d=_c.length;_b<_d;_b++){item=_c[_b];if(item){_a.push(item)}}return _a});helpers.count=(count=function(string,letter){var num,pos;num=0;pos=indexOf(string,letter);while(pos!==-1){num+=1;pos=indexOf(string,letter,pos+1)}return num});helpers.merge=(merge=function(options,overrides){var _a,_b,fresh,key,val;fresh={};_a=options;for(key in _a){val=_a[key];(fresh[key]=val)}if(overrides){_b=overrides;for(key in _b){val=_b[key];(fresh[key]=val)}}return fresh});helpers.extend=(extend=function(object,properties){var _a,_b,key,val;_a=[];_b=properties;for(key in _b){val=_b[key];_a.push((object[key]=val))}return _a});helpers.flatten=(flatten=function(array){var _a,_b,_c,item,memo;memo=[];_b=array;for(_a=0,_c=_b.length;_a<_c;_a++){item=_b[_a];if(item instanceof Array){memo=memo.concat(item)}else{memo.push(item)}}return memo});helpers.del=(del=function(obj,key){var val;val=obj[key];delete obj[key];return val})})();(function(){var BALANCED_PAIRS,EXPRESSION_CLOSE,EXPRESSION_END,EXPRESSION_START,IMPLICIT_BLOCK,IMPLICIT_CALL,IMPLICIT_END,IMPLICIT_FUNC,INVERSES,Rewriter,SINGLE_CLOSERS,SINGLE_LINERS,_a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,_m,helpers,include,pair;var __bind=function(func,context){return function(){return func.apply(context,arguments)}},__hasProp=Object.prototype.hasOwnProperty;if((typeof process!=="undefined"&&process!==null)){_a=require("./helpers");helpers=_a.helpers}else{this.exports=this;helpers=this.helpers}_b=helpers;include=_b.include;exports.Rewriter=(function(){Rewriter=function(){};Rewriter.prototype.rewrite=function(tokens){this.tokens=tokens;this.adjustComments();this.removeLeadingNewlines();this.removeMidExpressionNewlines();this.closeOpenCalls();this.closeOpenIndexes();this.addImplicitIndentation();this.addImplicitBraces();this.addImplicitParentheses();this.ensureBalance(BALANCED_PAIRS);this.rewriteClosingParens();return this.tokens};Rewriter.prototype.scanTokens=function(block){var i,move;i=0;while(true){if(!(this.tokens[i])){break}move=block(this.tokens[i],i);i+=move}return true};Rewriter.prototype.detectEnd=function(i,condition,action){var levels,token;levels=0;while(true){token=this.tokens[i];if(levels===0&&condition.call(this,token,i)){return action.call(this,token,i)}if(!token||levels<0){return action.call(this,token,i-1)}if(include(EXPRESSION_START,token[0])){levels+=1}if(include(EXPRESSION_END,token[0])){levels-=1}i+=1}return i-1};Rewriter.prototype.adjustComments=function(){return this.scanTokens(__bind(function(token,i){var _c,_d,after,before,post,prev;if(!(token[0]==="HERECOMMENT")){return 1}_c=[this.tokens[i-2],this.tokens[i-1],this.tokens[i+1],this.tokens[i+2]];before=_c[0];prev=_c[1];post=_c[2];after=_c[3];if(after&&after[0]==="INDENT"){this.tokens.splice(i+2,1);if(before&&before[0]==="OUTDENT"&&post&&(prev[0]===post[0])&&(post[0]==="TERMINATOR")){this.tokens.splice(i-2,1)}else{this.tokens.splice(i,0,after)}}else{if(prev&&!("TERMINATOR"===(_d=prev[0])||"INDENT"===_d||"OUTDENT"===_d)){if(post&&post[0]==="TERMINATOR"&&after&&after[0]==="OUTDENT"){this.tokens.splice.apply(this.tokens,[i+2,0].concat(this.tokens.splice(i,2)));if(this.tokens[i+2][0]!=="TERMINATOR"){this.tokens.splice(i+2,0,["TERMINATOR","\n",prev[2]])}}else{this.tokens.splice(i,0,["TERMINATOR","\n",prev[2]])}return 2}}return 1},this))};Rewriter.prototype.removeLeadingNewlines=function(){var _c;_c=[];while(this.tokens[0]&&this.tokens[0][0]==="TERMINATOR"){_c.push(this.tokens.shift())}return _c};Rewriter.prototype.removeMidExpressionNewlines=function(){return this.scanTokens(__bind(function(token,i){if(!(include(EXPRESSION_CLOSE,this.tag(i+1))&&token[0]==="TERMINATOR")){return 1}this.tokens.splice(i,1);return 0},this))};Rewriter.prototype.closeOpenCalls=function(){return this.scanTokens(__bind(function(token,i){var action,condition;if(token[0]==="CALL_START"){condition=function(token,i){var _c;return(")"===(_c=token[0])||"CALL_END"===_c)};action=function(token,i){return(token[0]="CALL_END")};this.detectEnd(i+1,condition,action)}return 1},this))};Rewriter.prototype.closeOpenIndexes=function(){return this.scanTokens(__bind(function(token,i){var action,condition;if(token[0]==="INDEX_START"){condition=function(token,i){var _c;return("]"===(_c=token[0])||"INDEX_END"===_c)};action=function(token,i){return(token[0]="INDEX_END")};this.detectEnd(i+1,condition,action)}return 1},this))};Rewriter.prototype.addImplicitBraces=function(){var stack;stack=[];return this.scanTokens(__bind(function(token,i){var action,condition,idx,last;if(include(EXPRESSION_START,token[0])){stack.push((token[0]==="INDENT"&&(this.tag(i-1)==="{"))?"{":token[0])}if(include(EXPRESSION_END,token[0])){stack.pop()}last=stack[stack.length-1];if(token[0]===":"&&(!last||last[0]!=="{")){stack.push("{");idx=this.tag(i-2)==="@"?i-2:i-1;this.tokens.splice(idx,0,["{","{",token[2]]);condition=function(token,i){var _c,_d,_e,one,three,two;_c=this.tokens.slice(i+1,i+4);one=_c[0];two=_c[1];three=_c[2];if((this.tag(i+1)==="HERECOMMENT"||this.tag(i-1)==="HERECOMMENT")){return false}return((("TERMINATOR"===(_d=token[0])||"OUTDENT"===_d))&&!((two&&two[0]===":")||(one&&one[0]==="@"&&three&&three[0]===":")))||(token[0]===","&&one&&(!("IDENTIFIER"===(_e=one[0])||"STRING"===_e||"@"===_e||"TERMINATOR"===_e||"OUTDENT"===_e)))};action=function(token,i){return this.tokens.splice(i,0,["}","}",token[2]])};this.detectEnd(i+2,condition,action);return 2}return 1},this))};Rewriter.prototype.addImplicitParentheses=function(){return this.scanTokens(__bind(function(token,i){var _c,action,condition,prev;prev=this.tokens[i-1];if(prev&&prev.spaced&&include(IMPLICIT_FUNC,prev[0])&&include(IMPLICIT_CALL,token[0])&&!(token[0]==="!"&&(("IN"===(_c=this.tag(i+1))||"OF"===_c)))){this.tokens.splice(i,0,["CALL_START","(",token[2]]);condition=function(token,i){return(!token.generated&&this.tokens[i-1][0]!==","&&include(IMPLICIT_END,token[0])&&!(token[0]==="INDENT"&&(include(IMPLICIT_BLOCK,this.tag(i-1))||this.tag(i-2)==="CLASS")))||token[0]==="PROPERTY_ACCESS"&&this.tag(i-1)==="OUTDENT"};action=function(token,i){var idx;idx=token[0]==="OUTDENT"?i+1:i;return this.tokens.splice(idx,0,["CALL_END",")",token[2]])};this.detectEnd(i+1,condition,action);return 2}return 1},this))};Rewriter.prototype.addImplicitIndentation=function(){return this.scanTokens(__bind(function(token,i){var _c,action,condition,indent,outdent,starter;if(token[0]==="ELSE"&&this.tag(i-1)!=="OUTDENT"){this.tokens.splice.apply(this.tokens,[i,0].concat(this.indentation(token)));return 2}if(token[0]==="CATCH"&&(this.tokens[i+2][0]==="TERMINATOR"||this.tokens[i+2][0]==="FINALLY")){this.tokens.splice.apply(this.tokens,[i+2,0].concat(this.indentation(token)));return 4}if(include(SINGLE_LINERS,token[0])&&this.tag(i+1)!=="INDENT"&&!(token[0]==="ELSE"&&this.tag(i+1)==="IF")){starter=token[0];_c=this.indentation(token);indent=_c[0];outdent=_c[1];indent.generated=(outdent.generated=true);this.tokens.splice(i+1,0,indent);condition=function(token,i){return(include(SINGLE_CLOSERS,token[0])&&token[1]!==";")&&!(token[0]==="ELSE"&&!("IF"===starter||"THEN"===starter))};action=function(token,i){var idx;idx=this.tokens[i-1][0]===","?i-1:i;return this.tokens.splice(idx,0,outdent)};this.detectEnd(i+2,condition,action);if(token[0]==="THEN"){this.tokens.splice(i,1)}return 2}return 1},this))};Rewriter.prototype.ensureBalance=function(pairs){var _c,_d,key,levels,line,open,openLine,unclosed,value;levels={};openLine={};this.scanTokens(__bind(function(token,i){var _c,_d,_e,_f,close,open,pair;_d=pairs;for(_c=0,_e=_d.length;_c<_e;_c++){pair=_d[_c];_f=pair;open=_f[0];close=_f[1];levels[open]=levels[open]||0;if(token[0]===open){if(levels[open]===0){openLine[open]=token[2]}levels[open]+=1}if(token[0]===close){levels[open]-=1}if(levels[open]<0){throw new Error(("too many "+(token[1])+" on line "+(token[2]+1)))}}return 1},this));unclosed=(function(){_c=[];_d=levels;for(key in _d){if(!__hasProp.call(_d,key)){continue}value=_d[key];if(value>0){_c.push(key)}}return _c})();if(unclosed.length){open=unclosed[0];line=openLine[open]+1;throw new Error(("unclosed "+(open)+" on line "+(line)))}};Rewriter.prototype.rewriteClosingParens=function(){var _c,debt,key,stack,val;stack=[];debt={};_c=INVERSES;for(key in _c){if(!__hasProp.call(_c,key)){continue}val=_c[key];(debt[key]=0)}return this.scanTokens(__bind(function(token,i){var inv,match,mtag,oppos,tag;tag=token[0];inv=INVERSES[token[0]];if(include(EXPRESSION_START,tag)){stack.push(token);return 1}else{if(include(EXPRESSION_END,tag)){if(debt[inv]>0){debt[inv]-=1;this.tokens.splice(i,1);return 0}else{match=stack.pop();mtag=match[0];oppos=INVERSES[mtag];if(tag===oppos){return 1}debt[mtag]+=1;val=[oppos,mtag==="INDENT"?match[1]:oppos];if((this.tokens[i+2]==undefined?undefined:this.tokens[i+2][0])===mtag){this.tokens.splice(i+3,0,val);stack.push(match)}else{this.tokens.splice(i,0,val)}return 1}}else{return 1}}},this))};Rewriter.prototype.indentation=function(token){return[["INDENT",2,token[2]],["OUTDENT",2,token[2]]]};Rewriter.prototype.tag=function(i){return this.tokens[i]&&this.tokens[i][0]};return Rewriter})();BALANCED_PAIRS=[["(",")"],["[","]"],["{","}"],["INDENT","OUTDENT"],["PARAM_START","PARAM_END"],["CALL_START","CALL_END"],["INDEX_START","INDEX_END"]];INVERSES={};_d=BALANCED_PAIRS;for(_c=0,_e=_d.length;_c<_e;_c++){pair=_d[_c];INVERSES[pair[0]]=pair[1];INVERSES[pair[1]]=pair[0]}EXPRESSION_START=(function(){_f=[];_h=BALANCED_PAIRS;for(_g=0,_i=_h.length;_g<_i;_g++){pair=_h[_g];_f.push(pair[0])}return _f})();EXPRESSION_END=(function(){_j=[];_l=BALANCED_PAIRS;for(_k=0,_m=_l.length;_k<_m;_k++){pair=_l[_k];_j.push(pair[1])}return _j})();EXPRESSION_CLOSE=["CATCH","WHEN","ELSE","FINALLY"].concat(EXPRESSION_END);IMPLICIT_FUNC=["IDENTIFIER","SUPER",")","CALL_END","]","INDEX_END","@"];IMPLICIT_CALL=["IDENTIFIER","NUMBER","STRING","JS","REGEX","NEW","PARAM_START","CLASS","TRY","DELETE","TYPEOF","SWITCH","THIS","NULL","TRUE","FALSE","YES","NO","ON","OFF","!","!!","@","->","=>","[","(","{"];IMPLICIT_BLOCK=["->","=>","{","[",","];IMPLICIT_END=["IF","UNLESS","FOR","WHILE","UNTIL","LOOP","TERMINATOR","INDENT"];SINGLE_LINERS=["ELSE","->","=>","TRY","FINALLY","THEN"];SINGLE_CLOSERS=["TERMINATOR","CATCH","FINALLY","ELSE","OUTDENT","LEADING_WHEN"]})();(function(){var ASSIGNED,CALLABLE,CODE,COFFEE_ALIASES,COFFEE_KEYWORDS,COMMENT,CONVERSIONS,HEREDOC,HEREDOC_INDENT,IDENTIFIER,JS_CLEANER,JS_FORBIDDEN,JS_KEYWORDS,LAST_DENT,LAST_DENTS,LINE_BREAK,Lexer,MULTILINER,MULTI_DENT,NEXT_CHARACTER,NOT_REGEX,NO_NEWLINE,NUMBER,OPERATOR,REGEX_END,REGEX_ESCAPE,REGEX_INTERPOLATION,REGEX_START,RESERVED,Rewriter,STRING_NEWLINES,WHITESPACE,_a,_b,_c,compact,count,helpers,include,starts;var __slice=Array.prototype.slice;if((typeof process!=="undefined"&&process!==null)){_a=require("./rewriter");Rewriter=_a.Rewriter;_b=require("./helpers");helpers=_b.helpers}else{this.exports=this;Rewriter=this.Rewriter;helpers=this.helpers}_c=helpers;include=_c.include;count=_c.count;starts=_c.starts;compact=_c.compact;exports.Lexer=(function(){Lexer=function(){};Lexer.prototype.tokenize=function(code,options){var o;code=code.replace(/(\r|\s+$)/g,"");o=options||{};this.code=code;this.i=0;this.line=o.line||0;this.indent=0;this.outdebt=0;this.indents=[];this.tokens=[];while(this.i<this.code.length){this.chunk=this.code.slice(this.i);this.extractNextToken()}this.closeIndentation();if(o.rewrite===false){return this.tokens}return(new Rewriter()).rewrite(this.tokens)};Lexer.prototype.extractNextToken=function(){if(this.identifierToken()){return null}if(this.commentToken()){return null}if(this.whitespaceToken()){return null}if(this.lineToken()){return null}if(this.heredocToken()){return null}if(this.stringToken()){return null}if(this.numberToken()){return null}if(this.regexToken()){return null}if(this.jsToken()){return null}return this.literalToken()};Lexer.prototype.identifierToken=function(){var close_index,forcedIdentifier,id,tag;if(!(id=this.match(IDENTIFIER,1))){return false}this.i+=id.length;forcedIdentifier=this.tagAccessor()||this.match(ASSIGNED,1);tag="IDENTIFIER";if(include(JS_KEYWORDS,id)||(!forcedIdentifier&&include(COFFEE_KEYWORDS,id))){tag=id.toUpperCase()}if(tag==="WHEN"&&include(LINE_BREAK,this.tag())){tag="LEADING_WHEN"}if(id==="all"&&this.tag()==="FOR"){tag="ALL"}if(include(JS_FORBIDDEN,id)){if(forcedIdentifier){tag="STRING";id=('"'+(id)+'"');if(forcedIdentifier==="accessor"){close_index=true;if(this.tag()!=="@"){this.tokens.pop()}this.token("INDEX_START","[")}}else{if(include(RESERVED,id)){this.identifierError(id)}}}if(!(forcedIdentifier)){if(include(COFFEE_ALIASES,id)){tag=(id=CONVERSIONS[id])}}this.token(tag,id);if(close_index){this.token("]","]")}return true};Lexer.prototype.numberToken=function(){var number;if(!(number=this.match(NUMBER,1))){return false}if(this.tag()==="."&&starts(number,".")){return false}this.i+=number.length;this.token("NUMBER",number);return true};Lexer.prototype.stringToken=function(){var string;if(!(starts(this.chunk,'"')||starts(this.chunk,"'"))){return false}if(!(string=this.balancedToken(['"','"'],["#{","}"])||this.balancedToken(["'","'"]))){return false}this.interpolateString(string.replace(STRING_NEWLINES," \\\n"));this.line+=count(string,"\n");this.i+=string.length;return true};Lexer.prototype.heredocToken=function(){var doc,match,quote;if(!(match=this.chunk.match(HEREDOC))){return false}quote=match[1].substr(0,1);doc=this.sanitizeHeredoc(match[2]||match[4]||"",{quote:quote});this.interpolateString(quote+doc+quote,{heredoc:true});this.line+=count(match[1],"\n");this.i+=match[1].length;return true};Lexer.prototype.commentToken=function(){var comment,match;if(!(match=this.chunk.match(COMMENT))){return false}this.line+=count(match[1],"\n");this.i+=match[1].length;if(match[2]){comment=this.sanitizeHeredoc(match[2],{herecomment:true});this.token("HERECOMMENT",comment.split(MULTILINER));this.token("TERMINATOR","\n")}return true};Lexer.prototype.jsToken=function(){var script;if(!(starts(this.chunk,"`"))){return false}if(!(script=this.balancedToken(["`","`"]))){return false}this.token("JS",script.replace(JS_CLEANER,""));this.i+=script.length;return true};Lexer.prototype.regexToken=function(){var end,flags,regex,str;if(!(this.chunk.match(REGEX_START))){return false}if(include(NOT_REGEX,this.tag())){return false}if(!(regex=this.balancedToken(["/","/"]))){return false}if(!(end=this.chunk.substr(regex.length).match(REGEX_END))){return false}if(end[2]){regex+=(flags=end[2])}if(regex.match(REGEX_INTERPOLATION)){str=regex.substring(1).split("/")[0];str=str.replace(REGEX_ESCAPE,function(escaped){return"\\"+escaped});this.tokens=this.tokens.concat([["(","("],["NEW","new"],["IDENTIFIER","RegExp"],["CALL_START","("]]);this.interpolateString(('"'+(str)+'"'),{escapeQuotes:true});if(flags){this.tokens.splice(this.tokens.length,0,[",",","],["STRING",('"'+(flags)+'"')])}this.tokens.splice(this.tokens.length,0,[")",")"],[")",")"])}else{this.token("REGEX",regex)}this.i+=regex.length;return true};Lexer.prototype.balancedToken=function(){var delimited;delimited=__slice.call(arguments,0);return this.balancedString(this.chunk,delimited)};Lexer.prototype.lineToken=function(){var diff,indent,nextCharacter,noNewlines,prev,size;if(!(indent=this.match(MULTI_DENT,1))){return false}this.line+=count(indent,"\n");this.i+=indent.length;prev=this.prev(2);size=indent.match(LAST_DENTS).reverse()[0].match(LAST_DENT)[1].length;nextCharacter=this.match(NEXT_CHARACTER,1);noNewlines=nextCharacter==="."||nextCharacter===","||this.unfinished();if(size===this.indent){if(noNewlines){return this.suppressNewlines()}return this.newlineToken(indent)}else{if(size>this.indent){if(noNewlines){return this.suppressNewlines()}this.outdebt=0;diff=size-this.indent;this.token("INDENT",diff);this.indents.push(diff)}else{this.outdentToken(this.indent-size,noNewlines)}}this.indent=size;return true};Lexer.prototype.outdentToken=function(moveOut,noNewlines,close){var dent,len;while(moveOut>0){len=this.indents.length-1;if(this.indents[len]===undefined){moveOut=0}else{if(this.indents[len]===this.outdebt){moveOut-=this.outdebt;this.outdebt=0}else{if(this.indents[len]<this.outdebt){this.outdebt-=this.indents[len];moveOut-=this.indents[len]}else{dent=this.indents.pop();dent-=this.outdebt;moveOut-=dent;this.outdebt=0;this.token("OUTDENT",dent)}}}}if(dent){this.outdebt-=moveOut}if(!(this.tag()==="TERMINATOR"||noNewlines)){this.token("TERMINATOR","\n")}return true};Lexer.prototype.whitespaceToken=function(){var prev,space;if(!(space=this.match(WHITESPACE,1))){return false}prev=this.prev();if(prev){prev.spaced=true}this.i+=space.length;return true};Lexer.prototype.newlineToken=function(newlines){if(!(this.tag()==="TERMINATOR")){this.token("TERMINATOR","\n")}return true};Lexer.prototype.suppressNewlines=function(){if(this.value()==="\\"){this.tokens.pop()}return true};Lexer.prototype.literalToken=function(){var _d,match,prevSpaced,space,tag,value;match=this.chunk.match(OPERATOR);value=match&&match[1];space=match&&match[2];if(value&&value.match(CODE)){this.tagParameters()}value=value||this.chunk.substr(0,1);this.i+=value.length;prevSpaced=this.prev()&&this.prev().spaced;tag=value;if(value==="="){if(include(JS_FORBIDDEN,this.value())){this.assignmentError()}if(("or"===(_d=this.value())||"and"===_d)){return this.tag(1,CONVERSIONS[this.value()]+"=")}}if(value===";"){tag="TERMINATOR"}else{if(value==="?"&&prevSpaced){tag="OP?"}else{if(include(CALLABLE,this.tag())&&!prevSpaced){if(value==="("){tag="CALL_START"}else{if(value==="["){tag="INDEX_START";if(this.tag()==="?"){this.tag(1,"INDEX_SOAK")}if(this.tag()==="::"){this.tag(1,"INDEX_PROTO")}}}}}}this.token(tag,value);return true};Lexer.prototype.tagAccessor=function(){var accessor,prev;if((!(prev=this.prev()))||(prev&&prev.spaced)){return false}accessor=(function(){if(prev[1]==="::"){return this.tag(1,"PROTOTYPE_ACCESS")}else{if(prev[1]==="."&&!(this.value(2)===".")){if(this.tag(2)==="?"){this.tag(1,"SOAK_ACCESS");return this.tokens.splice(-2,1)}else{return this.tag(1,"PROPERTY_ACCESS")}}else{return prev[0]==="@"}}}).call(this);return accessor?"accessor":false};Lexer.prototype.sanitizeHeredoc=function(doc,options){var _d,attempt,indent,match;while((match=HEREDOC_INDENT.exec(doc))){attempt=(typeof(_d=match[2])!=="undefined"&&_d!==null)?match[2]:match[3];if(!indent||attempt.length<indent.length){indent=attempt}}doc=doc.replace(new RegExp("^"+indent,"gm"),"");if(options.herecomment){return doc}return doc.replace(MULTILINER,"\\n").replace(new RegExp(options.quote,"g"),("\\"+(options.quote)))};Lexer.prototype.tagParameters=function(){var _d,i,tok;if(this.tag()!==")"){return null}i=0;while(true){i+=1;tok=this.prev(i);if(!tok){return null}if((_d=tok[0])==="IDENTIFIER"){tok[0]="PARAM"}else{if(_d===")"){tok[0]="PARAM_END"}else{if(_d==="("||_d==="CALL_START"){return(tok[0]="PARAM_START")}}}}return true};Lexer.prototype.closeIndentation=function(){return this.outdentToken(this.indent)};Lexer.prototype.identifierError=function(word){throw new Error(('SyntaxError: Reserved word "'+(word)+'" on line '+(this.line+1)))};Lexer.prototype.assignmentError=function(){throw new Error(('SyntaxError: Reserved word "'+(this.value())+'" on line '+(this.line+1)+" can't be assigned"))};Lexer.prototype.balancedString=function(str,delimited,options){var _d,_e,_f,_g,close,i,levels,open,pair,slash;options=options||{};slash=delimited[0][0]==="/";levels=[];i=0;while(i<str.length){if(levels.length&&starts(str,"\\",i)){i+=1}else{_e=delimited;for(_d=0,_f=_e.length;_d<_f;_d++){pair=_e[_d];_g=pair;open=_g[0];close=_g[1];if(levels.length&&starts(str,close,i)&&levels[levels.length-1]===pair){levels.pop();i+=close.length-1;if(!(levels.length)){i+=1}break}else{if(starts(str,open,i)){levels.push(pair);i+=open.length-1;break}}}}if(!levels.length||slash&&starts(str,"\n",i)){break}i+=1}if(levels.length){if(slash){return false}throw new Error(("SyntaxError: Unterminated "+(levels.pop()[0])+" starting on line "+(this.line+1)))}return !i?false:str.substring(0,i)};Lexer.prototype.interpolateString=function(str,options){var _d,_e,_f,_g,_h,_i,escaped,expr,i,idx,inner,interpolated,lexer,nested,pi,quote,tag,tok,token,tokens,value;options=options||{};if(str.length<3||!starts(str,'"')){return this.token("STRING",str)}else{lexer=new Lexer();tokens=[];quote=str.substring(0,1);_d=[1,1];i=_d[0];pi=_d[1];while(i<str.length-1){if(starts(str,"\\",i)){i+=1}else{if((expr=this.balancedString(str.substring(i),[["#{","}"]]))){if(pi<i){tokens.push(["STRING",quote+str.substring(pi,i)+quote])}inner=expr.substring(2,expr.length-1);if(inner.length){if(options.heredoc){inner=inner.replace(new RegExp("\\\\"+quote,"g"),quote)}nested=lexer.tokenize(("("+(inner)+")"),{line:this.line});_e=nested;for(idx=0,_f=_e.length;idx<_f;idx++){tok=_e[idx];if(tok[0]==="CALL_END"){(tok[0]=")")}}nested.pop();tokens.push(["TOKENS",nested])}else{tokens.push(["STRING",quote+quote])}i+=expr.length-1;pi=i+1}}i+=1}if(pi<i&&pi<str.length-1){tokens.push(["STRING",quote+str.substring(pi,i)+quote])}if(!(tokens[0][0]==="STRING")){tokens.unshift(["STRING",'""'])}interpolated=tokens.length>1;if(interpolated){this.token("(","(")}_g=tokens;for(i=0,_h=_g.length;i<_h;i++){token=_g[i];_i=token;tag=_i[0];value=_i[1];if(tag==="TOKENS"){this.tokens=this.tokens.concat(value)}else{if(tag==="STRING"&&options.escapeQuotes){escaped=value.substring(1,value.length-1).replace(/"/g,'\\"');this.token(tag,('"'+(escaped)+'"'))}else{this.token(tag,value)}}if(i<tokens.length-1){this.token("+","+")}}if(interpolated){this.token(")",")")}return tokens}};Lexer.prototype.token=function(tag,value){return this.tokens.push([tag,value,this.line])};Lexer.prototype.tag=function(index,newTag){var tok;if(!(tok=this.prev(index))){return null}if((typeof newTag!=="undefined"&&newTag!==null)){return(tok[0]=newTag)}return tok[0]};Lexer.prototype.value=function(index,val){var tok;if(!(tok=this.prev(index))){return null}if((typeof val!=="undefined"&&val!==null)){return(tok[1]=val)}return tok[1]};Lexer.prototype.prev=function(index){return this.tokens[this.tokens.length-(index||1)]};Lexer.prototype.match=function(regex,index){var m;if(!(m=this.chunk.match(regex))){return false}return m?m[index]:false};Lexer.prototype.unfinished=function(){var prev;prev=this.prev(2);return this.value()&&this.value().match&&this.value().match(NO_NEWLINE)&&prev&&(prev[0]!==".")&&!this.value().match(CODE)&&!this.chunk.match(ASSIGNED)};return Lexer})();JS_KEYWORDS=["if","else","true","false","new","return","try","catch","finally","throw","break","continue","for","in","while","delete","instanceof","typeof","switch","super","extends","class","this","null"];COFFEE_ALIASES=["and","or","is","isnt","not"];COFFEE_KEYWORDS=COFFEE_ALIASES.concat(["then","unless","until","loop","yes","no","on","off","of","by","where","when"]);RESERVED=["case","default","do","function","var","void","with","const","let","enum","export","import","native","__hasProp","__extends","__slice"];JS_FORBIDDEN=JS_KEYWORDS.concat(RESERVED);IDENTIFIER=/^([a-zA-Z\$_](\w|\$)*)/;NUMBER=/^(((\b0(x|X)[0-9a-fA-F]+)|((\b[0-9]+(\.[0-9]+)?|\.[0-9]+)(e[+\-]?[0-9]+)?)))\b/i;HEREDOC=/^("{6}|'{6}|"{3}\n?([\s\S]*?)\n?([ \t]*)"{3}|'{3}\n?([\s\S]*?)\n?([ \t]*)'{3})/;OPERATOR=/^(-[\-=>]?|\+[+=]?|[*&|\/%=<>:!?]+)([ \t]*)/;WHITESPACE=/^([ \t]+)/;COMMENT=/^(\s*\#{3}(?!#)[ \t]*\n+([\s\S]*?)[ \t]*\n+[ \t]*\#{3}|(\s*#(?!##[^#])[^\n]*)+)/;CODE=/^((-|=)>)/;MULTI_DENT=/^((\n([ \t]*))+)(\.)?/;LAST_DENTS=/\n([ \t]*)/g;LAST_DENT=/\n([ \t]*)/;REGEX_START=/^\/[^\/ ]/;REGEX_INTERPOLATION=/([^\\]#\{.*[^\\]\})/;REGEX_END=/^(([imgy]{1,4})\b|\W|$)/;REGEX_ESCAPE=/\\[^\$]/g;JS_CLEANER=/(^`|`$)/g;MULTILINER=/\n/g;STRING_NEWLINES=/\n[ \t]*/g;NO_NEWLINE=/^([+\*&|\/\-%=<>!.\\][<>=&|]*|and|or|is|isnt|not|delete|typeof|instanceof)$/;HEREDOC_INDENT=/(\n+([ \t]*)|^([ \t]+))/g;ASSIGNED=/^\s*([a-zA-Z\$_@]\w*[ \t]*?[:=][^=])/;NEXT_CHARACTER=/^\s*(\S)/;NOT_REGEX=["NUMBER","REGEX","++","--","FALSE","NULL","TRUE","]"];CALLABLE=["IDENTIFIER","SUPER",")","]","}","STRING","@","THIS","?","::"];LINE_BREAK=["INDENT","OUTDENT","TERMINATOR"];CONVERSIONS={and:"&&",or:"||",is:"==",isnt:"!=",not:"!","===":"=="}})();var parser=(function(){var parser={trace:function trace(){},yy:{},symbols_:{error:2,Root:3,TERMINATOR:4,Body:5,Block:6,Line:7,Expression:8,Statement:9,Return:10,Throw:11,BREAK:12,CONTINUE:13,Value:14,Call:15,Code:16,Operation:17,Assign:18,If:19,Try:20,While:21,For:22,Switch:23,Extends:24,Class:25,Splat:26,Existence:27,Comment:28,INDENT:29,OUTDENT:30,Identifier:31,IDENTIFIER:32,AlphaNumeric:33,NUMBER:34,STRING:35,Literal:36,JS:37,REGEX:38,TRUE:39,FALSE:40,YES:41,NO:42,ON:43,OFF:44,Assignable:45,"=":46,AssignObj:47,":":48,RETURN:49,HERECOMMENT:50,"?":51,PARAM_START:52,ParamList:53,PARAM_END:54,FuncGlyph:55,"->":56,"=>":57,OptComma:58,",":59,Param:60,PARAM:61,"@":62,".":63,SimpleAssignable:64,Accessor:65,Invocation:66,ThisProperty:67,Array:68,Object:69,Parenthetical:70,Range:71,This:72,NULL:73,PROPERTY_ACCESS:74,PROTOTYPE_ACCESS:75,"::":76,SOAK_ACCESS:77,Index:78,Slice:79,INDEX_START:80,INDEX_END:81,INDEX_SOAK:82,INDEX_PROTO:83,"{":84,AssignList:85,"}":86,CLASS:87,EXTENDS:88,ClassBody:89,ClassAssign:90,Super:91,NEW:92,Arguments:93,CALL_START:94,ArgList:95,CALL_END:96,SUPER:97,THIS:98,"[":99,"]":100,SimpleArgs:101,TRY:102,Catch:103,FINALLY:104,CATCH:105,THROW:106,"(":107,")":108,WhileSource:109,WHILE:110,WHEN:111,UNTIL:112,Loop:113,LOOP:114,ForBody:115,FOR:116,ForStart:117,ForSource:118,ForVariables:119,ALL:120,ForValue:121,IN:122,OF:123,BY:124,SWITCH:125,Whens:126,ELSE:127,When:128,LEADING_WHEN:129,IfBlock:130,IF:131,UNLESS:132,"!":133,"!!":134,"-":135,"+":136,"~":137,"--":138,"++":139,DELETE:140,TYPEOF:141,"*":142,"/":143,"%":144,"<<":145,">>":146,">>>":147,"&":148,"|":149,"^":150,"<=":151,"<":152,">":153,">=":154,"==":155,"!=":156,"&&":157,"||":158,"OP?":159,"-=":160,"+=":161,"/=":162,"*=":163,"%=":164,"||=":165,"&&=":166,"?=":167,INSTANCEOF:168,"$accept":0,"$end":1},terminals_:{"2":"error","4":"TERMINATOR","12":"BREAK","13":"CONTINUE","29":"INDENT","30":"OUTDENT","32":"IDENTIFIER","34":"NUMBER","35":"STRING","37":"JS","38":"REGEX","39":"TRUE","40":"FALSE","41":"YES","42":"NO","43":"ON","44":"OFF","46":"=","48":":","49":"RETURN","50":"HERECOMMENT","51":"?","52":"PARAM_START","54":"PARAM_END","56":"->","57":"=>","59":",","61":"PARAM","62":"@","63":".","73":"NULL","74":"PROPERTY_ACCESS","75":"PROTOTYPE_ACCESS","76":"::","77":"SOAK_ACCESS","80":"INDEX_START","81":"INDEX_END","82":"INDEX_SOAK","83":"INDEX_PROTO","84":"{","86":"}","87":"CLASS","88":"EXTENDS","92":"NEW","94":"CALL_START","96":"CALL_END","97":"SUPER","98":"THIS","99":"[","100":"]","102":"TRY","104":"FINALLY","105":"CATCH","106":"THROW","107":"(","108":")","110":"WHILE","111":"WHEN","112":"UNTIL","114":"LOOP","116":"FOR","120":"ALL","122":"IN","123":"OF","124":"BY","125":"SWITCH","127":"ELSE","129":"LEADING_WHEN","131":"IF","132":"UNLESS","133":"!","134":"!!","135":"-","136":"+","137":"~","138":"--","139":"++","140":"DELETE","141":"TYPEOF","142":"*","143":"/","144":"%","145":"<<","146":">>","147":">>>","148":"&","149":"|","150":"^","151":"<=","152":"<","153":">","154":">=","155":"==","156":"!=","157":"&&","158":"||","159":"OP?","160":"-=","161":"+=","162":"/=","163":"*=","164":"%=","165":"||=","166":"&&=","167":"?=","168":"INSTANCEOF"},productions_:[0,[3,0],[3,1],[3,1],[3,2],[5,1],[5,3],[5,2],[7,1],[7,1],[9,1],[9,1],[9,1],[9,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[6,3],[6,2],[6,2],[31,1],[33,1],[33,1],[36,1],[36,1],[36,1],[36,1],[36,1],[36,1],[36,1],[36,1],[36,1],[18,3],[18,5],[47,1],[47,1],[47,3],[47,3],[47,5],[47,5],[47,1],[10,2],[10,1],[28,1],[27,2],[16,5],[16,2],[55,1],[55,1],[58,0],[58,1],[53,0],[53,1],[53,3],[60,1],[60,2],[60,4],[60,5],[26,4],[64,1],[64,2],[64,2],[64,1],[45,1],[45,1],[45,1],[14,1],[14,1],[14,1],[14,1],[14,1],[14,1],[65,2],[65,2],[65,1],[65,2],[65,1],[65,1],[78,3],[78,2],[78,2],[69,4],[85,0],[85,1],[85,3],[85,4],[85,6],[25,2],[25,4],[25,5],[25,7],[25,4],[90,1],[90,3],[89,0],[89,1],[89,3],[89,3],[15,1],[15,1],[15,2],[15,2],[24,3],[66,2],[66,2],[93,4],[91,1],[91,2],[72,1],[72,1],[67,2],[71,6],[71,7],[79,6],[79,7],[68,4],[95,0],[95,1],[95,3],[95,4],[95,6],[101,1],[101,3],[20,3],[20,4],[20,5],[103,3],[11,2],[70,3],[109,2],[109,4],[109,2],[109,4],[21,2],[21,2],[21,2],[21,1],[113,2],[113,2],[22,2],[22,2],[22,2],[115,2],[115,2],[117,2],[117,3],[121,1],[121,1],[121,1],[119,1],[119,3],[118,2],[118,2],[118,4],[118,4],[118,4],[118,6],[118,6],[23,5],[23,7],[23,4],[23,6],[126,1],[126,2],[128,3],[128,4],[130,3],[130,3],[130,5],[130,3],[19,1],[19,3],[19,3],[19,3],[19,3],[17,2],[17,2],[17,2],[17,2],[17,2],[17,2],[17,2],[17,2],[17,2],[17,2],[17,2],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,4],[17,4]],performAction:function anonymous(yytext,yyleng,yylineno,yy){var $$=arguments[5],$0=arguments[5].length;switch(arguments[4]){case 1:return this.$=new Expressions();break;case 2:return this.$=new Expressions();break;case 3:return this.$=$$[$0-1+1-1];break;case 4:return this.$=$$[$0-2+1-1];break;case 5:this.$=Expressions.wrap([$$[$0-1+1-1]]);break;case 6:this.$=$$[$0-3+1-1].push($$[$0-3+3-1]);break;case 7:this.$=$$[$0-2+1-1];break;case 8:this.$=$$[$0-1+1-1];break;case 9:this.$=$$[$0-1+1-1];break;case 10:this.$=$$[$0-1+1-1];break;case 11:this.$=$$[$0-1+1-1];break;case 12:this.$=new LiteralNode($$[$0-1+1-1]);break;case 13:this.$=new LiteralNode($$[$0-1+1-1]);break;case 14:this.$=$$[$0-1+1-1];break;case 15:this.$=$$[$0-1+1-1];break;case 16:this.$=$$[$0-1+1-1];break;case 17:this.$=$$[$0-1+1-1];break;case 18:this.$=$$[$0-1+1-1];break;case 19:this.$=$$[$0-1+1-1];break;case 20:this.$=$$[$0-1+1-1];break;case 21:this.$=$$[$0-1+1-1];break;case 22:this.$=$$[$0-1+1-1];break;case 23:this.$=$$[$0-1+1-1];break;case 24:this.$=$$[$0-1+1-1];break;case 25:this.$=$$[$0-1+1-1];break;case 26:this.$=$$[$0-1+1-1];break;case 27:this.$=$$[$0-1+1-1];break;case 28:this.$=$$[$0-1+1-1];break;case 29:this.$=$$[$0-3+2-1];break;case 30:this.$=new Expressions();break;case 31:this.$=Expressions.wrap([$$[$0-2+2-1]]);break;case 32:this.$=new LiteralNode($$[$0-1+1-1]);break;case 33:this.$=new LiteralNode($$[$0-1+1-1]);break;case 34:this.$=new LiteralNode($$[$0-1+1-1]);break;case 35:this.$=$$[$0-1+1-1];break;case 36:this.$=new LiteralNode($$[$0-1+1-1]);break;case 37:this.$=new LiteralNode($$[$0-1+1-1]);break;case 38:this.$=new LiteralNode(true);break;case 39:this.$=new LiteralNode(false);break;case 40:this.$=new LiteralNode(true);break;case 41:this.$=new LiteralNode(false);break;case 42:this.$=new LiteralNode(true);break;case 43:this.$=new LiteralNode(false);break;case 44:this.$=new AssignNode($$[$0-3+1-1],$$[$0-3+3-1]);break;case 45:this.$=new AssignNode($$[$0-5+1-1],$$[$0-5+4-1]);break;case 46:this.$=new ValueNode($$[$0-1+1-1]);break;case 47:this.$=$$[$0-1+1-1];break;case 48:this.$=new AssignNode(new ValueNode($$[$0-3+1-1]),$$[$0-3+3-1],"object");break;case 49:this.$=new AssignNode(new ValueNode($$[$0-3+1-1]),$$[$0-3+3-1],"object");break;case 50:this.$=new AssignNode(new ValueNode($$[$0-5+1-1]),$$[$0-5+4-1],"object");break;case 51:this.$=new AssignNode(new ValueNode($$[$0-5+1-1]),$$[$0-5+4-1],"object");break;case 52:this.$=$$[$0-1+1-1];break;case 53:this.$=new ReturnNode($$[$0-2+2-1]);break;case 54:this.$=new ReturnNode(new ValueNode(new LiteralNode("null")));break;case 55:this.$=new CommentNode($$[$0-1+1-1]);break;case 56:this.$=new ExistenceNode($$[$0-2+1-1]);break;case 57:this.$=new CodeNode($$[$0-5+2-1],$$[$0-5+5-1],$$[$0-5+4-1]);break;case 58:this.$=new CodeNode([],$$[$0-2+2-1],$$[$0-2+1-1]);break;case 59:this.$="func";break;case 60:this.$="boundfunc";break;case 61:this.$=$$[$0-1+1-1];break;case 62:this.$=$$[$0-1+1-1];break;case 63:this.$=[];break;case 64:this.$=[$$[$0-1+1-1]];break;case 65:this.$=$$[$0-3+1-1].concat([$$[$0-3+3-1]]);break;case 66:this.$=new LiteralNode($$[$0-1+1-1]);break;case 67:this.$=new ParamNode($$[$0-2+2-1],true);break;case 68:this.$=new ParamNode($$[$0-4+1-1],false,true);break;case 69:this.$=new ParamNode($$[$0-5+2-1],true,true);break;case 70:this.$=new SplatNode($$[$0-4+1-1]);break;case 71:this.$=new ValueNode($$[$0-1+1-1]);break;case 72:this.$=$$[$0-2+1-1].push($$[$0-2+2-1]);break;case 73:this.$=new ValueNode($$[$0-2+1-1],[$$[$0-2+2-1]]);break;case 74:this.$=$$[$0-1+1-1];break;case 75:this.$=$$[$0-1+1-1];break;case 76:this.$=new ValueNode($$[$0-1+1-1]);break;case 77:this.$=new ValueNode($$[$0-1+1-1]);break;case 78:this.$=$$[$0-1+1-1];break;case 79:this.$=new ValueNode($$[$0-1+1-1]);break;case 80:this.$=new ValueNode($$[$0-1+1-1]);break;case 81:this.$=new ValueNode($$[$0-1+1-1]);break;case 82:this.$=$$[$0-1+1-1];break;case 83:this.$=new ValueNode(new LiteralNode("null"));break;case 84:this.$=new AccessorNode($$[$0-2+2-1]);break;case 85:this.$=new AccessorNode($$[$0-2+2-1],"prototype");break;case 86:this.$=new AccessorNode(new LiteralNode("prototype"));break;case 87:this.$=new AccessorNode($$[$0-2+2-1],"soak");break;case 88:this.$=$$[$0-1+1-1];break;case 89:this.$=new SliceNode($$[$0-1+1-1]);break;case 90:this.$=new IndexNode($$[$0-3+2-1]);break;case 91:this.$=(function(){$$[$0-2+2-1].soakNode=true;return $$[$0-2+2-1]}());break;case 92:this.$=(function(){$$[$0-2+2-1].proto=true;return $$[$0-2+2-1]}());break;case 93:this.$=new ObjectNode($$[$0-4+2-1]);break;case 94:this.$=[];break;case 95:this.$=[$$[$0-1+1-1]];break;case 96:this.$=$$[$0-3+1-1].concat([$$[$0-3+3-1]]);break;case 97:this.$=$$[$0-4+1-1].concat([$$[$0-4+4-1]]);break;case 98:this.$=$$[$0-6+1-1].concat($$[$0-6+4-1]);break;case 99:this.$=new ClassNode($$[$0-2+2-1]);break;case 100:this.$=new ClassNode($$[$0-4+2-1],$$[$0-4+4-1]);break;case 101:this.$=new ClassNode($$[$0-5+2-1],null,$$[$0-5+4-1]);break;case 102:this.$=new ClassNode($$[$0-7+2-1],$$[$0-7+4-1],$$[$0-7+6-1]);break;case 103:this.$=new ClassNode("__temp__",null,$$[$0-4+3-1]);break;case 104:this.$=$$[$0-1+1-1];break;case 105:this.$=new AssignNode(new ValueNode($$[$0-3+1-1]),$$[$0-3+3-1],"this");break;case 106:this.$=[];break;case 107:this.$=[$$[$0-1+1-1]];break;case 108:this.$=$$[$0-3+1-1].concat($$[$0-3+3-1]);break;case 109:this.$=$$[$0-3+2-1];break;case 110:this.$=$$[$0-1+1-1];break;case 111:this.$=$$[$0-1+1-1];break;case 112:this.$=$$[$0-2+2-1].newInstance();break;case 113:this.$=(new CallNode($$[$0-2+2-1],[])).newInstance();break;case 114:this.$=new ExtendsNode($$[$0-3+1-1],$$[$0-3+3-1]);break;case 115:this.$=new CallNode($$[$0-2+1-1],$$[$0-2+2-1]);break;case 116:this.$=new CallNode($$[$0-2+1-1],$$[$0-2+2-1]);break;case 117:this.$=$$[$0-4+2-1];break;case 118:this.$=new CallNode("super",[new SplatNode(new LiteralNode("arguments"))]);break;case 119:this.$=new CallNode("super",$$[$0-2+2-1]);break;case 120:this.$=new ValueNode(new LiteralNode("this"));break;case 121:this.$=new ValueNode(new LiteralNode("this"));break;case 122:this.$=new ValueNode(new LiteralNode("this"),[new AccessorNode($$[$0-2+2-1])]);break;case 123:this.$=new RangeNode($$[$0-6+2-1],$$[$0-6+5-1]);break;case 124:this.$=new RangeNode($$[$0-7+2-1],$$[$0-7+6-1],true);break;case 125:this.$=new RangeNode($$[$0-6+2-1],$$[$0-6+5-1]);break;case 126:this.$=new RangeNode($$[$0-7+2-1],$$[$0-7+6-1],true);break;case 127:this.$=new ArrayNode($$[$0-4+2-1]);break;case 128:this.$=[];break;case 129:this.$=[$$[$0-1+1-1]];break;case 130:this.$=$$[$0-3+1-1].concat([$$[$0-3+3-1]]);break;case 131:this.$=$$[$0-4+1-1].concat([$$[$0-4+4-1]]);break;case 132:this.$=$$[$0-6+1-1].concat($$[$0-6+4-1]);break;case 133:this.$=$$[$0-1+1-1];break;case 134:this.$=$$[$0-3+1-1] instanceof Array?$$[$0-3+1-1].concat([$$[$0-3+3-1]]):[$$[$0-3+1-1]].concat([$$[$0-3+3-1]]);break;case 135:this.$=new TryNode($$[$0-3+2-1],$$[$0-3+3-1][0],$$[$0-3+3-1][1]);break;case 136:this.$=new TryNode($$[$0-4+2-1],null,null,$$[$0-4+4-1]);break;case 137:this.$=new TryNode($$[$0-5+2-1],$$[$0-5+3-1][0],$$[$0-5+3-1][1],$$[$0-5+5-1]);break;case 138:this.$=[$$[$0-3+2-1],$$[$0-3+3-1]];break;case 139:this.$=new ThrowNode($$[$0-2+2-1]);break;case 140:this.$=new ParentheticalNode($$[$0-3+2-1]);break;case 141:this.$=new WhileNode($$[$0-2+2-1]);break;case 142:this.$=new WhileNode($$[$0-4+2-1],{guard:$$[$0-4+4-1]});break;case 143:this.$=new WhileNode($$[$0-2+2-1],{invert:true});break;case 144:this.$=new WhileNode($$[$0-4+2-1],{invert:true,guard:$$[$0-4+4-1]});break;case 145:this.$=$$[$0-2+1-1].addBody($$[$0-2+2-1]);break;case 146:this.$=$$[$0-2+2-1].addBody(Expressions.wrap([$$[$0-2+1-1]]));break;case 147:this.$=$$[$0-2+2-1].addBody(Expressions.wrap([$$[$0-2+1-1]]));break;case 148:this.$=$$[$0-1+1-1];break;case 149:this.$=new WhileNode(new LiteralNode("true")).addBody($$[$0-2+2-1]);break;case 150:this.$=new WhileNode(new LiteralNode("true")).addBody(Expressions.wrap([$$[$0-2+2-1]]));break;case 151:this.$=new ForNode($$[$0-2+1-1],$$[$0-2+2-1],$$[$0-2+2-1].vars[0],$$[$0-2+2-1].vars[1]);break;case 152:this.$=new ForNode($$[$0-2+1-1],$$[$0-2+2-1],$$[$0-2+2-1].vars[0],$$[$0-2+2-1].vars[1]);break;case 153:this.$=new ForNode($$[$0-2+2-1],$$[$0-2+1-1],$$[$0-2+1-1].vars[0],$$[$0-2+1-1].vars[1]);break;case 154:this.$={source:new ValueNode($$[$0-2+2-1]),vars:[]};break;case 155:this.$=(function(){$$[$0-2+2-1].raw=$$[$0-2+1-1].raw;$$[$0-2+2-1].vars=$$[$0-2+1-1];return $$[$0-2+2-1]}());break;case 156:this.$=$$[$0-2+2-1];break;case 157:this.$=(function(){$$[$0-3+3-1].raw=true;return $$[$0-3+3-1]}());break;case 158:this.$=$$[$0-1+1-1];break;case 159:this.$=new ValueNode($$[$0-1+1-1]);break;case 160:this.$=new ValueNode($$[$0-1+1-1]);break;case 161:this.$=[$$[$0-1+1-1]];break;case 162:this.$=[$$[$0-3+1-1],$$[$0-3+3-1]];break;case 163:this.$={source:$$[$0-2+2-1]};break;case 164:this.$={source:$$[$0-2+2-1],object:true};break;case 165:this.$={source:$$[$0-4+2-1],guard:$$[$0-4+4-1]};break;case 166:this.$={source:$$[$0-4+2-1],guard:$$[$0-4+4-1],object:true};break;case 167:this.$={source:$$[$0-4+2-1],step:$$[$0-4+4-1]};break;case 168:this.$={source:$$[$0-6+2-1],guard:$$[$0-6+4-1],step:$$[$0-6+6-1]};break;case 169:this.$={source:$$[$0-6+2-1],step:$$[$0-6+4-1],guard:$$[$0-6+6-1]};break;case 170:this.$=$$[$0-5+4-1].switchesOver($$[$0-5+2-1]);break;case 171:this.$=$$[$0-7+4-1].switchesOver($$[$0-7+2-1]).addElse($$[$0-7+6-1],true);break;case 172:this.$=$$[$0-4+3-1];break;case 173:this.$=$$[$0-6+3-1].addElse($$[$0-6+5-1],true);break;case 174:this.$=$$[$0-1+1-1];break;case 175:this.$=$$[$0-2+1-1].addElse($$[$0-2+2-1]);break;case 176:this.$=new IfNode($$[$0-3+2-1],$$[$0-3+3-1],{statement:true});break;case 177:this.$=new IfNode($$[$0-4+2-1],$$[$0-4+3-1],{statement:true});break;case 178:this.$=new IfNode($$[$0-3+2-1],$$[$0-3+3-1]);break;case 179:this.$=new IfNode($$[$0-3+2-1],$$[$0-3+3-1],{invert:true});break;case 180:this.$=$$[$0-5+1-1].addElse((new IfNode($$[$0-5+4-1],$$[$0-5+5-1])).forceStatement());break;case 181:this.$=$$[$0-3+1-1].addElse($$[$0-3+3-1]);break;case 182:this.$=$$[$0-1+1-1];break;case 183:this.$=new IfNode($$[$0-3+3-1],Expressions.wrap([$$[$0-3+1-1]]),{statement:true});break;case 184:this.$=new IfNode($$[$0-3+3-1],Expressions.wrap([$$[$0-3+1-1]]),{statement:true});break;case 185:this.$=new IfNode($$[$0-3+3-1],Expressions.wrap([$$[$0-3+1-1]]),{statement:true,invert:true});break;case 186:this.$=new IfNode($$[$0-3+3-1],Expressions.wrap([$$[$0-3+1-1]]),{statement:true,invert:true});break;case 187:this.$=new OpNode("!",$$[$0-2+2-1]);break;case 188:this.$=new OpNode("!!",$$[$0-2+2-1]);break;case 189:this.$=new OpNode("-",$$[$0-2+2-1]);break;case 190:this.$=new OpNode("+",$$[$0-2+2-1]);break;case 191:this.$=new OpNode("~",$$[$0-2+2-1]);break;case 192:this.$=new OpNode("--",$$[$0-2+2-1]);break;case 193:this.$=new OpNode("++",$$[$0-2+2-1]);break;case 194:this.$=new OpNode("delete",$$[$0-2+2-1]);break;case 195:this.$=new OpNode("typeof",$$[$0-2+2-1]);break;case 196:this.$=new OpNode("--",$$[$0-2+1-1],null,true);break;case 197:this.$=new OpNode("++",$$[$0-2+1-1],null,true);break;case 198:this.$=new OpNode("*",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 199:this.$=new OpNode("/",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 200:this.$=new OpNode("%",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 201:this.$=new OpNode("+",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 202:this.$=new OpNode("-",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 203:this.$=new OpNode("<<",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 204:this.$=new OpNode(">>",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 205:this.$=new OpNode(">>>",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 206:this.$=new OpNode("&",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 207:this.$=new OpNode("|",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 208:this.$=new OpNode("^",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 209:this.$=new OpNode("<=",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 210:this.$=new OpNode("<",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 211:this.$=new OpNode(">",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 212:this.$=new OpNode(">=",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 213:this.$=new OpNode("==",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 214:this.$=new OpNode("!=",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 215:this.$=new OpNode("&&",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 216:this.$=new OpNode("||",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 217:this.$=new OpNode("?",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 218:this.$=new OpNode("-=",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 219:this.$=new OpNode("+=",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 220:this.$=new OpNode("/=",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 221:this.$=new OpNode("*=",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 222:this.$=new OpNode("%=",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 223:this.$=new OpNode("||=",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 224:this.$=new OpNode("&&=",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 225:this.$=new OpNode("?=",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 226:this.$=new OpNode("instanceof",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 227:this.$=new InNode($$[$0-3+1-1],$$[$0-3+3-1]);break;case 228:this.$=new OpNode("in",$$[$0-3+1-1],$$[$0-3+3-1]);break;case 229:this.$=new OpNode("!",new InNode($$[$0-4+1-1],$$[$0-4+4-1]));break;case 230:this.$=new OpNode("!",new ParentheticalNode(new OpNode("in",$$[$0-4+1-1],$$[$0-4+4-1])));break}},table:[{"1":[2,1],"3":1,"4":[1,2],"5":3,"6":4,"7":5,"8":7,"9":8,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"29":[1,6],"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[3]},{"1":[2,2],"28":90,"50":[1,56]},{"1":[2,3],"4":[1,91]},{"4":[1,92]},{"1":[2,5],"4":[2,5],"30":[2,5]},{"5":93,"7":5,"8":7,"9":8,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"30":[1,94],"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,8],"4":[2,8],"30":[2,8],"51":[1,134],"63":[1,133],"108":[2,8],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,9],"4":[2,9],"30":[2,9],"108":[2,9],"109":137,"110":[1,79],"112":[1,80],"115":138,"116":[1,82],"117":83,"131":[1,135],"132":[1,136]},{"1":[2,14],"4":[2,14],"29":[2,14],"30":[2,14],"51":[2,14],"59":[2,14],"63":[2,14],"65":140,"74":[1,142],"75":[1,143],"76":[1,144],"77":[1,145],"78":146,"79":147,"80":[1,148],"81":[2,14],"82":[1,149],"83":[1,150],"86":[2,14],"93":139,"94":[1,141],"96":[2,14],"100":[2,14],"108":[2,14],"110":[2,14],"111":[2,14],"112":[2,14],"116":[2,14],"122":[2,14],"123":[2,14],"124":[2,14],"131":[2,14],"132":[2,14],"133":[2,14],"135":[2,14],"136":[2,14],"138":[2,14],"139":[2,14],"142":[2,14],"143":[2,14],"144":[2,14],"145":[2,14],"146":[2,14],"147":[2,14],"148":[2,14],"149":[2,14],"150":[2,14],"151":[2,14],"152":[2,14],"153":[2,14],"154":[2,14],"155":[2,14],"156":[2,14],"157":[2,14],"158":[2,14],"159":[2,14],"160":[2,14],"161":[2,14],"162":[2,14],"163":[2,14],"164":[2,14],"165":[2,14],"166":[2,14],"167":[2,14],"168":[2,14]},{"1":[2,15],"4":[2,15],"29":[2,15],"30":[2,15],"51":[2,15],"59":[2,15],"63":[2,15],"81":[2,15],"86":[2,15],"96":[2,15],"100":[2,15],"108":[2,15],"110":[2,15],"111":[2,15],"112":[2,15],"116":[2,15],"122":[2,15],"123":[2,15],"124":[2,15],"131":[2,15],"132":[2,15],"133":[2,15],"135":[2,15],"136":[2,15],"138":[2,15],"139":[2,15],"142":[2,15],"143":[2,15],"144":[2,15],"145":[2,15],"146":[2,15],"147":[2,15],"148":[2,15],"149":[2,15],"150":[2,15],"151":[2,15],"152":[2,15],"153":[2,15],"154":[2,15],"155":[2,15],"156":[2,15],"157":[2,15],"158":[2,15],"159":[2,15],"160":[2,15],"161":[2,15],"162":[2,15],"163":[2,15],"164":[2,15],"165":[2,15],"166":[2,15],"167":[2,15],"168":[2,15]},{"1":[2,16],"4":[2,16],"29":[2,16],"30":[2,16],"51":[2,16],"59":[2,16],"63":[2,16],"81":[2,16],"86":[2,16],"96":[2,16],"100":[2,16],"108":[2,16],"110":[2,16],"111":[2,16],"112":[2,16],"116":[2,16],"122":[2,16],"123":[2,16],"124":[2,16],"131":[2,16],"132":[2,16],"133":[2,16],"135":[2,16],"136":[2,16],"138":[2,16],"139":[2,16],"142":[2,16],"143":[2,16],"144":[2,16],"145":[2,16],"146":[2,16],"147":[2,16],"148":[2,16],"149":[2,16],"150":[2,16],"151":[2,16],"152":[2,16],"153":[2,16],"154":[2,16],"155":[2,16],"156":[2,16],"157":[2,16],"158":[2,16],"159":[2,16],"160":[2,16],"161":[2,16],"162":[2,16],"163":[2,16],"164":[2,16],"165":[2,16],"166":[2,16],"167":[2,16],"168":[2,16]},{"1":[2,17],"4":[2,17],"29":[2,17],"30":[2,17],"51":[2,17],"59":[2,17],"63":[2,17],"81":[2,17],"86":[2,17],"96":[2,17],"100":[2,17],"108":[2,17],"110":[2,17],"111":[2,17],"112":[2,17],"116":[2,17],"122":[2,17],"123":[2,17],"124":[2,17],"131":[2,17],"132":[2,17],"133":[2,17],"135":[2,17],"136":[2,17],"138":[2,17],"139":[2,17],"142":[2,17],"143":[2,17],"144":[2,17],"145":[2,17],"146":[2,17],"147":[2,17],"148":[2,17],"149":[2,17],"150":[2,17],"151":[2,17],"152":[2,17],"153":[2,17],"154":[2,17],"155":[2,17],"156":[2,17],"157":[2,17],"158":[2,17],"159":[2,17],"160":[2,17],"161":[2,17],"162":[2,17],"163":[2,17],"164":[2,17],"165":[2,17],"166":[2,17],"167":[2,17],"168":[2,17]},{"1":[2,18],"4":[2,18],"29":[2,18],"30":[2,18],"51":[2,18],"59":[2,18],"63":[2,18],"81":[2,18],"86":[2,18],"96":[2,18],"100":[2,18],"108":[2,18],"110":[2,18],"111":[2,18],"112":[2,18],"116":[2,18],"122":[2,18],"123":[2,18],"124":[2,18],"131":[2,18],"132":[2,18],"133":[2,18],"135":[2,18],"136":[2,18],"138":[2,18],"139":[2,18],"142":[2,18],"143":[2,18],"144":[2,18],"145":[2,18],"146":[2,18],"147":[2,18],"148":[2,18],"149":[2,18],"150":[2,18],"151":[2,18],"152":[2,18],"153":[2,18],"154":[2,18],"155":[2,18],"156":[2,18],"157":[2,18],"158":[2,18],"159":[2,18],"160":[2,18],"161":[2,18],"162":[2,18],"163":[2,18],"164":[2,18],"165":[2,18],"166":[2,18],"167":[2,18],"168":[2,18]},{"1":[2,19],"4":[2,19],"29":[2,19],"30":[2,19],"51":[2,19],"59":[2,19],"63":[2,19],"81":[2,19],"86":[2,19],"96":[2,19],"100":[2,19],"108":[2,19],"110":[2,19],"111":[2,19],"112":[2,19],"116":[2,19],"122":[2,19],"123":[2,19],"124":[2,19],"131":[2,19],"132":[2,19],"133":[2,19],"135":[2,19],"136":[2,19],"138":[2,19],"139":[2,19],"142":[2,19],"143":[2,19],"144":[2,19],"145":[2,19],"146":[2,19],"147":[2,19],"148":[2,19],"149":[2,19],"150":[2,19],"151":[2,19],"152":[2,19],"153":[2,19],"154":[2,19],"155":[2,19],"156":[2,19],"157":[2,19],"158":[2,19],"159":[2,19],"160":[2,19],"161":[2,19],"162":[2,19],"163":[2,19],"164":[2,19],"165":[2,19],"166":[2,19],"167":[2,19],"168":[2,19]},{"1":[2,20],"4":[2,20],"29":[2,20],"30":[2,20],"51":[2,20],"59":[2,20],"63":[2,20],"81":[2,20],"86":[2,20],"96":[2,20],"100":[2,20],"108":[2,20],"110":[2,20],"111":[2,20],"112":[2,20],"116":[2,20],"122":[2,20],"123":[2,20],"124":[2,20],"131":[2,20],"132":[2,20],"133":[2,20],"135":[2,20],"136":[2,20],"138":[2,20],"139":[2,20],"142":[2,20],"143":[2,20],"144":[2,20],"145":[2,20],"146":[2,20],"147":[2,20],"148":[2,20],"149":[2,20],"150":[2,20],"151":[2,20],"152":[2,20],"153":[2,20],"154":[2,20],"155":[2,20],"156":[2,20],"157":[2,20],"158":[2,20],"159":[2,20],"160":[2,20],"161":[2,20],"162":[2,20],"163":[2,20],"164":[2,20],"165":[2,20],"166":[2,20],"167":[2,20],"168":[2,20]},{"1":[2,21],"4":[2,21],"29":[2,21],"30":[2,21],"51":[2,21],"59":[2,21],"63":[2,21],"81":[2,21],"86":[2,21],"96":[2,21],"100":[2,21],"108":[2,21],"110":[2,21],"111":[2,21],"112":[2,21],"116":[2,21],"122":[2,21],"123":[2,21],"124":[2,21],"131":[2,21],"132":[2,21],"133":[2,21],"135":[2,21],"136":[2,21],"138":[2,21],"139":[2,21],"142":[2,21],"143":[2,21],"144":[2,21],"145":[2,21],"146":[2,21],"147":[2,21],"148":[2,21],"149":[2,21],"150":[2,21],"151":[2,21],"152":[2,21],"153":[2,21],"154":[2,21],"155":[2,21],"156":[2,21],"157":[2,21],"158":[2,21],"159":[2,21],"160":[2,21],"161":[2,21],"162":[2,21],"163":[2,21],"164":[2,21],"165":[2,21],"166":[2,21],"167":[2,21],"168":[2,21]},{"1":[2,22],"4":[2,22],"29":[2,22],"30":[2,22],"51":[2,22],"59":[2,22],"63":[2,22],"81":[2,22],"86":[2,22],"96":[2,22],"100":[2,22],"108":[2,22],"110":[2,22],"111":[2,22],"112":[2,22],"116":[2,22],"122":[2,22],"123":[2,22],"124":[2,22],"131":[2,22],"132":[2,22],"133":[2,22],"135":[2,22],"136":[2,22],"138":[2,22],"139":[2,22],"142":[2,22],"143":[2,22],"144":[2,22],"145":[2,22],"146":[2,22],"147":[2,22],"148":[2,22],"149":[2,22],"150":[2,22],"151":[2,22],"152":[2,22],"153":[2,22],"154":[2,22],"155":[2,22],"156":[2,22],"157":[2,22],"158":[2,22],"159":[2,22],"160":[2,22],"161":[2,22],"162":[2,22],"163":[2,22],"164":[2,22],"165":[2,22],"166":[2,22],"167":[2,22],"168":[2,22]},{"1":[2,23],"4":[2,23],"29":[2,23],"30":[2,23],"51":[2,23],"59":[2,23],"63":[2,23],"81":[2,23],"86":[2,23],"96":[2,23],"100":[2,23],"108":[2,23],"110":[2,23],"111":[2,23],"112":[2,23],"116":[2,23],"122":[2,23],"123":[2,23],"124":[2,23],"131":[2,23],"132":[2,23],"133":[2,23],"135":[2,23],"136":[2,23],"138":[2,23],"139":[2,23],"142":[2,23],"143":[2,23],"144":[2,23],"145":[2,23],"146":[2,23],"147":[2,23],"148":[2,23],"149":[2,23],"150":[2,23],"151":[2,23],"152":[2,23],"153":[2,23],"154":[2,23],"155":[2,23],"156":[2,23],"157":[2,23],"158":[2,23],"159":[2,23],"160":[2,23],"161":[2,23],"162":[2,23],"163":[2,23],"164":[2,23],"165":[2,23],"166":[2,23],"167":[2,23],"168":[2,23]},{"1":[2,24],"4":[2,24],"29":[2,24],"30":[2,24],"51":[2,24],"59":[2,24],"63":[2,24],"81":[2,24],"86":[2,24],"96":[2,24],"100":[2,24],"108":[2,24],"110":[2,24],"111":[2,24],"112":[2,24],"116":[2,24],"122":[2,24],"123":[2,24],"124":[2,24],"131":[2,24],"132":[2,24],"133":[2,24],"135":[2,24],"136":[2,24],"138":[2,24],"139":[2,24],"142":[2,24],"143":[2,24],"144":[2,24],"145":[2,24],"146":[2,24],"147":[2,24],"148":[2,24],"149":[2,24],"150":[2,24],"151":[2,24],"152":[2,24],"153":[2,24],"154":[2,24],"155":[2,24],"156":[2,24],"157":[2,24],"158":[2,24],"159":[2,24],"160":[2,24],"161":[2,24],"162":[2,24],"163":[2,24],"164":[2,24],"165":[2,24],"166":[2,24],"167":[2,24],"168":[2,24]},{"1":[2,25],"4":[2,25],"29":[2,25],"30":[2,25],"51":[2,25],"59":[2,25],"63":[2,25],"81":[2,25],"86":[2,25],"96":[2,25],"100":[2,25],"108":[2,25],"110":[2,25],"111":[2,25],"112":[2,25],"116":[2,25],"122":[2,25],"123":[2,25],"124":[2,25],"131":[2,25],"132":[2,25],"133":[2,25],"135":[2,25],"136":[2,25],"138":[2,25],"139":[2,25],"142":[2,25],"143":[2,25],"144":[2,25],"145":[2,25],"146":[2,25],"147":[2,25],"148":[2,25],"149":[2,25],"150":[2,25],"151":[2,25],"152":[2,25],"153":[2,25],"154":[2,25],"155":[2,25],"156":[2,25],"157":[2,25],"158":[2,25],"159":[2,25],"160":[2,25],"161":[2,25],"162":[2,25],"163":[2,25],"164":[2,25],"165":[2,25],"166":[2,25],"167":[2,25],"168":[2,25]},{"1":[2,26],"4":[2,26],"29":[2,26],"30":[2,26],"51":[2,26],"59":[2,26],"63":[2,26],"81":[2,26],"86":[2,26],"96":[2,26],"100":[2,26],"108":[2,26],"110":[2,26],"111":[2,26],"112":[2,26],"116":[2,26],"122":[2,26],"123":[2,26],"124":[2,26],"131":[2,26],"132":[2,26],"133":[2,26],"135":[2,26],"136":[2,26],"138":[2,26],"139":[2,26],"142":[2,26],"143":[2,26],"144":[2,26],"145":[2,26],"146":[2,26],"147":[2,26],"148":[2,26],"149":[2,26],"150":[2,26],"151":[2,26],"152":[2,26],"153":[2,26],"154":[2,26],"155":[2,26],"156":[2,26],"157":[2,26],"158":[2,26],"159":[2,26],"160":[2,26],"161":[2,26],"162":[2,26],"163":[2,26],"164":[2,26],"165":[2,26],"166":[2,26],"167":[2,26],"168":[2,26]},{"1":[2,27],"4":[2,27],"29":[2,27],"30":[2,27],"51":[2,27],"59":[2,27],"63":[2,27],"81":[2,27],"86":[2,27],"96":[2,27],"100":[2,27],"108":[2,27],"110":[2,27],"111":[2,27],"112":[2,27],"116":[2,27],"122":[2,27],"123":[2,27],"124":[2,27],"131":[2,27],"132":[2,27],"133":[2,27],"135":[2,27],"136":[2,27],"138":[2,27],"139":[2,27],"142":[2,27],"143":[2,27],"144":[2,27],"145":[2,27],"146":[2,27],"147":[2,27],"148":[2,27],"149":[2,27],"150":[2,27],"151":[2,27],"152":[2,27],"153":[2,27],"154":[2,27],"155":[2,27],"156":[2,27],"157":[2,27],"158":[2,27],"159":[2,27],"160":[2,27],"161":[2,27],"162":[2,27],"163":[2,27],"164":[2,27],"165":[2,27],"166":[2,27],"167":[2,27],"168":[2,27]},{"1":[2,28],"4":[2,28],"29":[2,28],"30":[2,28],"51":[2,28],"59":[2,28],"63":[2,28],"81":[2,28],"86":[2,28],"96":[2,28],"100":[2,28],"108":[2,28],"110":[2,28],"111":[2,28],"112":[2,28],"116":[2,28],"122":[2,28],"123":[2,28],"124":[2,28],"131":[2,28],"132":[2,28],"133":[2,28],"135":[2,28],"136":[2,28],"138":[2,28],"139":[2,28],"142":[2,28],"143":[2,28],"144":[2,28],"145":[2,28],"146":[2,28],"147":[2,28],"148":[2,28],"149":[2,28],"150":[2,28],"151":[2,28],"152":[2,28],"153":[2,28],"154":[2,28],"155":[2,28],"156":[2,28],"157":[2,28],"158":[2,28],"159":[2,28],"160":[2,28],"161":[2,28],"162":[2,28],"163":[2,28],"164":[2,28],"165":[2,28],"166":[2,28],"167":[2,28],"168":[2,28]},{"1":[2,10],"4":[2,10],"30":[2,10],"108":[2,10],"110":[2,10],"112":[2,10],"116":[2,10],"131":[2,10],"132":[2,10]},{"1":[2,11],"4":[2,11],"30":[2,11],"108":[2,11],"110":[2,11],"112":[2,11],"116":[2,11],"131":[2,11],"132":[2,11]},{"1":[2,12],"4":[2,12],"30":[2,12],"108":[2,12],"110":[2,12],"112":[2,12],"116":[2,12],"131":[2,12],"132":[2,12]},{"1":[2,13],"4":[2,13],"30":[2,13],"108":[2,13],"110":[2,13],"112":[2,13],"116":[2,13],"131":[2,13],"132":[2,13]},{"1":[2,78],"4":[2,78],"29":[2,78],"30":[2,78],"46":[1,151],"51":[2,78],"59":[2,78],"63":[2,78],"74":[2,78],"75":[2,78],"76":[2,78],"77":[2,78],"80":[2,78],"81":[2,78],"82":[2,78],"83":[2,78],"86":[2,78],"94":[2,78],"96":[2,78],"100":[2,78],"108":[2,78],"110":[2,78],"111":[2,78],"112":[2,78],"116":[2,78],"122":[2,78],"123":[2,78],"124":[2,78],"131":[2,78],"132":[2,78],"133":[2,78],"135":[2,78],"136":[2,78],"138":[2,78],"139":[2,78],"142":[2,78],"143":[2,78],"144":[2,78],"145":[2,78],"146":[2,78],"147":[2,78],"148":[2,78],"149":[2,78],"150":[2,78],"151":[2,78],"152":[2,78],"153":[2,78],"154":[2,78],"155":[2,78],"156":[2,78],"157":[2,78],"158":[2,78],"159":[2,78],"160":[2,78],"161":[2,78],"162":[2,78],"163":[2,78],"164":[2,78],"165":[2,78],"166":[2,78],"167":[2,78],"168":[2,78]},{"1":[2,79],"4":[2,79],"29":[2,79],"30":[2,79],"51":[2,79],"59":[2,79],"63":[2,79],"74":[2,79],"75":[2,79],"76":[2,79],"77":[2,79],"80":[2,79],"81":[2,79],"82":[2,79],"83":[2,79],"86":[2,79],"94":[2,79],"96":[2,79],"100":[2,79],"108":[2,79],"110":[2,79],"111":[2,79],"112":[2,79],"116":[2,79],"122":[2,79],"123":[2,79],"124":[2,79],"131":[2,79],"132":[2,79],"133":[2,79],"135":[2,79],"136":[2,79],"138":[2,79],"139":[2,79],"142":[2,79],"143":[2,79],"144":[2,79],"145":[2,79],"146":[2,79],"147":[2,79],"148":[2,79],"149":[2,79],"150":[2,79],"151":[2,79],"152":[2,79],"153":[2,79],"154":[2,79],"155":[2,79],"156":[2,79],"157":[2,79],"158":[2,79],"159":[2,79],"160":[2,79],"161":[2,79],"162":[2,79],"163":[2,79],"164":[2,79],"165":[2,79],"166":[2,79],"167":[2,79],"168":[2,79]},{"1":[2,80],"4":[2,80],"29":[2,80],"30":[2,80],"51":[2,80],"59":[2,80],"63":[2,80],"74":[2,80],"75":[2,80],"76":[2,80],"77":[2,80],"80":[2,80],"81":[2,80],"82":[2,80],"83":[2,80],"86":[2,80],"94":[2,80],"96":[2,80],"100":[2,80],"108":[2,80],"110":[2,80],"111":[2,80],"112":[2,80],"116":[2,80],"122":[2,80],"123":[2,80],"124":[2,80],"131":[2,80],"132":[2,80],"133":[2,80],"135":[2,80],"136":[2,80],"138":[2,80],"139":[2,80],"142":[2,80],"143":[2,80],"144":[2,80],"145":[2,80],"146":[2,80],"147":[2,80],"148":[2,80],"149":[2,80],"150":[2,80],"151":[2,80],"152":[2,80],"153":[2,80],"154":[2,80],"155":[2,80],"156":[2,80],"157":[2,80],"158":[2,80],"159":[2,80],"160":[2,80],"161":[2,80],"162":[2,80],"163":[2,80],"164":[2,80],"165":[2,80],"166":[2,80],"167":[2,80],"168":[2,80]},{"1":[2,81],"4":[2,81],"29":[2,81],"30":[2,81],"51":[2,81],"59":[2,81],"63":[2,81],"74":[2,81],"75":[2,81],"76":[2,81],"77":[2,81],"80":[2,81],"81":[2,81],"82":[2,81],"83":[2,81],"86":[2,81],"94":[2,81],"96":[2,81],"100":[2,81],"108":[2,81],"110":[2,81],"111":[2,81],"112":[2,81],"116":[2,81],"122":[2,81],"123":[2,81],"124":[2,81],"131":[2,81],"132":[2,81],"133":[2,81],"135":[2,81],"136":[2,81],"138":[2,81],"139":[2,81],"142":[2,81],"143":[2,81],"144":[2,81],"145":[2,81],"146":[2,81],"147":[2,81],"148":[2,81],"149":[2,81],"150":[2,81],"151":[2,81],"152":[2,81],"153":[2,81],"154":[2,81],"155":[2,81],"156":[2,81],"157":[2,81],"158":[2,81],"159":[2,81],"160":[2,81],"161":[2,81],"162":[2,81],"163":[2,81],"164":[2,81],"165":[2,81],"166":[2,81],"167":[2,81],"168":[2,81]},{"1":[2,82],"4":[2,82],"29":[2,82],"30":[2,82],"51":[2,82],"59":[2,82],"63":[2,82],"74":[2,82],"75":[2,82],"76":[2,82],"77":[2,82],"80":[2,82],"81":[2,82],"82":[2,82],"83":[2,82],"86":[2,82],"94":[2,82],"96":[2,82],"100":[2,82],"108":[2,82],"110":[2,82],"111":[2,82],"112":[2,82],"116":[2,82],"122":[2,82],"123":[2,82],"124":[2,82],"131":[2,82],"132":[2,82],"133":[2,82],"135":[2,82],"136":[2,82],"138":[2,82],"139":[2,82],"142":[2,82],"143":[2,82],"144":[2,82],"145":[2,82],"146":[2,82],"147":[2,82],"148":[2,82],"149":[2,82],"150":[2,82],"151":[2,82],"152":[2,82],"153":[2,82],"154":[2,82],"155":[2,82],"156":[2,82],"157":[2,82],"158":[2,82],"159":[2,82],"160":[2,82],"161":[2,82],"162":[2,82],"163":[2,82],"164":[2,82],"165":[2,82],"166":[2,82],"167":[2,82],"168":[2,82]},{"1":[2,83],"4":[2,83],"29":[2,83],"30":[2,83],"51":[2,83],"59":[2,83],"63":[2,83],"74":[2,83],"75":[2,83],"76":[2,83],"77":[2,83],"80":[2,83],"81":[2,83],"82":[2,83],"83":[2,83],"86":[2,83],"94":[2,83],"96":[2,83],"100":[2,83],"108":[2,83],"110":[2,83],"111":[2,83],"112":[2,83],"116":[2,83],"122":[2,83],"123":[2,83],"124":[2,83],"131":[2,83],"132":[2,83],"133":[2,83],"135":[2,83],"136":[2,83],"138":[2,83],"139":[2,83],"142":[2,83],"143":[2,83],"144":[2,83],"145":[2,83],"146":[2,83],"147":[2,83],"148":[2,83],"149":[2,83],"150":[2,83],"151":[2,83],"152":[2,83],"153":[2,83],"154":[2,83],"155":[2,83],"156":[2,83],"157":[2,83],"158":[2,83],"159":[2,83],"160":[2,83],"161":[2,83],"162":[2,83],"163":[2,83],"164":[2,83],"165":[2,83],"166":[2,83],"167":[2,83],"168":[2,83]},{"1":[2,110],"4":[2,110],"29":[2,110],"30":[2,110],"51":[2,110],"59":[2,110],"63":[2,110],"65":153,"74":[1,142],"75":[1,143],"76":[1,144],"77":[1,145],"78":146,"79":147,"80":[1,148],"81":[2,110],"82":[1,149],"83":[1,150],"86":[2,110],"93":152,"94":[1,141],"96":[2,110],"100":[2,110],"108":[2,110],"110":[2,110],"111":[2,110],"112":[2,110],"116":[2,110],"122":[2,110],"123":[2,110],"124":[2,110],"131":[2,110],"132":[2,110],"133":[2,110],"135":[2,110],"136":[2,110],"138":[2,110],"139":[2,110],"142":[2,110],"143":[2,110],"144":[2,110],"145":[2,110],"146":[2,110],"147":[2,110],"148":[2,110],"149":[2,110],"150":[2,110],"151":[2,110],"152":[2,110],"153":[2,110],"154":[2,110],"155":[2,110],"156":[2,110],"157":[2,110],"158":[2,110],"159":[2,110],"160":[2,110],"161":[2,110],"162":[2,110],"163":[2,110],"164":[2,110],"165":[2,110],"166":[2,110],"167":[2,110],"168":[2,110]},{"1":[2,111],"4":[2,111],"29":[2,111],"30":[2,111],"51":[2,111],"59":[2,111],"63":[2,111],"81":[2,111],"86":[2,111],"96":[2,111],"100":[2,111],"108":[2,111],"110":[2,111],"111":[2,111],"112":[2,111],"116":[2,111],"122":[2,111],"123":[2,111],"124":[2,111],"131":[2,111],"132":[2,111],"133":[2,111],"135":[2,111],"136":[2,111],"138":[2,111],"139":[2,111],"142":[2,111],"143":[2,111],"144":[2,111],"145":[2,111],"146":[2,111],"147":[2,111],"148":[2,111],"149":[2,111],"150":[2,111],"151":[2,111],"152":[2,111],"153":[2,111],"154":[2,111],"155":[2,111],"156":[2,111],"157":[2,111],"158":[2,111],"159":[2,111],"160":[2,111],"161":[2,111],"162":[2,111],"163":[2,111],"164":[2,111],"165":[2,111],"166":[2,111],"167":[2,111],"168":[2,111]},{"14":155,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":156,"62":[1,73],"64":157,"66":154,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"98":[1,72],"99":[1,71],"107":[1,70]},{"53":158,"54":[2,63],"59":[2,63],"60":159,"61":[1,160],"62":[1,161]},{"4":[1,163],"6":162,"29":[1,6]},{"8":164,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":166,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":167,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":168,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":169,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":170,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":171,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":172,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":173,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,182],"4":[2,182],"29":[2,182],"30":[2,182],"51":[2,182],"59":[2,182],"63":[2,182],"81":[2,182],"86":[2,182],"96":[2,182],"100":[2,182],"108":[2,182],"110":[2,182],"111":[2,182],"112":[2,182],"116":[2,182],"122":[2,182],"123":[2,182],"124":[2,182],"127":[1,174],"131":[2,182],"132":[2,182],"133":[2,182],"135":[2,182],"136":[2,182],"138":[2,182],"139":[2,182],"142":[2,182],"143":[2,182],"144":[2,182],"145":[2,182],"146":[2,182],"147":[2,182],"148":[2,182],"149":[2,182],"150":[2,182],"151":[2,182],"152":[2,182],"153":[2,182],"154":[2,182],"155":[2,182],"156":[2,182],"157":[2,182],"158":[2,182],"159":[2,182],"160":[2,182],"161":[2,182],"162":[2,182],"163":[2,182],"164":[2,182],"165":[2,182],"166":[2,182],"167":[2,182],"168":[2,182]},{"4":[1,163],"6":175,"29":[1,6]},{"4":[1,163],"6":176,"29":[1,6]},{"1":[2,148],"4":[2,148],"29":[2,148],"30":[2,148],"51":[2,148],"59":[2,148],"63":[2,148],"81":[2,148],"86":[2,148],"96":[2,148],"100":[2,148],"108":[2,148],"110":[2,148],"111":[2,148],"112":[2,148],"116":[2,148],"122":[2,148],"123":[2,148],"124":[2,148],"131":[2,148],"132":[2,148],"133":[2,148],"135":[2,148],"136":[2,148],"138":[2,148],"139":[2,148],"142":[2,148],"143":[2,148],"144":[2,148],"145":[2,148],"146":[2,148],"147":[2,148],"148":[2,148],"149":[2,148],"150":[2,148],"151":[2,148],"152":[2,148],"153":[2,148],"154":[2,148],"155":[2,148],"156":[2,148],"157":[2,148],"158":[2,148],"159":[2,148],"160":[2,148],"161":[2,148],"162":[2,148],"163":[2,148],"164":[2,148],"165":[2,148],"166":[2,148],"167":[2,148],"168":[2,148]},{"4":[1,163],"6":177,"29":[1,6]},{"8":178,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"29":[1,179],"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,75],"4":[2,75],"29":[2,75],"30":[2,75],"46":[2,75],"51":[2,75],"59":[2,75],"63":[2,75],"74":[2,75],"75":[2,75],"76":[2,75],"77":[2,75],"80":[2,75],"81":[2,75],"82":[2,75],"83":[2,75],"86":[2,75],"88":[1,180],"94":[2,75],"96":[2,75],"100":[2,75],"108":[2,75],"110":[2,75],"111":[2,75],"112":[2,75],"116":[2,75],"122":[2,75],"123":[2,75],"124":[2,75],"131":[2,75],"132":[2,75],"133":[2,75],"135":[2,75],"136":[2,75],"138":[2,75],"139":[2,75],"142":[2,75],"143":[2,75],"144":[2,75],"145":[2,75],"146":[2,75],"147":[2,75],"148":[2,75],"149":[2,75],"150":[2,75],"151":[2,75],"152":[2,75],"153":[2,75],"154":[2,75],"155":[2,75],"156":[2,75],"157":[2,75],"158":[2,75],"159":[2,75],"160":[2,75],"161":[2,75],"162":[2,75],"163":[2,75],"164":[2,75],"165":[2,75],"166":[2,75],"167":[2,75],"168":[2,75]},{"14":183,"29":[1,182],"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":156,"62":[1,73],"64":181,"66":184,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"98":[1,72],"99":[1,71],"107":[1,70]},{"1":[2,55],"4":[2,55],"29":[2,55],"30":[2,55],"51":[2,55],"59":[2,55],"63":[2,55],"81":[2,55],"86":[2,55],"96":[2,55],"100":[2,55],"104":[2,55],"105":[2,55],"108":[2,55],"110":[2,55],"111":[2,55],"112":[2,55],"116":[2,55],"122":[2,55],"123":[2,55],"124":[2,55],"127":[2,55],"129":[2,55],"131":[2,55],"132":[2,55],"133":[2,55],"135":[2,55],"136":[2,55],"138":[2,55],"139":[2,55],"142":[2,55],"143":[2,55],"144":[2,55],"145":[2,55],"146":[2,55],"147":[2,55],"148":[2,55],"149":[2,55],"150":[2,55],"151":[2,55],"152":[2,55],"153":[2,55],"154":[2,55],"155":[2,55],"156":[2,55],"157":[2,55],"158":[2,55],"159":[2,55],"160":[2,55],"161":[2,55],"162":[2,55],"163":[2,55],"164":[2,55],"165":[2,55],"166":[2,55],"167":[2,55],"168":[2,55]},{"1":[2,54],"4":[2,54],"8":185,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"30":[2,54],"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"108":[2,54],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[2,54],"132":[2,54],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":186,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,76],"4":[2,76],"29":[2,76],"30":[2,76],"46":[2,76],"51":[2,76],"59":[2,76],"63":[2,76],"74":[2,76],"75":[2,76],"76":[2,76],"77":[2,76],"80":[2,76],"81":[2,76],"82":[2,76],"83":[2,76],"86":[2,76],"94":[2,76],"96":[2,76],"100":[2,76],"108":[2,76],"110":[2,76],"111":[2,76],"112":[2,76],"116":[2,76],"122":[2,76],"123":[2,76],"124":[2,76],"131":[2,76],"132":[2,76],"133":[2,76],"135":[2,76],"136":[2,76],"138":[2,76],"139":[2,76],"142":[2,76],"143":[2,76],"144":[2,76],"145":[2,76],"146":[2,76],"147":[2,76],"148":[2,76],"149":[2,76],"150":[2,76],"151":[2,76],"152":[2,76],"153":[2,76],"154":[2,76],"155":[2,76],"156":[2,76],"157":[2,76],"158":[2,76],"159":[2,76],"160":[2,76],"161":[2,76],"162":[2,76],"163":[2,76],"164":[2,76],"165":[2,76],"166":[2,76],"167":[2,76],"168":[2,76]},{"1":[2,77],"4":[2,77],"29":[2,77],"30":[2,77],"46":[2,77],"51":[2,77],"59":[2,77],"63":[2,77],"74":[2,77],"75":[2,77],"76":[2,77],"77":[2,77],"80":[2,77],"81":[2,77],"82":[2,77],"83":[2,77],"86":[2,77],"94":[2,77],"96":[2,77],"100":[2,77],"108":[2,77],"110":[2,77],"111":[2,77],"112":[2,77],"116":[2,77],"122":[2,77],"123":[2,77],"124":[2,77],"131":[2,77],"132":[2,77],"133":[2,77],"135":[2,77],"136":[2,77],"138":[2,77],"139":[2,77],"142":[2,77],"143":[2,77],"144":[2,77],"145":[2,77],"146":[2,77],"147":[2,77],"148":[2,77],"149":[2,77],"150":[2,77],"151":[2,77],"152":[2,77],"153":[2,77],"154":[2,77],"155":[2,77],"156":[2,77],"157":[2,77],"158":[2,77],"159":[2,77],"160":[2,77],"161":[2,77],"162":[2,77],"163":[2,77],"164":[2,77],"165":[2,77],"166":[2,77],"167":[2,77],"168":[2,77]},{"1":[2,35],"4":[2,35],"29":[2,35],"30":[2,35],"51":[2,35],"59":[2,35],"63":[2,35],"74":[2,35],"75":[2,35],"76":[2,35],"77":[2,35],"80":[2,35],"81":[2,35],"82":[2,35],"83":[2,35],"86":[2,35],"94":[2,35],"96":[2,35],"100":[2,35],"108":[2,35],"110":[2,35],"111":[2,35],"112":[2,35],"116":[2,35],"122":[2,35],"123":[2,35],"124":[2,35],"131":[2,35],"132":[2,35],"133":[2,35],"135":[2,35],"136":[2,35],"138":[2,35],"139":[2,35],"142":[2,35],"143":[2,35],"144":[2,35],"145":[2,35],"146":[2,35],"147":[2,35],"148":[2,35],"149":[2,35],"150":[2,35],"151":[2,35],"152":[2,35],"153":[2,35],"154":[2,35],"155":[2,35],"156":[2,35],"157":[2,35],"158":[2,35],"159":[2,35],"160":[2,35],"161":[2,35],"162":[2,35],"163":[2,35],"164":[2,35],"165":[2,35],"166":[2,35],"167":[2,35],"168":[2,35]},{"1":[2,36],"4":[2,36],"29":[2,36],"30":[2,36],"51":[2,36],"59":[2,36],"63":[2,36],"74":[2,36],"75":[2,36],"76":[2,36],"77":[2,36],"80":[2,36],"81":[2,36],"82":[2,36],"83":[2,36],"86":[2,36],"94":[2,36],"96":[2,36],"100":[2,36],"108":[2,36],"110":[2,36],"111":[2,36],"112":[2,36],"116":[2,36],"122":[2,36],"123":[2,36],"124":[2,36],"131":[2,36],"132":[2,36],"133":[2,36],"135":[2,36],"136":[2,36],"138":[2,36],"139":[2,36],"142":[2,36],"143":[2,36],"144":[2,36],"145":[2,36],"146":[2,36],"147":[2,36],"148":[2,36],"149":[2,36],"150":[2,36],"151":[2,36],"152":[2,36],"153":[2,36],"154":[2,36],"155":[2,36],"156":[2,36],"157":[2,36],"158":[2,36],"159":[2,36],"160":[2,36],"161":[2,36],"162":[2,36],"163":[2,36],"164":[2,36],"165":[2,36],"166":[2,36],"167":[2,36],"168":[2,36]},{"1":[2,37],"4":[2,37],"29":[2,37],"30":[2,37],"51":[2,37],"59":[2,37],"63":[2,37],"74":[2,37],"75":[2,37],"76":[2,37],"77":[2,37],"80":[2,37],"81":[2,37],"82":[2,37],"83":[2,37],"86":[2,37],"94":[2,37],"96":[2,37],"100":[2,37],"108":[2,37],"110":[2,37],"111":[2,37],"112":[2,37],"116":[2,37],"122":[2,37],"123":[2,37],"124":[2,37],"131":[2,37],"132":[2,37],"133":[2,37],"135":[2,37],"136":[2,37],"138":[2,37],"139":[2,37],"142":[2,37],"143":[2,37],"144":[2,37],"145":[2,37],"146":[2,37],"147":[2,37],"148":[2,37],"149":[2,37],"150":[2,37],"151":[2,37],"152":[2,37],"153":[2,37],"154":[2,37],"155":[2,37],"156":[2,37],"157":[2,37],"158":[2,37],"159":[2,37],"160":[2,37],"161":[2,37],"162":[2,37],"163":[2,37],"164":[2,37],"165":[2,37],"166":[2,37],"167":[2,37],"168":[2,37]},{"1":[2,38],"4":[2,38],"29":[2,38],"30":[2,38],"51":[2,38],"59":[2,38],"63":[2,38],"74":[2,38],"75":[2,38],"76":[2,38],"77":[2,38],"80":[2,38],"81":[2,38],"82":[2,38],"83":[2,38],"86":[2,38],"94":[2,38],"96":[2,38],"100":[2,38],"108":[2,38],"110":[2,38],"111":[2,38],"112":[2,38],"116":[2,38],"122":[2,38],"123":[2,38],"124":[2,38],"131":[2,38],"132":[2,38],"133":[2,38],"135":[2,38],"136":[2,38],"138":[2,38],"139":[2,38],"142":[2,38],"143":[2,38],"144":[2,38],"145":[2,38],"146":[2,38],"147":[2,38],"148":[2,38],"149":[2,38],"150":[2,38],"151":[2,38],"152":[2,38],"153":[2,38],"154":[2,38],"155":[2,38],"156":[2,38],"157":[2,38],"158":[2,38],"159":[2,38],"160":[2,38],"161":[2,38],"162":[2,38],"163":[2,38],"164":[2,38],"165":[2,38],"166":[2,38],"167":[2,38],"168":[2,38]},{"1":[2,39],"4":[2,39],"29":[2,39],"30":[2,39],"51":[2,39],"59":[2,39],"63":[2,39],"74":[2,39],"75":[2,39],"76":[2,39],"77":[2,39],"80":[2,39],"81":[2,39],"82":[2,39],"83":[2,39],"86":[2,39],"94":[2,39],"96":[2,39],"100":[2,39],"108":[2,39],"110":[2,39],"111":[2,39],"112":[2,39],"116":[2,39],"122":[2,39],"123":[2,39],"124":[2,39],"131":[2,39],"132":[2,39],"133":[2,39],"135":[2,39],"136":[2,39],"138":[2,39],"139":[2,39],"142":[2,39],"143":[2,39],"144":[2,39],"145":[2,39],"146":[2,39],"147":[2,39],"148":[2,39],"149":[2,39],"150":[2,39],"151":[2,39],"152":[2,39],"153":[2,39],"154":[2,39],"155":[2,39],"156":[2,39],"157":[2,39],"158":[2,39],"159":[2,39],"160":[2,39],"161":[2,39],"162":[2,39],"163":[2,39],"164":[2,39],"165":[2,39],"166":[2,39],"167":[2,39],"168":[2,39]},{"1":[2,40],"4":[2,40],"29":[2,40],"30":[2,40],"51":[2,40],"59":[2,40],"63":[2,40],"74":[2,40],"75":[2,40],"76":[2,40],"77":[2,40],"80":[2,40],"81":[2,40],"82":[2,40],"83":[2,40],"86":[2,40],"94":[2,40],"96":[2,40],"100":[2,40],"108":[2,40],"110":[2,40],"111":[2,40],"112":[2,40],"116":[2,40],"122":[2,40],"123":[2,40],"124":[2,40],"131":[2,40],"132":[2,40],"133":[2,40],"135":[2,40],"136":[2,40],"138":[2,40],"139":[2,40],"142":[2,40],"143":[2,40],"144":[2,40],"145":[2,40],"146":[2,40],"147":[2,40],"148":[2,40],"149":[2,40],"150":[2,40],"151":[2,40],"152":[2,40],"153":[2,40],"154":[2,40],"155":[2,40],"156":[2,40],"157":[2,40],"158":[2,40],"159":[2,40],"160":[2,40],"161":[2,40],"162":[2,40],"163":[2,40],"164":[2,40],"165":[2,40],"166":[2,40],"167":[2,40],"168":[2,40]},{"1":[2,41],"4":[2,41],"29":[2,41],"30":[2,41],"51":[2,41],"59":[2,41],"63":[2,41],"74":[2,41],"75":[2,41],"76":[2,41],"77":[2,41],"80":[2,41],"81":[2,41],"82":[2,41],"83":[2,41],"86":[2,41],"94":[2,41],"96":[2,41],"100":[2,41],"108":[2,41],"110":[2,41],"111":[2,41],"112":[2,41],"116":[2,41],"122":[2,41],"123":[2,41],"124":[2,41],"131":[2,41],"132":[2,41],"133":[2,41],"135":[2,41],"136":[2,41],"138":[2,41],"139":[2,41],"142":[2,41],"143":[2,41],"144":[2,41],"145":[2,41],"146":[2,41],"147":[2,41],"148":[2,41],"149":[2,41],"150":[2,41],"151":[2,41],"152":[2,41],"153":[2,41],"154":[2,41],"155":[2,41],"156":[2,41],"157":[2,41],"158":[2,41],"159":[2,41],"160":[2,41],"161":[2,41],"162":[2,41],"163":[2,41],"164":[2,41],"165":[2,41],"166":[2,41],"167":[2,41],"168":[2,41]},{"1":[2,42],"4":[2,42],"29":[2,42],"30":[2,42],"51":[2,42],"59":[2,42],"63":[2,42],"74":[2,42],"75":[2,42],"76":[2,42],"77":[2,42],"80":[2,42],"81":[2,42],"82":[2,42],"83":[2,42],"86":[2,42],"94":[2,42],"96":[2,42],"100":[2,42],"108":[2,42],"110":[2,42],"111":[2,42],"112":[2,42],"116":[2,42],"122":[2,42],"123":[2,42],"124":[2,42],"131":[2,42],"132":[2,42],"133":[2,42],"135":[2,42],"136":[2,42],"138":[2,42],"139":[2,42],"142":[2,42],"143":[2,42],"144":[2,42],"145":[2,42],"146":[2,42],"147":[2,42],"148":[2,42],"149":[2,42],"150":[2,42],"151":[2,42],"152":[2,42],"153":[2,42],"154":[2,42],"155":[2,42],"156":[2,42],"157":[2,42],"158":[2,42],"159":[2,42],"160":[2,42],"161":[2,42],"162":[2,42],"163":[2,42],"164":[2,42],"165":[2,42],"166":[2,42],"167":[2,42],"168":[2,42]},{"1":[2,43],"4":[2,43],"29":[2,43],"30":[2,43],"51":[2,43],"59":[2,43],"63":[2,43],"74":[2,43],"75":[2,43],"76":[2,43],"77":[2,43],"80":[2,43],"81":[2,43],"82":[2,43],"83":[2,43],"86":[2,43],"94":[2,43],"96":[2,43],"100":[2,43],"108":[2,43],"110":[2,43],"111":[2,43],"112":[2,43],"116":[2,43],"122":[2,43],"123":[2,43],"124":[2,43],"131":[2,43],"132":[2,43],"133":[2,43],"135":[2,43],"136":[2,43],"138":[2,43],"139":[2,43],"142":[2,43],"143":[2,43],"144":[2,43],"145":[2,43],"146":[2,43],"147":[2,43],"148":[2,43],"149":[2,43],"150":[2,43],"151":[2,43],"152":[2,43],"153":[2,43],"154":[2,43],"155":[2,43],"156":[2,43],"157":[2,43],"158":[2,43],"159":[2,43],"160":[2,43],"161":[2,43],"162":[2,43],"163":[2,43],"164":[2,43],"165":[2,43],"166":[2,43],"167":[2,43],"168":[2,43]},{"7":187,"8":7,"9":8,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"4":[2,128],"8":188,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"29":[2,128],"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"59":[2,128],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"95":189,"97":[1,74],"98":[1,72],"99":[1,71],"100":[2,128],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,120],"4":[2,120],"29":[2,120],"30":[2,120],"51":[2,120],"59":[2,120],"63":[2,120],"74":[2,120],"75":[2,120],"76":[2,120],"77":[2,120],"80":[2,120],"81":[2,120],"82":[2,120],"83":[2,120],"86":[2,120],"94":[2,120],"96":[2,120],"100":[2,120],"108":[2,120],"110":[2,120],"111":[2,120],"112":[2,120],"116":[2,120],"122":[2,120],"123":[2,120],"124":[2,120],"131":[2,120],"132":[2,120],"133":[2,120],"135":[2,120],"136":[2,120],"138":[2,120],"139":[2,120],"142":[2,120],"143":[2,120],"144":[2,120],"145":[2,120],"146":[2,120],"147":[2,120],"148":[2,120],"149":[2,120],"150":[2,120],"151":[2,120],"152":[2,120],"153":[2,120],"154":[2,120],"155":[2,120],"156":[2,120],"157":[2,120],"158":[2,120],"159":[2,120],"160":[2,120],"161":[2,120],"162":[2,120],"163":[2,120],"164":[2,120],"165":[2,120],"166":[2,120],"167":[2,120],"168":[2,120]},{"1":[2,121],"4":[2,121],"29":[2,121],"30":[2,121],"31":190,"32":[1,89],"51":[2,121],"59":[2,121],"63":[2,121],"74":[2,121],"75":[2,121],"76":[2,121],"77":[2,121],"80":[2,121],"81":[2,121],"82":[2,121],"83":[2,121],"86":[2,121],"94":[2,121],"96":[2,121],"100":[2,121],"108":[2,121],"110":[2,121],"111":[2,121],"112":[2,121],"116":[2,121],"122":[2,121],"123":[2,121],"124":[2,121],"131":[2,121],"132":[2,121],"133":[2,121],"135":[2,121],"136":[2,121],"138":[2,121],"139":[2,121],"142":[2,121],"143":[2,121],"144":[2,121],"145":[2,121],"146":[2,121],"147":[2,121],"148":[2,121],"149":[2,121],"150":[2,121],"151":[2,121],"152":[2,121],"153":[2,121],"154":[2,121],"155":[2,121],"156":[2,121],"157":[2,121],"158":[2,121],"159":[2,121],"160":[2,121],"161":[2,121],"162":[2,121],"163":[2,121],"164":[2,121],"165":[2,121],"166":[2,121],"167":[2,121],"168":[2,121]},{"1":[2,118],"4":[2,118],"29":[2,118],"30":[2,118],"51":[2,118],"59":[2,118],"63":[2,118],"81":[2,118],"86":[2,118],"93":191,"94":[1,141],"96":[2,118],"100":[2,118],"108":[2,118],"110":[2,118],"111":[2,118],"112":[2,118],"116":[2,118],"122":[2,118],"123":[2,118],"124":[2,118],"131":[2,118],"132":[2,118],"133":[2,118],"135":[2,118],"136":[2,118],"138":[2,118],"139":[2,118],"142":[2,118],"143":[2,118],"144":[2,118],"145":[2,118],"146":[2,118],"147":[2,118],"148":[2,118],"149":[2,118],"150":[2,118],"151":[2,118],"152":[2,118],"153":[2,118],"154":[2,118],"155":[2,118],"156":[2,118],"157":[2,118],"158":[2,118],"159":[2,118],"160":[2,118],"161":[2,118],"162":[2,118],"163":[2,118],"164":[2,118],"165":[2,118],"166":[2,118],"167":[2,118],"168":[2,118]},{"4":[2,59],"29":[2,59]},{"4":[2,60],"29":[2,60]},{"8":192,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":193,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":194,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":195,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"4":[1,163],"6":196,"8":197,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"29":[1,6],"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"31":202,"32":[1,89],"68":203,"69":204,"71":198,"84":[1,86],"99":[1,71],"119":199,"120":[1,200],"121":201},{"118":205,"122":[1,206],"123":[1,207]},{"1":[2,71],"4":[2,71],"29":[2,71],"30":[2,71],"46":[2,71],"51":[2,71],"59":[2,71],"63":[2,71],"74":[2,71],"75":[2,71],"76":[2,71],"77":[2,71],"80":[2,71],"81":[2,71],"82":[2,71],"83":[2,71],"86":[2,71],"88":[2,71],"94":[2,71],"96":[2,71],"100":[2,71],"108":[2,71],"110":[2,71],"111":[2,71],"112":[2,71],"116":[2,71],"122":[2,71],"123":[2,71],"124":[2,71],"131":[2,71],"132":[2,71],"133":[2,71],"135":[2,71],"136":[2,71],"138":[2,71],"139":[2,71],"142":[2,71],"143":[2,71],"144":[2,71],"145":[2,71],"146":[2,71],"147":[2,71],"148":[2,71],"149":[2,71],"150":[2,71],"151":[2,71],"152":[2,71],"153":[2,71],"154":[2,71],"155":[2,71],"156":[2,71],"157":[2,71],"158":[2,71],"159":[2,71],"160":[2,71],"161":[2,71],"162":[2,71],"163":[2,71],"164":[2,71],"165":[2,71],"166":[2,71],"167":[2,71],"168":[2,71]},{"1":[2,74],"4":[2,74],"29":[2,74],"30":[2,74],"46":[2,74],"51":[2,74],"59":[2,74],"63":[2,74],"74":[2,74],"75":[2,74],"76":[2,74],"77":[2,74],"80":[2,74],"81":[2,74],"82":[2,74],"83":[2,74],"86":[2,74],"88":[2,74],"94":[2,74],"96":[2,74],"100":[2,74],"108":[2,74],"110":[2,74],"111":[2,74],"112":[2,74],"116":[2,74],"122":[2,74],"123":[2,74],"124":[2,74],"131":[2,74],"132":[2,74],"133":[2,74],"135":[2,74],"136":[2,74],"138":[2,74],"139":[2,74],"142":[2,74],"143":[2,74],"144":[2,74],"145":[2,74],"146":[2,74],"147":[2,74],"148":[2,74],"149":[2,74],"150":[2,74],"151":[2,74],"152":[2,74],"153":[2,74],"154":[2,74],"155":[2,74],"156":[2,74],"157":[2,74],"158":[2,74],"159":[2,74],"160":[2,74],"161":[2,74],"162":[2,74],"163":[2,74],"164":[2,74],"165":[2,74],"166":[2,74],"167":[2,74],"168":[2,74]},{"4":[2,94],"28":212,"29":[2,94],"31":210,"32":[1,89],"33":211,"34":[1,87],"35":[1,88],"47":209,"50":[1,56],"59":[2,94],"85":208,"86":[2,94]},{"1":[2,33],"4":[2,33],"29":[2,33],"30":[2,33],"48":[2,33],"51":[2,33],"59":[2,33],"63":[2,33],"74":[2,33],"75":[2,33],"76":[2,33],"77":[2,33],"80":[2,33],"81":[2,33],"82":[2,33],"83":[2,33],"86":[2,33],"94":[2,33],"96":[2,33],"100":[2,33],"108":[2,33],"110":[2,33],"111":[2,33],"112":[2,33],"116":[2,33],"122":[2,33],"123":[2,33],"124":[2,33],"131":[2,33],"132":[2,33],"133":[2,33],"135":[2,33],"136":[2,33],"138":[2,33],"139":[2,33],"142":[2,33],"143":[2,33],"144":[2,33],"145":[2,33],"146":[2,33],"147":[2,33],"148":[2,33],"149":[2,33],"150":[2,33],"151":[2,33],"152":[2,33],"153":[2,33],"154":[2,33],"155":[2,33],"156":[2,33],"157":[2,33],"158":[2,33],"159":[2,33],"160":[2,33],"161":[2,33],"162":[2,33],"163":[2,33],"164":[2,33],"165":[2,33],"166":[2,33],"167":[2,33],"168":[2,33]},{"1":[2,34],"4":[2,34],"29":[2,34],"30":[2,34],"48":[2,34],"51":[2,34],"59":[2,34],"63":[2,34],"74":[2,34],"75":[2,34],"76":[2,34],"77":[2,34],"80":[2,34],"81":[2,34],"82":[2,34],"83":[2,34],"86":[2,34],"94":[2,34],"96":[2,34],"100":[2,34],"108":[2,34],"110":[2,34],"111":[2,34],"112":[2,34],"116":[2,34],"122":[2,34],"123":[2,34],"124":[2,34],"131":[2,34],"132":[2,34],"133":[2,34],"135":[2,34],"136":[2,34],"138":[2,34],"139":[2,34],"142":[2,34],"143":[2,34],"144":[2,34],"145":[2,34],"146":[2,34],"147":[2,34],"148":[2,34],"149":[2,34],"150":[2,34],"151":[2,34],"152":[2,34],"153":[2,34],"154":[2,34],"155":[2,34],"156":[2,34],"157":[2,34],"158":[2,34],"159":[2,34],"160":[2,34],"161":[2,34],"162":[2,34],"163":[2,34],"164":[2,34],"165":[2,34],"166":[2,34],"167":[2,34],"168":[2,34]},{"1":[2,32],"4":[2,32],"29":[2,32],"30":[2,32],"46":[2,32],"48":[2,32],"51":[2,32],"59":[2,32],"63":[2,32],"74":[2,32],"75":[2,32],"76":[2,32],"77":[2,32],"80":[2,32],"81":[2,32],"82":[2,32],"83":[2,32],"86":[2,32],"88":[2,32],"94":[2,32],"96":[2,32],"100":[2,32],"108":[2,32],"110":[2,32],"111":[2,32],"112":[2,32],"116":[2,32],"122":[2,32],"123":[2,32],"124":[2,32],"131":[2,32],"132":[2,32],"133":[2,32],"135":[2,32],"136":[2,32],"138":[2,32],"139":[2,32],"142":[2,32],"143":[2,32],"144":[2,32],"145":[2,32],"146":[2,32],"147":[2,32],"148":[2,32],"149":[2,32],"150":[2,32],"151":[2,32],"152":[2,32],"153":[2,32],"154":[2,32],"155":[2,32],"156":[2,32],"157":[2,32],"158":[2,32],"159":[2,32],"160":[2,32],"161":[2,32],"162":[2,32],"163":[2,32],"164":[2,32],"165":[2,32],"166":[2,32],"167":[2,32],"168":[2,32]},{"1":[2,31],"4":[2,31],"29":[2,31],"30":[2,31],"51":[2,31],"59":[2,31],"63":[2,31],"81":[2,31],"86":[2,31],"96":[2,31],"100":[2,31],"104":[2,31],"105":[2,31],"108":[2,31],"110":[2,31],"111":[2,31],"112":[2,31],"116":[2,31],"122":[2,31],"123":[2,31],"124":[2,31],"127":[2,31],"129":[2,31],"131":[2,31],"132":[2,31],"133":[2,31],"135":[2,31],"136":[2,31],"138":[2,31],"139":[2,31],"142":[2,31],"143":[2,31],"144":[2,31],"145":[2,31],"146":[2,31],"147":[2,31],"148":[2,31],"149":[2,31],"150":[2,31],"151":[2,31],"152":[2,31],"153":[2,31],"154":[2,31],"155":[2,31],"156":[2,31],"157":[2,31],"158":[2,31],"159":[2,31],"160":[2,31],"161":[2,31],"162":[2,31],"163":[2,31],"164":[2,31],"165":[2,31],"166":[2,31],"167":[2,31],"168":[2,31]},{"1":[2,7],"4":[2,7],"7":213,"8":7,"9":8,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"30":[2,7],"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,4]},{"4":[1,91],"30":[1,214]},{"1":[2,30],"4":[2,30],"29":[2,30],"30":[2,30],"51":[2,30],"59":[2,30],"63":[2,30],"81":[2,30],"86":[2,30],"96":[2,30],"100":[2,30],"104":[2,30],"105":[2,30],"108":[2,30],"110":[2,30],"111":[2,30],"112":[2,30],"116":[2,30],"122":[2,30],"123":[2,30],"124":[2,30],"127":[2,30],"129":[2,30],"131":[2,30],"132":[2,30],"133":[2,30],"135":[2,30],"136":[2,30],"138":[2,30],"139":[2,30],"142":[2,30],"143":[2,30],"144":[2,30],"145":[2,30],"146":[2,30],"147":[2,30],"148":[2,30],"149":[2,30],"150":[2,30],"151":[2,30],"152":[2,30],"153":[2,30],"154":[2,30],"155":[2,30],"156":[2,30],"157":[2,30],"158":[2,30],"159":[2,30],"160":[2,30],"161":[2,30],"162":[2,30],"163":[2,30],"164":[2,30],"165":[2,30],"166":[2,30],"167":[2,30],"168":[2,30]},{"1":[2,196],"4":[2,196],"29":[2,196],"30":[2,196],"51":[2,196],"59":[2,196],"63":[2,196],"81":[2,196],"86":[2,196],"96":[2,196],"100":[2,196],"108":[2,196],"110":[2,196],"111":[2,196],"112":[2,196],"116":[2,196],"122":[2,196],"123":[2,196],"124":[2,196],"131":[2,196],"132":[2,196],"133":[2,196],"135":[2,196],"136":[2,196],"138":[2,196],"139":[2,196],"142":[2,196],"143":[2,196],"144":[2,196],"145":[2,196],"146":[2,196],"147":[2,196],"148":[2,196],"149":[2,196],"150":[2,196],"151":[2,196],"152":[2,196],"153":[2,196],"154":[2,196],"155":[2,196],"156":[2,196],"157":[2,196],"158":[2,196],"159":[2,196],"160":[2,196],"161":[2,196],"162":[2,196],"163":[2,196],"164":[2,196],"165":[2,196],"166":[2,196],"167":[2,196],"168":[2,196]},{"1":[2,197],"4":[2,197],"29":[2,197],"30":[2,197],"51":[2,197],"59":[2,197],"63":[2,197],"81":[2,197],"86":[2,197],"96":[2,197],"100":[2,197],"108":[2,197],"110":[2,197],"111":[2,197],"112":[2,197],"116":[2,197],"122":[2,197],"123":[2,197],"124":[2,197],"131":[2,197],"132":[2,197],"133":[2,197],"135":[2,197],"136":[2,197],"138":[2,197],"139":[2,197],"142":[2,197],"143":[2,197],"144":[2,197],"145":[2,197],"146":[2,197],"147":[2,197],"148":[2,197],"149":[2,197],"150":[2,197],"151":[2,197],"152":[2,197],"153":[2,197],"154":[2,197],"155":[2,197],"156":[2,197],"157":[2,197],"158":[2,197],"159":[2,197],"160":[2,197],"161":[2,197],"162":[2,197],"163":[2,197],"164":[2,197],"165":[2,197],"166":[2,197],"167":[2,197],"168":[2,197]},{"8":215,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":216,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":217,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":218,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":219,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":220,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":221,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":222,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":223,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":224,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":225,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":226,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":227,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":228,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":229,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":230,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":231,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":232,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":233,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":234,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":235,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":236,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":237,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":238,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":239,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":240,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":241,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":242,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":243,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":244,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":245,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"122":[1,246],"123":[1,247]},{"8":248,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":249,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,147],"4":[2,147],"29":[2,147],"30":[2,147],"51":[2,147],"59":[2,147],"63":[2,147],"81":[2,147],"86":[2,147],"96":[2,147],"100":[2,147],"108":[2,147],"110":[2,147],"111":[2,147],"112":[2,147],"116":[2,147],"122":[2,147],"123":[2,147],"124":[2,147],"131":[2,147],"132":[2,147],"133":[2,147],"135":[2,147],"136":[2,147],"138":[2,147],"139":[2,147],"142":[2,147],"143":[2,147],"144":[2,147],"145":[2,147],"146":[2,147],"147":[2,147],"148":[2,147],"149":[2,147],"150":[2,147],"151":[2,147],"152":[2,147],"153":[2,147],"154":[2,147],"155":[2,147],"156":[2,147],"157":[2,147],"158":[2,147],"159":[2,147],"160":[2,147],"161":[2,147],"162":[2,147],"163":[2,147],"164":[2,147],"165":[2,147],"166":[2,147],"167":[2,147],"168":[2,147]},{"1":[2,152],"4":[2,152],"29":[2,152],"30":[2,152],"51":[2,152],"59":[2,152],"63":[2,152],"81":[2,152],"86":[2,152],"96":[2,152],"100":[2,152],"108":[2,152],"110":[2,152],"111":[2,152],"112":[2,152],"116":[2,152],"122":[2,152],"123":[2,152],"124":[2,152],"131":[2,152],"132":[2,152],"133":[2,152],"135":[2,152],"136":[2,152],"138":[2,152],"139":[2,152],"142":[2,152],"143":[2,152],"144":[2,152],"145":[2,152],"146":[2,152],"147":[2,152],"148":[2,152],"149":[2,152],"150":[2,152],"151":[2,152],"152":[2,152],"153":[2,152],"154":[2,152],"155":[2,152],"156":[2,152],"157":[2,152],"158":[2,152],"159":[2,152],"160":[2,152],"161":[2,152],"162":[2,152],"163":[2,152],"164":[2,152],"165":[2,152],"166":[2,152],"167":[2,152],"168":[2,152]},{"63":[1,250]},{"1":[2,56],"4":[2,56],"29":[2,56],"30":[2,56],"51":[2,56],"59":[2,56],"63":[2,56],"81":[2,56],"86":[2,56],"96":[2,56],"100":[2,56],"108":[2,56],"110":[2,56],"111":[2,56],"112":[2,56],"116":[2,56],"122":[2,56],"123":[2,56],"124":[2,56],"131":[2,56],"132":[2,56],"133":[2,56],"135":[2,56],"136":[2,56],"138":[2,56],"139":[2,56],"142":[2,56],"143":[2,56],"144":[2,56],"145":[2,56],"146":[2,56],"147":[2,56],"148":[2,56],"149":[2,56],"150":[2,56],"151":[2,56],"152":[2,56],"153":[2,56],"154":[2,56],"155":[2,56],"156":[2,56],"157":[2,56],"158":[2,56],"159":[2,56],"160":[2,56],"161":[2,56],"162":[2,56],"163":[2,56],"164":[2,56],"165":[2,56],"166":[2,56],"167":[2,56],"168":[2,56]},{"8":251,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":252,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,146],"4":[2,146],"29":[2,146],"30":[2,146],"51":[2,146],"59":[2,146],"63":[2,146],"81":[2,146],"86":[2,146],"96":[2,146],"100":[2,146],"108":[2,146],"110":[2,146],"111":[2,146],"112":[2,146],"116":[2,146],"122":[2,146],"123":[2,146],"124":[2,146],"131":[2,146],"132":[2,146],"133":[2,146],"135":[2,146],"136":[2,146],"138":[2,146],"139":[2,146],"142":[2,146],"143":[2,146],"144":[2,146],"145":[2,146],"146":[2,146],"147":[2,146],"148":[2,146],"149":[2,146],"150":[2,146],"151":[2,146],"152":[2,146],"153":[2,146],"154":[2,146],"155":[2,146],"156":[2,146],"157":[2,146],"158":[2,146],"159":[2,146],"160":[2,146],"161":[2,146],"162":[2,146],"163":[2,146],"164":[2,146],"165":[2,146],"166":[2,146],"167":[2,146],"168":[2,146]},{"1":[2,151],"4":[2,151],"29":[2,151],"30":[2,151],"51":[2,151],"59":[2,151],"63":[2,151],"81":[2,151],"86":[2,151],"96":[2,151],"100":[2,151],"108":[2,151],"110":[2,151],"111":[2,151],"112":[2,151],"116":[2,151],"122":[2,151],"123":[2,151],"124":[2,151],"131":[2,151],"132":[2,151],"133":[2,151],"135":[2,151],"136":[2,151],"138":[2,151],"139":[2,151],"142":[2,151],"143":[2,151],"144":[2,151],"145":[2,151],"146":[2,151],"147":[2,151],"148":[2,151],"149":[2,151],"150":[2,151],"151":[2,151],"152":[2,151],"153":[2,151],"154":[2,151],"155":[2,151],"156":[2,151],"157":[2,151],"158":[2,151],"159":[2,151],"160":[2,151],"161":[2,151],"162":[2,151],"163":[2,151],"164":[2,151],"165":[2,151],"166":[2,151],"167":[2,151],"168":[2,151]},{"1":[2,115],"4":[2,115],"29":[2,115],"30":[2,115],"51":[2,115],"59":[2,115],"63":[2,115],"74":[2,115],"75":[2,115],"76":[2,115],"77":[2,115],"80":[2,115],"81":[2,115],"82":[2,115],"83":[2,115],"86":[2,115],"94":[2,115],"96":[2,115],"100":[2,115],"108":[2,115],"110":[2,115],"111":[2,115],"112":[2,115],"116":[2,115],"122":[2,115],"123":[2,115],"124":[2,115],"131":[2,115],"132":[2,115],"133":[2,115],"135":[2,115],"136":[2,115],"138":[2,115],"139":[2,115],"142":[2,115],"143":[2,115],"144":[2,115],"145":[2,115],"146":[2,115],"147":[2,115],"148":[2,115],"149":[2,115],"150":[2,115],"151":[2,115],"152":[2,115],"153":[2,115],"154":[2,115],"155":[2,115],"156":[2,115],"157":[2,115],"158":[2,115],"159":[2,115],"160":[2,115],"161":[2,115],"162":[2,115],"163":[2,115],"164":[2,115],"165":[2,115],"166":[2,115],"167":[2,115],"168":[2,115]},{"1":[2,72],"4":[2,72],"29":[2,72],"30":[2,72],"46":[2,72],"51":[2,72],"59":[2,72],"63":[2,72],"74":[2,72],"75":[2,72],"76":[2,72],"77":[2,72],"80":[2,72],"81":[2,72],"82":[2,72],"83":[2,72],"86":[2,72],"88":[2,72],"94":[2,72],"96":[2,72],"100":[2,72],"108":[2,72],"110":[2,72],"111":[2,72],"112":[2,72],"116":[2,72],"122":[2,72],"123":[2,72],"124":[2,72],"131":[2,72],"132":[2,72],"133":[2,72],"135":[2,72],"136":[2,72],"138":[2,72],"139":[2,72],"142":[2,72],"143":[2,72],"144":[2,72],"145":[2,72],"146":[2,72],"147":[2,72],"148":[2,72],"149":[2,72],"150":[2,72],"151":[2,72],"152":[2,72],"153":[2,72],"154":[2,72],"155":[2,72],"156":[2,72],"157":[2,72],"158":[2,72],"159":[2,72],"160":[2,72],"161":[2,72],"162":[2,72],"163":[2,72],"164":[2,72],"165":[2,72],"166":[2,72],"167":[2,72],"168":[2,72]},{"4":[2,128],"8":254,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"29":[2,128],"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"59":[2,128],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"95":253,"96":[2,128],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"31":255,"32":[1,89]},{"31":256,"32":[1,89]},{"1":[2,86],"4":[2,86],"29":[2,86],"30":[2,86],"46":[2,86],"51":[2,86],"59":[2,86],"63":[2,86],"74":[2,86],"75":[2,86],"76":[2,86],"77":[2,86],"80":[2,86],"81":[2,86],"82":[2,86],"83":[2,86],"86":[2,86],"88":[2,86],"94":[2,86],"96":[2,86],"100":[2,86],"108":[2,86],"110":[2,86],"111":[2,86],"112":[2,86],"116":[2,86],"122":[2,86],"123":[2,86],"124":[2,86],"131":[2,86],"132":[2,86],"133":[2,86],"135":[2,86],"136":[2,86],"138":[2,86],"139":[2,86],"142":[2,86],"143":[2,86],"144":[2,86],"145":[2,86],"146":[2,86],"147":[2,86],"148":[2,86],"149":[2,86],"150":[2,86],"151":[2,86],"152":[2,86],"153":[2,86],"154":[2,86],"155":[2,86],"156":[2,86],"157":[2,86],"158":[2,86],"159":[2,86],"160":[2,86],"161":[2,86],"162":[2,86],"163":[2,86],"164":[2,86],"165":[2,86],"166":[2,86],"167":[2,86],"168":[2,86]},{"31":257,"32":[1,89]},{"1":[2,88],"4":[2,88],"29":[2,88],"30":[2,88],"46":[2,88],"51":[2,88],"59":[2,88],"63":[2,88],"74":[2,88],"75":[2,88],"76":[2,88],"77":[2,88],"80":[2,88],"81":[2,88],"82":[2,88],"83":[2,88],"86":[2,88],"88":[2,88],"94":[2,88],"96":[2,88],"100":[2,88],"108":[2,88],"110":[2,88],"111":[2,88],"112":[2,88],"116":[2,88],"122":[2,88],"123":[2,88],"124":[2,88],"131":[2,88],"132":[2,88],"133":[2,88],"135":[2,88],"136":[2,88],"138":[2,88],"139":[2,88],"142":[2,88],"143":[2,88],"144":[2,88],"145":[2,88],"146":[2,88],"147":[2,88],"148":[2,88],"149":[2,88],"150":[2,88],"151":[2,88],"152":[2,88],"153":[2,88],"154":[2,88],"155":[2,88],"156":[2,88],"157":[2,88],"158":[2,88],"159":[2,88],"160":[2,88],"161":[2,88],"162":[2,88],"163":[2,88],"164":[2,88],"165":[2,88],"166":[2,88],"167":[2,88],"168":[2,88]},{"1":[2,89],"4":[2,89],"29":[2,89],"30":[2,89],"46":[2,89],"51":[2,89],"59":[2,89],"63":[2,89],"74":[2,89],"75":[2,89],"76":[2,89],"77":[2,89],"80":[2,89],"81":[2,89],"82":[2,89],"83":[2,89],"86":[2,89],"88":[2,89],"94":[2,89],"96":[2,89],"100":[2,89],"108":[2,89],"110":[2,89],"111":[2,89],"112":[2,89],"116":[2,89],"122":[2,89],"123":[2,89],"124":[2,89],"131":[2,89],"132":[2,89],"133":[2,89],"135":[2,89],"136":[2,89],"138":[2,89],"139":[2,89],"142":[2,89],"143":[2,89],"144":[2,89],"145":[2,89],"146":[2,89],"147":[2,89],"148":[2,89],"149":[2,89],"150":[2,89],"151":[2,89],"152":[2,89],"153":[2,89],"154":[2,89],"155":[2,89],"156":[2,89],"157":[2,89],"158":[2,89],"159":[2,89],"160":[2,89],"161":[2,89],"162":[2,89],"163":[2,89],"164":[2,89],"165":[2,89],"166":[2,89],"167":[2,89],"168":[2,89]},{"8":258,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"78":259,"80":[1,260],"82":[1,149],"83":[1,150]},{"78":261,"80":[1,260],"82":[1,149],"83":[1,150]},{"8":262,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"29":[1,263],"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,116],"4":[2,116],"29":[2,116],"30":[2,116],"51":[2,116],"59":[2,116],"63":[2,116],"74":[2,116],"75":[2,116],"76":[2,116],"77":[2,116],"80":[2,116],"81":[2,116],"82":[2,116],"83":[2,116],"86":[2,116],"94":[2,116],"96":[2,116],"100":[2,116],"108":[2,116],"110":[2,116],"111":[2,116],"112":[2,116],"116":[2,116],"122":[2,116],"123":[2,116],"124":[2,116],"131":[2,116],"132":[2,116],"133":[2,116],"135":[2,116],"136":[2,116],"138":[2,116],"139":[2,116],"142":[2,116],"143":[2,116],"144":[2,116],"145":[2,116],"146":[2,116],"147":[2,116],"148":[2,116],"149":[2,116],"150":[2,116],"151":[2,116],"152":[2,116],"153":[2,116],"154":[2,116],"155":[2,116],"156":[2,116],"157":[2,116],"158":[2,116],"159":[2,116],"160":[2,116],"161":[2,116],"162":[2,116],"163":[2,116],"164":[2,116],"165":[2,116],"166":[2,116],"167":[2,116],"168":[2,116]},{"1":[2,73],"4":[2,73],"29":[2,73],"30":[2,73],"46":[2,73],"51":[2,73],"59":[2,73],"63":[2,73],"74":[2,73],"75":[2,73],"76":[2,73],"77":[2,73],"80":[2,73],"81":[2,73],"82":[2,73],"83":[2,73],"86":[2,73],"88":[2,73],"94":[2,73],"96":[2,73],"100":[2,73],"108":[2,73],"110":[2,73],"111":[2,73],"112":[2,73],"116":[2,73],"122":[2,73],"123":[2,73],"124":[2,73],"131":[2,73],"132":[2,73],"133":[2,73],"135":[2,73],"136":[2,73],"138":[2,73],"139":[2,73],"142":[2,73],"143":[2,73],"144":[2,73],"145":[2,73],"146":[2,73],"147":[2,73],"148":[2,73],"149":[2,73],"150":[2,73],"151":[2,73],"152":[2,73],"153":[2,73],"154":[2,73],"155":[2,73],"156":[2,73],"157":[2,73],"158":[2,73],"159":[2,73],"160":[2,73],"161":[2,73],"162":[2,73],"163":[2,73],"164":[2,73],"165":[2,73],"166":[2,73],"167":[2,73],"168":[2,73]},{"1":[2,112],"4":[2,112],"29":[2,112],"30":[2,112],"51":[2,112],"59":[2,112],"63":[2,112],"65":153,"74":[1,142],"75":[1,143],"76":[1,144],"77":[1,145],"78":146,"79":147,"80":[1,148],"81":[2,112],"82":[1,149],"83":[1,150],"86":[2,112],"93":152,"94":[1,141],"96":[2,112],"100":[2,112],"108":[2,112],"110":[2,112],"111":[2,112],"112":[2,112],"116":[2,112],"122":[2,112],"123":[2,112],"124":[2,112],"131":[2,112],"132":[2,112],"133":[2,112],"135":[2,112],"136":[2,112],"138":[2,112],"139":[2,112],"142":[2,112],"143":[2,112],"144":[2,112],"145":[2,112],"146":[2,112],"147":[2,112],"148":[2,112],"149":[2,112],"150":[2,112],"151":[2,112],"152":[2,112],"153":[2,112],"154":[2,112],"155":[2,112],"156":[2,112],"157":[2,112],"158":[2,112],"159":[2,112],"160":[2,112],"161":[2,112],"162":[2,112],"163":[2,112],"164":[2,112],"165":[2,112],"166":[2,112],"167":[2,112],"168":[2,112]},{"1":[2,113],"4":[2,113],"29":[2,113],"30":[2,113],"51":[2,113],"59":[2,113],"63":[2,113],"65":140,"74":[1,142],"75":[1,143],"76":[1,144],"77":[1,145],"78":146,"79":147,"80":[1,148],"81":[2,113],"82":[1,149],"83":[1,150],"86":[2,113],"93":139,"94":[1,141],"96":[2,113],"100":[2,113],"108":[2,113],"110":[2,113],"111":[2,113],"112":[2,113],"116":[2,113],"122":[2,113],"123":[2,113],"124":[2,113],"131":[2,113],"132":[2,113],"133":[2,113],"135":[2,113],"136":[2,113],"138":[2,113],"139":[2,113],"142":[2,113],"143":[2,113],"144":[2,113],"145":[2,113],"146":[2,113],"147":[2,113],"148":[2,113],"149":[2,113],"150":[2,113],"151":[2,113],"152":[2,113],"153":[2,113],"154":[2,113],"155":[2,113],"156":[2,113],"157":[2,113],"158":[2,113],"159":[2,113],"160":[2,113],"161":[2,113],"162":[2,113],"163":[2,113],"164":[2,113],"165":[2,113],"166":[2,113],"167":[2,113],"168":[2,113]},{"1":[2,78],"4":[2,78],"29":[2,78],"30":[2,78],"51":[2,78],"59":[2,78],"63":[2,78],"74":[2,78],"75":[2,78],"76":[2,78],"77":[2,78],"80":[2,78],"81":[2,78],"82":[2,78],"83":[2,78],"86":[2,78],"94":[2,78],"96":[2,78],"100":[2,78],"108":[2,78],"110":[2,78],"111":[2,78],"112":[2,78],"116":[2,78],"122":[2,78],"123":[2,78],"124":[2,78],"131":[2,78],"132":[2,78],"133":[2,78],"135":[2,78],"136":[2,78],"138":[2,78],"139":[2,78],"142":[2,78],"143":[2,78],"144":[2,78],"145":[2,78],"146":[2,78],"147":[2,78],"148":[2,78],"149":[2,78],"150":[2,78],"151":[2,78],"152":[2,78],"153":[2,78],"154":[2,78],"155":[2,78],"156":[2,78],"157":[2,78],"158":[2,78],"159":[2,78],"160":[2,78],"161":[2,78],"162":[2,78],"163":[2,78],"164":[2,78],"165":[2,78],"166":[2,78],"167":[2,78],"168":[2,78]},{"1":[2,75],"4":[2,75],"29":[2,75],"30":[2,75],"51":[2,75],"59":[2,75],"63":[2,75],"74":[2,75],"75":[2,75],"76":[2,75],"77":[2,75],"80":[2,75],"81":[2,75],"82":[2,75],"83":[2,75],"86":[2,75],"94":[2,75],"96":[2,75],"100":[2,75],"108":[2,75],"110":[2,75],"111":[2,75],"112":[2,75],"116":[2,75],"122":[2,75],"123":[2,75],"124":[2,75],"131":[2,75],"132":[2,75],"133":[2,75],"135":[2,75],"136":[2,75],"138":[2,75],"139":[2,75],"142":[2,75],"143":[2,75],"144":[2,75],"145":[2,75],"146":[2,75],"147":[2,75],"148":[2,75],"149":[2,75],"150":[2,75],"151":[2,75],"152":[2,75],"153":[2,75],"154":[2,75],"155":[2,75],"156":[2,75],"157":[2,75],"158":[2,75],"159":[2,75],"160":[2,75],"161":[2,75],"162":[2,75],"163":[2,75],"164":[2,75],"165":[2,75],"166":[2,75],"167":[2,75],"168":[2,75]},{"54":[1,264],"59":[1,265]},{"54":[2,64],"59":[2,64]},{"54":[2,66],"59":[2,66],"63":[1,266]},{"61":[1,267]},{"1":[2,58],"4":[2,58],"29":[2,58],"30":[2,58],"51":[2,58],"59":[2,58],"63":[2,58],"81":[2,58],"86":[2,58],"96":[2,58],"100":[2,58],"108":[2,58],"110":[2,58],"111":[2,58],"112":[2,58],"116":[2,58],"122":[2,58],"123":[2,58],"124":[2,58],"131":[2,58],"132":[2,58],"133":[2,58],"135":[2,58],"136":[2,58],"138":[2,58],"139":[2,58],"142":[2,58],"143":[2,58],"144":[2,58],"145":[2,58],"146":[2,58],"147":[2,58],"148":[2,58],"149":[2,58],"150":[2,58],"151":[2,58],"152":[2,58],"153":[2,58],"154":[2,58],"155":[2,58],"156":[2,58],"157":[2,58],"158":[2,58],"159":[2,58],"160":[2,58],"161":[2,58],"162":[2,58],"163":[2,58],"164":[2,58],"165":[2,58],"166":[2,58],"167":[2,58],"168":[2,58]},{"28":90,"50":[1,56]},{"1":[2,187],"4":[2,187],"29":[2,187],"30":[2,187],"51":[1,134],"59":[2,187],"63":[2,187],"81":[2,187],"86":[2,187],"96":[2,187],"100":[2,187],"108":[2,187],"109":131,"110":[2,187],"111":[2,187],"112":[2,187],"115":132,"116":[2,187],"117":83,"122":[2,187],"123":[2,187],"124":[2,187],"131":[2,187],"132":[2,187],"135":[2,187],"136":[2,187],"142":[2,187],"143":[2,187],"144":[2,187],"145":[2,187],"146":[2,187],"147":[2,187],"148":[2,187],"149":[2,187],"150":[2,187],"151":[2,187],"152":[2,187],"153":[2,187],"154":[2,187],"155":[2,187],"156":[2,187],"157":[2,187],"158":[2,187],"159":[2,187],"160":[2,187],"161":[2,187],"162":[2,187],"163":[2,187],"164":[2,187],"165":[2,187],"166":[2,187],"167":[2,187],"168":[2,187]},{"109":137,"110":[1,79],"112":[1,80],"115":138,"116":[1,82],"117":83,"131":[1,135],"132":[1,136]},{"1":[2,188],"4":[2,188],"29":[2,188],"30":[2,188],"51":[1,134],"59":[2,188],"63":[2,188],"81":[2,188],"86":[2,188],"96":[2,188],"100":[2,188],"108":[2,188],"109":131,"110":[2,188],"111":[2,188],"112":[2,188],"115":132,"116":[2,188],"117":83,"122":[2,188],"123":[2,188],"124":[2,188],"131":[2,188],"132":[2,188],"135":[2,188],"136":[2,188],"142":[2,188],"143":[2,188],"144":[2,188],"145":[2,188],"146":[2,188],"147":[2,188],"148":[2,188],"149":[2,188],"150":[2,188],"151":[2,188],"152":[2,188],"153":[2,188],"154":[2,188],"155":[2,188],"156":[2,188],"157":[2,188],"158":[2,188],"159":[2,188],"160":[2,188],"161":[2,188],"162":[2,188],"163":[2,188],"164":[2,188],"165":[2,188],"166":[2,188],"167":[2,188],"168":[2,188]},{"1":[2,189],"4":[2,189],"29":[2,189],"30":[2,189],"51":[1,134],"59":[2,189],"63":[2,189],"81":[2,189],"86":[2,189],"96":[2,189],"100":[2,189],"108":[2,189],"109":131,"110":[2,189],"111":[2,189],"112":[2,189],"115":132,"116":[2,189],"117":83,"122":[2,189],"123":[2,189],"124":[2,189],"131":[2,189],"132":[2,189],"135":[2,189],"136":[2,189],"142":[2,189],"143":[2,189],"144":[2,189],"145":[2,189],"146":[2,189],"147":[2,189],"148":[2,189],"149":[2,189],"150":[2,189],"151":[2,189],"152":[2,189],"153":[2,189],"154":[2,189],"155":[2,189],"156":[2,189],"157":[2,189],"158":[2,189],"159":[2,189],"160":[2,189],"161":[2,189],"162":[2,189],"163":[2,189],"164":[2,189],"165":[2,189],"166":[2,189],"167":[2,189],"168":[2,189]},{"1":[2,190],"4":[2,190],"29":[2,190],"30":[2,190],"51":[1,134],"59":[2,190],"63":[2,190],"81":[2,190],"86":[2,190],"96":[2,190],"100":[2,190],"108":[2,190],"109":131,"110":[2,190],"111":[2,190],"112":[2,190],"115":132,"116":[2,190],"117":83,"122":[2,190],"123":[2,190],"124":[2,190],"131":[2,190],"132":[2,190],"135":[2,190],"136":[2,190],"142":[2,190],"143":[2,190],"144":[2,190],"145":[2,190],"146":[2,190],"147":[2,190],"148":[2,190],"149":[2,190],"150":[2,190],"151":[2,190],"152":[2,190],"153":[2,190],"154":[2,190],"155":[2,190],"156":[2,190],"157":[2,190],"158":[2,190],"159":[2,190],"160":[2,190],"161":[2,190],"162":[2,190],"163":[2,190],"164":[2,190],"165":[2,190],"166":[2,190],"167":[2,190],"168":[2,190]},{"1":[2,191],"4":[2,191],"29":[2,191],"30":[2,191],"51":[1,134],"59":[2,191],"63":[2,191],"81":[2,191],"86":[2,191],"96":[2,191],"100":[2,191],"108":[2,191],"109":131,"110":[2,191],"111":[2,191],"112":[2,191],"115":132,"116":[2,191],"117":83,"122":[2,191],"123":[2,191],"124":[2,191],"131":[2,191],"132":[2,191],"135":[2,191],"136":[2,191],"142":[2,191],"143":[2,191],"144":[2,191],"145":[2,191],"146":[2,191],"147":[2,191],"148":[2,191],"149":[2,191],"150":[2,191],"151":[2,191],"152":[2,191],"153":[2,191],"154":[2,191],"155":[2,191],"156":[2,191],"157":[2,191],"158":[2,191],"159":[2,191],"160":[2,191],"161":[2,191],"162":[2,191],"163":[2,191],"164":[2,191],"165":[2,191],"166":[2,191],"167":[2,191],"168":[2,191]},{"1":[2,192],"4":[2,192],"29":[2,192],"30":[2,192],"51":[1,134],"59":[2,192],"63":[2,192],"81":[2,192],"86":[2,192],"96":[2,192],"100":[2,192],"108":[2,192],"109":131,"110":[2,192],"111":[2,192],"112":[2,192],"115":132,"116":[2,192],"117":83,"122":[2,192],"123":[2,192],"124":[2,192],"131":[2,192],"132":[2,192],"135":[2,192],"136":[2,192],"142":[2,192],"143":[2,192],"144":[2,192],"145":[2,192],"146":[2,192],"147":[2,192],"148":[2,192],"149":[2,192],"150":[2,192],"151":[2,192],"152":[2,192],"153":[2,192],"154":[2,192],"155":[2,192],"156":[2,192],"157":[2,192],"158":[2,192],"159":[2,192],"160":[2,192],"161":[2,192],"162":[2,192],"163":[2,192],"164":[2,192],"165":[2,192],"166":[2,192],"167":[2,192],"168":[2,192]},{"1":[2,193],"4":[2,193],"29":[2,193],"30":[2,193],"51":[1,134],"59":[2,193],"63":[2,193],"81":[2,193],"86":[2,193],"96":[2,193],"100":[2,193],"108":[2,193],"109":131,"110":[2,193],"111":[2,193],"112":[2,193],"115":132,"116":[2,193],"117":83,"122":[2,193],"123":[2,193],"124":[2,193],"131":[2,193],"132":[2,193],"135":[2,193],"136":[2,193],"142":[2,193],"143":[2,193],"144":[2,193],"145":[2,193],"146":[2,193],"147":[2,193],"148":[2,193],"149":[2,193],"150":[2,193],"151":[2,193],"152":[2,193],"153":[2,193],"154":[2,193],"155":[2,193],"156":[2,193],"157":[2,193],"158":[2,193],"159":[2,193],"160":[2,193],"161":[2,193],"162":[2,193],"163":[2,193],"164":[2,193],"165":[2,193],"166":[2,193],"167":[2,193],"168":[2,193]},{"1":[2,194],"4":[2,194],"29":[2,194],"30":[2,194],"51":[1,134],"59":[2,194],"63":[2,194],"81":[2,194],"86":[2,194],"96":[2,194],"100":[2,194],"108":[2,194],"109":131,"110":[2,194],"111":[2,194],"112":[2,194],"115":132,"116":[2,194],"117":83,"122":[2,194],"123":[2,194],"124":[2,194],"131":[2,194],"132":[2,194],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[2,194],"156":[2,194],"157":[2,194],"158":[2,194],"159":[2,194],"160":[2,194],"161":[2,194],"162":[2,194],"163":[2,194],"164":[2,194],"165":[2,194],"166":[2,194],"167":[2,194],"168":[1,125]},{"1":[2,195],"4":[2,195],"29":[2,195],"30":[2,195],"51":[1,134],"59":[2,195],"63":[2,195],"81":[2,195],"86":[2,195],"96":[2,195],"100":[2,195],"108":[2,195],"109":131,"110":[2,195],"111":[2,195],"112":[2,195],"115":132,"116":[2,195],"117":83,"122":[2,195],"123":[2,195],"124":[2,195],"131":[2,195],"132":[2,195],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[2,195],"156":[2,195],"157":[2,195],"158":[2,195],"159":[2,195],"160":[2,195],"161":[2,195],"162":[2,195],"163":[2,195],"164":[2,195],"165":[2,195],"166":[2,195],"167":[2,195],"168":[1,125]},{"4":[1,163],"6":269,"29":[1,6],"131":[1,268]},{"103":270,"104":[1,271],"105":[1,272]},{"1":[2,145],"4":[2,145],"29":[2,145],"30":[2,145],"51":[2,145],"59":[2,145],"63":[2,145],"81":[2,145],"86":[2,145],"96":[2,145],"100":[2,145],"108":[2,145],"110":[2,145],"111":[2,145],"112":[2,145],"116":[2,145],"122":[2,145],"123":[2,145],"124":[2,145],"131":[2,145],"132":[2,145],"133":[2,145],"135":[2,145],"136":[2,145],"138":[2,145],"139":[2,145],"142":[2,145],"143":[2,145],"144":[2,145],"145":[2,145],"146":[2,145],"147":[2,145],"148":[2,145],"149":[2,145],"150":[2,145],"151":[2,145],"152":[2,145],"153":[2,145],"154":[2,145],"155":[2,145],"156":[2,145],"157":[2,145],"158":[2,145],"159":[2,145],"160":[2,145],"161":[2,145],"162":[2,145],"163":[2,145],"164":[2,145],"165":[2,145],"166":[2,145],"167":[2,145],"168":[2,145]},{"1":[2,153],"4":[2,153],"29":[2,153],"30":[2,153],"51":[2,153],"59":[2,153],"63":[2,153],"81":[2,153],"86":[2,153],"96":[2,153],"100":[2,153],"108":[2,153],"110":[2,153],"111":[2,153],"112":[2,153],"116":[2,153],"122":[2,153],"123":[2,153],"124":[2,153],"131":[2,153],"132":[2,153],"133":[2,153],"135":[2,153],"136":[2,153],"138":[2,153],"139":[2,153],"142":[2,153],"143":[2,153],"144":[2,153],"145":[2,153],"146":[2,153],"147":[2,153],"148":[2,153],"149":[2,153],"150":[2,153],"151":[2,153],"152":[2,153],"153":[2,153],"154":[2,153],"155":[2,153],"156":[2,153],"157":[2,153],"158":[2,153],"159":[2,153],"160":[2,153],"161":[2,153],"162":[2,153],"163":[2,153],"164":[2,153],"165":[2,153],"166":[2,153],"167":[2,153],"168":[2,153]},{"29":[1,273],"51":[1,134],"63":[1,133],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"126":274,"128":275,"129":[1,276]},{"14":277,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":156,"62":[1,73],"64":157,"66":184,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"98":[1,72],"99":[1,71],"107":[1,70]},{"1":[2,99],"4":[2,99],"29":[1,279],"30":[2,99],"51":[2,99],"59":[2,99],"63":[2,99],"74":[2,75],"75":[2,75],"76":[2,75],"77":[2,75],"80":[2,75],"81":[2,99],"82":[2,75],"83":[2,75],"86":[2,99],"88":[1,278],"94":[2,75],"96":[2,99],"100":[2,99],"108":[2,99],"110":[2,99],"111":[2,99],"112":[2,99],"116":[2,99],"122":[2,99],"123":[2,99],"124":[2,99],"131":[2,99],"132":[2,99],"133":[2,99],"135":[2,99],"136":[2,99],"138":[2,99],"139":[2,99],"142":[2,99],"143":[2,99],"144":[2,99],"145":[2,99],"146":[2,99],"147":[2,99],"148":[2,99],"149":[2,99],"150":[2,99],"151":[2,99],"152":[2,99],"153":[2,99],"154":[2,99],"155":[2,99],"156":[2,99],"157":[2,99],"158":[2,99],"159":[2,99],"160":[2,99],"161":[2,99],"162":[2,99],"163":[2,99],"164":[2,99],"165":[2,99],"166":[2,99],"167":[2,99],"168":[2,99]},{"4":[2,106],"28":212,"30":[2,106],"31":210,"32":[1,89],"33":211,"34":[1,87],"35":[1,88],"47":283,"50":[1,56],"62":[1,285],"67":284,"84":[1,282],"89":280,"90":281},{"65":140,"74":[1,142],"75":[1,143],"76":[1,144],"77":[1,145],"78":146,"79":147,"80":[1,148],"82":[1,149],"83":[1,150],"93":139,"94":[1,141]},{"65":153,"74":[1,142],"75":[1,143],"76":[1,144],"77":[1,145],"78":146,"79":147,"80":[1,148],"82":[1,149],"83":[1,150],"93":152,"94":[1,141]},{"1":[2,53],"4":[2,53],"30":[2,53],"51":[1,134],"63":[1,133],"108":[2,53],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[2,53],"132":[2,53],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,139],"4":[2,139],"30":[2,139],"51":[1,134],"63":[1,133],"108":[2,139],"109":131,"110":[2,139],"112":[2,139],"115":132,"116":[2,139],"117":83,"122":[1,126],"123":[1,127],"131":[2,139],"132":[2,139],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"108":[1,286]},{"4":[2,129],"29":[2,129],"51":[1,134],"59":[2,129],"63":[1,287],"100":[2,129],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"4":[2,61],"29":[2,61],"58":288,"59":[1,289],"100":[2,61]},{"1":[2,122],"4":[2,122],"29":[2,122],"30":[2,122],"46":[2,122],"48":[2,122],"51":[2,122],"59":[2,122],"63":[2,122],"74":[2,122],"75":[2,122],"76":[2,122],"77":[2,122],"80":[2,122],"81":[2,122],"82":[2,122],"83":[2,122],"86":[2,122],"88":[2,122],"94":[2,122],"96":[2,122],"100":[2,122],"108":[2,122],"110":[2,122],"111":[2,122],"112":[2,122],"116":[2,122],"122":[2,122],"123":[2,122],"124":[2,122],"131":[2,122],"132":[2,122],"133":[2,122],"135":[2,122],"136":[2,122],"138":[2,122],"139":[2,122],"142":[2,122],"143":[2,122],"144":[2,122],"145":[2,122],"146":[2,122],"147":[2,122],"148":[2,122],"149":[2,122],"150":[2,122],"151":[2,122],"152":[2,122],"153":[2,122],"154":[2,122],"155":[2,122],"156":[2,122],"157":[2,122],"158":[2,122],"159":[2,122],"160":[2,122],"161":[2,122],"162":[2,122],"163":[2,122],"164":[2,122],"165":[2,122],"166":[2,122],"167":[2,122],"168":[2,122]},{"1":[2,119],"4":[2,119],"29":[2,119],"30":[2,119],"51":[2,119],"59":[2,119],"63":[2,119],"81":[2,119],"86":[2,119],"96":[2,119],"100":[2,119],"108":[2,119],"110":[2,119],"111":[2,119],"112":[2,119],"116":[2,119],"122":[2,119],"123":[2,119],"124":[2,119],"131":[2,119],"132":[2,119],"133":[2,119],"135":[2,119],"136":[2,119],"138":[2,119],"139":[2,119],"142":[2,119],"143":[2,119],"144":[2,119],"145":[2,119],"146":[2,119],"147":[2,119],"148":[2,119],"149":[2,119],"150":[2,119],"151":[2,119],"152":[2,119],"153":[2,119],"154":[2,119],"155":[2,119],"156":[2,119],"157":[2,119],"158":[2,119],"159":[2,119],"160":[2,119],"161":[2,119],"162":[2,119],"163":[2,119],"164":[2,119],"165":[2,119],"166":[2,119],"167":[2,119],"168":[2,119]},{"4":[1,163],"6":290,"29":[1,6],"51":[1,134],"63":[1,133],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"4":[1,163],"6":291,"29":[1,6],"51":[1,134],"63":[1,133],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,141],"4":[2,141],"29":[2,141],"30":[2,141],"51":[1,134],"59":[2,141],"63":[1,133],"81":[2,141],"86":[2,141],"96":[2,141],"100":[2,141],"108":[2,141],"109":131,"110":[1,79],"111":[1,292],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"124":[2,141],"131":[2,141],"132":[2,141],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,143],"4":[2,143],"29":[2,143],"30":[2,143],"51":[1,134],"59":[2,143],"63":[1,133],"81":[2,143],"86":[2,143],"96":[2,143],"100":[2,143],"108":[2,143],"109":131,"110":[1,79],"111":[1,293],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"124":[2,143],"131":[2,143],"132":[2,143],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,149],"4":[2,149],"29":[2,149],"30":[2,149],"51":[2,149],"59":[2,149],"63":[2,149],"81":[2,149],"86":[2,149],"96":[2,149],"100":[2,149],"108":[2,149],"110":[2,149],"111":[2,149],"112":[2,149],"116":[2,149],"122":[2,149],"123":[2,149],"124":[2,149],"131":[2,149],"132":[2,149],"133":[2,149],"135":[2,149],"136":[2,149],"138":[2,149],"139":[2,149],"142":[2,149],"143":[2,149],"144":[2,149],"145":[2,149],"146":[2,149],"147":[2,149],"148":[2,149],"149":[2,149],"150":[2,149],"151":[2,149],"152":[2,149],"153":[2,149],"154":[2,149],"155":[2,149],"156":[2,149],"157":[2,149],"158":[2,149],"159":[2,149],"160":[2,149],"161":[2,149],"162":[2,149],"163":[2,149],"164":[2,149],"165":[2,149],"166":[2,149],"167":[2,149],"168":[2,149]},{"1":[2,150],"4":[2,150],"29":[2,150],"30":[2,150],"51":[1,134],"59":[2,150],"63":[1,133],"81":[2,150],"86":[2,150],"96":[2,150],"100":[2,150],"108":[2,150],"109":131,"110":[1,79],"111":[2,150],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"124":[2,150],"131":[2,150],"132":[2,150],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,154],"4":[2,154],"29":[2,154],"30":[2,154],"51":[2,154],"59":[2,154],"63":[2,154],"81":[2,154],"86":[2,154],"96":[2,154],"100":[2,154],"108":[2,154],"110":[2,154],"111":[2,154],"112":[2,154],"116":[2,154],"122":[2,154],"123":[2,154],"124":[2,154],"131":[2,154],"132":[2,154],"133":[2,154],"135":[2,154],"136":[2,154],"138":[2,154],"139":[2,154],"142":[2,154],"143":[2,154],"144":[2,154],"145":[2,154],"146":[2,154],"147":[2,154],"148":[2,154],"149":[2,154],"150":[2,154],"151":[2,154],"152":[2,154],"153":[2,154],"154":[2,154],"155":[2,154],"156":[2,154],"157":[2,154],"158":[2,154],"159":[2,154],"160":[2,154],"161":[2,154],"162":[2,154],"163":[2,154],"164":[2,154],"165":[2,154],"166":[2,154],"167":[2,154],"168":[2,154]},{"122":[2,156],"123":[2,156]},{"31":202,"32":[1,89],"68":203,"69":204,"84":[1,86],"99":[1,295],"119":294,"121":201},{"59":[1,296],"122":[2,161],"123":[2,161]},{"59":[2,158],"122":[2,158],"123":[2,158]},{"59":[2,159],"122":[2,159],"123":[2,159]},{"59":[2,160],"122":[2,160],"123":[2,160]},{"1":[2,155],"4":[2,155],"29":[2,155],"30":[2,155],"51":[2,155],"59":[2,155],"63":[2,155],"81":[2,155],"86":[2,155],"96":[2,155],"100":[2,155],"108":[2,155],"110":[2,155],"111":[2,155],"112":[2,155],"116":[2,155],"122":[2,155],"123":[2,155],"124":[2,155],"131":[2,155],"132":[2,155],"133":[2,155],"135":[2,155],"136":[2,155],"138":[2,155],"139":[2,155],"142":[2,155],"143":[2,155],"144":[2,155],"145":[2,155],"146":[2,155],"147":[2,155],"148":[2,155],"149":[2,155],"150":[2,155],"151":[2,155],"152":[2,155],"153":[2,155],"154":[2,155],"155":[2,155],"156":[2,155],"157":[2,155],"158":[2,155],"159":[2,155],"160":[2,155],"161":[2,155],"162":[2,155],"163":[2,155],"164":[2,155],"165":[2,155],"166":[2,155],"167":[2,155],"168":[2,155]},{"8":297,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":298,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"4":[2,61],"29":[2,61],"58":299,"59":[1,300],"86":[2,61]},{"4":[2,95],"29":[2,95],"30":[2,95],"59":[2,95],"86":[2,95]},{"4":[2,46],"29":[2,46],"30":[2,46],"48":[1,301],"59":[2,46],"86":[2,46]},{"4":[2,47],"29":[2,47],"30":[2,47],"48":[1,302],"59":[2,47],"86":[2,47]},{"4":[2,52],"29":[2,52],"30":[2,52],"59":[2,52],"86":[2,52]},{"1":[2,6],"4":[2,6],"30":[2,6]},{"1":[2,29],"4":[2,29],"29":[2,29],"30":[2,29],"51":[2,29],"59":[2,29],"63":[2,29],"81":[2,29],"86":[2,29],"96":[2,29],"100":[2,29],"104":[2,29],"105":[2,29],"108":[2,29],"110":[2,29],"111":[2,29],"112":[2,29],"116":[2,29],"122":[2,29],"123":[2,29],"124":[2,29],"127":[2,29],"129":[2,29],"131":[2,29],"132":[2,29],"133":[2,29],"135":[2,29],"136":[2,29],"138":[2,29],"139":[2,29],"142":[2,29],"143":[2,29],"144":[2,29],"145":[2,29],"146":[2,29],"147":[2,29],"148":[2,29],"149":[2,29],"150":[2,29],"151":[2,29],"152":[2,29],"153":[2,29],"154":[2,29],"155":[2,29],"156":[2,29],"157":[2,29],"158":[2,29],"159":[2,29],"160":[2,29],"161":[2,29],"162":[2,29],"163":[2,29],"164":[2,29],"165":[2,29],"166":[2,29],"167":[2,29],"168":[2,29]},{"1":[2,198],"4":[2,198],"29":[2,198],"30":[2,198],"51":[1,134],"59":[2,198],"63":[2,198],"81":[2,198],"86":[2,198],"96":[2,198],"100":[2,198],"108":[2,198],"109":131,"110":[2,198],"111":[2,198],"112":[2,198],"115":132,"116":[2,198],"117":83,"122":[2,198],"123":[2,198],"124":[2,198],"131":[2,198],"132":[2,198],"133":[1,128],"135":[2,198],"136":[2,198],"138":[1,95],"139":[1,96],"142":[2,198],"143":[2,198],"144":[2,198],"145":[2,198],"146":[2,198],"147":[2,198],"148":[2,198],"149":[2,198],"150":[2,198],"151":[2,198],"152":[2,198],"153":[2,198],"154":[2,198],"155":[2,198],"156":[2,198],"157":[2,198],"158":[2,198],"159":[2,198],"160":[2,198],"161":[2,198],"162":[2,198],"163":[2,198],"164":[2,198],"165":[2,198],"166":[2,198],"167":[2,198],"168":[2,198]},{"1":[2,199],"4":[2,199],"29":[2,199],"30":[2,199],"51":[1,134],"59":[2,199],"63":[2,199],"81":[2,199],"86":[2,199],"96":[2,199],"100":[2,199],"108":[2,199],"109":131,"110":[2,199],"111":[2,199],"112":[2,199],"115":132,"116":[2,199],"117":83,"122":[2,199],"123":[2,199],"124":[2,199],"131":[2,199],"132":[2,199],"133":[1,128],"135":[2,199],"136":[2,199],"138":[1,95],"139":[1,96],"142":[2,199],"143":[2,199],"144":[2,199],"145":[2,199],"146":[2,199],"147":[2,199],"148":[2,199],"149":[2,199],"150":[2,199],"151":[2,199],"152":[2,199],"153":[2,199],"154":[2,199],"155":[2,199],"156":[2,199],"157":[2,199],"158":[2,199],"159":[2,199],"160":[2,199],"161":[2,199],"162":[2,199],"163":[2,199],"164":[2,199],"165":[2,199],"166":[2,199],"167":[2,199],"168":[2,199]},{"1":[2,200],"4":[2,200],"29":[2,200],"30":[2,200],"51":[1,134],"59":[2,200],"63":[2,200],"81":[2,200],"86":[2,200],"96":[2,200],"100":[2,200],"108":[2,200],"109":131,"110":[2,200],"111":[2,200],"112":[2,200],"115":132,"116":[2,200],"117":83,"122":[2,200],"123":[2,200],"124":[2,200],"131":[2,200],"132":[2,200],"133":[1,128],"135":[2,200],"136":[2,200],"138":[1,95],"139":[1,96],"142":[2,200],"143":[2,200],"144":[2,200],"145":[2,200],"146":[2,200],"147":[2,200],"148":[2,200],"149":[2,200],"150":[2,200],"151":[2,200],"152":[2,200],"153":[2,200],"154":[2,200],"155":[2,200],"156":[2,200],"157":[2,200],"158":[2,200],"159":[2,200],"160":[2,200],"161":[2,200],"162":[2,200],"163":[2,200],"164":[2,200],"165":[2,200],"166":[2,200],"167":[2,200],"168":[2,200]},{"1":[2,201],"4":[2,201],"29":[2,201],"30":[2,201],"51":[1,134],"59":[2,201],"63":[2,201],"81":[2,201],"86":[2,201],"96":[2,201],"100":[2,201],"108":[2,201],"109":131,"110":[2,201],"111":[2,201],"112":[2,201],"115":132,"116":[2,201],"117":83,"122":[2,201],"123":[2,201],"124":[2,201],"131":[2,201],"132":[2,201],"133":[1,128],"135":[2,201],"136":[2,201],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[2,201],"146":[2,201],"147":[2,201],"148":[2,201],"149":[2,201],"150":[2,201],"151":[2,201],"152":[2,201],"153":[2,201],"154":[2,201],"155":[2,201],"156":[2,201],"157":[2,201],"158":[2,201],"159":[2,201],"160":[2,201],"161":[2,201],"162":[2,201],"163":[2,201],"164":[2,201],"165":[2,201],"166":[2,201],"167":[2,201],"168":[2,201]},{"1":[2,202],"4":[2,202],"29":[2,202],"30":[2,202],"51":[1,134],"59":[2,202],"63":[2,202],"81":[2,202],"86":[2,202],"96":[2,202],"100":[2,202],"108":[2,202],"109":131,"110":[2,202],"111":[2,202],"112":[2,202],"115":132,"116":[2,202],"117":83,"122":[2,202],"123":[2,202],"124":[2,202],"131":[2,202],"132":[2,202],"133":[1,128],"135":[2,202],"136":[2,202],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[2,202],"146":[2,202],"147":[2,202],"148":[2,202],"149":[2,202],"150":[2,202],"151":[2,202],"152":[2,202],"153":[2,202],"154":[2,202],"155":[2,202],"156":[2,202],"157":[2,202],"158":[2,202],"159":[2,202],"160":[2,202],"161":[2,202],"162":[2,202],"163":[2,202],"164":[2,202],"165":[2,202],"166":[2,202],"167":[2,202],"168":[2,202]},{"1":[2,203],"4":[2,203],"29":[2,203],"30":[2,203],"51":[1,134],"59":[2,203],"63":[2,203],"81":[2,203],"86":[2,203],"96":[2,203],"100":[2,203],"108":[2,203],"109":131,"110":[2,203],"111":[2,203],"112":[2,203],"115":132,"116":[2,203],"117":83,"122":[2,203],"123":[2,203],"124":[2,203],"131":[2,203],"132":[2,203],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[2,203],"146":[2,203],"147":[2,203],"148":[2,203],"149":[2,203],"150":[2,203],"151":[2,203],"152":[2,203],"153":[2,203],"154":[2,203],"155":[2,203],"156":[2,203],"157":[2,203],"158":[2,203],"159":[2,203],"160":[2,203],"161":[2,203],"162":[2,203],"163":[2,203],"164":[2,203],"165":[2,203],"166":[2,203],"167":[2,203],"168":[2,203]},{"1":[2,204],"4":[2,204],"29":[2,204],"30":[2,204],"51":[1,134],"59":[2,204],"63":[2,204],"81":[2,204],"86":[2,204],"96":[2,204],"100":[2,204],"108":[2,204],"109":131,"110":[2,204],"111":[2,204],"112":[2,204],"115":132,"116":[2,204],"117":83,"122":[2,204],"123":[2,204],"124":[2,204],"131":[2,204],"132":[2,204],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[2,204],"146":[2,204],"147":[2,204],"148":[2,204],"149":[2,204],"150":[2,204],"151":[2,204],"152":[2,204],"153":[2,204],"154":[2,204],"155":[2,204],"156":[2,204],"157":[2,204],"158":[2,204],"159":[2,204],"160":[2,204],"161":[2,204],"162":[2,204],"163":[2,204],"164":[2,204],"165":[2,204],"166":[2,204],"167":[2,204],"168":[2,204]},{"1":[2,205],"4":[2,205],"29":[2,205],"30":[2,205],"51":[1,134],"59":[2,205],"63":[2,205],"81":[2,205],"86":[2,205],"96":[2,205],"100":[2,205],"108":[2,205],"109":131,"110":[2,205],"111":[2,205],"112":[2,205],"115":132,"116":[2,205],"117":83,"122":[2,205],"123":[2,205],"124":[2,205],"131":[2,205],"132":[2,205],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[2,205],"146":[2,205],"147":[2,205],"148":[2,205],"149":[2,205],"150":[2,205],"151":[2,205],"152":[2,205],"153":[2,205],"154":[2,205],"155":[2,205],"156":[2,205],"157":[2,205],"158":[2,205],"159":[2,205],"160":[2,205],"161":[2,205],"162":[2,205],"163":[2,205],"164":[2,205],"165":[2,205],"166":[2,205],"167":[2,205],"168":[2,205]},{"1":[2,206],"4":[2,206],"29":[2,206],"30":[2,206],"51":[1,134],"59":[2,206],"63":[2,206],"81":[2,206],"86":[2,206],"96":[2,206],"100":[2,206],"108":[2,206],"109":131,"110":[2,206],"111":[2,206],"112":[2,206],"115":132,"116":[2,206],"117":83,"122":[2,206],"123":[2,206],"124":[2,206],"131":[2,206],"132":[2,206],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[2,206],"149":[2,206],"150":[2,206],"151":[2,206],"152":[2,206],"153":[2,206],"154":[2,206],"155":[2,206],"156":[2,206],"157":[2,206],"158":[2,206],"159":[2,206],"160":[2,206],"161":[2,206],"162":[2,206],"163":[2,206],"164":[2,206],"165":[2,206],"166":[2,206],"167":[2,206],"168":[2,206]},{"1":[2,207],"4":[2,207],"29":[2,207],"30":[2,207],"51":[1,134],"59":[2,207],"63":[2,207],"81":[2,207],"86":[2,207],"96":[2,207],"100":[2,207],"108":[2,207],"109":131,"110":[2,207],"111":[2,207],"112":[2,207],"115":132,"116":[2,207],"117":83,"122":[2,207],"123":[2,207],"124":[2,207],"131":[2,207],"132":[2,207],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[2,207],"149":[2,207],"150":[2,207],"151":[2,207],"152":[2,207],"153":[2,207],"154":[2,207],"155":[2,207],"156":[2,207],"157":[2,207],"158":[2,207],"159":[2,207],"160":[2,207],"161":[2,207],"162":[2,207],"163":[2,207],"164":[2,207],"165":[2,207],"166":[2,207],"167":[2,207],"168":[2,207]},{"1":[2,208],"4":[2,208],"29":[2,208],"30":[2,208],"51":[1,134],"59":[2,208],"63":[2,208],"81":[2,208],"86":[2,208],"96":[2,208],"100":[2,208],"108":[2,208],"109":131,"110":[2,208],"111":[2,208],"112":[2,208],"115":132,"116":[2,208],"117":83,"122":[2,208],"123":[2,208],"124":[2,208],"131":[2,208],"132":[2,208],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[2,208],"149":[2,208],"150":[2,208],"151":[2,208],"152":[2,208],"153":[2,208],"154":[2,208],"155":[2,208],"156":[2,208],"157":[2,208],"158":[2,208],"159":[2,208],"160":[2,208],"161":[2,208],"162":[2,208],"163":[2,208],"164":[2,208],"165":[2,208],"166":[2,208],"167":[2,208],"168":[2,208]},{"1":[2,209],"4":[2,209],"29":[2,209],"30":[2,209],"51":[1,134],"59":[2,209],"63":[2,209],"81":[2,209],"86":[2,209],"96":[2,209],"100":[2,209],"108":[2,209],"109":131,"110":[2,209],"111":[2,209],"112":[2,209],"115":132,"116":[2,209],"117":83,"122":[2,209],"123":[2,209],"124":[2,209],"131":[2,209],"132":[2,209],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[2,209],"152":[2,209],"153":[2,209],"154":[2,209],"155":[2,209],"156":[2,209],"157":[2,209],"158":[2,209],"159":[2,209],"160":[2,209],"161":[2,209],"162":[2,209],"163":[2,209],"164":[2,209],"165":[2,209],"166":[2,209],"167":[2,209],"168":[2,209]},{"1":[2,210],"4":[2,210],"29":[2,210],"30":[2,210],"51":[1,134],"59":[2,210],"63":[2,210],"81":[2,210],"86":[2,210],"96":[2,210],"100":[2,210],"108":[2,210],"109":131,"110":[2,210],"111":[2,210],"112":[2,210],"115":132,"116":[2,210],"117":83,"122":[2,210],"123":[2,210],"124":[2,210],"131":[2,210],"132":[2,210],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[2,210],"152":[2,210],"153":[2,210],"154":[2,210],"155":[2,210],"156":[2,210],"157":[2,210],"158":[2,210],"159":[2,210],"160":[2,210],"161":[2,210],"162":[2,210],"163":[2,210],"164":[2,210],"165":[2,210],"166":[2,210],"167":[2,210],"168":[2,210]},{"1":[2,211],"4":[2,211],"29":[2,211],"30":[2,211],"51":[1,134],"59":[2,211],"63":[2,211],"81":[2,211],"86":[2,211],"96":[2,211],"100":[2,211],"108":[2,211],"109":131,"110":[2,211],"111":[2,211],"112":[2,211],"115":132,"116":[2,211],"117":83,"122":[2,211],"123":[2,211],"124":[2,211],"131":[2,211],"132":[2,211],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[2,211],"152":[2,211],"153":[2,211],"154":[2,211],"155":[2,211],"156":[2,211],"157":[2,211],"158":[2,211],"159":[2,211],"160":[2,211],"161":[2,211],"162":[2,211],"163":[2,211],"164":[2,211],"165":[2,211],"166":[2,211],"167":[2,211],"168":[2,211]},{"1":[2,212],"4":[2,212],"29":[2,212],"30":[2,212],"51":[1,134],"59":[2,212],"63":[2,212],"81":[2,212],"86":[2,212],"96":[2,212],"100":[2,212],"108":[2,212],"109":131,"110":[2,212],"111":[2,212],"112":[2,212],"115":132,"116":[2,212],"117":83,"122":[2,212],"123":[2,212],"124":[2,212],"131":[2,212],"132":[2,212],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[2,212],"152":[2,212],"153":[2,212],"154":[2,212],"155":[2,212],"156":[2,212],"157":[2,212],"158":[2,212],"159":[2,212],"160":[2,212],"161":[2,212],"162":[2,212],"163":[2,212],"164":[2,212],"165":[2,212],"166":[2,212],"167":[2,212],"168":[2,212]},{"1":[2,213],"4":[2,213],"29":[2,213],"30":[2,213],"51":[1,134],"59":[2,213],"63":[2,213],"81":[2,213],"86":[2,213],"96":[2,213],"100":[2,213],"108":[2,213],"109":131,"110":[2,213],"111":[2,213],"112":[2,213],"115":132,"116":[2,213],"117":83,"122":[2,213],"123":[2,213],"124":[2,213],"131":[2,213],"132":[2,213],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[2,213],"156":[2,213],"157":[2,213],"158":[2,213],"159":[2,213],"160":[2,213],"161":[2,213],"162":[2,213],"163":[2,213],"164":[2,213],"165":[2,213],"166":[2,213],"167":[2,213],"168":[1,125]},{"1":[2,214],"4":[2,214],"29":[2,214],"30":[2,214],"51":[1,134],"59":[2,214],"63":[2,214],"81":[2,214],"86":[2,214],"96":[2,214],"100":[2,214],"108":[2,214],"109":131,"110":[2,214],"111":[2,214],"112":[2,214],"115":132,"116":[2,214],"117":83,"122":[2,214],"123":[2,214],"124":[2,214],"131":[2,214],"132":[2,214],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[2,214],"156":[2,214],"157":[2,214],"158":[2,214],"159":[2,214],"160":[2,214],"161":[2,214],"162":[2,214],"163":[2,214],"164":[2,214],"165":[2,214],"166":[2,214],"167":[2,214],"168":[1,125]},{"1":[2,215],"4":[2,215],"29":[2,215],"30":[2,215],"51":[1,134],"59":[2,215],"63":[2,215],"81":[2,215],"86":[2,215],"96":[2,215],"100":[2,215],"108":[2,215],"109":131,"110":[2,215],"111":[2,215],"112":[2,215],"115":132,"116":[2,215],"117":83,"122":[2,215],"123":[2,215],"124":[2,215],"131":[2,215],"132":[2,215],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[2,215],"158":[2,215],"159":[2,215],"160":[2,215],"161":[2,215],"162":[2,215],"163":[2,215],"164":[2,215],"165":[2,215],"166":[2,215],"167":[2,215],"168":[1,125]},{"1":[2,216],"4":[2,216],"29":[2,216],"30":[2,216],"51":[1,134],"59":[2,216],"63":[2,216],"81":[2,216],"86":[2,216],"96":[2,216],"100":[2,216],"108":[2,216],"109":131,"110":[2,216],"111":[2,216],"112":[2,216],"115":132,"116":[2,216],"117":83,"122":[2,216],"123":[2,216],"124":[2,216],"131":[2,216],"132":[2,216],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[2,216],"158":[2,216],"159":[2,216],"160":[2,216],"161":[2,216],"162":[2,216],"163":[2,216],"164":[2,216],"165":[2,216],"166":[2,216],"167":[2,216],"168":[1,125]},{"1":[2,217],"4":[2,217],"29":[2,217],"30":[2,217],"51":[1,134],"59":[2,217],"63":[2,217],"81":[2,217],"86":[2,217],"96":[2,217],"100":[2,217],"108":[2,217],"109":131,"110":[2,217],"111":[2,217],"112":[2,217],"115":132,"116":[2,217],"117":83,"122":[2,217],"123":[2,217],"124":[2,217],"131":[2,217],"132":[2,217],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[2,217],"158":[2,217],"159":[2,217],"160":[2,217],"161":[2,217],"162":[2,217],"163":[2,217],"164":[2,217],"165":[2,217],"166":[2,217],"167":[2,217],"168":[1,125]},{"1":[2,218],"4":[2,218],"29":[2,218],"30":[2,218],"51":[1,134],"59":[2,218],"63":[2,218],"81":[2,218],"86":[2,218],"96":[2,218],"100":[2,218],"108":[2,218],"109":131,"110":[2,218],"111":[2,218],"112":[2,218],"115":132,"116":[2,218],"117":83,"122":[2,218],"123":[2,218],"124":[2,218],"131":[2,218],"132":[2,218],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,219],"4":[2,219],"29":[2,219],"30":[2,219],"51":[1,134],"59":[2,219],"63":[2,219],"81":[2,219],"86":[2,219],"96":[2,219],"100":[2,219],"108":[2,219],"109":131,"110":[2,219],"111":[2,219],"112":[2,219],"115":132,"116":[2,219],"117":83,"122":[2,219],"123":[2,219],"124":[2,219],"131":[2,219],"132":[2,219],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,220],"4":[2,220],"29":[2,220],"30":[2,220],"51":[1,134],"59":[2,220],"63":[2,220],"81":[2,220],"86":[2,220],"96":[2,220],"100":[2,220],"108":[2,220],"109":131,"110":[2,220],"111":[2,220],"112":[2,220],"115":132,"116":[2,220],"117":83,"122":[2,220],"123":[2,220],"124":[2,220],"131":[2,220],"132":[2,220],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,221],"4":[2,221],"29":[2,221],"30":[2,221],"51":[1,134],"59":[2,221],"63":[2,221],"81":[2,221],"86":[2,221],"96":[2,221],"100":[2,221],"108":[2,221],"109":131,"110":[2,221],"111":[2,221],"112":[2,221],"115":132,"116":[2,221],"117":83,"122":[2,221],"123":[2,221],"124":[2,221],"131":[2,221],"132":[2,221],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,222],"4":[2,222],"29":[2,222],"30":[2,222],"51":[1,134],"59":[2,222],"63":[2,222],"81":[2,222],"86":[2,222],"96":[2,222],"100":[2,222],"108":[2,222],"109":131,"110":[2,222],"111":[2,222],"112":[2,222],"115":132,"116":[2,222],"117":83,"122":[2,222],"123":[2,222],"124":[2,222],"131":[2,222],"132":[2,222],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,223],"4":[2,223],"29":[2,223],"30":[2,223],"51":[1,134],"59":[2,223],"63":[2,223],"81":[2,223],"86":[2,223],"96":[2,223],"100":[2,223],"108":[2,223],"109":131,"110":[2,223],"111":[2,223],"112":[2,223],"115":132,"116":[2,223],"117":83,"122":[2,223],"123":[2,223],"124":[2,223],"131":[2,223],"132":[2,223],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,224],"4":[2,224],"29":[2,224],"30":[2,224],"51":[1,134],"59":[2,224],"63":[2,224],"81":[2,224],"86":[2,224],"96":[2,224],"100":[2,224],"108":[2,224],"109":131,"110":[2,224],"111":[2,224],"112":[2,224],"115":132,"116":[2,224],"117":83,"122":[2,224],"123":[2,224],"124":[2,224],"131":[2,224],"132":[2,224],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,225],"4":[2,225],"29":[2,225],"30":[2,225],"51":[1,134],"59":[2,225],"63":[2,225],"81":[2,225],"86":[2,225],"96":[2,225],"100":[2,225],"108":[2,225],"109":131,"110":[2,225],"111":[2,225],"112":[2,225],"115":132,"116":[2,225],"117":83,"122":[2,225],"123":[2,225],"124":[2,225],"131":[2,225],"132":[2,225],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,226],"4":[2,226],"29":[2,226],"30":[2,226],"51":[1,134],"59":[2,226],"63":[2,226],"81":[2,226],"86":[2,226],"96":[2,226],"100":[2,226],"108":[2,226],"109":131,"110":[2,226],"111":[2,226],"112":[2,226],"115":132,"116":[2,226],"117":83,"122":[2,226],"123":[2,226],"124":[2,226],"131":[2,226],"132":[2,226],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[2,226],"156":[2,226],"157":[2,226],"158":[2,226],"159":[2,226],"160":[2,226],"161":[2,226],"162":[2,226],"163":[2,226],"164":[2,226],"165":[2,226],"166":[2,226],"167":[2,226],"168":[1,125]},{"1":[2,227],"4":[2,227],"29":[2,227],"30":[2,227],"51":[1,134],"59":[2,227],"63":[1,133],"81":[2,227],"86":[2,227],"96":[2,227],"100":[2,227],"108":[2,227],"109":131,"110":[2,227],"111":[2,227],"112":[2,227],"115":132,"116":[2,227],"117":83,"122":[1,126],"123":[1,127],"124":[2,227],"131":[2,227],"132":[2,227],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,228],"4":[2,228],"29":[2,228],"30":[2,228],"51":[1,134],"59":[2,228],"63":[1,133],"81":[2,228],"86":[2,228],"96":[2,228],"100":[2,228],"108":[2,228],"109":131,"110":[2,228],"111":[2,228],"112":[2,228],"115":132,"116":[2,228],"117":83,"122":[1,126],"123":[1,127],"124":[2,228],"131":[2,228],"132":[2,228],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"8":303,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":304,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,184],"4":[2,184],"29":[2,184],"30":[2,184],"51":[1,134],"59":[2,184],"63":[1,133],"81":[2,184],"86":[2,184],"96":[2,184],"100":[2,184],"108":[2,184],"109":131,"110":[1,79],"111":[2,184],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"124":[2,184],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,186],"4":[2,186],"29":[2,186],"30":[2,186],"51":[1,134],"59":[2,186],"63":[1,133],"81":[2,186],"86":[2,186],"96":[2,186],"100":[2,186],"108":[2,186],"109":131,"110":[1,79],"111":[2,186],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"124":[2,186],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"63":[1,305]},{"1":[2,183],"4":[2,183],"29":[2,183],"30":[2,183],"51":[1,134],"59":[2,183],"63":[1,133],"81":[2,183],"86":[2,183],"96":[2,183],"100":[2,183],"108":[2,183],"109":131,"110":[1,79],"111":[2,183],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"124":[2,183],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,185],"4":[2,185],"29":[2,185],"30":[2,185],"51":[1,134],"59":[2,185],"63":[1,133],"81":[2,185],"86":[2,185],"96":[2,185],"100":[2,185],"108":[2,185],"109":131,"110":[1,79],"111":[2,185],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"124":[2,185],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"4":[2,61],"29":[2,61],"58":306,"59":[1,289],"96":[2,61]},{"4":[2,129],"29":[2,129],"30":[2,129],"51":[1,134],"59":[2,129],"63":[1,133],"96":[2,129],"100":[2,129],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,84],"4":[2,84],"29":[2,84],"30":[2,84],"46":[2,84],"51":[2,84],"59":[2,84],"63":[2,84],"74":[2,84],"75":[2,84],"76":[2,84],"77":[2,84],"80":[2,84],"81":[2,84],"82":[2,84],"83":[2,84],"86":[2,84],"88":[2,84],"94":[2,84],"96":[2,84],"100":[2,84],"108":[2,84],"110":[2,84],"111":[2,84],"112":[2,84],"116":[2,84],"122":[2,84],"123":[2,84],"124":[2,84],"131":[2,84],"132":[2,84],"133":[2,84],"135":[2,84],"136":[2,84],"138":[2,84],"139":[2,84],"142":[2,84],"143":[2,84],"144":[2,84],"145":[2,84],"146":[2,84],"147":[2,84],"148":[2,84],"149":[2,84],"150":[2,84],"151":[2,84],"152":[2,84],"153":[2,84],"154":[2,84],"155":[2,84],"156":[2,84],"157":[2,84],"158":[2,84],"159":[2,84],"160":[2,84],"161":[2,84],"162":[2,84],"163":[2,84],"164":[2,84],"165":[2,84],"166":[2,84],"167":[2,84],"168":[2,84]},{"1":[2,85],"4":[2,85],"29":[2,85],"30":[2,85],"46":[2,85],"51":[2,85],"59":[2,85],"63":[2,85],"74":[2,85],"75":[2,85],"76":[2,85],"77":[2,85],"80":[2,85],"81":[2,85],"82":[2,85],"83":[2,85],"86":[2,85],"88":[2,85],"94":[2,85],"96":[2,85],"100":[2,85],"108":[2,85],"110":[2,85],"111":[2,85],"112":[2,85],"116":[2,85],"122":[2,85],"123":[2,85],"124":[2,85],"131":[2,85],"132":[2,85],"133":[2,85],"135":[2,85],"136":[2,85],"138":[2,85],"139":[2,85],"142":[2,85],"143":[2,85],"144":[2,85],"145":[2,85],"146":[2,85],"147":[2,85],"148":[2,85],"149":[2,85],"150":[2,85],"151":[2,85],"152":[2,85],"153":[2,85],"154":[2,85],"155":[2,85],"156":[2,85],"157":[2,85],"158":[2,85],"159":[2,85],"160":[2,85],"161":[2,85],"162":[2,85],"163":[2,85],"164":[2,85],"165":[2,85],"166":[2,85],"167":[2,85],"168":[2,85]},{"1":[2,87],"4":[2,87],"29":[2,87],"30":[2,87],"46":[2,87],"51":[2,87],"59":[2,87],"63":[2,87],"74":[2,87],"75":[2,87],"76":[2,87],"77":[2,87],"80":[2,87],"81":[2,87],"82":[2,87],"83":[2,87],"86":[2,87],"88":[2,87],"94":[2,87],"96":[2,87],"100":[2,87],"108":[2,87],"110":[2,87],"111":[2,87],"112":[2,87],"116":[2,87],"122":[2,87],"123":[2,87],"124":[2,87],"131":[2,87],"132":[2,87],"133":[2,87],"135":[2,87],"136":[2,87],"138":[2,87],"139":[2,87],"142":[2,87],"143":[2,87],"144":[2,87],"145":[2,87],"146":[2,87],"147":[2,87],"148":[2,87],"149":[2,87],"150":[2,87],"151":[2,87],"152":[2,87],"153":[2,87],"154":[2,87],"155":[2,87],"156":[2,87],"157":[2,87],"158":[2,87],"159":[2,87],"160":[2,87],"161":[2,87],"162":[2,87],"163":[2,87],"164":[2,87],"165":[2,87],"166":[2,87],"167":[2,87],"168":[2,87]},{"51":[1,134],"63":[1,308],"81":[1,307],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,91],"4":[2,91],"29":[2,91],"30":[2,91],"46":[2,91],"51":[2,91],"59":[2,91],"63":[2,91],"74":[2,91],"75":[2,91],"76":[2,91],"77":[2,91],"80":[2,91],"81":[2,91],"82":[2,91],"83":[2,91],"86":[2,91],"88":[2,91],"94":[2,91],"96":[2,91],"100":[2,91],"108":[2,91],"110":[2,91],"111":[2,91],"112":[2,91],"116":[2,91],"122":[2,91],"123":[2,91],"124":[2,91],"131":[2,91],"132":[2,91],"133":[2,91],"135":[2,91],"136":[2,91],"138":[2,91],"139":[2,91],"142":[2,91],"143":[2,91],"144":[2,91],"145":[2,91],"146":[2,91],"147":[2,91],"148":[2,91],"149":[2,91],"150":[2,91],"151":[2,91],"152":[2,91],"153":[2,91],"154":[2,91],"155":[2,91],"156":[2,91],"157":[2,91],"158":[2,91],"159":[2,91],"160":[2,91],"161":[2,91],"162":[2,91],"163":[2,91],"164":[2,91],"165":[2,91],"166":[2,91],"167":[2,91],"168":[2,91]},{"8":309,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,92],"4":[2,92],"29":[2,92],"30":[2,92],"46":[2,92],"51":[2,92],"59":[2,92],"63":[2,92],"74":[2,92],"75":[2,92],"76":[2,92],"77":[2,92],"80":[2,92],"81":[2,92],"82":[2,92],"83":[2,92],"86":[2,92],"88":[2,92],"94":[2,92],"96":[2,92],"100":[2,92],"108":[2,92],"110":[2,92],"111":[2,92],"112":[2,92],"116":[2,92],"122":[2,92],"123":[2,92],"124":[2,92],"131":[2,92],"132":[2,92],"133":[2,92],"135":[2,92],"136":[2,92],"138":[2,92],"139":[2,92],"142":[2,92],"143":[2,92],"144":[2,92],"145":[2,92],"146":[2,92],"147":[2,92],"148":[2,92],"149":[2,92],"150":[2,92],"151":[2,92],"152":[2,92],"153":[2,92],"154":[2,92],"155":[2,92],"156":[2,92],"157":[2,92],"158":[2,92],"159":[2,92],"160":[2,92],"161":[2,92],"162":[2,92],"163":[2,92],"164":[2,92],"165":[2,92],"166":[2,92],"167":[2,92],"168":[2,92]},{"1":[2,44],"4":[2,44],"29":[2,44],"30":[2,44],"51":[1,134],"59":[2,44],"63":[1,133],"81":[2,44],"86":[2,44],"96":[2,44],"100":[2,44],"108":[2,44],"109":131,"110":[1,79],"111":[2,44],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"124":[2,44],"131":[2,44],"132":[2,44],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"8":310,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"55":311,"56":[1,75],"57":[1,76]},{"60":312,"61":[1,160],"62":[1,161]},{"63":[1,313]},{"54":[2,67],"59":[2,67],"63":[1,314]},{"8":315,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,181],"4":[2,181],"29":[2,181],"30":[2,181],"51":[2,181],"59":[2,181],"63":[2,181],"81":[2,181],"86":[2,181],"96":[2,181],"100":[2,181],"108":[2,181],"110":[2,181],"111":[2,181],"112":[2,181],"116":[2,181],"122":[2,181],"123":[2,181],"124":[2,181],"127":[2,181],"131":[2,181],"132":[2,181],"133":[2,181],"135":[2,181],"136":[2,181],"138":[2,181],"139":[2,181],"142":[2,181],"143":[2,181],"144":[2,181],"145":[2,181],"146":[2,181],"147":[2,181],"148":[2,181],"149":[2,181],"150":[2,181],"151":[2,181],"152":[2,181],"153":[2,181],"154":[2,181],"155":[2,181],"156":[2,181],"157":[2,181],"158":[2,181],"159":[2,181],"160":[2,181],"161":[2,181],"162":[2,181],"163":[2,181],"164":[2,181],"165":[2,181],"166":[2,181],"167":[2,181],"168":[2,181]},{"1":[2,135],"4":[2,135],"29":[2,135],"30":[2,135],"51":[2,135],"59":[2,135],"63":[2,135],"81":[2,135],"86":[2,135],"96":[2,135],"100":[2,135],"104":[1,316],"108":[2,135],"110":[2,135],"111":[2,135],"112":[2,135],"116":[2,135],"122":[2,135],"123":[2,135],"124":[2,135],"131":[2,135],"132":[2,135],"133":[2,135],"135":[2,135],"136":[2,135],"138":[2,135],"139":[2,135],"142":[2,135],"143":[2,135],"144":[2,135],"145":[2,135],"146":[2,135],"147":[2,135],"148":[2,135],"149":[2,135],"150":[2,135],"151":[2,135],"152":[2,135],"153":[2,135],"154":[2,135],"155":[2,135],"156":[2,135],"157":[2,135],"158":[2,135],"159":[2,135],"160":[2,135],"161":[2,135],"162":[2,135],"163":[2,135],"164":[2,135],"165":[2,135],"166":[2,135],"167":[2,135],"168":[2,135]},{"4":[1,163],"6":317,"29":[1,6]},{"31":318,"32":[1,89]},{"126":319,"128":275,"129":[1,276]},{"30":[1,320],"127":[1,321],"128":322,"129":[1,276]},{"30":[2,174],"127":[2,174],"129":[2,174]},{"8":324,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"101":323,"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,114],"4":[2,114],"29":[2,114],"30":[2,114],"51":[2,114],"59":[2,114],"63":[2,114],"65":140,"74":[1,142],"75":[1,143],"76":[1,144],"77":[1,145],"78":146,"79":147,"80":[1,148],"81":[2,114],"82":[1,149],"83":[1,150],"86":[2,114],"93":139,"94":[1,141],"96":[2,114],"100":[2,114],"108":[2,114],"110":[2,114],"111":[2,114],"112":[2,114],"116":[2,114],"122":[2,114],"123":[2,114],"124":[2,114],"131":[2,114],"132":[2,114],"133":[2,114],"135":[2,114],"136":[2,114],"138":[2,114],"139":[2,114],"142":[2,114],"143":[2,114],"144":[2,114],"145":[2,114],"146":[2,114],"147":[2,114],"148":[2,114],"149":[2,114],"150":[2,114],"151":[2,114],"152":[2,114],"153":[2,114],"154":[2,114],"155":[2,114],"156":[2,114],"157":[2,114],"158":[2,114],"159":[2,114],"160":[2,114],"161":[2,114],"162":[2,114],"163":[2,114],"164":[2,114],"165":[2,114],"166":[2,114],"167":[2,114],"168":[2,114]},{"14":325,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":156,"62":[1,73],"64":157,"66":184,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"98":[1,72],"99":[1,71],"107":[1,70]},{"4":[2,106],"28":212,"30":[2,106],"31":210,"32":[1,89],"33":211,"34":[1,87],"35":[1,88],"47":283,"50":[1,56],"62":[1,285],"67":284,"84":[1,282],"89":326,"90":281},{"4":[1,328],"30":[1,327]},{"4":[2,107],"30":[2,107],"86":[2,107]},{"4":[2,106],"28":212,"31":210,"32":[1,89],"33":211,"34":[1,87],"35":[1,88],"47":283,"50":[1,56],"62":[1,285],"67":284,"84":[1,282],"86":[2,106],"89":329,"90":281},{"4":[2,104],"30":[2,104],"86":[2,104]},{"48":[1,330]},{"31":190,"32":[1,89]},{"1":[2,140],"4":[2,140],"29":[2,140],"30":[2,140],"51":[2,140],"59":[2,140],"63":[2,140],"74":[2,140],"75":[2,140],"76":[2,140],"77":[2,140],"80":[2,140],"81":[2,140],"82":[2,140],"83":[2,140],"86":[2,140],"94":[2,140],"96":[2,140],"100":[2,140],"108":[2,140],"110":[2,140],"111":[2,140],"112":[2,140],"116":[2,140],"122":[2,140],"123":[2,140],"124":[2,140],"131":[2,140],"132":[2,140],"133":[2,140],"135":[2,140],"136":[2,140],"138":[2,140],"139":[2,140],"142":[2,140],"143":[2,140],"144":[2,140],"145":[2,140],"146":[2,140],"147":[2,140],"148":[2,140],"149":[2,140],"150":[2,140],"151":[2,140],"152":[2,140],"153":[2,140],"154":[2,140],"155":[2,140],"156":[2,140],"157":[2,140],"158":[2,140],"159":[2,140],"160":[2,140],"161":[2,140],"162":[2,140],"163":[2,140],"164":[2,140],"165":[2,140],"166":[2,140],"167":[2,140],"168":[2,140]},{"63":[1,331]},{"4":[1,333],"29":[1,334],"100":[1,332]},{"4":[2,62],"8":335,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"29":[2,62],"30":[2,62],"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"96":[2,62],"97":[1,74],"98":[1,72],"99":[1,71],"100":[2,62],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,178],"4":[2,178],"29":[2,178],"30":[2,178],"51":[2,178],"59":[2,178],"63":[2,178],"81":[2,178],"86":[2,178],"96":[2,178],"100":[2,178],"108":[2,178],"110":[2,178],"111":[2,178],"112":[2,178],"116":[2,178],"122":[2,178],"123":[2,178],"124":[2,178],"127":[2,178],"131":[2,178],"132":[2,178],"133":[2,178],"135":[2,178],"136":[2,178],"138":[2,178],"139":[2,178],"142":[2,178],"143":[2,178],"144":[2,178],"145":[2,178],"146":[2,178],"147":[2,178],"148":[2,178],"149":[2,178],"150":[2,178],"151":[2,178],"152":[2,178],"153":[2,178],"154":[2,178],"155":[2,178],"156":[2,178],"157":[2,178],"158":[2,178],"159":[2,178],"160":[2,178],"161":[2,178],"162":[2,178],"163":[2,178],"164":[2,178],"165":[2,178],"166":[2,178],"167":[2,178],"168":[2,178]},{"1":[2,179],"4":[2,179],"29":[2,179],"30":[2,179],"51":[2,179],"59":[2,179],"63":[2,179],"81":[2,179],"86":[2,179],"96":[2,179],"100":[2,179],"108":[2,179],"110":[2,179],"111":[2,179],"112":[2,179],"116":[2,179],"122":[2,179],"123":[2,179],"124":[2,179],"127":[2,179],"131":[2,179],"132":[2,179],"133":[2,179],"135":[2,179],"136":[2,179],"138":[2,179],"139":[2,179],"142":[2,179],"143":[2,179],"144":[2,179],"145":[2,179],"146":[2,179],"147":[2,179],"148":[2,179],"149":[2,179],"150":[2,179],"151":[2,179],"152":[2,179],"153":[2,179],"154":[2,179],"155":[2,179],"156":[2,179],"157":[2,179],"158":[2,179],"159":[2,179],"160":[2,179],"161":[2,179],"162":[2,179],"163":[2,179],"164":[2,179],"165":[2,179],"166":[2,179],"167":[2,179],"168":[2,179]},{"8":336,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":337,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"122":[2,157],"123":[2,157]},{"4":[2,128],"8":254,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"29":[2,128],"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"59":[2,128],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"95":189,"97":[1,74],"98":[1,72],"99":[1,71],"100":[2,128],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"31":202,"32":[1,89],"68":203,"69":204,"84":[1,86],"99":[1,295],"121":338},{"1":[2,163],"4":[2,163],"29":[2,163],"30":[2,163],"51":[1,134],"59":[2,163],"63":[1,133],"81":[2,163],"86":[2,163],"96":[2,163],"100":[2,163],"108":[2,163],"109":131,"110":[2,163],"111":[1,339],"112":[2,163],"115":132,"116":[2,163],"117":83,"122":[1,126],"123":[1,127],"124":[1,340],"131":[2,163],"132":[2,163],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,164],"4":[2,164],"29":[2,164],"30":[2,164],"51":[1,134],"59":[2,164],"63":[1,133],"81":[2,164],"86":[2,164],"96":[2,164],"100":[2,164],"108":[2,164],"109":131,"110":[2,164],"111":[1,341],"112":[2,164],"115":132,"116":[2,164],"117":83,"122":[1,126],"123":[1,127],"124":[2,164],"131":[2,164],"132":[2,164],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"4":[1,343],"29":[1,344],"86":[1,342]},{"4":[2,62],"28":212,"29":[2,62],"30":[2,62],"31":210,"32":[1,89],"33":211,"34":[1,87],"35":[1,88],"47":345,"50":[1,56],"86":[2,62]},{"8":346,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"29":[1,347],"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":348,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"29":[1,349],"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,229],"4":[2,229],"29":[2,229],"30":[2,229],"51":[1,134],"59":[2,229],"63":[2,229],"81":[2,229],"86":[2,229],"96":[2,229],"100":[2,229],"108":[2,229],"109":131,"110":[2,229],"111":[2,229],"112":[2,229],"115":132,"116":[2,229],"117":83,"122":[2,229],"123":[2,229],"124":[2,229],"131":[2,229],"132":[2,229],"135":[2,229],"136":[2,229],"142":[2,229],"143":[2,229],"144":[2,229],"145":[2,229],"146":[2,229],"147":[2,229],"148":[2,229],"149":[2,229],"150":[2,229],"151":[2,229],"152":[2,229],"153":[2,229],"154":[2,229],"155":[2,229],"156":[2,229],"157":[2,229],"158":[2,229],"159":[2,229],"160":[2,229],"161":[2,229],"162":[2,229],"163":[2,229],"164":[2,229],"165":[2,229],"166":[2,229],"167":[2,229],"168":[2,229]},{"1":[2,230],"4":[2,230],"29":[2,230],"30":[2,230],"51":[1,134],"59":[2,230],"63":[2,230],"81":[2,230],"86":[2,230],"96":[2,230],"100":[2,230],"108":[2,230],"109":131,"110":[2,230],"111":[2,230],"112":[2,230],"115":132,"116":[2,230],"117":83,"122":[2,230],"123":[2,230],"124":[2,230],"131":[2,230],"132":[2,230],"135":[2,230],"136":[2,230],"142":[2,230],"143":[2,230],"144":[2,230],"145":[2,230],"146":[2,230],"147":[2,230],"148":[2,230],"149":[2,230],"150":[2,230],"151":[2,230],"152":[2,230],"153":[2,230],"154":[2,230],"155":[2,230],"156":[2,230],"157":[2,230],"158":[2,230],"159":[2,230],"160":[2,230],"161":[2,230],"162":[2,230],"163":[2,230],"164":[2,230],"165":[2,230],"166":[2,230],"167":[2,230],"168":[2,230]},{"1":[2,70],"4":[2,70],"29":[2,70],"30":[2,70],"51":[2,70],"59":[2,70],"63":[2,70],"81":[2,70],"86":[2,70],"96":[2,70],"100":[2,70],"108":[2,70],"110":[2,70],"111":[2,70],"112":[2,70],"116":[2,70],"122":[2,70],"123":[2,70],"124":[2,70],"131":[2,70],"132":[2,70],"133":[2,70],"135":[2,70],"136":[2,70],"138":[2,70],"139":[2,70],"142":[2,70],"143":[2,70],"144":[2,70],"145":[2,70],"146":[2,70],"147":[2,70],"148":[2,70],"149":[2,70],"150":[2,70],"151":[2,70],"152":[2,70],"153":[2,70],"154":[2,70],"155":[2,70],"156":[2,70],"157":[2,70],"158":[2,70],"159":[2,70],"160":[2,70],"161":[2,70],"162":[2,70],"163":[2,70],"164":[2,70],"165":[2,70],"166":[2,70],"167":[2,70],"168":[2,70]},{"4":[1,333],"29":[1,334],"96":[1,350]},{"1":[2,90],"4":[2,90],"29":[2,90],"30":[2,90],"46":[2,90],"51":[2,90],"59":[2,90],"63":[2,90],"74":[2,90],"75":[2,90],"76":[2,90],"77":[2,90],"80":[2,90],"81":[2,90],"82":[2,90],"83":[2,90],"86":[2,90],"88":[2,90],"94":[2,90],"96":[2,90],"100":[2,90],"108":[2,90],"110":[2,90],"111":[2,90],"112":[2,90],"116":[2,90],"122":[2,90],"123":[2,90],"124":[2,90],"131":[2,90],"132":[2,90],"133":[2,90],"135":[2,90],"136":[2,90],"138":[2,90],"139":[2,90],"142":[2,90],"143":[2,90],"144":[2,90],"145":[2,90],"146":[2,90],"147":[2,90],"148":[2,90],"149":[2,90],"150":[2,90],"151":[2,90],"152":[2,90],"153":[2,90],"154":[2,90],"155":[2,90],"156":[2,90],"157":[2,90],"158":[2,90],"159":[2,90],"160":[2,90],"161":[2,90],"162":[2,90],"163":[2,90],"164":[2,90],"165":[2,90],"166":[2,90],"167":[2,90],"168":[2,90]},{"63":[1,351]},{"51":[1,134],"63":[1,133],"81":[1,307],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"30":[1,352],"51":[1,134],"63":[1,133],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"4":[1,163],"6":353,"29":[1,6]},{"54":[2,65],"59":[2,65]},{"63":[1,354]},{"63":[1,355]},{"4":[1,163],"6":356,"29":[1,6],"51":[1,134],"63":[1,133],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"4":[1,163],"6":357,"29":[1,6]},{"1":[2,136],"4":[2,136],"29":[2,136],"30":[2,136],"51":[2,136],"59":[2,136],"63":[2,136],"81":[2,136],"86":[2,136],"96":[2,136],"100":[2,136],"108":[2,136],"110":[2,136],"111":[2,136],"112":[2,136],"116":[2,136],"122":[2,136],"123":[2,136],"124":[2,136],"131":[2,136],"132":[2,136],"133":[2,136],"135":[2,136],"136":[2,136],"138":[2,136],"139":[2,136],"142":[2,136],"143":[2,136],"144":[2,136],"145":[2,136],"146":[2,136],"147":[2,136],"148":[2,136],"149":[2,136],"150":[2,136],"151":[2,136],"152":[2,136],"153":[2,136],"154":[2,136],"155":[2,136],"156":[2,136],"157":[2,136],"158":[2,136],"159":[2,136],"160":[2,136],"161":[2,136],"162":[2,136],"163":[2,136],"164":[2,136],"165":[2,136],"166":[2,136],"167":[2,136],"168":[2,136]},{"4":[1,163],"6":358,"29":[1,6]},{"30":[1,359],"127":[1,360],"128":322,"129":[1,276]},{"1":[2,172],"4":[2,172],"29":[2,172],"30":[2,172],"51":[2,172],"59":[2,172],"63":[2,172],"81":[2,172],"86":[2,172],"96":[2,172],"100":[2,172],"108":[2,172],"110":[2,172],"111":[2,172],"112":[2,172],"116":[2,172],"122":[2,172],"123":[2,172],"124":[2,172],"131":[2,172],"132":[2,172],"133":[2,172],"135":[2,172],"136":[2,172],"138":[2,172],"139":[2,172],"142":[2,172],"143":[2,172],"144":[2,172],"145":[2,172],"146":[2,172],"147":[2,172],"148":[2,172],"149":[2,172],"150":[2,172],"151":[2,172],"152":[2,172],"153":[2,172],"154":[2,172],"155":[2,172],"156":[2,172],"157":[2,172],"158":[2,172],"159":[2,172],"160":[2,172],"161":[2,172],"162":[2,172],"163":[2,172],"164":[2,172],"165":[2,172],"166":[2,172],"167":[2,172],"168":[2,172]},{"4":[1,163],"6":361,"29":[1,6]},{"30":[2,175],"127":[2,175],"129":[2,175]},{"4":[1,163],"6":362,"29":[1,6],"59":[1,363]},{"4":[2,133],"29":[2,133],"51":[1,134],"59":[2,133],"63":[1,133],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,100],"4":[2,100],"29":[1,364],"30":[2,100],"51":[2,100],"59":[2,100],"63":[2,100],"65":140,"74":[1,142],"75":[1,143],"76":[1,144],"77":[1,145],"78":146,"79":147,"80":[1,148],"81":[2,100],"82":[1,149],"83":[1,150],"86":[2,100],"93":139,"94":[1,141],"96":[2,100],"100":[2,100],"108":[2,100],"110":[2,100],"111":[2,100],"112":[2,100],"116":[2,100],"122":[2,100],"123":[2,100],"124":[2,100],"131":[2,100],"132":[2,100],"133":[2,100],"135":[2,100],"136":[2,100],"138":[2,100],"139":[2,100],"142":[2,100],"143":[2,100],"144":[2,100],"145":[2,100],"146":[2,100],"147":[2,100],"148":[2,100],"149":[2,100],"150":[2,100],"151":[2,100],"152":[2,100],"153":[2,100],"154":[2,100],"155":[2,100],"156":[2,100],"157":[2,100],"158":[2,100],"159":[2,100],"160":[2,100],"161":[2,100],"162":[2,100],"163":[2,100],"164":[2,100],"165":[2,100],"166":[2,100],"167":[2,100],"168":[2,100]},{"4":[1,328],"30":[1,365]},{"1":[2,103],"4":[2,103],"29":[2,103],"30":[2,103],"51":[2,103],"59":[2,103],"63":[2,103],"81":[2,103],"86":[2,103],"96":[2,103],"100":[2,103],"108":[2,103],"110":[2,103],"111":[2,103],"112":[2,103],"116":[2,103],"122":[2,103],"123":[2,103],"124":[2,103],"131":[2,103],"132":[2,103],"133":[2,103],"135":[2,103],"136":[2,103],"138":[2,103],"139":[2,103],"142":[2,103],"143":[2,103],"144":[2,103],"145":[2,103],"146":[2,103],"147":[2,103],"148":[2,103],"149":[2,103],"150":[2,103],"151":[2,103],"152":[2,103],"153":[2,103],"154":[2,103],"155":[2,103],"156":[2,103],"157":[2,103],"158":[2,103],"159":[2,103],"160":[2,103],"161":[2,103],"162":[2,103],"163":[2,103],"164":[2,103],"165":[2,103],"166":[2,103],"167":[2,103],"168":[2,103]},{"28":212,"31":210,"32":[1,89],"33":211,"34":[1,87],"35":[1,88],"47":283,"50":[1,56],"62":[1,285],"67":284,"90":366},{"4":[1,328],"86":[1,367]},{"8":368,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":369,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"63":[1,370],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,127],"4":[2,127],"29":[2,127],"30":[2,127],"46":[2,127],"51":[2,127],"59":[2,127],"63":[2,127],"74":[2,127],"75":[2,127],"76":[2,127],"77":[2,127],"80":[2,127],"81":[2,127],"82":[2,127],"83":[2,127],"86":[2,127],"94":[2,127],"96":[2,127],"100":[2,127],"108":[2,127],"110":[2,127],"111":[2,127],"112":[2,127],"116":[2,127],"122":[2,127],"123":[2,127],"124":[2,127],"131":[2,127],"132":[2,127],"133":[2,127],"135":[2,127],"136":[2,127],"138":[2,127],"139":[2,127],"142":[2,127],"143":[2,127],"144":[2,127],"145":[2,127],"146":[2,127],"147":[2,127],"148":[2,127],"149":[2,127],"150":[2,127],"151":[2,127],"152":[2,127],"153":[2,127],"154":[2,127],"155":[2,127],"156":[2,127],"157":[2,127],"158":[2,127],"159":[2,127],"160":[2,127],"161":[2,127],"162":[2,127],"163":[2,127],"164":[2,127],"165":[2,127],"166":[2,127],"167":[2,127],"168":[2,127]},{"8":371,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"4":[2,128],"8":254,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"29":[2,128],"30":[2,128],"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"59":[2,128],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"95":372,"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"4":[2,130],"29":[2,130],"30":[2,130],"51":[1,134],"59":[2,130],"63":[1,133],"96":[2,130],"100":[2,130],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,142],"4":[2,142],"29":[2,142],"30":[2,142],"51":[1,134],"59":[2,142],"63":[1,133],"81":[2,142],"86":[2,142],"96":[2,142],"100":[2,142],"108":[2,142],"109":131,"110":[1,79],"111":[2,142],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"124":[2,142],"131":[2,142],"132":[2,142],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,144],"4":[2,144],"29":[2,144],"30":[2,144],"51":[1,134],"59":[2,144],"63":[1,133],"81":[2,144],"86":[2,144],"96":[2,144],"100":[2,144],"108":[2,144],"109":131,"110":[1,79],"111":[2,144],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"124":[2,144],"131":[2,144],"132":[2,144],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"122":[2,162],"123":[2,162]},{"8":373,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":374,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":375,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,93],"4":[2,93],"29":[2,93],"30":[2,93],"46":[2,93],"51":[2,93],"59":[2,93],"63":[2,93],"74":[2,93],"75":[2,93],"76":[2,93],"77":[2,93],"80":[2,93],"81":[2,93],"82":[2,93],"83":[2,93],"86":[2,93],"94":[2,93],"96":[2,93],"100":[2,93],"108":[2,93],"110":[2,93],"111":[2,93],"112":[2,93],"116":[2,93],"122":[2,93],"123":[2,93],"124":[2,93],"131":[2,93],"132":[2,93],"133":[2,93],"135":[2,93],"136":[2,93],"138":[2,93],"139":[2,93],"142":[2,93],"143":[2,93],"144":[2,93],"145":[2,93],"146":[2,93],"147":[2,93],"148":[2,93],"149":[2,93],"150":[2,93],"151":[2,93],"152":[2,93],"153":[2,93],"154":[2,93],"155":[2,93],"156":[2,93],"157":[2,93],"158":[2,93],"159":[2,93],"160":[2,93],"161":[2,93],"162":[2,93],"163":[2,93],"164":[2,93],"165":[2,93],"166":[2,93],"167":[2,93],"168":[2,93]},{"28":212,"31":210,"32":[1,89],"33":211,"34":[1,87],"35":[1,88],"47":376,"50":[1,56]},{"4":[2,94],"28":212,"29":[2,94],"30":[2,94],"31":210,"32":[1,89],"33":211,"34":[1,87],"35":[1,88],"47":209,"50":[1,56],"59":[2,94],"85":377},{"4":[2,96],"29":[2,96],"30":[2,96],"59":[2,96],"86":[2,96]},{"4":[2,48],"29":[2,48],"30":[2,48],"51":[1,134],"59":[2,48],"63":[1,133],"86":[2,48],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"8":378,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"4":[2,49],"29":[2,49],"30":[2,49],"51":[1,134],"59":[2,49],"63":[1,133],"86":[2,49],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"8":379,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,117],"4":[2,117],"29":[2,117],"30":[2,117],"51":[2,117],"59":[2,117],"63":[2,117],"74":[2,117],"75":[2,117],"76":[2,117],"77":[2,117],"80":[2,117],"81":[2,117],"82":[2,117],"83":[2,117],"86":[2,117],"94":[2,117],"96":[2,117],"100":[2,117],"108":[2,117],"110":[2,117],"111":[2,117],"112":[2,117],"116":[2,117],"122":[2,117],"123":[2,117],"124":[2,117],"131":[2,117],"132":[2,117],"133":[2,117],"135":[2,117],"136":[2,117],"138":[2,117],"139":[2,117],"142":[2,117],"143":[2,117],"144":[2,117],"145":[2,117],"146":[2,117],"147":[2,117],"148":[2,117],"149":[2,117],"150":[2,117],"151":[2,117],"152":[2,117],"153":[2,117],"154":[2,117],"155":[2,117],"156":[2,117],"157":[2,117],"158":[2,117],"159":[2,117],"160":[2,117],"161":[2,117],"162":[2,117],"163":[2,117],"164":[2,117],"165":[2,117],"166":[2,117],"167":[2,117],"168":[2,117]},{"8":380,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"63":[1,381],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"1":[2,45],"4":[2,45],"29":[2,45],"30":[2,45],"51":[2,45],"59":[2,45],"63":[2,45],"81":[2,45],"86":[2,45],"96":[2,45],"100":[2,45],"108":[2,45],"110":[2,45],"111":[2,45],"112":[2,45],"116":[2,45],"122":[2,45],"123":[2,45],"124":[2,45],"131":[2,45],"132":[2,45],"133":[2,45],"135":[2,45],"136":[2,45],"138":[2,45],"139":[2,45],"142":[2,45],"143":[2,45],"144":[2,45],"145":[2,45],"146":[2,45],"147":[2,45],"148":[2,45],"149":[2,45],"150":[2,45],"151":[2,45],"152":[2,45],"153":[2,45],"154":[2,45],"155":[2,45],"156":[2,45],"157":[2,45],"158":[2,45],"159":[2,45],"160":[2,45],"161":[2,45],"162":[2,45],"163":[2,45],"164":[2,45],"165":[2,45],"166":[2,45],"167":[2,45],"168":[2,45]},{"1":[2,57],"4":[2,57],"29":[2,57],"30":[2,57],"51":[2,57],"59":[2,57],"63":[2,57],"81":[2,57],"86":[2,57],"96":[2,57],"100":[2,57],"108":[2,57],"110":[2,57],"111":[2,57],"112":[2,57],"116":[2,57],"122":[2,57],"123":[2,57],"124":[2,57],"131":[2,57],"132":[2,57],"133":[2,57],"135":[2,57],"136":[2,57],"138":[2,57],"139":[2,57],"142":[2,57],"143":[2,57],"144":[2,57],"145":[2,57],"146":[2,57],"147":[2,57],"148":[2,57],"149":[2,57],"150":[2,57],"151":[2,57],"152":[2,57],"153":[2,57],"154":[2,57],"155":[2,57],"156":[2,57],"157":[2,57],"158":[2,57],"159":[2,57],"160":[2,57],"161":[2,57],"162":[2,57],"163":[2,57],"164":[2,57],"165":[2,57],"166":[2,57],"167":[2,57],"168":[2,57]},{"54":[2,68],"59":[2,68]},{"63":[1,382]},{"1":[2,180],"4":[2,180],"29":[2,180],"30":[2,180],"51":[2,180],"59":[2,180],"63":[2,180],"81":[2,180],"86":[2,180],"96":[2,180],"100":[2,180],"108":[2,180],"110":[2,180],"111":[2,180],"112":[2,180],"116":[2,180],"122":[2,180],"123":[2,180],"124":[2,180],"127":[2,180],"131":[2,180],"132":[2,180],"133":[2,180],"135":[2,180],"136":[2,180],"138":[2,180],"139":[2,180],"142":[2,180],"143":[2,180],"144":[2,180],"145":[2,180],"146":[2,180],"147":[2,180],"148":[2,180],"149":[2,180],"150":[2,180],"151":[2,180],"152":[2,180],"153":[2,180],"154":[2,180],"155":[2,180],"156":[2,180],"157":[2,180],"158":[2,180],"159":[2,180],"160":[2,180],"161":[2,180],"162":[2,180],"163":[2,180],"164":[2,180],"165":[2,180],"166":[2,180],"167":[2,180],"168":[2,180]},{"1":[2,137],"4":[2,137],"29":[2,137],"30":[2,137],"51":[2,137],"59":[2,137],"63":[2,137],"81":[2,137],"86":[2,137],"96":[2,137],"100":[2,137],"108":[2,137],"110":[2,137],"111":[2,137],"112":[2,137],"116":[2,137],"122":[2,137],"123":[2,137],"124":[2,137],"131":[2,137],"132":[2,137],"133":[2,137],"135":[2,137],"136":[2,137],"138":[2,137],"139":[2,137],"142":[2,137],"143":[2,137],"144":[2,137],"145":[2,137],"146":[2,137],"147":[2,137],"148":[2,137],"149":[2,137],"150":[2,137],"151":[2,137],"152":[2,137],"153":[2,137],"154":[2,137],"155":[2,137],"156":[2,137],"157":[2,137],"158":[2,137],"159":[2,137],"160":[2,137],"161":[2,137],"162":[2,137],"163":[2,137],"164":[2,137],"165":[2,137],"166":[2,137],"167":[2,137],"168":[2,137]},{"1":[2,138],"4":[2,138],"29":[2,138],"30":[2,138],"51":[2,138],"59":[2,138],"63":[2,138],"81":[2,138],"86":[2,138],"96":[2,138],"100":[2,138],"104":[2,138],"108":[2,138],"110":[2,138],"111":[2,138],"112":[2,138],"116":[2,138],"122":[2,138],"123":[2,138],"124":[2,138],"131":[2,138],"132":[2,138],"133":[2,138],"135":[2,138],"136":[2,138],"138":[2,138],"139":[2,138],"142":[2,138],"143":[2,138],"144":[2,138],"145":[2,138],"146":[2,138],"147":[2,138],"148":[2,138],"149":[2,138],"150":[2,138],"151":[2,138],"152":[2,138],"153":[2,138],"154":[2,138],"155":[2,138],"156":[2,138],"157":[2,138],"158":[2,138],"159":[2,138],"160":[2,138],"161":[2,138],"162":[2,138],"163":[2,138],"164":[2,138],"165":[2,138],"166":[2,138],"167":[2,138],"168":[2,138]},{"1":[2,170],"4":[2,170],"29":[2,170],"30":[2,170],"51":[2,170],"59":[2,170],"63":[2,170],"81":[2,170],"86":[2,170],"96":[2,170],"100":[2,170],"108":[2,170],"110":[2,170],"111":[2,170],"112":[2,170],"116":[2,170],"122":[2,170],"123":[2,170],"124":[2,170],"131":[2,170],"132":[2,170],"133":[2,170],"135":[2,170],"136":[2,170],"138":[2,170],"139":[2,170],"142":[2,170],"143":[2,170],"144":[2,170],"145":[2,170],"146":[2,170],"147":[2,170],"148":[2,170],"149":[2,170],"150":[2,170],"151":[2,170],"152":[2,170],"153":[2,170],"154":[2,170],"155":[2,170],"156":[2,170],"157":[2,170],"158":[2,170],"159":[2,170],"160":[2,170],"161":[2,170],"162":[2,170],"163":[2,170],"164":[2,170],"165":[2,170],"166":[2,170],"167":[2,170],"168":[2,170]},{"4":[1,163],"6":383,"29":[1,6]},{"30":[1,384]},{"4":[1,385],"30":[2,176],"127":[2,176],"129":[2,176]},{"8":386,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"4":[2,106],"28":212,"30":[2,106],"31":210,"32":[1,89],"33":211,"34":[1,87],"35":[1,88],"47":283,"50":[1,56],"62":[1,285],"67":284,"84":[1,282],"89":387,"90":281},{"1":[2,101],"4":[2,101],"29":[2,101],"30":[2,101],"51":[2,101],"59":[2,101],"63":[2,101],"81":[2,101],"86":[2,101],"96":[2,101],"100":[2,101],"108":[2,101],"110":[2,101],"111":[2,101],"112":[2,101],"116":[2,101],"122":[2,101],"123":[2,101],"124":[2,101],"131":[2,101],"132":[2,101],"133":[2,101],"135":[2,101],"136":[2,101],"138":[2,101],"139":[2,101],"142":[2,101],"143":[2,101],"144":[2,101],"145":[2,101],"146":[2,101],"147":[2,101],"148":[2,101],"149":[2,101],"150":[2,101],"151":[2,101],"152":[2,101],"153":[2,101],"154":[2,101],"155":[2,101],"156":[2,101],"157":[2,101],"158":[2,101],"159":[2,101],"160":[2,101],"161":[2,101],"162":[2,101],"163":[2,101],"164":[2,101],"165":[2,101],"166":[2,101],"167":[2,101],"168":[2,101]},{"4":[2,108],"30":[2,108],"86":[2,108]},{"4":[2,109],"30":[2,109],"86":[2,109]},{"4":[2,105],"30":[2,105],"51":[1,134],"63":[1,133],"86":[2,105],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"51":[1,134],"63":[1,133],"100":[1,388],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"4":[2,70],"8":389,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"29":[2,70],"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"51":[2,70],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"59":[2,70],"62":[1,73],"63":[2,70],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"100":[2,70],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[2,70],"112":[2,70],"113":51,"114":[1,81],"115":52,"116":[2,70],"117":83,"122":[2,70],"123":[2,70],"125":[1,53],"130":48,"131":[2,70],"132":[2,70],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47],"142":[2,70],"143":[2,70],"144":[2,70],"145":[2,70],"146":[2,70],"147":[2,70],"148":[2,70],"149":[2,70],"150":[2,70],"151":[2,70],"152":[2,70],"153":[2,70],"154":[2,70],"155":[2,70],"156":[2,70],"157":[2,70],"158":[2,70],"159":[2,70],"160":[2,70],"161":[2,70],"162":[2,70],"163":[2,70],"164":[2,70],"165":[2,70],"166":[2,70],"167":[2,70],"168":[2,70]},{"4":[2,131],"29":[2,131],"30":[2,131],"51":[1,134],"59":[2,131],"63":[1,133],"96":[2,131],"100":[2,131],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"4":[2,61],"29":[2,61],"30":[2,61],"58":390,"59":[1,289]},{"1":[2,165],"4":[2,165],"29":[2,165],"30":[2,165],"51":[1,134],"59":[2,165],"63":[1,133],"81":[2,165],"86":[2,165],"96":[2,165],"100":[2,165],"108":[2,165],"109":131,"110":[2,165],"111":[2,165],"112":[2,165],"115":132,"116":[2,165],"117":83,"122":[1,126],"123":[1,127],"124":[1,391],"131":[2,165],"132":[2,165],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,167],"4":[2,167],"29":[2,167],"30":[2,167],"51":[1,134],"59":[2,167],"63":[1,133],"81":[2,167],"86":[2,167],"96":[2,167],"100":[2,167],"108":[2,167],"109":131,"110":[2,167],"111":[1,392],"112":[2,167],"115":132,"116":[2,167],"117":83,"122":[1,126],"123":[1,127],"124":[2,167],"131":[2,167],"132":[2,167],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,166],"4":[2,166],"29":[2,166],"30":[2,166],"51":[1,134],"59":[2,166],"63":[1,133],"81":[2,166],"86":[2,166],"96":[2,166],"100":[2,166],"108":[2,166],"109":131,"110":[2,166],"111":[2,166],"112":[2,166],"115":132,"116":[2,166],"117":83,"122":[1,126],"123":[1,127],"124":[2,166],"131":[2,166],"132":[2,166],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"4":[2,97],"29":[2,97],"30":[2,97],"59":[2,97],"86":[2,97]},{"4":[2,61],"29":[2,61],"30":[2,61],"58":393,"59":[1,300]},{"30":[1,394],"51":[1,134],"63":[1,133],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"30":[1,395],"51":[1,134],"63":[1,133],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"51":[1,134],"63":[1,133],"81":[1,396],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"8":397,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"51":[2,70],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"63":[2,70],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"81":[2,70],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[2,70],"112":[2,70],"113":51,"114":[1,81],"115":52,"116":[2,70],"117":83,"122":[2,70],"123":[2,70],"125":[1,53],"130":48,"131":[2,70],"132":[2,70],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47],"142":[2,70],"143":[2,70],"144":[2,70],"145":[2,70],"146":[2,70],"147":[2,70],"148":[2,70],"149":[2,70],"150":[2,70],"151":[2,70],"152":[2,70],"153":[2,70],"154":[2,70],"155":[2,70],"156":[2,70],"157":[2,70],"158":[2,70],"159":[2,70],"160":[2,70],"161":[2,70],"162":[2,70],"163":[2,70],"164":[2,70],"165":[2,70],"166":[2,70],"167":[2,70],"168":[2,70]},{"54":[2,69],"59":[2,69]},{"30":[1,398]},{"1":[2,173],"4":[2,173],"29":[2,173],"30":[2,173],"51":[2,173],"59":[2,173],"63":[2,173],"81":[2,173],"86":[2,173],"96":[2,173],"100":[2,173],"108":[2,173],"110":[2,173],"111":[2,173],"112":[2,173],"116":[2,173],"122":[2,173],"123":[2,173],"124":[2,173],"131":[2,173],"132":[2,173],"133":[2,173],"135":[2,173],"136":[2,173],"138":[2,173],"139":[2,173],"142":[2,173],"143":[2,173],"144":[2,173],"145":[2,173],"146":[2,173],"147":[2,173],"148":[2,173],"149":[2,173],"150":[2,173],"151":[2,173],"152":[2,173],"153":[2,173],"154":[2,173],"155":[2,173],"156":[2,173],"157":[2,173],"158":[2,173],"159":[2,173],"160":[2,173],"161":[2,173],"162":[2,173],"163":[2,173],"164":[2,173],"165":[2,173],"166":[2,173],"167":[2,173],"168":[2,173]},{"30":[2,177],"127":[2,177],"129":[2,177]},{"4":[2,134],"29":[2,134],"51":[1,134],"59":[2,134],"63":[1,133],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"4":[1,328],"30":[1,399]},{"1":[2,123],"4":[2,123],"29":[2,123],"30":[2,123],"51":[2,123],"59":[2,123],"63":[2,123],"74":[2,123],"75":[2,123],"76":[2,123],"77":[2,123],"80":[2,123],"81":[2,123],"82":[2,123],"83":[2,123],"86":[2,123],"94":[2,123],"96":[2,123],"100":[2,123],"108":[2,123],"110":[2,123],"111":[2,123],"112":[2,123],"116":[2,123],"122":[2,123],"123":[2,123],"124":[2,123],"131":[2,123],"132":[2,123],"133":[2,123],"135":[2,123],"136":[2,123],"138":[2,123],"139":[2,123],"142":[2,123],"143":[2,123],"144":[2,123],"145":[2,123],"146":[2,123],"147":[2,123],"148":[2,123],"149":[2,123],"150":[2,123],"151":[2,123],"152":[2,123],"153":[2,123],"154":[2,123],"155":[2,123],"156":[2,123],"157":[2,123],"158":[2,123],"159":[2,123],"160":[2,123],"161":[2,123],"162":[2,123],"163":[2,123],"164":[2,123],"165":[2,123],"166":[2,123],"167":[2,123],"168":[2,123]},{"51":[1,134],"63":[1,133],"100":[1,400],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"4":[1,333],"29":[1,334],"30":[1,401]},{"8":402,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"8":403,"9":165,"10":24,"11":25,"12":[1,26],"13":[1,27],"14":9,"15":10,"16":11,"17":12,"18":13,"19":14,"20":15,"21":16,"22":17,"23":18,"24":19,"25":20,"26":21,"27":22,"28":23,"31":84,"32":[1,89],"33":61,"34":[1,87],"35":[1,88],"36":29,"37":[1,62],"38":[1,63],"39":[1,64],"40":[1,65],"41":[1,66],"42":[1,67],"43":[1,68],"44":[1,69],"45":28,"49":[1,57],"50":[1,56],"52":[1,37],"55":38,"56":[1,75],"57":[1,76],"62":[1,73],"64":54,"66":34,"67":85,"68":59,"69":60,"70":30,"71":31,"72":32,"73":[1,33],"84":[1,86],"87":[1,55],"91":35,"92":[1,36],"97":[1,74],"98":[1,72],"99":[1,71],"102":[1,49],"106":[1,58],"107":[1,70],"109":50,"110":[1,79],"112":[1,80],"113":51,"114":[1,81],"115":52,"116":[1,82],"117":83,"125":[1,53],"130":48,"131":[1,77],"132":[1,78],"133":[1,39],"134":[1,40],"135":[1,41],"136":[1,42],"137":[1,43],"138":[1,44],"139":[1,45],"140":[1,46],"141":[1,47]},{"4":[1,343],"29":[1,344],"30":[1,404]},{"4":[2,50],"29":[2,50],"30":[2,50],"59":[2,50],"86":[2,50]},{"4":[2,51],"29":[2,51],"30":[2,51],"59":[2,51],"86":[2,51]},{"1":[2,125],"4":[2,125],"29":[2,125],"30":[2,125],"46":[2,125],"51":[2,125],"59":[2,125],"63":[2,125],"74":[2,125],"75":[2,125],"76":[2,125],"77":[2,125],"80":[2,125],"81":[2,125],"82":[2,125],"83":[2,125],"86":[2,125],"88":[2,125],"94":[2,125],"96":[2,125],"100":[2,125],"108":[2,125],"110":[2,125],"111":[2,125],"112":[2,125],"116":[2,125],"122":[2,125],"123":[2,125],"124":[2,125],"131":[2,125],"132":[2,125],"133":[2,125],"135":[2,125],"136":[2,125],"138":[2,125],"139":[2,125],"142":[2,125],"143":[2,125],"144":[2,125],"145":[2,125],"146":[2,125],"147":[2,125],"148":[2,125],"149":[2,125],"150":[2,125],"151":[2,125],"152":[2,125],"153":[2,125],"154":[2,125],"155":[2,125],"156":[2,125],"157":[2,125],"158":[2,125],"159":[2,125],"160":[2,125],"161":[2,125],"162":[2,125],"163":[2,125],"164":[2,125],"165":[2,125],"166":[2,125],"167":[2,125],"168":[2,125]},{"51":[1,134],"63":[1,133],"81":[1,405],"109":131,"110":[1,79],"112":[1,80],"115":132,"116":[1,82],"117":83,"122":[1,126],"123":[1,127],"131":[1,129],"132":[1,130],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,171],"4":[2,171],"29":[2,171],"30":[2,171],"51":[2,171],"59":[2,171],"63":[2,171],"81":[2,171],"86":[2,171],"96":[2,171],"100":[2,171],"108":[2,171],"110":[2,171],"111":[2,171],"112":[2,171],"116":[2,171],"122":[2,171],"123":[2,171],"124":[2,171],"131":[2,171],"132":[2,171],"133":[2,171],"135":[2,171],"136":[2,171],"138":[2,171],"139":[2,171],"142":[2,171],"143":[2,171],"144":[2,171],"145":[2,171],"146":[2,171],"147":[2,171],"148":[2,171],"149":[2,171],"150":[2,171],"151":[2,171],"152":[2,171],"153":[2,171],"154":[2,171],"155":[2,171],"156":[2,171],"157":[2,171],"158":[2,171],"159":[2,171],"160":[2,171],"161":[2,171],"162":[2,171],"163":[2,171],"164":[2,171],"165":[2,171],"166":[2,171],"167":[2,171],"168":[2,171]},{"1":[2,102],"4":[2,102],"29":[2,102],"30":[2,102],"51":[2,102],"59":[2,102],"63":[2,102],"81":[2,102],"86":[2,102],"96":[2,102],"100":[2,102],"108":[2,102],"110":[2,102],"111":[2,102],"112":[2,102],"116":[2,102],"122":[2,102],"123":[2,102],"124":[2,102],"131":[2,102],"132":[2,102],"133":[2,102],"135":[2,102],"136":[2,102],"138":[2,102],"139":[2,102],"142":[2,102],"143":[2,102],"144":[2,102],"145":[2,102],"146":[2,102],"147":[2,102],"148":[2,102],"149":[2,102],"150":[2,102],"151":[2,102],"152":[2,102],"153":[2,102],"154":[2,102],"155":[2,102],"156":[2,102],"157":[2,102],"158":[2,102],"159":[2,102],"160":[2,102],"161":[2,102],"162":[2,102],"163":[2,102],"164":[2,102],"165":[2,102],"166":[2,102],"167":[2,102],"168":[2,102]},{"1":[2,124],"4":[2,124],"29":[2,124],"30":[2,124],"51":[2,124],"59":[2,124],"63":[2,124],"74":[2,124],"75":[2,124],"76":[2,124],"77":[2,124],"80":[2,124],"81":[2,124],"82":[2,124],"83":[2,124],"86":[2,124],"94":[2,124],"96":[2,124],"100":[2,124],"108":[2,124],"110":[2,124],"111":[2,124],"112":[2,124],"116":[2,124],"122":[2,124],"123":[2,124],"124":[2,124],"131":[2,124],"132":[2,124],"133":[2,124],"135":[2,124],"136":[2,124],"138":[2,124],"139":[2,124],"142":[2,124],"143":[2,124],"144":[2,124],"145":[2,124],"146":[2,124],"147":[2,124],"148":[2,124],"149":[2,124],"150":[2,124],"151":[2,124],"152":[2,124],"153":[2,124],"154":[2,124],"155":[2,124],"156":[2,124],"157":[2,124],"158":[2,124],"159":[2,124],"160":[2,124],"161":[2,124],"162":[2,124],"163":[2,124],"164":[2,124],"165":[2,124],"166":[2,124],"167":[2,124],"168":[2,124]},{"4":[2,132],"29":[2,132],"30":[2,132],"59":[2,132],"96":[2,132],"100":[2,132]},{"1":[2,168],"4":[2,168],"29":[2,168],"30":[2,168],"51":[1,134],"59":[2,168],"63":[1,133],"81":[2,168],"86":[2,168],"96":[2,168],"100":[2,168],"108":[2,168],"109":131,"110":[2,168],"111":[2,168],"112":[2,168],"115":132,"116":[2,168],"117":83,"122":[1,126],"123":[1,127],"124":[2,168],"131":[2,168],"132":[2,168],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"1":[2,169],"4":[2,169],"29":[2,169],"30":[2,169],"51":[1,134],"59":[2,169],"63":[1,133],"81":[2,169],"86":[2,169],"96":[2,169],"100":[2,169],"108":[2,169],"109":131,"110":[2,169],"111":[2,169],"112":[2,169],"115":132,"116":[2,169],"117":83,"122":[1,126],"123":[1,127],"124":[2,169],"131":[2,169],"132":[2,169],"133":[1,128],"135":[1,101],"136":[1,100],"138":[1,95],"139":[1,96],"142":[1,97],"143":[1,98],"144":[1,99],"145":[1,102],"146":[1,103],"147":[1,104],"148":[1,105],"149":[1,106],"150":[1,107],"151":[1,108],"152":[1,109],"153":[1,110],"154":[1,111],"155":[1,112],"156":[1,113],"157":[1,114],"158":[1,115],"159":[1,116],"160":[1,117],"161":[1,118],"162":[1,119],"163":[1,120],"164":[1,121],"165":[1,122],"166":[1,123],"167":[1,124],"168":[1,125]},{"4":[2,98],"29":[2,98],"30":[2,98],"59":[2,98],"86":[2,98]},{"1":[2,126],"4":[2,126],"29":[2,126],"30":[2,126],"46":[2,126],"51":[2,126],"59":[2,126],"63":[2,126],"74":[2,126],"75":[2,126],"76":[2,126],"77":[2,126],"80":[2,126],"81":[2,126],"82":[2,126],"83":[2,126],"86":[2,126],"88":[2,126],"94":[2,126],"96":[2,126],"100":[2,126],"108":[2,126],"110":[2,126],"111":[2,126],"112":[2,126],"116":[2,126],"122":[2,126],"123":[2,126],"124":[2,126],"131":[2,126],"132":[2,126],"133":[2,126],"135":[2,126],"136":[2,126],"138":[2,126],"139":[2,126],"142":[2,126],"143":[2,126],"144":[2,126],"145":[2,126],"146":[2,126],"147":[2,126],"148":[2,126],"149":[2,126],"150":[2,126],"151":[2,126],"152":[2,126],"153":[2,126],"154":[2,126],"155":[2,126],"156":[2,126],"157":[2,126],"158":[2,126],"159":[2,126],"160":[2,126],"161":[2,126],"162":[2,126],"163":[2,126],"164":[2,126],"165":[2,126],"166":[2,126],"167":[2,126],"168":[2,126]}],defaultActions:{"92":[2,4]},parseError:function parseError(str,hash){throw new Error(str)},parse:function parse(input){var self=this,stack=[0],vstack=[null],table=this.table,yytext="",yylineno=0,yyleng=0,shifts=0,reductions=0,recovering=0,TERROR=2,EOF=1;this.lexer.setInput(input);this.lexer.yy=this.yy;this.yy.lexer=this.lexer;var parseError=this.yy.parseError=typeof this.yy.parseError=="function"?this.yy.parseError:this.parseError;function popStack(n){stack.length=stack.length-2*n;vstack.length=vstack.length-n}function checkRecover(st){for(var p in table[st]){if(p==TERROR){return true}}return false}function lex(){var token;token=self.lexer.lex()||1;if(typeof token!=="number"){token=self.symbols_[token]||token}return token}var symbol,preErrorSymbol,state,action,a,r,yyval={},p,len,newState,expected,recovered=false;while(true){state=stack[stack.length-1];if(this.defaultActions[state]){action=this.defaultActions[state]}else{if(symbol==null){symbol=lex()}action=table[state]&&table[state][symbol]}if(typeof action==="undefined"||!action.length||!action[0]){if(!recovering){expected=[];for(p in table[state]){if(this.terminals_[p]&&p>2){expected.push("'"+this.terminals_[p]+"'")}}if(this.lexer.showPosition){parseError.call(this,"Parse error on line "+(yylineno+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+expected.join(", "),{text:this.lexer.match,token:this.terminals_[symbol]||symbol,line:this.lexer.yylineno,expected:expected})}else{parseError.call(this,"Parse error on line "+(yylineno+1)+": Unexpected '"+(this.terminals_[symbol]||symbol)+"'",{text:this.lexer.match,token:this.terminals_[symbol]||symbol,line:this.lexer.yylineno,expected:expected})}}if(recovering==3){if(symbol==EOF){throw"Parsing halted."}yyleng=this.lexer.yyleng;yytext=this.lexer.yytext;yylineno=this.lexer.yylineno;symbol=lex()}while(1){if(checkRecover(state)){break}if(state==0){throw"Parsing halted."}popStack(1);state=stack[stack.length-1]}preErrorSymbol=symbol;symbol=TERROR;state=stack[stack.length-1];action=table[state]&&table[state][TERROR];recovering=3}if(action[0] instanceof Array&&action.length>1){throw new Error("Parse Error: multiple actions possible at state: "+state+", token: "+symbol)}a=action;switch(a[0]){case 1:shifts++;stack.push(symbol);vstack.push(this.lexer.yytext);stack.push(a[1]);symbol=null;if(!preErrorSymbol){yyleng=this.lexer.yyleng;yytext=this.lexer.yytext;yylineno=this.lexer.yylineno;if(recovering>0){recovering--}}else{symbol=preErrorSymbol;preErrorSymbol=null}break;case 2:reductions++;len=this.productions_[a[1]][1];yyval.$=vstack[vstack.length-len];r=this.performAction.call(yyval,yytext,yyleng,yylineno,this.yy,a[1],vstack);if(typeof r!=="undefined"){return r}if(len){stack=stack.slice(0,-1*len*2);vstack=vstack.slice(0,-1*len)}stack.push(this.productions_[a[1]][0]);vstack.push(yyval.$);newState=table[stack[stack.length-2]][stack[stack.length-1]];stack.push(newState);break;case 3:this.reductionCount=reductions;this.shiftCount=shifts;return true}}return true}};return parser})();if(typeof require!=="undefined"){exports.parser=parser;exports.parse=function(){return parser.parse.apply(parser,arguments)};exports.main=function commonjsMain(args){if(!args[1]){throw new Error("Usage: "+args[0]+" FILE")}if(typeof process!=="undefined"){var source=require("fs").readFileSync(require("path").join(process.cwd(),args[1]),"utf8")}else{var cwd=require("file").path(require("file").cwd());var source=cwd.join(args[1]).read({charset:"utf-8"})}return exports.parser.parse(source)};if(require.main===module){exports.main(typeof process!=="undefined"?process.argv.slice(1):require("system").args)}}(function(){var Scope;var __hasProp=Object.prototype.hasOwnProperty;if(!((typeof process!=="undefined"&&process!==null))){this.exports=this}exports.Scope=(function(){Scope=function(parent,expressions,method){var _a;_a=[parent,expressions,method];this.parent=_a[0];this.expressions=_a[1];this.method=_a[2];this.variables={};if(this.parent){this.tempVar=this.parent.tempVar}else{Scope.root=this;this.tempVar="_a"}return this};Scope.root=null;Scope.prototype.find=function(name){if(this.check(name)){return true}this.variables[name]="var";return false};Scope.prototype.any=function(fn){var _a,k,v;_a=this.variables;for(v in _a){if(!__hasProp.call(_a,v)){continue}k=_a[v];if(fn(v,k)){return true}}return false};Scope.prototype.parameter=function(name){return(this.variables[name]="param")};Scope.prototype.check=function(name){if(this.variables.hasOwnProperty(name)){return true}return !!(this.parent&&this.parent.check(name))};Scope.prototype.freeVariable=function(){var ordinal;while(this.check(this.tempVar)){ordinal=1+parseInt(this.tempVar.substr(1),36);this.tempVar="_"+ordinal.toString(36).replace(/\d/g,"a")}this.variables[this.tempVar]="var";return this.tempVar};Scope.prototype.assign=function(name,value){return(this.variables[name]={value:value,assigned:true})};Scope.prototype.hasDeclarations=function(body){return body===this.expressions&&this.any(function(k,val){return val==="var"})};Scope.prototype.hasAssignments=function(body){return body===this.expressions&&this.any(function(k,val){return val.assigned})};Scope.prototype.declaredVariables=function(){var _a,_b,key,val;return(function(){_a=[];_b=this.variables;for(key in _b){if(!__hasProp.call(_b,key)){continue}val=_b[key];if(val==="var"){_a.push(key)}}return _a}).call(this).sort()};Scope.prototype.assignedVariables=function(){var _a,_b,key,val;_a=[];_b=this.variables;for(key in _b){if(!__hasProp.call(_b,key)){continue}val=_b[key];if(val.assigned){_a.push((""+(key)+" = "+(val.value)))}}return _a};Scope.prototype.compiledDeclarations=function(){return this.declaredVariables().join(", ")};Scope.prototype.compiledAssignments=function(){return this.assignedVariables().join(", ")};return Scope}).call(this)})();(function(){var AccessorNode,ArrayNode,AssignNode,BaseNode,CallNode,ClassNode,ClosureNode,CodeNode,CommentNode,ExistenceNode,Expressions,ExtendsNode,ForNode,IDENTIFIER,IS_STRING,IfNode,InNode,IndexNode,LiteralNode,NUMBER,ObjectNode,OpNode,ParamNode,ParentheticalNode,PushNode,RangeNode,ReturnNode,SIMPLENUM,Scope,SliceNode,SplatNode,TAB,TRAILING_WHITESPACE,ThrowNode,TryNode,UTILITIES,ValueNode,WhileNode,_a,compact,del,ends,flatten,helpers,include,indexOf,literal,merge,starts,utility;var __extends=function(child,parent){var ctor=function(){};ctor.prototype=parent.prototype;child.prototype=new ctor();child.prototype.constructor=child;if(typeof parent.extended==="function"){parent.extended(child)}child.__superClass__=parent.prototype};if((typeof process!=="undefined"&&process!==null)){Scope=require("./scope").Scope;helpers=require("./helpers").helpers}else{this.exports=this;helpers=this.helpers;Scope=this.Scope}_a=helpers;compact=_a.compact;flatten=_a.flatten;merge=_a.merge;del=_a.del;include=_a.include;indexOf=_a.indexOf;starts=_a.starts;ends=_a.ends;exports.BaseNode=(function(){BaseNode=function(){};BaseNode.prototype.compile=function(o){var closure,top;this.options=merge(o||{});this.tab=o.indent;if(!(this instanceof ValueNode||this instanceof CallNode)){del(this.options,"operation");if(!(this instanceof AccessorNode||this instanceof IndexNode)){del(this.options,"chainRoot")}}top=this.topSensitive()?this.options.top:del(this.options,"top");closure=this.isStatement()&&!this.isPureStatement()&&!top&&!this.options.asStatement&&!(this instanceof CommentNode)&&!this.containsPureStatement();return closure?this.compileClosure(this.options):this.compileNode(this.options)};BaseNode.prototype.compileClosure=function(o){this.tab=o.indent;o.sharedScope=o.scope;return ClosureNode.wrap(this).compile(o)};BaseNode.prototype.compileReference=function(o,options){var compiled,pair,reference;options=options||{};pair=(function(){if(!((this instanceof CallNode||this.contains(function(n){return n instanceof CallNode}))||(this instanceof ValueNode&&(!(this.base instanceof LiteralNode)||this.hasProperties())))){return[this,this]}else{if(this instanceof ValueNode&&options.assignment){return this.cacheIndexes(o)}else{reference=literal(o.scope.freeVariable());compiled=new AssignNode(reference,this);return[compiled,reference]}}}).call(this);if(options.precompile){return[pair[0].compile(o),pair[1].compile(o)]}return pair};BaseNode.prototype.idt=function(tabs){var idt,num;idt=this.tab||"";num=(tabs||0)+1;while(num-=1){idt+=TAB}return idt};BaseNode.prototype.makeReturn=function(){return new ReturnNode(this)};BaseNode.prototype.contains=function(block){var contains;contains=false;this.traverseChildren(false,function(node){if(block(node)){contains=true;return false}});return contains};BaseNode.prototype.containsType=function(type){return this instanceof type||this.contains(function(n){return n instanceof type})};BaseNode.prototype.containsPureStatement=function(){return this.isPureStatement()||this.contains(function(n){return n.isPureStatement&&n.isPureStatement()})};BaseNode.prototype.traverse=function(block){return this.traverseChildren(true,block)};BaseNode.prototype.toString=function(idt,override){var _b,_c,_d,_e,child,children;idt=idt||"";children=(function(){_b=[];_d=this.collectChildren();for(_c=0,_e=_d.length;_c<_e;_c++){child=_d[_c];_b.push(child.toString(idt+TAB))}return _b}).call(this).join("");return"\n"+idt+(override||this["class"])+children};BaseNode.prototype.eachChild=function(func){var _b,_c,_d,_e,_f,_g,_h,attr,child;if(!(this.children)){return null}_b=[];_d=this.children;for(_c=0,_e=_d.length;_c<_e;_c++){attr=_d[_c];if(this[attr]){_g=flatten([this[attr]]);for(_f=0,_h=_g.length;_f<_h;_f++){child=_g[_f];if(func(child)===false){return null}}}}return _b};BaseNode.prototype.collectChildren=function(){var nodes;nodes=[];this.eachChild(function(node){return nodes.push(node)});return nodes};BaseNode.prototype.traverseChildren=function(crossScope,func){return this.eachChild(function(child){func.apply(this,arguments);if(child instanceof BaseNode){return child.traverseChildren(crossScope,func)}})};BaseNode.prototype["class"]="BaseNode";BaseNode.prototype.children=[];BaseNode.prototype.unwrap=function(){return this};BaseNode.prototype.isStatement=function(){return false};BaseNode.prototype.isPureStatement=function(){return false};BaseNode.prototype.topSensitive=function(){return false};return BaseNode})();exports.Expressions=(function(){Expressions=function(nodes){this.expressions=compact(flatten(nodes||[]));return this};__extends(Expressions,BaseNode);Expressions.prototype["class"]="Expressions";Expressions.prototype.children=["expressions"];Expressions.prototype.isStatement=function(){return true};Expressions.prototype.push=function(node){this.expressions.push(node);return this};Expressions.prototype.unshift=function(node){this.expressions.unshift(node);return this};Expressions.prototype.unwrap=function(){return this.expressions.length===1?this.expressions[0]:this};Expressions.prototype.empty=function(){return this.expressions.length===0};Expressions.prototype.makeReturn=function(){var idx,last;idx=this.expressions.length-1;last=this.expressions[idx];if(last instanceof CommentNode){last=this.expressions[idx-=1]}if(!last||last instanceof ReturnNode){return this}this.expressions[idx]=last.makeReturn();return this};Expressions.prototype.compile=function(o){o=o||{};return o.scope?Expressions.__superClass__.compile.call(this,o):this.compileRoot(o)};Expressions.prototype.compileNode=function(o){var _b,_c,_d,_e,node;return(function(){_b=[];_d=this.expressions;for(_c=0,_e=_d.length;_c<_e;_c++){node=_d[_c];_b.push(this.compileExpression(node,merge(o)))}return _b}).call(this).join("\n")};Expressions.prototype.compileRoot=function(o){var code;o.indent=(this.tab=o.noWrap?"":TAB);o.scope=new Scope(null,this,null);code=this.compileWithDeclarations(o);code=code.replace(TRAILING_WHITESPACE,"");return o.noWrap?code:("(function() {\n"+(code)+"\n})();\n")};Expressions.prototype.compileWithDeclarations=function(o){var code;code=this.compileNode(o);if(o.scope.hasAssignments(this)){code=(""+(this.tab)+"var "+(o.scope.compiledAssignments())+";\n"+(code))}if(!o.globals&&o.scope.hasDeclarations(this)){code=(""+(this.tab)+"var "+(o.scope.compiledDeclarations())+";\n"+(code))}return code};Expressions.prototype.compileExpression=function(node,o){var compiledNode;this.tab=o.indent;compiledNode=node.compile(merge(o,{top:true}));return node.isStatement()?compiledNode:(""+(this.idt())+(compiledNode)+";")};return Expressions})();Expressions.wrap=function(nodes){if(nodes.length===1&&nodes[0] instanceof Expressions){return nodes[0]}return new Expressions(nodes)};exports.LiteralNode=(function(){LiteralNode=function(_b){this.value=_b;return this};__extends(LiteralNode,BaseNode);LiteralNode.prototype["class"]="LiteralNode";LiteralNode.prototype.makeReturn=function(){return this.isStatement()?this:LiteralNode.__superClass__.makeReturn.call(this)};LiteralNode.prototype.isStatement=function(){return this.value==="break"||this.value==="continue"};LiteralNode.prototype.isPureStatement=LiteralNode.prototype.isStatement;LiteralNode.prototype.compileNode=function(o){var end,idt;idt=this.isStatement()?this.idt():"";end=this.isStatement()?";":"";return idt+this.value+end};LiteralNode.prototype.toString=function(idt){return'"'+this.value+'"'};return LiteralNode})();exports.ReturnNode=(function(){ReturnNode=function(_b){this.expression=_b;return this};__extends(ReturnNode,BaseNode);ReturnNode.prototype["class"]="ReturnNode";ReturnNode.prototype.isStatement=function(){return true};ReturnNode.prototype.isPureStatement=function(){return true};ReturnNode.prototype.children=["expression"];ReturnNode.prototype.makeReturn=function(){return this};ReturnNode.prototype.compile=function(o){var expr;expr=this.expression.makeReturn();if(!(expr instanceof ReturnNode)){return expr.compile(o)}return ReturnNode.__superClass__.compile.call(this,o)};ReturnNode.prototype.compileNode=function(o){if(this.expression.isStatement()){o.asStatement=true}return""+(this.tab)+"return "+(this.expression.compile(o))+";"};return ReturnNode})();exports.ValueNode=(function(){ValueNode=function(_b,_c){this.properties=_c;this.base=_b;this.properties=this.properties||[];return this};__extends(ValueNode,BaseNode);ValueNode.prototype.SOAK=" == undefined ? undefined : ";ValueNode.prototype["class"]="ValueNode";ValueNode.prototype.children=["base","properties"];ValueNode.prototype.push=function(prop){this.properties.push(prop);return this};ValueNode.prototype.hasProperties=function(){return !!this.properties.length};ValueNode.prototype.isArray=function(){return this.base instanceof ArrayNode&&!this.hasProperties()};ValueNode.prototype.isObject=function(){return this.base instanceof ObjectNode&&!this.hasProperties()};ValueNode.prototype.isSplice=function(){return this.hasProperties()&&this.properties[this.properties.length-1] instanceof SliceNode};ValueNode.prototype.makeReturn=function(){return this.hasProperties()?ValueNode.__superClass__.makeReturn.call(this):this.base.makeReturn()};ValueNode.prototype.unwrap=function(){return this.properties.length?this:this.base};ValueNode.prototype.isStatement=function(){return this.base.isStatement&&this.base.isStatement()&&!this.hasProperties()};ValueNode.prototype.isNumber=function(){return this.base instanceof LiteralNode&&this.base.value.match(NUMBER)};ValueNode.prototype.isStart=function(o){var node;if(this===o.chainRoot&&this.properties[0] instanceof AccessorNode){return true}node=o.chainRoot.base||o.chainRoot.variable;while(node instanceof CallNode){node=node.variable}return node===this};ValueNode.prototype.cacheIndexes=function(o){var _b,_c,_d,copy,i;copy=new ValueNode(this.base,this.properties.slice(0));_c=copy.properties;for(_b=0,_d=_c.length;_b<_d;_b++){(function(){var _e,index,indexVar;var i=_b;var prop=_c[_b];if(prop instanceof IndexNode&&prop.contains(function(n){return n instanceof CallNode})){_e=prop.index.compileReference(o);index=_e[0];indexVar=_e[1];this.properties[i]=new IndexNode(index);return(copy.properties[i]=new IndexNode(indexVar))}}).call(this)}return[this,copy]};ValueNode.prototype.compile=function(o){return !o.top||this.properties.length?ValueNode.__superClass__.compile.call(this,o):this.base.compile(o)};ValueNode.prototype.compileNode=function(o){var _b,_c,_d,baseline,complete,i,only,op,props;only=del(o,"onlyFirst");op=del(o,"operation");props=only?this.properties.slice(0,this.properties.length-1):this.properties;o.chainRoot=o.chainRoot||this;baseline=this.base.compile(o);if(this.hasProperties()&&(this.base instanceof ObjectNode||this.isNumber())){baseline=("("+(baseline)+")")}complete=(this.last=baseline);_c=props;for(_b=0,_d=_c.length;_b<_d;_b++){(function(){var part,temp;var i=_b;var prop=_c[_b];this.source=baseline;if(prop.soakNode){if(this.base instanceof CallNode||this.base.contains(function(n){return n instanceof CallNode})&&i===0){temp=o.scope.freeVariable();complete=("("+(baseline=temp)+" = ("+(complete)+"))")}if(i===0&&this.isStart(o)){complete=("typeof "+(complete)+' === "undefined" || '+(baseline))}return complete+=this.SOAK+(baseline+=prop.compile(o))}else{part=prop.compile(o);baseline+=part;complete+=part;return(this.last=part)}}).call(this)}return op&&this.wrapped?("("+(complete)+")"):complete};return ValueNode})();exports.CommentNode=(function(){CommentNode=function(_b){this.lines=_b;return this};__extends(CommentNode,BaseNode);CommentNode.prototype["class"]="CommentNode";CommentNode.prototype.isStatement=function(){return true};CommentNode.prototype.makeReturn=function(){return this};CommentNode.prototype.compileNode=function(o){var sep;sep="\n"+this.tab;return""+(this.tab)+"/*"+(sep+this.lines.join(sep))+"\n"+(this.tab)+"*/"};return CommentNode})();exports.CallNode=(function(){CallNode=function(variable,_b){this.args=_b;this.isNew=false;this.isSuper=variable==="super";this.variable=this.isSuper?null:variable;this.args=this.args||[];this.compileSplatArguments=function(o){return SplatNode.compileSplattedArray.call(this,this.args,o)};return this};__extends(CallNode,BaseNode);CallNode.prototype["class"]="CallNode";CallNode.prototype.children=["variable","args"];CallNode.prototype.newInstance=function(){this.isNew=true;return this};CallNode.prototype.prefix=function(){return this.isNew?"new ":""};CallNode.prototype.superReference=function(o){var meth,methname;methname=o.scope.method.name;return(meth=(function(){if(o.scope.method.proto){return""+(o.scope.method.proto)+".__superClass__."+(methname)}else{if(methname){return""+(methname)+".__superClass__.constructor"}else{throw new Error("cannot call super on an anonymous function.")}}})())};CallNode.prototype.compileNode=function(o){var _b,_c,_d,_e,_f,_g,_h,arg,args,compilation;if(!(o.chainRoot)){o.chainRoot=this}_c=this.args;for(_b=0,_d=_c.length;_b<_d;_b++){arg=_c[_b];if(arg instanceof SplatNode){compilation=this.compileSplat(o)}}if(!(compilation)){args=(function(){_e=[];_g=this.args;for(_f=0,_h=_g.length;_f<_h;_f++){arg=_g[_f];_e.push(arg.compile(o))}return _e}).call(this).join(", ");compilation=this.isSuper?this.compileSuper(args,o):(""+(this.prefix())+(this.variable.compile(o))+"("+(args)+")")}return o.operation&&this.wrapped?("("+(compilation)+")"):compilation};CallNode.prototype.compileSuper=function(args,o){return""+(this.superReference(o))+".call(this"+(args.length?", ":"")+(args)+")"};CallNode.prototype.compileSplat=function(o){var meth,obj,temp;meth=this.variable?this.variable.compile(o):this.superReference(o);obj=this.variable&&this.variable.source||"this";if(obj.match(/\(/)){temp=o.scope.freeVariable();obj=temp;meth=("("+(temp)+" = "+(this.variable.source)+")"+(this.variable.last))}if(this.isNew){utility("extends");return"(function() {\n"+(this.idt(1))+"var ctor = function(){};\n"+(this.idt(1))+"__extends(ctor, "+(meth)+");\n"+(this.idt(1))+"return "+(meth)+".apply(new ctor, "+(this.compileSplatArguments(o))+");\n"+(this.tab)+"}).call(this)"}else{return""+(this.prefix())+(meth)+".apply("+(obj)+", "+(this.compileSplatArguments(o))+")"}};return CallNode})();exports.ExtendsNode=(function(){ExtendsNode=function(_b,_c){this.parent=_c;this.child=_b;return this};__extends(ExtendsNode,BaseNode);ExtendsNode.prototype["class"]="ExtendsNode";ExtendsNode.prototype.children=["child","parent"];ExtendsNode.prototype.compileNode=function(o){var ref;ref=new ValueNode(literal(utility("extends")));return(new CallNode(ref,[this.child,this.parent])).compile(o)};return ExtendsNode})();exports.AccessorNode=(function(){AccessorNode=function(_b,tag){this.name=_b;this.prototype=tag==="prototype"?".prototype":"";this.soakNode=tag==="soak";return this};__extends(AccessorNode,BaseNode);AccessorNode.prototype["class"]="AccessorNode";AccessorNode.prototype.children=["name"];AccessorNode.prototype.compileNode=function(o){var name,namePart;name=this.name.compile(o);o.chainRoot.wrapped=o.chainRoot.wrapped||this.soakNode;namePart=name.match(IS_STRING)?("["+(name)+"]"):("."+(name));return this.prototype+namePart};return AccessorNode})();exports.IndexNode=(function(){IndexNode=function(_b){this.index=_b;return this};__extends(IndexNode,BaseNode);IndexNode.prototype["class"]="IndexNode";IndexNode.prototype.children=["index"];IndexNode.prototype.compileNode=function(o){var idx,prefix;o.chainRoot.wrapped=o.chainRoot.wrapped||this.soakNode;idx=this.index.compile(o);prefix=this.proto?".prototype":"";return""+(prefix)+"["+(idx)+"]"};return IndexNode})();exports.RangeNode=(function(){RangeNode=function(_b,_c,exclusive){this.to=_c;this.from=_b;this.exclusive=!!exclusive;this.equals=this.exclusive?"":"=";return this};__extends(RangeNode,BaseNode);RangeNode.prototype["class"]="RangeNode";RangeNode.prototype.children=["from","to"];RangeNode.prototype.compileVariables=function(o){var _b,_c,_d,parts;o=merge(o,{top:true});_b=this.from.compileReference(o,{precompile:true});this.from=_b[0];this.fromVar=_b[1];_c=this.to.compileReference(o,{precompile:true});this.to=_c[0];this.toVar=_c[1];_d=[this.fromVar.match(SIMPLENUM),this.toVar.match(SIMPLENUM)];this.fromNum=_d[0];this.toNum=_d[1];parts=[];if(this.from!==this.fromVar){parts.push(this.from)}if(this.to!==this.toVar){parts.push(this.to)}return parts.length?(""+(parts.join("; "))+"; "):""};RangeNode.prototype.compileNode=function(o){var compare,idx,incr,intro,step,stepPart,vars;if(!(o.index)){return this.compileArray(o)}if(this.fromNum&&this.toNum){return this.compileSimple(o)}idx=del(o,"index");step=del(o,"step");vars=(""+(idx)+" = "+(this.fromVar));intro=("("+(this.fromVar)+" <= "+(this.toVar)+" ? "+(idx));compare=(""+(intro)+" <"+(this.equals)+" "+(this.toVar)+" : "+(idx)+" >"+(this.equals)+" "+(this.toVar)+")");stepPart=step?step.compile(o):"1";incr=step?(""+(idx)+" += "+(stepPart)):(""+(intro)+" += "+(stepPart)+" : "+(idx)+" -= "+(stepPart)+")");return""+(vars)+"; "+(compare)+"; "+(incr)};RangeNode.prototype.compileSimple=function(o){var _b,from,idx,step,to;_b=[parseInt(this.fromNum,10),parseInt(this.toNum,10)];from=_b[0];to=_b[1];idx=del(o,"index");step=del(o,"step");step=step&&(""+(idx)+" += "+(step.compile(o)));return from<=to?(""+(idx)+" = "+(from)+"; "+(idx)+" <"+(this.equals)+" "+(to)+"; "+(step||(""+(idx)+"++"))):(""+(idx)+" = "+(from)+"; "+(idx)+" >"+(this.equals)+" "+(to)+"; "+(step||(""+(idx)+"--")))};RangeNode.prototype.compileArray=function(o){var _b,_c,body,clause,i,idt,post,pre,range,result,vars;idt=this.idt(1);vars=this.compileVariables(merge(o,{indent:idt}));if(this.fromNum&&this.toNum&&Math.abs(+this.fromNum-+this.toNum)<=20){range=(function(){_c=[];for(var _b=+this.fromNum;+this.fromNum<=+this.toNum?_b<=+this.toNum:_b>=+this.toNum;+this.fromNum<=+this.toNum?_b+=1:_b-=1){_c.push(_b)}return _c}).call(this);if(this.exclusive){range.pop()}return("["+(range.join(", "))+"]")}i=o.scope.freeVariable();result=o.scope.freeVariable();pre=("\n"+(idt)+(result)+" = []; "+(vars));if(this.fromNum&&this.toNum){o.index=i;body=this.compileSimple(o)}else{clause=(""+(this.fromVar)+" <= "+(this.toVar)+" ?");body=("var "+(i)+" = "+(this.fromVar)+"; "+(clause)+" "+(i)+" <"+(this.equals)+" "+(this.toVar)+" : "+(i)+" >"+(this.equals)+" "+(this.toVar)+"; "+(clause)+" "+(i)+" += 1 : "+(i)+" -= 1")}post=("{ "+(result)+".push("+(i)+"); }\n"+(idt)+"return "+(result)+";\n"+(o.indent));return"(function() {"+(pre)+"\n"+(idt)+"for ("+(body)+")"+(post)+"}).call(this)"};return RangeNode})();exports.SliceNode=(function(){SliceNode=function(_b){this.range=_b;return this};__extends(SliceNode,BaseNode);SliceNode.prototype["class"]="SliceNode";SliceNode.prototype.children=["range"];SliceNode.prototype.compileNode=function(o){var from,plusPart,to;from=this.range.from.compile(o);to=this.range.to.compile(o);plusPart=this.range.exclusive?"":" + 1";return".slice("+(from)+", "+(to)+(plusPart)+")"};return SliceNode})();exports.ObjectNode=(function(){ObjectNode=function(props){this.objects=(this.properties=props||[]);return this};__extends(ObjectNode,BaseNode);ObjectNode.prototype["class"]="ObjectNode";ObjectNode.prototype.children=["properties"];ObjectNode.prototype.topSensitive=function(){return true};ObjectNode.prototype.compileNode=function(o){var _b,_c,_d,_e,_f,_g,_h,i,indent,join,lastNoncom,nonComments,obj,prop,props,top;top=del(o,"top");o.indent=this.idt(1);nonComments=(function(){_b=[];_d=this.properties;for(_c=0,_e=_d.length;_c<_e;_c++){prop=_d[_c];if(!(prop instanceof CommentNode)){_b.push(prop)}}return _b}).call(this);lastNoncom=nonComments[nonComments.length-1];props=(function(){_f=[];_g=this.properties;for(i=0,_h=_g.length;i<_h;i++){prop=_g[i];_f.push((function(){join=",\n";if((prop===lastNoncom)||(prop instanceof CommentNode)){join="\n"}if(i===this.properties.length-1){join=""}indent=prop instanceof CommentNode?"":this.idt(1);if(!(prop instanceof AssignNode||prop instanceof CommentNode)){prop=new AssignNode(prop,prop,"object")}return indent+prop.compile(o)+join}).call(this))}return _f}).call(this);props=props.join("");obj="{"+(props?"\n"+props+"\n"+this.idt():"")+"}";return top?("("+(obj)+")"):obj};return ObjectNode})();exports.ArrayNode=(function(){ArrayNode=function(_b){this.objects=_b;this.objects=this.objects||[];this.compileSplatLiteral=function(o){return SplatNode.compileSplattedArray.call(this,this.objects,o)};return this};__extends(ArrayNode,BaseNode);ArrayNode.prototype["class"]="ArrayNode";ArrayNode.prototype.children=["objects"];ArrayNode.prototype.compileNode=function(o){var _b,_c,code,i,obj,objects;o.indent=this.idt(1);objects=[];_b=this.objects;for(i=0,_c=_b.length;i<_c;i++){obj=_b[i];code=obj.compile(o);if(obj instanceof SplatNode){return this.compileSplatLiteral(o)}else{if(obj instanceof CommentNode){objects.push(("\n"+(code)+"\n"+(o.indent)))}else{if(i===this.objects.length-1){objects.push(code)}else{objects.push((""+(code)+", "))}}}}objects=objects.join("");return indexOf(objects,"\n")>=0?("[\n"+(this.idt(1))+(objects)+"\n"+(this.tab)+"]"):("["+(objects)+"]")};return ArrayNode})();exports.ClassNode=(function(){ClassNode=function(_b,_c,_d){this.properties=_d;this.parent=_c;this.variable=_b;this.properties=this.properties||[];this.returns=false;return this};__extends(ClassNode,BaseNode);ClassNode.prototype["class"]="ClassNode";ClassNode.prototype.children=["variable","parent","properties"];ClassNode.prototype.isStatement=function(){return true};ClassNode.prototype.makeReturn=function(){this.returns=true;return this};ClassNode.prototype.compileNode=function(o){var _b,_c,_d,_e,access,applied,className,constScope,construct,constructor,extension,func,me,pname,prop,props,pvar,returns,val;if(this.variable==="__temp__"){this.variable=literal(o.scope.freeVariable())}extension=this.parent&&new ExtendsNode(this.variable,this.parent);props=new Expressions();o.top=true;me=null;className=this.variable.compile(o);constScope=null;if(this.parent){applied=new ValueNode(this.parent,[new AccessorNode(literal("apply"))]);constructor=new CodeNode([],new Expressions([new CallNode(applied,[literal("this"),literal("arguments")])]))}else{constructor=new CodeNode()}_c=this.properties;for(_b=0,_d=_c.length;_b<_d;_b++){prop=_c[_b];_e=[prop.variable,prop.value];pvar=_e[0];func=_e[1];if(pvar&&pvar.base.value==="constructor"&&func instanceof CodeNode){if(func.bound){throw new Error("cannot define a constructor as a bound function.")}func.name=className;func.body.push(new ReturnNode(literal("this")));this.variable=new ValueNode(this.variable);this.variable.namespaced=include(func.name,".");constructor=func;continue}if(func instanceof CodeNode&&func.bound){func.bound=false;constScope=constScope||new Scope(o.scope,constructor.body,constructor);me=me||constScope.freeVariable();pname=pvar.compile(o);if(constructor.body.empty()){constructor.body.push(new ReturnNode(literal("this")))}constructor.body.unshift(literal(("this."+(pname)+" = function(){ return "+(className)+".prototype."+(pname)+".apply("+(me)+", arguments); }")))}if(pvar){access=prop.context==="this"?pvar.base.properties[0]:new AccessorNode(pvar,"prototype");val=new ValueNode(this.variable,[access]);prop=new AssignNode(val,func)}props.push(prop)}if(me){constructor.body.unshift(literal((""+(me)+" = this")))}construct=this.idt()+(new AssignNode(this.variable,constructor)).compile(merge(o,{sharedScope:constScope}))+";";props=!props.empty()?"\n"+props.compile(o):"";extension=extension?"\n"+this.idt()+extension.compile(o)+";":"";returns=this.returns?"\n"+new ReturnNode(this.variable).compile(o):"";return construct+extension+props+returns};return ClassNode})();exports.AssignNode=(function(){AssignNode=function(_b,_c,_d){this.context=_d;this.value=_c;this.variable=_b;return this};__extends(AssignNode,BaseNode);AssignNode.prototype.PROTO_ASSIGN=/^(\S+)\.prototype/;AssignNode.prototype.LEADING_DOT=/^\.(prototype\.)?/;AssignNode.prototype["class"]="AssignNode";AssignNode.prototype.children=["variable","value"];AssignNode.prototype.topSensitive=function(){return true};AssignNode.prototype.isValue=function(){return this.variable instanceof ValueNode};AssignNode.prototype.makeReturn=function(){if(this.isStatement()){return new Expressions([this,new ReturnNode(this.variable)])}else{return AssignNode.__superClass__.makeReturn.call(this)}};AssignNode.prototype.isStatement=function(){return this.isValue()&&(this.variable.isArray()||this.variable.isObject())};AssignNode.prototype.compileNode=function(o){var last,match,name,proto,stmt,top,val;top=del(o,"top");if(this.isStatement()){return this.compilePatternMatch(o)}if(this.isValue()&&this.variable.isSplice()){return this.compileSplice(o)}stmt=del(o,"asStatement");name=this.variable.compile(o);last=this.isValue()?this.variable.last.replace(this.LEADING_DOT,""):name;match=name.match(this.PROTO_ASSIGN);proto=match&&match[1];if(this.value instanceof CodeNode){if(last.match(IDENTIFIER)){this.value.name=last}if(proto){this.value.proto=proto}}val=this.value.compile(o);if(this.context==="object"){return(""+(name)+": "+(val))}if(!(this.isValue()&&(this.variable.hasProperties()||this.variable.namespaced))){o.scope.find(name)}val=(""+(name)+" = "+(val));if(stmt){return(""+(this.tab)+(val)+";")}return top?val:("("+(val)+")")};AssignNode.prototype.compilePatternMatch=function(o){var _b,_c,_d,accessClass,assigns,code,i,idx,isString,obj,oindex,olength,splat,val,valVar,value;valVar=o.scope.freeVariable();value=this.value.isStatement()?ClosureNode.wrap(this.value):this.value;assigns=[(""+(this.tab)+(valVar)+" = "+(value.compile(o))+";")];o.top=true;o.asStatement=true;splat=false;_b=this.variable.base.objects;for(i=0,_c=_b.length;i<_c;i++){obj=_b[i];idx=i;if(this.variable.isObject()){if(obj instanceof AssignNode){_d=[obj.value,obj.variable.base];obj=_d[0];idx=_d[1]}else{idx=obj}}if(!(obj instanceof ValueNode||obj instanceof SplatNode)){throw new Error("pattern matching must use only identifiers on the left-hand side.")}isString=idx.value&&idx.value.match(IS_STRING);accessClass=isString||this.variable.isArray()?IndexNode:AccessorNode;if(obj instanceof SplatNode&&!splat){val=literal(obj.compileValue(o,valVar,(oindex=indexOf(this.variable.base.objects,obj)),(olength=this.variable.base.objects.length)-oindex-1));splat=true}else{if(typeof idx!=="object"){idx=literal(splat?(""+(valVar)+".length - "+(olength-idx)):idx)}val=new ValueNode(literal(valVar),[new accessClass(idx)])}assigns.push(new AssignNode(obj,val).compile(o))}code=assigns.join("\n");return code};AssignNode.prototype.compileSplice=function(o){var from,l,name,plus,range,to,val;name=this.variable.compile(merge(o,{onlyFirst:true}));l=this.variable.properties.length;range=this.variable.properties[l-1].range;plus=range.exclusive?"":" + 1";from=range.from.compile(o);to=range.to.compile(o)+" - "+from+plus;val=this.value.compile(o);return""+(name)+".splice.apply("+(name)+", ["+(from)+", "+(to)+"].concat("+(val)+"))"};return AssignNode})();exports.CodeNode=(function(){CodeNode=function(_b,_c,tag){this.body=_c;this.params=_b;this.params=this.params||[];this.body=this.body||new Expressions();this.bound=tag==="boundfunc";return this};__extends(CodeNode,BaseNode);CodeNode.prototype["class"]="CodeNode";CodeNode.prototype.children=["params","body"];CodeNode.prototype.compileNode=function(o){var _b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,code,empty,func,i,param,params,sharedScope,splat,top,value;sharedScope=del(o,"sharedScope");top=del(o,"top");o.scope=sharedScope||new Scope(o.scope,this.body,this);o.top=true;o.indent=this.idt(1);empty=this.body.expressions.length===0;del(o,"noWrap");del(o,"globals");splat=undefined;params=[];_b=this.params;for(i=0,_c=_b.length;i<_c;i++){param=_b[i];if(splat){if(param.attach){param.assign=new AssignNode(new ValueNode(literal("this"),[new AccessorNode(param.value)]));this.body.expressions.splice(splat.index+1,0,param.assign)}splat.trailings.push(param)}else{if(param.attach){_d=param;value=_d.value;_e=[literal(o.scope.freeVariable()),param.splat];param=_e[0];param.splat=_e[1];this.body.unshift(new AssignNode(new ValueNode(literal("this"),[new AccessorNode(value)]),param))}if(param.splat){splat=new SplatNode(param.value);splat.index=i;splat.trailings=[];splat.arglength=this.params.length;this.body.unshift(splat)}else{params.push(param)}}}params=(function(){_f=[];_h=params;for(_g=0,_i=_h.length;_g<_i;_g++){param=_h[_g];_f.push(param.compile(o))}return _f})();if(!(empty)){this.body.makeReturn()}_k=params;for(_j=0,_l=_k.length;_j<_l;_j++){param=_k[_j];(o.scope.parameter(param))}code=this.body.expressions.length?("\n"+(this.body.compileWithDeclarations(o))+"\n"):"";func=("function("+(params.join(", "))+") {"+(code)+(code&&this.tab)+"}");if(this.bound){return(""+(utility("bind"))+"("+(func)+", this)")}return top?("("+(func)+")"):func};CodeNode.prototype.topSensitive=function(){return true};CodeNode.prototype.traverseChildren=function(crossScope,func){if(crossScope){return CodeNode.__superClass__.traverseChildren.call(this,crossScope,func)}};CodeNode.prototype.toString=function(idt){var _b,_c,_d,_e,child,children;idt=idt||"";children=(function(){_b=[];_d=this.collectChildren();for(_c=0,_e=_d.length;_c<_e;_c++){child=_d[_c];_b.push(child.toString(idt+TAB))}return _b}).call(this).join("");return"\n"+idt+children};return CodeNode})();exports.ParamNode=(function(){ParamNode=function(_b,_c,_d){this.splat=_d;this.attach=_c;this.name=_b;this.value=literal(this.name);return this};__extends(ParamNode,BaseNode);ParamNode.prototype["class"]="ParamNode";ParamNode.prototype.children=["name"];ParamNode.prototype.compileNode=function(o){return this.value.compile(o)};ParamNode.prototype.toString=function(idt){return this.attach?(literal("@"+this.name)).toString(idt):this.value.toString(idt)};return ParamNode})();exports.SplatNode=(function(){SplatNode=function(name){if(!(name.compile)){name=literal(name)}this.name=name;return this};__extends(SplatNode,BaseNode);SplatNode.prototype["class"]="SplatNode";SplatNode.prototype.children=["name"];SplatNode.prototype.compileNode=function(o){var _b;return(typeof(_b=this.index)!=="undefined"&&_b!==null)?this.compileParam(o):this.name.compile(o)};SplatNode.prototype.compileParam=function(o){var _b,_c,assign,end,idx,len,name,pos,trailing,variadic;name=this.name.compile(o);o.scope.find(name);end="";if(this.trailings.length){len=o.scope.freeVariable();o.scope.assign(len,"arguments.length");variadic=o.scope.freeVariable();o.scope.assign(variadic,len+" >= "+this.arglength);end=this.trailings.length?(", "+(len)+" - "+(this.trailings.length)):null;_b=this.trailings;for(idx=0,_c=_b.length;idx<_c;idx++){trailing=_b[idx];if(trailing.attach){assign=trailing.assign;trailing=literal(o.scope.freeVariable());assign.value=trailing}pos=this.trailings.length-idx;o.scope.assign(trailing.compile(o),("arguments["+(variadic)+" ? "+(len)+" - "+(pos)+" : "+(this.index+idx)+"]"))}}return""+(name)+" = "+(utility("slice"))+".call(arguments, "+(this.index)+(end)+")"};SplatNode.prototype.compileValue=function(o,name,index,trailings){var trail;trail=trailings?(", "+(name)+".length - "+(trailings)):"";return""+(utility("slice"))+".call("+(name)+", "+(index)+(trail)+")"};SplatNode.compileSplattedArray=function(list,o){var _b,_c,arg,args,code,i,last,prev;args=[];_b=list;for(i=0,_c=_b.length;i<_c;i++){arg=_b[i];code=arg.compile(o);prev=args[(last=args.length-1)];if(!(arg instanceof SplatNode)){if(prev&&starts(prev,"[")&&ends(prev,"]")){args[last]=(""+(prev.substr(0,prev.length-1))+", "+(code)+"]");continue}else{if(prev&&starts(prev,".concat([")&&ends(prev,"])")){args[last]=(""+(prev.substr(0,prev.length-2))+", "+(code)+"])");continue}else{code=("["+(code)+"]")}}}args.push(i===0?code:(".concat("+(code)+")"))}return args.join("")};return SplatNode}).call(this);exports.WhileNode=(function(){WhileNode=function(condition,opts){if(opts&&opts.invert){if(condition instanceof OpNode){condition=new ParentheticalNode(condition)}condition=new OpNode("!",condition)}this.condition=condition;this.guard=opts&&opts.guard;return this};__extends(WhileNode,BaseNode);WhileNode.prototype["class"]="WhileNode";WhileNode.prototype.children=["condition","guard","body"];WhileNode.prototype.isStatement=function(){return true};WhileNode.prototype.addBody=function(body){this.body=body;return this};WhileNode.prototype.makeReturn=function(){this.returns=true;return this};WhileNode.prototype.topSensitive=function(){return true};WhileNode.prototype.compileNode=function(o){var cond,post,pre,rvar,set,top;top=del(o,"top")&&!this.returns;o.indent=this.idt(1);o.top=true;cond=this.condition.compile(o);set="";if(!(top)){rvar=o.scope.freeVariable();set=(""+(this.tab)+(rvar)+" = [];\n");if(this.body){this.body=PushNode.wrap(rvar,this.body)}}pre=(""+(set)+(this.tab)+"while ("+(cond)+")");if(this.guard){this.body=Expressions.wrap([new IfNode(this.guard,this.body)])}if(this.returns){post="\n"+new ReturnNode(literal(rvar)).compile(merge(o,{indent:this.idt()}))}else{post=""}return""+(pre)+" {\n"+(this.body.compile(o))+"\n"+(this.tab)+"}"+(post)};return WhileNode})();exports.OpNode=(function(){OpNode=function(_b,_c,_d,flip){this.second=_d;this.first=_c;this.operator=_b;this.operator=this.CONVERSIONS[this.operator]||this.operator;this.flip=!!flip;if(this.first instanceof ValueNode&&this.first.base instanceof ObjectNode){this.first=new ParentheticalNode(this.first)}return this};__extends(OpNode,BaseNode);OpNode.prototype.CONVERSIONS={"==":"===","!=":"!=="};OpNode.prototype.CHAINABLE=["<",">",">=","<=","===","!=="];OpNode.prototype.ASSIGNMENT=["||=","&&=","?="];OpNode.prototype.PREFIX_OPERATORS=["typeof","delete"];OpNode.prototype["class"]="OpNode";OpNode.prototype.children=["first","second"];OpNode.prototype.isUnary=function(){return !this.second};OpNode.prototype.isChainable=function(){return indexOf(this.CHAINABLE,this.operator)>=0};OpNode.prototype.toString=function(idt){return OpNode.__superClass__.toString.call(this,idt,this["class"]+" "+this.operator)};OpNode.prototype.compileNode=function(o){o.operation=true;if(this.isChainable()&&this.first.unwrap() instanceof OpNode&&this.first.unwrap().isChainable()){return this.compileChain(o)}if(indexOf(this.ASSIGNMENT,this.operator)>=0){return this.compileAssignment(o)}if(this.isUnary()){return this.compileUnary(o)}if(this.operator==="?"){return this.compileExistence(o)}return[this.first.compile(o),this.operator,this.second.compile(o)].join(" ")};OpNode.prototype.compileChain=function(o){var _b,_c,first,second,shared;shared=this.first.unwrap().second;if(shared.containsType(CallNode)){_b=shared.compileReference(o);this.first.second=_b[0];shared=_b[1]}_c=[this.first.compile(o),this.second.compile(o),shared.compile(o)];first=_c[0];second=_c[1];shared=_c[2];return"("+(first)+") && ("+(shared)+" "+(this.operator)+" "+(second)+")"};OpNode.prototype.compileAssignment=function(o){var _b,first,firstVar,second;_b=this.first.compileReference(o,{precompile:true,assignment:true});first=_b[0];firstVar=_b[1];second=this.second.compile(o);if(this.second instanceof OpNode){second=("("+(second)+")")}if(first.match(IDENTIFIER)){o.scope.find(first)}if(this.operator==="?="){return(""+(first)+" = "+(ExistenceNode.compileTest(o,literal(firstVar)))+" ? "+(firstVar)+" : "+(second))}return""+(first)+" = "+(firstVar)+" "+(this.operator.substr(0,2))+" "+(second)};OpNode.prototype.compileExistence=function(o){var _b,first,second,test;_b=[this.first.compile(o),this.second.compile(o)];first=_b[0];second=_b[1];test=ExistenceNode.compileTest(o,this.first);return""+(test)+" ? "+(first)+" : "+(second)};OpNode.prototype.compileUnary=function(o){var parts,space;space=indexOf(this.PREFIX_OPERATORS,this.operator)>=0?" ":"";parts=[this.operator,space,this.first.compile(o)];if(this.flip){parts=parts.reverse()}return parts.join("")};return OpNode})();exports.InNode=(function(){InNode=function(_b,_c){this.array=_c;this.object=_b;return this};__extends(InNode,BaseNode);InNode.prototype["class"]="InNode";InNode.prototype.children=["object","array"];InNode.prototype.isArray=function(){return this.array instanceof ValueNode&&this.array.isArray()};InNode.prototype.compileNode=function(o){var _b;_b=this.object.compileReference(o,{precompile:true});this.obj1=_b[0];this.obj2=_b[1];return this.isArray()?this.compileOrTest(o):this.compileLoopTest(o)};InNode.prototype.compileOrTest=function(o){var _b,_c,_d,i,item,tests;tests=(function(){_b=[];_c=this.array.base.objects;for(i=0,_d=_c.length;i<_d;i++){item=_c[i];_b.push((""+(item.compile(o))+" === "+(i?this.obj2:this.obj1)))}return _b}).call(this);return"("+(tests.join(" || "))+")"};InNode.prototype.compileLoopTest=function(o){var _b,_c,i,l,prefix;_b=this.array.compileReference(o,{precompile:true});this.arr1=_b[0];this.arr2=_b[1];_c=[o.scope.freeVariable(),o.scope.freeVariable()];i=_c[0];l=_c[1];prefix=this.obj1!==this.obj2?this.obj1+"; ":"";return"(function(){ "+(prefix)+"for (var "+(i)+"=0, "+(l)+"="+(this.arr1)+".length; "+(i)+"<"+(l)+"; "+(i)+"++) { if ("+(this.arr2)+"["+(i)+"] === "+(this.obj2)+") return true; } return false; }).call(this)"};return InNode})();exports.TryNode=(function(){TryNode=function(_b,_c,_d,_e){this.ensure=_e;this.recovery=_d;this.error=_c;this.attempt=_b;return this};__extends(TryNode,BaseNode);TryNode.prototype["class"]="TryNode";TryNode.prototype.children=["attempt","recovery","ensure"];TryNode.prototype.isStatement=function(){return true};TryNode.prototype.makeReturn=function(){if(this.attempt){this.attempt=this.attempt.makeReturn()}if(this.recovery){this.recovery=this.recovery.makeReturn()}return this};TryNode.prototype.compileNode=function(o){var attemptPart,catchPart,errorPart,finallyPart;o.indent=this.idt(1);o.top=true;attemptPart=this.attempt.compile(o);errorPart=this.error?(" ("+(this.error.compile(o))+") "):" ";catchPart=this.recovery?(" catch"+(errorPart)+"{\n"+(this.recovery.compile(o))+"\n"+(this.tab)+"}"):"";finallyPart=(this.ensure||"")&&" finally {\n"+this.ensure.compile(merge(o))+("\n"+(this.tab)+"}");return""+(this.tab)+"try {\n"+(attemptPart)+"\n"+(this.tab)+"}"+(catchPart)+(finallyPart)};return TryNode})();exports.ThrowNode=(function(){ThrowNode=function(_b){this.expression=_b;return this};__extends(ThrowNode,BaseNode);ThrowNode.prototype["class"]="ThrowNode";ThrowNode.prototype.children=["expression"];ThrowNode.prototype.isStatement=function(){return true};ThrowNode.prototype.makeReturn=function(){return this};ThrowNode.prototype.compileNode=function(o){return""+(this.tab)+"throw "+(this.expression.compile(o))+";"};return ThrowNode})();exports.ExistenceNode=(function(){ExistenceNode=function(_b){this.expression=_b;return this};__extends(ExistenceNode,BaseNode);ExistenceNode.prototype["class"]="ExistenceNode";ExistenceNode.prototype.children=["expression"];ExistenceNode.prototype.compileNode=function(o){return ExistenceNode.compileTest(o,this.expression)};ExistenceNode.compileTest=function(o,variable){var _b,first,second;_b=variable.compileReference(o);first=_b[0];second=_b[1];return"(typeof "+(first.compile(o))+' !== "undefined" && '+(second.compile(o))+" !== null)"};return ExistenceNode}).call(this);exports.ParentheticalNode=(function(){ParentheticalNode=function(_b){this.expression=_b;return this};__extends(ParentheticalNode,BaseNode);ParentheticalNode.prototype["class"]="ParentheticalNode";ParentheticalNode.prototype.children=["expression"];ParentheticalNode.prototype.isStatement=function(){return this.expression.isStatement()};ParentheticalNode.prototype.makeReturn=function(){return this.expression.makeReturn()};ParentheticalNode.prototype.topSensitive=function(){return true};ParentheticalNode.prototype.compileNode=function(o){var code,l,top;top=del(o,"top");code=this.expression.compile(o);if(this.isStatement()){return(top?this.tab+code+";":code)}l=code.length;if(code.substr(l-1,1)===";"){code=code.substr(o,l-1)}return this.expression instanceof AssignNode?code:("("+(code)+")")};return ParentheticalNode})();exports.ForNode=(function(){ForNode=function(_b,source,_c,_d){var _e;this.index=_d;this.name=_c;this.body=_b;this.index=this.index||null;this.source=source.source;this.guard=source.guard;this.step=source.step;this.raw=!!source.raw;this.object=!!source.object;if(this.object){_e=[this.index,this.name];this.name=_e[0];this.index=_e[1]}this.pattern=this.name instanceof ValueNode;if(this.index instanceof ValueNode){throw new Error("index cannot be a pattern matching expression")}this.returns=false;return this};__extends(ForNode,BaseNode);ForNode.prototype["class"]="ForNode";ForNode.prototype.children=["body","source","guard"];ForNode.prototype.isStatement=function(){return true};ForNode.prototype.topSensitive=function(){return true};ForNode.prototype.makeReturn=function(){this.returns=true;return this};ForNode.prototype.compileReturnValue=function(val,o){if(this.returns){return"\n"+new ReturnNode(literal(val)).compile(o)}if(val){return"\n"+val}return""};ForNode.prototype.compileNode=function(o){var body,codeInBody,forPart,guardPart,index,ivar,lvar,name,namePart,range,returnResult,rvar,scope,source,sourcePart,stepPart,svar,topLevel,varPart,vars;topLevel=del(o,"top")&&!this.returns;range=this.source instanceof ValueNode&&this.source.base instanceof RangeNode&&!this.source.properties.length;source=range?this.source.base:this.source;codeInBody=this.body.contains(function(n){return n instanceof CodeNode});scope=o.scope;name=(this.name&&this.name.compile(o))||scope.freeVariable();index=this.index&&this.index.compile(o);if(name&&!this.pattern&&(range||!codeInBody)){scope.find(name)}if(index){scope.find(index)}if(!(topLevel)){rvar=scope.freeVariable()}ivar=(function(){if(codeInBody){return scope.freeVariable()}else{if(range){return name}else{return index||scope.freeVariable()}}})();varPart="";guardPart="";body=Expressions.wrap([this.body]);if(range){sourcePart=source.compileVariables(o);forPart=source.compile(merge(o,{index:ivar,step:this.step}))}else{svar=scope.freeVariable();sourcePart=(""+(svar)+" = "+(this.source.compile(o))+";");if(this.pattern){namePart=new AssignNode(this.name,literal((""+(svar)+"["+(ivar)+"]"))).compile(merge(o,{indent:this.idt(1),top:true}))+"\n"}else{if(name){namePart=(""+(name)+" = "+(svar)+"["+(ivar)+"]")}}if(!(this.object)){lvar=scope.freeVariable();stepPart=this.step?(""+(ivar)+" += "+(this.step.compile(o))):(""+(ivar)+"++");forPart=(""+(ivar)+" = 0, "+(lvar)+" = "+(svar)+".length; "+(ivar)+" < "+(lvar)+"; "+(stepPart))}}sourcePart=(rvar?(""+(rvar)+" = []; "):"")+sourcePart;sourcePart=sourcePart?(""+(this.tab)+(sourcePart)+"\n"+(this.tab)):this.tab;returnResult=this.compileReturnValue(rvar,o);if(!(topLevel)){body=PushNode.wrap(rvar,body)}if(this.guard){body=Expressions.wrap([new IfNode(this.guard,body)])}if(codeInBody){if(range){body.unshift(literal(("var "+(name)+" = "+(ivar))))}if(namePart){body.unshift(literal(("var "+(namePart))))}if(index){body.unshift(literal(("var "+(index)+" = "+(ivar))))}body=ClosureNode.wrap(body,true)}else{varPart=(namePart||"")&&(this.pattern?namePart:(""+(this.idt(1))+(namePart)+";\n"))}if(this.object){forPart=(""+(ivar)+" in "+(svar));if(!(this.raw)){guardPart=("\n"+(this.idt(1))+"if (!"+(utility("hasProp"))+".call("+(svar)+", "+(ivar)+")) continue;")}}body=body.compile(merge(o,{indent:this.idt(1),top:true}));vars=range?name:(""+(name)+", "+(ivar));return""+(sourcePart)+"for ("+(forPart)+") {"+(guardPart)+"\n"+(varPart)+(body)+"\n"+(this.tab)+"}"+(returnResult)};return ForNode})();exports.IfNode=(function(){IfNode=function(_b,_c,_d){this.tags=_d;this.body=_c;this.condition=_b;this.tags=this.tags||{};if(this.tags.invert){this.condition=new OpNode("!",new ParentheticalNode(this.condition))}this.elseBody=null;this.isChain=false;return this};__extends(IfNode,BaseNode);IfNode.prototype["class"]="IfNode";IfNode.prototype.children=["condition","switchSubject","body","elseBody","assigner"];IfNode.prototype.topSensitive=function(){return true};IfNode.prototype.bodyNode=function(){return this.body==undefined?undefined:this.body.unwrap()};IfNode.prototype.elseBodyNode=function(){return this.elseBody==undefined?undefined:this.elseBody.unwrap()};IfNode.prototype.forceStatement=function(){this.tags.statement=true;return this};IfNode.prototype.switchesOver=function(expression){this.switchSubject=expression;return this};IfNode.prototype.rewriteSwitch=function(o){var _b,_c,_d,cond,i,variable;this.assigner=this.switchSubject;if(!((this.switchSubject.unwrap() instanceof LiteralNode))){variable=literal(o.scope.freeVariable());this.assigner=new AssignNode(variable,this.switchSubject);this.switchSubject=variable}this.condition=(function(){_b=[];_c=flatten([this.condition]);for(i=0,_d=_c.length;i<_d;i++){cond=_c[i];_b.push((function(){if(cond instanceof OpNode){cond=new ParentheticalNode(cond)}return new OpNode("==",(i===0?this.assigner:this.switchSubject),cond)}).call(this))}return _b}).call(this);if(this.isChain){this.elseBodyNode().switchesOver(this.switchSubject)}this.switchSubject=undefined;return this};IfNode.prototype.addElse=function(elseBody,statement){if(this.isChain){this.elseBodyNode().addElse(elseBody,statement)}else{this.isChain=elseBody instanceof IfNode;this.elseBody=this.ensureExpressions(elseBody)}return this};IfNode.prototype.isStatement=function(){return this.statement=this.statement||(!!(this.tags.statement||this.bodyNode().isStatement()||(this.elseBody&&this.elseBodyNode().isStatement())))};IfNode.prototype.compileCondition=function(o){var _b,_c,_d,_e,cond;return(function(){_b=[];_d=flatten([this.condition]);for(_c=0,_e=_d.length;_c<_e;_c++){cond=_d[_c];_b.push(cond.compile(o))}return _b}).call(this).join(" || ")};IfNode.prototype.compileNode=function(o){return o.top||this.isStatement()?this.compileStatement(o):this.compileTernary(o)};IfNode.prototype.makeReturn=function(){if(this.isStatement()){this.body=this.body&&this.ensureExpressions(this.body.makeReturn());this.elseBody=this.elseBody&&this.ensureExpressions(this.elseBody.makeReturn());return this}else{return new ReturnNode(this)}};IfNode.prototype.ensureExpressions=function(node){return node instanceof Expressions?node:new Expressions([node])};IfNode.prototype.compileStatement=function(o){var body,child,comDent,condO,elsePart,ifDent,ifPart,top;if(this.switchSubject){this.rewriteSwitch(o)}top=del(o,"top");child=del(o,"chainChild");condO=merge(o);o.indent=this.idt(1);o.top=true;ifDent=child||(top&&!this.isStatement())?"":this.idt();comDent=child?this.idt():"";body=this.body.compile(o);ifPart=(""+(ifDent)+"if ("+(this.compileCondition(condO))+") {\n"+(body)+"\n"+(this.tab)+"}");if(!(this.elseBody)){return ifPart}elsePart=this.isChain?" else "+this.elseBodyNode().compile(merge(o,{indent:this.idt(),chainChild:true})):(" else {\n"+(this.elseBody.compile(o))+"\n"+(this.tab)+"}");return""+(ifPart)+(elsePart)};IfNode.prototype.compileTernary=function(o){var elsePart,ifPart;o.operation=true;ifPart=this.condition.compile(o)+" ? "+this.bodyNode().compile(o);elsePart=this.elseBody?this.elseBodyNode().compile(o):"null";return""+(ifPart)+" : "+(elsePart)};return IfNode})();PushNode=(exports.PushNode={wrap:function(array,expressions){var expr;expr=expressions.unwrap();if(expr.isPureStatement()||expr.containsPureStatement()){return expressions}return Expressions.wrap([new CallNode(new ValueNode(literal(array),[new AccessorNode(literal("push"))]),[expr])])}});ClosureNode=(exports.ClosureNode={wrap:function(expressions,statement){var args,call,func,mentionsArgs,mentionsThis,meth;if(expressions.containsPureStatement()){return expressions}func=new ParentheticalNode(new CodeNode([],Expressions.wrap([expressions])));args=[];mentionsArgs=expressions.contains(function(n){return n instanceof LiteralNode&&(n.value==="arguments")});mentionsThis=expressions.contains(function(n){return(n instanceof LiteralNode&&(n.value==="this"))||(n instanceof CodeNode&&n.bound)});if(mentionsArgs||mentionsThis){meth=literal(mentionsArgs?"apply":"call");args=[literal("this")];if(mentionsArgs){args.push(literal("arguments"))}func=new ValueNode(func,[new AccessorNode(meth)])}call=new CallNode(func,args);return statement?Expressions.wrap([call]):call}});UTILITIES={"extends":'function(child, parent) {\n    var ctor = function(){};\n    ctor.prototype = parent.prototype;\n    child.prototype = new ctor();\n    child.prototype.constructor = child;\n    if (typeof parent.extended === "function") parent.extended(child);\n    child.__superClass__ = parent.prototype;\n  }',bind:"function(func, context) {\n    return function(){ return func.apply(context, arguments); };\n  }",hasProp:"Object.prototype.hasOwnProperty",slice:"Array.prototype.slice"};TAB="  ";TRAILING_WHITESPACE=/[ \t]+$/gm;IDENTIFIER=/^[a-zA-Z\$_](\w|\$)*$/;NUMBER=/^(((\b0(x|X)[0-9a-fA-F]+)|((\b[0-9]+(\.[0-9]+)?|\.[0-9]+)(e[+\-]?[0-9]+)?)))\b$/i;SIMPLENUM=/^-?\d+/;IS_STRING=/^['"]/;literal=function(name){return new LiteralNode(name)};utility=function(name){var ref;ref=("__"+(name));Scope.root.assign(ref,UTILITIES[name]);return ref}})();(function(){var Lexer,compile,helpers,lexer,parser,path,processScripts;if((typeof process!=="undefined"&&process!==null)){path=require("path");Lexer=require("./lexer").Lexer;parser=require("./parser").parser;helpers=require("./helpers").helpers;helpers.extend(global,require("./nodes"));if(require.registerExtension){require.registerExtension(".coffee",function(content){return compile(content)})}}else{this.exports=(this.CoffeeScript={});Lexer=this.Lexer;parser=this.parser;helpers=this.helpers}exports.VERSION="0.9.1";lexer=new Lexer();exports.compile=(compile=function(code,options){options=options||{};try{return(parser.parse(lexer.tokenize(code))).compile(options)}catch(err){if(options.fileName){err.message=("In "+(options.fileName)+", "+(err.message))}throw err}});exports.tokens=function(code){return lexer.tokenize(code)};exports.nodes=function(code){return parser.parse(lexer.tokenize(code))};exports.run=(function(code,options){var __dirname,__filename;module.filename=(__filename=options.fileName);__dirname=path.dirname(__filename);return eval(exports.compile(code,options))});parser.lexer={lex:function(){var token;token=this.tokens[this.pos]||[""];this.pos+=1;this.yylineno=token[2];this.yytext=token[1];return token[0]},setInput:function(tokens){this.tokens=tokens;return(this.pos=0)},upcomingInput:function(){return""}};if((typeof document!=="undefined"&&document!==null)&&document.getElementsByTagName){processScripts=function(){var _a,_b,_c,_d,tag;_a=[];_c=document.getElementsByTagName("script");for(_b=0,_d=_c.length;_b<_d;_b++){tag=_c[_b];if(tag.type==="text/coffeescript"){_a.push(eval(exports.compile(tag.innerHTML)))}}return _a};if(window.addEventListener){window.addEventListener("load",processScripts,false)}else{if(window.attachEvent){window.attachEvent("onload",processScripts)}}}})();
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/coffee/coffee.js b/browserid/static/dialog/steal/coffee/coffee.js
new file mode 100644
index 0000000000000000000000000000000000000000..ae6ad8870b06f8053ee4ab0f82dae147bd0f4b6f
--- /dev/null
+++ b/browserid/static/dialog/steal/coffee/coffee.js
@@ -0,0 +1,62 @@
+/**
+ * @add steal.static
+ */
+steal({
+	path: "coffee-script.js",
+	ignore: true
+}, function() {
+
+	/**
+	 * @function coffee
+	 * @plugin steal/coffee
+	 * <p>Requires a [http://jashkenas.github.com/coffee-script/ CoffeeScript] script.</p>
+	 * 
+	 * <p>CoffeeScript is a more 'refined' version of JavaScript that lets you write code like:</p>
+	 * @codestart
+	 * number = -42 if opposite
+	 * @codeend
+	 * CoffeeScript is normally used on the server, but steal lets you load CoffeeScripts
+	 * in the browser, and compress their JavaScript output into your production builds.
+	 * 
+	 * <h2>Use</h2>
+	 * <p>First, create a coffee script like:</p>
+	 * @codestart
+	 * console.log "There are no () around this string!"
+	 * @codeend
+	 * <p>Save this in a file named <code>log.coffee</code>.</p>
+	 * <p>Next, you have to require the <code>steal/coffee</code> plugin and then use
+	 * steal.coffee to load your coffee script:
+	 * </p>
+	 * @codestart
+	 * steal.plugins('steal/coffee').then(function(){
+	 *   steal.coffee('log');
+	 * });
+	 * @codeend
+	 *
+	 * Loads CoffeeScript files relative to the current file.  It's expected that all
+	 * CoffeeScript files end with <code>coffee</code>.
+	 * @param {String+} path the relative path from the current file to the coffee file.
+	 * You can pass multiple paths.
+	 * @return {steal} returns the steal function.
+	 */
+	steal.coffee = function() {
+		//if production, 
+		if ( steal.options.env == 'production' ) {
+			return this;
+		}
+		//@steal-remove-start
+		var current, path;
+		for ( var i = 0; i < arguments.length; i++ ) {
+			steal({
+				path: arguments[0] + ".coffee",
+				type: "text/coffee",
+				process: function( text ) {
+					return CoffeeScript.compile(text)
+				}
+			})
+		}
+		//@steal-remove-end
+		return this;
+	}
+
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/dev/dev.js b/browserid/static/dialog/steal/dev/dev.js
new file mode 100644
index 0000000000000000000000000000000000000000..557d3e2b7e9ed6c17c3dd0340a1378f7fb6f00d7
--- /dev/null
+++ b/browserid/static/dialog/steal/dev/dev.js
@@ -0,0 +1,95 @@
+/*global  window: false, console: true, opera: true */
+/**
+ * @class steal.dev
+ * @parent stealjs
+ * Provides helper functions for development that get removed when put in production mode.
+ * This means you can leave <code>steal.dev.log("hello world")</code> in your code and it
+ * will get removed in prodution.
+ * <h3>Examples</h3>
+ * @codestart
+ * steal.dev.log("Something is happening");
+ * steal.dev.warn("Something bad is happening");
+ * @codeend
+ */
+steal.dev = {
+	regexps: {
+		colons: /::/,
+		words: /([A-Z]+)([A-Z][a-z])/g,
+		lowerUpper: /([a-z\d])([A-Z])/g,
+		dash: /([a-z\d])([A-Z])/g
+	},
+	underscore: function( s ) {
+		var regs = this.regexps;
+		return s.replace(regs.colons, '/').
+		replace(regs.words, '$1_$2').
+		replace(regs.lowerUpper, '$1_$2').
+		replace(regs.dash, '_').toLowerCase();
+	},
+	isHappyName: function( name ) {
+		//make sure names are close to the current path
+		var path = steal.cur().path.replace(/\.[^$]+$/, "").split('/'),
+			//make sure parts in name match
+			parts = name.split('.');
+		
+		for ( var i = 0; i < parts.length && path.length; i++ ) {
+			if (path[i] && parts[i].toLowerCase() != path[i] && this.underscore(parts[i]) != path[i] && this.underscore(parts[i]) != path[i].replace(/_controller/, "") ) {
+				this.warn("Are you sure " + name + " belongs in " + steal.cur().path);
+			}
+		}
+		
+		
+	},
+
+	logLevel : 0,
+	/**
+	 * Adds a warning message to the console.
+	 * @codestart
+	 * steal.dev.warn("something evil");
+	 * @codeend
+	 * @param {String} out the message
+	 */
+	warn: function( out ) {
+		if(steal.options.logLevel < 2){
+			if ( window.console && console.log ) {
+				console.log("steal.js WARNING: " + out);
+			} else if ( window.opera && window.opera.postError ) {
+				opera.postError("steal.js WARNING: " + out);
+			}
+		}
+		
+	},
+	/**
+	 * Adds a message to the console.
+	 * @codestart
+	 * steal.dev.log("hi");
+	 * @codeend
+	 * @param {String} out the message
+	 */
+	log: function( out ) {
+		if (steal.options.logLevel < 1) {
+			if (window.console && console.log) {
+				console.log("steal.js INFO: " + out);
+			}
+			else if (window.opera && window.opera.postError) {
+				opera.postError("steal.js INFO: " + out);
+			}
+		}
+	}
+};
+
+//stuff for jmvc
+/**
+ * @class jQuery
+ * @constructor blah
+ */
+
+//
+/**
+ * @class jQuery.fn
+ * @constructor blah
+ */
+//
+/**
+ * @class jQuery.event.special
+ */
+// as fasf sa
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/end.js b/browserid/static/dialog/steal/end.js
new file mode 100644
index 0000000000000000000000000000000000000000..7dfa823c6ef8e89c3649386ae05bf2cc47c405ca
--- /dev/null
+++ b/browserid/static/dialog/steal/end.js
@@ -0,0 +1 @@
+steal.end();
diff --git a/browserid/static/dialog/steal/generate/app b/browserid/static/dialog/steal/generate/app
new file mode 100644
index 0000000000000000000000000000000000000000..f7bd08021e249d66b9ac11300729b6c8a8cf0be3
--- /dev/null
+++ b/browserid/static/dialog/steal/generate/app
@@ -0,0 +1,21 @@
+// _args = ['cookbook']; load('steal/generate/app')
+
+if (!_args[0]) {
+	print("Usage: steal/js steal/generate/app path");
+	quit();
+}
+
+load('steal/rhino/steal.js');
+
+steal('//steal/generate/generate','//steal/generate/system',function(steal){
+	var path =  _args[0].toLowerCase().replace('.',"/");
+	var	data = steal.extend({
+		path: path, 
+		application_name: path.match(/[^\/]*$/)[0],
+		current_path: steal.File.cwdURL(),
+		path_to_steal: new steal.File(path).pathToRoot()
+	}, steal.system);
+	
+	steal.generate("steal/generate/templates/app", path, data);
+	
+});
diff --git a/browserid/static/dialog/steal/generate/ejs.js b/browserid/static/dialog/steal/generate/ejs.js
new file mode 100644
index 0000000000000000000000000000000000000000..15bd5000c09c90323821582ea11cdb6a11c1f8da
--- /dev/null
+++ b/browserid/static/dialog/steal/generate/ejs.js
@@ -0,0 +1,531 @@
+//@documentjs-ignore
+steal.then(function( steal ) {
+
+
+	var rsplit = function( string, regex ) {
+		var result = regex.exec(string),
+			retArr = [],
+			first_idx, last_idx, first_bit;
+		while ( result !== null ) {
+			first_idx = result.index;
+			last_idx = regex.lastIndex;
+			if ((first_idx) !== 0 ) {
+				first_bit = string.substring(0, first_idx);
+				retArr.push(string.substring(0, first_idx));
+				string = string.slice(first_idx);
+			}
+			retArr.push(result[0]);
+			string = string.slice(result[0].length);
+			result = regex.exec(string);
+		}
+		if (!string == '' ) {
+			retArr.push(string);
+		}
+		return retArr;
+	},
+		chop = function( string ) {
+			return string.substr(0, string.length - 1);
+		},
+		extend = function( d, s ) {
+			for ( var n in s ) {
+				if ( s.hasOwnProperty(n) ) {
+					d[n] = s[n];
+				}
+			}
+		};
+
+		steal.EJS = function( options ) {
+			options = typeof options === "string" ? {
+				view: options
+			} : options;
+			
+			this.set_options(options);
+			if ( options.precompiled ) {
+				this.template = {};
+				this.template.process = options.precompiled;
+				vEJS.update(this.name, this);
+				return;
+			}
+			if ( options.element ) {
+				if ( typeof options.element === 'string' ) {
+					var name = options.element;
+					options.element = document.getElementById(options.element);
+					
+					if ( options.element == null ){
+						throw name + 'does not exist!';
+					}
+				}
+				if ( options.element.value ) {
+					this.text = options.element.value;
+				} else {
+					this.text = options.element.innerHTML;
+				}
+				this.name = options.element.id;
+				this.type = '[';
+			} else if ( options.url ) {
+				options.url = vEJS.endExt(options.url, this.extMatch);
+				this.name = this.name ? this.name : options.url;
+				var url = options.url;
+				//options.view = options.absolute_url || options.view || options.;
+				var template = vEJS.get(this.name
+				/*url*/
+				, this.cache);
+				
+				if ( template ){
+					return template;
+				}
+				
+				if ( template === vEJS.INVALID_PATH ){
+					return null;
+				}
+				
+				try {
+					this.text = vEJS.request(url + (this.cache ? '' : '?' + Math.random()));
+				} catch (e) {}
+
+				if ( this.text == null ) {
+					throw ('There is no template at ' + url);
+				}
+				//this.name = url;
+			}
+			
+			var template = new vEJS.Compiler(this.text, this.type);
+
+			template.compile(options, this.name);
+
+			vEJS.update(this.name, this);
+			this.template = template;
+		};
+	var vEJS = steal.EJS;
+	/* @Prototype*/
+	vEJS.prototype = {
+		/**
+		 * Renders an object with extra view helpers attached to the view.
+		 * @param {Object} object data to be rendered
+		 * @param {Object} extra_helpers an object with additonal view helpers
+		 * @return {String} returns the result of the string
+		 */
+		render: function( object, extra_helpers ) {
+			object = object || {};
+			this._extra_helpers = extra_helpers;
+			var v = new vEJS.Helpers(object, extra_helpers || {});
+			return this.template.process.call(object, object, v);
+		},
+		update: function( element, options ) {
+			if ( typeof element === 'string' ) {
+				element = document.getElementById(element);
+			}
+			if ( options == null ) {
+				_template = this;
+				return function( object ) {
+					vEJS.prototype.update.call(_template, element, object);
+				};
+			}
+			if ( typeof options === 'string' ) {
+				params = {};
+				params.url = options;
+				_template = this;
+				
+				params.onComplete = function( request ) {
+					var object = eval(request.responseText);
+					vEJS.prototype.update.call(_template, element, object);
+				};
+				
+				vEJS.ajax_request(params);
+			} else {
+				element.innerHTML = this.render(options);
+			}
+		},
+		out: function() {
+			return this.template.out;
+		},
+		/**
+		 * Sets options on this view to be rendered with.
+		 * @param {Object} options
+		 */
+		set_options: function( options ) {
+			this.type = options.type || vEJS.type;
+			this.cache = options.cache != null ? options.cache : vEJS.cache;
+			this.text = options.text || null;
+			this.name = options.name || null;
+			this.ext = options.ext || vEJS.ext;
+			this.extMatch = new RegExp(this.ext.replace(/\./, '\.'));
+		}
+	};
+	vEJS.endExt = function( path, match ) {
+		if (!path ){
+			return null;
+		}
+		match.lastIndex = 0;
+		return path + (match.test(path) ? '' : this.ext);
+	};
+
+	/* @Static*/
+	vEJS.Scanner = function( source, left, right ) {
+
+		extend(this, {
+			left_delimiter: left + '%',
+			right_delimiter: '%' + right,
+			double_left: left + '%%',
+			double_right: '%%' + right,
+			left_equal: left + '%=',
+			left_comment: left + '%#'
+		});
+
+		this.SplitRegexp = left === '[' 
+							? /(\[%%)|(%%\])|(\[%=)|(\[%#)|(\[%)|(%\]\n)|(%\])|(\n)/ 
+							: new RegExp('(' + this.double_left + ')|(%%' + this.double_right + ')|(' + this.left_equal + ')|(' + this.left_comment + ')|(' + this.left_delimiter + ')|(' + this.right_delimiter + '\n)|(' + this.right_delimiter + ')|(\n)');
+
+		this.source = source;
+		this.stag = null;
+		this.lines = 0;
+	};
+
+	vEJS.Scanner.to_text = function( input ) {
+		if ( input == null || input === undefined ){
+			return '';
+		}
+		
+		if ( input instanceof Date ) {
+			return input.toDateString();
+		}
+		
+		if ( input.toString ) {
+			return input.toString();
+		}
+		
+		return '';
+	};
+
+	vEJS.Scanner.prototype = {
+		scan: function( block ) {
+			scanline = this.scanline;
+			regex = this.SplitRegexp;
+			if ( !this.source == '' ) {
+				var source_split = rsplit(this.source, /\n/);
+				for ( var i = 0; i < source_split.length; i++ ) {
+					var item = source_split[i];
+					this.scanline(item, regex, block);
+				}
+			}
+		},
+		scanline: function( line, regex, block ) {
+			this.lines++;
+			var line_split = rsplit(line, regex);
+			for ( var i = 0; i < line_split.length; i++ ) {
+				var token = line_split[i];
+				if ( token != null ) {
+					try {
+						block(token, this);
+					} catch (e) {
+						throw {
+							type: 'vEJS.Scanner',
+							line: this.lines
+						};
+					}
+				}
+			}
+		}
+	};
+
+
+	vEJS.Buffer = function( pre_cmd, post_cmd ) {
+		this.line = [];
+		this.script = "";
+		this.pre_cmd = pre_cmd;
+		this.post_cmd = post_cmd;
+		for ( var i = 0; i < this.pre_cmd.length; i++ ) {
+			this.push(pre_cmd[i]);
+		}
+	};
+	vEJS.Buffer.prototype = {
+
+		push: function( cmd ) {
+			this.line.push(cmd);
+		},
+
+		cr: function() {
+			this.script = this.script + this.line.join('; ');
+			this.line = [];
+			this.script = this.script + "\n";
+		},
+
+		close: function() {
+			if ( this.line.length > 0 ) {
+				for ( var i = 0; i < this.post_cmd.length; i++ ) {
+					this.push(pre_cmd[i]);
+				}
+				this.script = this.script + this.line.join('; ');
+				line = null;
+			}
+		}
+
+	};
+
+
+	vEJS.Compiler = function( source, left ) {
+		this.pre_cmd = ['var ___ViewO = [];'];
+		this.post_cmd = [];
+		this.source = ' ';
+		if ( source != null ) {
+			if ( typeof source === 'string' ) {
+				source = source.replace(/\r\n/g, "\n");
+				source = source.replace(/\r/g, "\n");
+				this.source = source;
+			} else if ( source.innerHTML ) {
+				this.source = source.innerHTML;
+			}
+			if ( typeof this.source !== 'string' ) {
+				this.source = "";
+			}
+		}
+		left = left || '<';
+		var right = '>';
+		switch ( left ) {
+		case '[':
+			right = ']';
+			break;
+		case '<':
+			break;
+		default:
+			throw left + ' is not a supported deliminator';
+			//break;
+		}
+		this.scanner = new vEJS.Scanner(this.source, left, right);
+		this.out = '';
+	};
+	vEJS.Compiler.prototype = {
+		compile: function( options, name ) {
+			options = options || {};
+			this.out = '';
+			var put_cmd = "___ViewO.push(";
+			var insert_cmd = put_cmd;
+			var buff = new vEJS.Buffer(this.pre_cmd, this.post_cmd);
+			var content = '';
+			var clean = function( content ) {
+				content = content.replace(/\\/g, '\\\\');
+				content = content.replace(/\n/g, '\\n');
+				content = content.replace(/"/g, '\\"');
+				return content;
+			};
+			this.scanner.scan(function( token, scanner ) {
+				if ( scanner.stag == null ) {
+					switch ( token ) {
+					case '\n':
+						content = content + "\n";
+						buff.push(put_cmd + '"' + clean(content) + '");');
+						buff.cr();
+						content = '';
+						break;
+					case scanner.left_delimiter:
+					case scanner.left_equal:
+					case scanner.left_comment:
+						scanner.stag = token;
+						if ( content.length > 0 ) {
+							buff.push(put_cmd + '"' + clean(content) + '")');
+						}
+						content = '';
+						break;
+					case scanner.double_left:
+						content = content + scanner.left_delimiter;
+						break;
+					default:
+						content = content + token;
+						break;
+					}
+				}
+				else {
+					switch ( token ) {
+					case scanner.right_delimiter:
+						switch ( scanner.stag ) {
+						case scanner.left_delimiter:
+							if ( content[content.length - 1] === '\n' ) {
+								content = chop(content);
+								buff.push(content);
+								buff.cr();
+							}
+							else {
+								buff.push(content);
+							}
+							break;
+						case scanner.left_equal:
+							buff.push(insert_cmd + "(vEJS.Scanner.to_text(" + content + ")))");
+							break;
+						}
+						scanner.stag = null;
+						content = '';
+						break;
+					case scanner.double_right:
+						content = content + scanner.right_delimiter;
+						break;
+					default:
+						content = content + token;
+						break;
+					}
+				}
+			});
+			if ( content.length > 0 ) {
+				// Chould be content.dump in Ruby
+				buff.push(put_cmd + '"' + clean(content) + '")');
+			}
+			buff.close();
+			this.out = buff.script + ";";
+			var to_be_evaled = '/*' + name + '*/this.process = function(_CONTEXT,_VIEW) { try { with(_VIEW) { with (_CONTEXT) {' + this.out + " return ___ViewO.join('');}}}catch(e){e.lineNumber=null;throw e;}};";
+
+			try {
+				eval(to_be_evaled);
+			} catch (e) {
+				if ( typeof JSLINT !== 'undefined' ) {
+					JSLINT(this.out);
+					for ( var i = 0; i < JSLINT.errors.length; i++ ) {
+						var error = JSLINT.errors[i];
+						if ( error.reason !== "Unnecessary semicolon." ) {
+							error.line++;
+							e = new Error();
+							e.lineNumber = error.line;
+							e.message = error.reason;
+							if ( options.view ){
+								e.fileName = options.view;
+							}
+							throw e;
+						}
+					}
+				} else {
+					throw e;
+				}
+			}
+		}
+	};
+
+
+	//type, cache, folder
+	vEJS.config = function( options ) {
+		vEJS.cache = options.cache != null ? options.cache : vEJS.cache;
+		vEJS.type = options.type != null ? options.type : vEJS.type;
+		vEJS.ext = options.ext != null ? options.ext : vEJS.ext;
+
+		var templates_directory = vEJS.templates_directory || {}; //nice and private container
+		vEJS.templates_directory = templates_directory;
+		vEJS.get = function( path, cache ) {
+			if ( cache == false ){
+				return null;
+			}
+			
+			if ( templates_directory[path] ){ 
+				return templates_directory[path];
+			}
+			
+			return null;
+		};
+
+		vEJS.update = function( path, template ) {
+			if ( path == null ) {
+				return;
+			}
+			
+			templates_directory[path] = template;
+		};
+
+		vEJS.INVALID_PATH = -1;
+	};
+	vEJS.config({
+		cache: true,
+		type: '<',
+		ext: '.ejs'
+	});
+
+
+
+
+	vEJS.Helpers = function( data, extras ) {
+		this._data = data;
+		this._extras = extras;
+		extend(this, extras);
+	};
+	/* @prototype*/
+	vEJS.Helpers.prototype = {
+		view: function( options, data, helpers ) {
+			if ( !helpers ){
+				helpers = this._extras;
+			}
+			if ( !data ){
+				data = this._data;
+			}
+			
+			return new vEJS(options).render(data, helpers);
+		},
+		to_text: function( input, null_text ) {
+			if ( input == null || input === undefined ) {
+				return null_text || '';
+			}
+			
+			if ( input instanceof Date ) {
+				return input.toDateString();
+			}
+			
+			if ( input.toString ) {
+				return input.toString().replace(/\n/g, '<br />').replace(/''/g, "'");
+			}
+			
+			return '';
+		}
+	};
+	vEJS.newRequest = function() {
+		var factories = [function() {
+			return new ActiveXObject("Msxml2.XMLHTTP");
+		}, function() {
+			return new XMLHttpRequest();
+		}, function() {
+			return new ActiveXObject("Microsoft.XMLHTTP");
+		}];
+		for ( var i = 0; i < factories.length; i++ ) {
+			try {
+				var request = factories[i]();
+				if ( request != null ) {
+					return request;
+				} 
+			}
+			catch (e) {
+				continue;
+			}
+		}
+	};
+
+	vEJS.request = function( path ) {
+		var request = new vEJS.newRequest();
+		
+		request.open("GET", path, false);
+
+		try {
+			request.send(null);
+		}
+		catch (e) {
+			return null;
+		}
+
+		if ( request.status == 404 || request.status == 2 || (request.status == 0 && request.responseText == '') ){
+			return null;
+		} 
+
+		return request.responseText;
+	};
+	
+	vEJS.ajax_request = function( params ) {
+		params.method = (params.method ? params.method : 'GET');
+
+		var request = new vEJS.newRequest();
+		
+		request.onreadystatechange = function() {
+			if ( request.readyState == 4 ) {
+				if ( request.status == 200 ) {
+					params.onComplete(request);
+				} else {
+					params.onComplete(request);
+				}
+			}
+		};
+		
+		request.open(params.method, params.url);
+		request.send(null);
+	};
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/generate/generate.js b/browserid/static/dialog/steal/generate/generate.js
new file mode 100644
index 0000000000000000000000000000000000000000..ddcbccce646070d55d6d51464cb846f74d08c660
--- /dev/null
+++ b/browserid/static/dialog/steal/generate/generate.js
@@ -0,0 +1,204 @@
+steal("//steal/generate/ejs", '//steal/generate/inflector', '//steal/rhino/prompt', function( steal ) {
+
+	var render = function( from, to, data ) {
+		var text = readFile(from);
+
+		var res = new steal.EJS({
+			text: text,
+			name: from
+		}).render(data);
+		var file = steal.File(to);
+		//check if we are overwriting
+		if ( data.force || !file.exists() || readFile(to) == res || steal.prompt.yesno("Overwrite " + to + "? [Yn]") ) {
+			steal.File(to).save(res);
+			return true;
+		} else {
+			return false;
+		}
+
+	},
+
+		/**
+		 * @plugin steal/generate
+		 * @parent stealjs
+		 * The Generate plugin makes building code generators crazy easy.
+		 * StealJS comes with its own app generator.  JavaScriptMVC has more complex generators.
+		 * <h2>Steal Generators</h2>
+		 * <ul>
+		 * <li><code>app</code> - creates an application structure, build and clean scripts.
+		 * @codestart text
+		 * js steal/generate/app <i>path/to/app</i> [OPTIONS]
+		 * @codeend
+		 * <dl>
+		 * <dt>path/to/app</dt>
+		 * <dd>The lowercase path you want your application in. 
+		 * </dd>
+		 * </dl>
+		 * </li>
+		 * </ul>
+		 * <h2>JavaScriptMVC Generators</h3>
+		 * <ul>
+		 * <li><code>app</code> - creates a JavaScriptMVC application structure.
+		 * @codestart text
+		 * js jquery/generate/app <i>path/to/app</i> [OPTIONS]
+		 * @codeend
+		 * <dl>
+		 * <dt>path/to/app</dt>
+		 * <dd>The lowercase path you want your application in. Keep application names short because they 
+		 * are used as namespaces.  The last part of the path will be taken to be your application's name.
+		 * </dd>
+		 * </dl>
+		 * </li>
+		 * <li style='padding-top: 10px;'><code>controller</code> - creates a JavaScriptMVC [jQuery.Controller].
+		 * @codestart text
+		 * js jquery/generate/controller <i>App.Controllers.Name</i> [OPTIONS]
+		 * @codeend
+		 * <dl>
+		 * <dt>App.Controllers.Name</dt>
+		 * <dd>The namespaced name of your controller.  For example, if your controller is named
+		 * <code>Cookbook.Controllers.Recipe</code>, the generator will create 
+		 * <code>cookbook/controllers/recipe_controller.js</code>. 
+		 * </dd>
+		 * </dl>
+		 * </li>
+		 * 
+		 * <li style='padding-top: 10px;'><code>model</code> - creates a JavaScriptMVC [jQuery.Model].
+		 * @codestart text
+		 * js jquery/generate/model <i>App.Models.Name</i> [TYPE] [OPTIONS]
+		 * @codeend
+		 * <dl>
+		 * <dt>App.Models.Name</dt>
+		 * <dd>The namespaced name of your model.  For example, if your model is named
+		 * <code>Cookbook.Models.Recipe</code>, the generator will create 
+		 * <code>cookbook/models/recipe.js</code>. 
+		 * </dd>
+		 * </dl>
+		 * </li>
+		 * 
+		 * <li style='padding-top: 10px;'><code>page</code> - creates a page that loads steal.js and an application.
+		 * @codestart text
+		 * js jquery/generate/model <i>path/to/app</i> <i>path/to/page.html</i>
+		 * @codeend
+		 * <dl>
+		 * <dt>path/to/app</dt>
+		 * <dd>The path to your apps folder. 
+		 * </dd>
+		 * <dt>path/to/page.html</dt>
+		 * <dd>The path to the page you want to create. 
+		 * </dd>
+		 * </dl>
+		 * </li>
+		 * 
+		 * <li style='padding-top: 10px;'><code>plugin</code> - creates a JavaScriptMVC plugin file and folder structure.
+		 * @codestart text
+		 * js jquery/generate/plugin <i>path/to/plugin</i> [OPTIONS]
+		 * @codeend
+		 * <dl>
+		 * <dt>path/to/plugin</dt>
+		 * <dd>The path to where you want your plugin.  This also should be the namespace and name of
+		 * whatever JavaScript object created.  Check out mxui for examples.
+		 * </dd>
+		 * </dl>
+		 * </li>
+		 * <li style='padding-top: 10px;'><code>scaffold</code> - creates the controllers, models, and fixtures used
+		 * to provide basic CRUD functionality..
+		 * @codestart text
+		 * js jquery/generate/scaffold <i>App.Models.ModelName</i> [OPTIONS]
+		 * @codeend
+		 * <dl>
+		 * <dt>App.Models.ModelName</dt>
+		 * <dd>The model resource you want to add CRUD functionality to.
+		 * </dd>
+		 * </dl>
+		 * </li>
+		 * </ul>
+		 * 
+		 * <h2>The Generator Function</h2>
+		 * <p>Renders a folders contents with EJS and data and then copies it to another folder.</p>
+		 * @codestart
+		 * steal.generate(
+		 *   "path/to/my_template_folder",
+		 *   "render/templates/here", 
+		 *   {
+		 *     data: "to be used"
+		 *   })
+		 * @codeend
+		 * @param {String} path the folder to get templates from
+		 * @param {String} where where to put the results of the rendered templates
+		 * @param {Object} data data to render the templates with.  If force is true, it will overwrite everything
+		 */
+		generate = (steal.generate = function( path, where, data ) {
+			//get all files in a folder
+			var folder = new steal.File(path);
+
+			//first make sure the folder exists
+			new steal.File(where).mkdirs();
+
+			folder.contents(function( name, type, current ) {
+				var loc = (current ? current + "/" : "") + name,
+					convert = loc.replace(/\(([^\)]+)\)/g, function( replace, inside ) {
+						return data[inside];
+					});
+
+					if ( type === 'file' ) {
+						//if it's ejs, draw it where it belongs
+						if (/\.ignore/.test(name) ) {
+							//do nothing
+						} else if (/\.ejs$/.test(name) ) {
+							var put = where + "/" + convert.replace(/\.ejs$/, "");
+
+
+
+							if ( render(path + "/" + loc, put, data) ) {
+								steal.print('      ' + put);
+							}
+
+						} else if (/\.link$/.test(name) ) {
+							var copy = readFile(path + "/" + loc);
+							//if points to a file, copy that one file; otherwise copy the folder
+							steal.generate(copy, where + "/" + convert.replace(/\.link$/, ""), data);
+
+						}
+					} else if(!/^\.\w+$/.test(name)){
+
+						//create file
+						steal.print('      ' + where + "/" + convert);
+						new steal.File(where + "/" + convert).mkdirs();
+
+						//recurse in new folder
+						new steal.File(path + "/" + (current ? current + "/" : "") + name).contents(arguments.callee, (current ? current + "/" : "") + name);
+					}
+			});
+		});
+	steal.extend(generate, {
+		regexps: {
+			colons: /::/,
+			words: /([A-Z]+)([A-Z][a-z])/g,
+			lowerUpper: /([a-z\d])([A-Z])/g,
+			dash: /([a-z\d])([A-Z])/g
+		},
+		underscore: function( s ) {
+			var regs = this.regexps;
+			return s.replace(regs.colons, '/')
+				.replace(regs.words, '$1_$2')
+				.replace(regs.lowerUpper, '$1_$2')
+				.replace(regs.dash, '_').toLowerCase();
+		},
+		//converts a name to a bunch of useful things
+		convert: function( name ) {
+			var className = name.match(/[^\.]*$/)[0]; //Customer
+			var appName = name.split(".")[0]; //Customer
+			return {
+				underscore: generate.underscore(className),
+				path: generate.underscore(name).replace(/\./g, "/").replace(/\/[^\/]*$/, ""),
+				name: name,
+				fullName: name,
+				className: className,
+				plural: steal.Inflector.pluralize(generate.underscore(className)),
+				appName: appName.toLowerCase()
+			};
+		},
+		render: render
+	});
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/generate/inflector.js b/browserid/static/dialog/steal/generate/inflector.js
new file mode 100644
index 0000000000000000000000000000000000000000..f9bbc1957b0cdc144fd355556b7daea40a00123b
--- /dev/null
+++ b/browserid/static/dialog/steal/generate/inflector.js
@@ -0,0 +1,108 @@
+// based on the Inflector class found on a DZone snippet contributed by Todd Sayre
+// http://snippets.dzone.com/posts/show/3205
+steal(function( steal ) {
+	steal.Inflector = {
+		Inflections: {
+			plural: [
+				[/(quiz)$/i, "$1zes"],
+				[/^(ox)$/i, "$1en"],
+				[/([m|l])ouse$/i, "$1ice"],
+				[/(matr|vert|ind)ix|ex$/i, "$1ices"],
+				[/(x|ch|ss|sh)$/i, "$1es"],
+				[/([^aeiouy]|qu)y$/i, "$1ies"],
+				[/(hive)$/i, "$1s"],
+				[/(?:([^f])fe|([lr])f)$/i, "$1$2ves"],
+				[/sis$/i, "ses"],
+				[/([ti])um$/i, "$1a"],
+				[/(buffal|tomat)o$/i, "$1oes"],
+				[/(bu)s$/i, "$1ses"],
+				[/(alias|status)$/i, "$1es"],
+				[/(octop|vir)us$/i, "$1i"],
+				[/(ax|test)is$/i, "$1es"],
+				[/s$/i, "s"],
+				[/$/, "s"]
+			],
+			singular: [
+				[/(quiz)zes$/i, "$1"],
+				[/(matr)ices$/i, "$1ix"],
+				[/(vert|ind)ices$/i, "$1ex"],
+				[/^(ox)en/i, "$1"],
+				[/(alias|status)es$/i, "$1"],
+				[/(octop|vir)i$/i, "$1us"],
+				[/(cris|ax|test)es$/i, "$1is"],
+				[/(shoe)s$/i, "$1"],
+				[/(o)es$/i, "$1"],
+				[/(bus)es$/i, "$1"],
+				[/([m|l])ice$/i, "$1ouse"],
+				[/(x|ch|ss|sh)es$/i, "$1"],
+				[/(m)ovies$/i, "$1ovie"],
+				[/(s)eries$/i, "$1eries"],
+				[/([^aeiouy]|qu)ies$/i, "$1y"],
+				[/([lr])ves$/i, "$1f"],
+				[/(tive)s$/i, "$1"],
+				[/(hive)s$/i, "$1"],
+				[/([^f])ves$/i, "$1fe"],
+				[/(^analy)ses$/i, "$1sis"],
+				[/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, "$1$2sis"],
+				[/([ti])a$/i, "$1um"],
+				[/(n)ews$/i, "$1ews"],
+				[/s$/i, ""]
+			],
+			irregular: [
+				['move', 'moves'],
+				['sex', 'sexes'],
+				['child', 'children'],
+				['man', 'men'],
+				['woman', 'women'],
+				['foreman', 'foremen'],
+				['person', 'people']
+			],
+			uncountable: ["sheep", "fish", "series", "species", "money", "rice", "information", "equipment"]
+		},
+		pluralize: function( word ) {
+			for ( var i = 0; i < steal.Inflector.Inflections.uncountable.length; i++ ) {
+				var uncountable = steal.Inflector.Inflections.uncountable[i];
+				if ( word.toLowerCase() === uncountable ) {
+					return uncountable;
+				}
+			}
+			for ( i = 0; i < steal.Inflector.Inflections.irregular.length; i++ ) {
+				var singular = steal.Inflector.Inflections.irregular[i][0];
+				var plural = steal.Inflector.Inflections.irregular[i][1];
+				if ((word.toLowerCase() === singular) || (word === plural)) {
+					return word.substring(0, 1) + plural.substring(1);
+				}
+			}
+			for ( i = 0; i < steal.Inflector.Inflections.plural.length; i++ ) {
+				var regex = steal.Inflector.Inflections.plural[i][0];
+				var replace_string = steal.Inflector.Inflections.plural[i][1];
+				if ( regex.test(word) ) {
+					return word.replace(regex, replace_string);
+				}
+			}
+		},
+		singularize: function( word ) {
+			for ( var i = 0; i < steal.Inflector.Inflections.uncountable.length; i++ ) {
+				var uncountable = steal.Inflector.Inflections.uncountable[i];
+				if ( word.toLowerCase() === uncountable ) {
+					return uncountable;
+				}
+			}
+			for ( i = 0; i < steal.Inflector.Inflections.irregular.length; i++ ) {
+				var singular = steal.Inflector.Inflections.irregular[i][0];
+				var plural = steal.Inflector.Inflections.irregular[i][1];
+				if ((word.toLowerCase() === singular) || (word.toLowerCase() === plural)) {
+					return word.substring(0, 1) + singular.substring(1);
+				}
+			}
+			for ( i = 0; i < steal.Inflector.Inflections.singular.length; i++ ) {
+				var regex = steal.Inflector.Inflections.singular[i][0];
+				var replace_string = steal.Inflector.Inflections.singular[i][1];
+				if ( regex.test(word) ) {
+					return word.replace(regex, replace_string);
+				}
+			}
+			return word;
+		}
+	};
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/generate/system.js b/browserid/static/dialog/steal/generate/system.js
new file mode 100644
index 0000000000000000000000000000000000000000..11023c8b9e76a2679c8a5467463321073a418e60
--- /dev/null
+++ b/browserid/static/dialog/steal/generate/system.js
@@ -0,0 +1,32 @@
+//gets system info (mostly if windows and where FF is
+steal(function( steal ) {
+
+	var get_browser_location = function( browser_name ) {
+		var is = java.lang.Runtime.getRuntime().exec(["sh", "-c", "which " + browser_name]).getInputStream(),
+			isr = new java.io.InputStreamReader(is),
+			br = new java.io.BufferedReader(isr),
+			line = br.readLine();
+
+		return line;
+	};
+	
+	// am i non-windows?
+	var windows = true,
+		firefox_location = "*firefox",
+		filesystemPath = new java.io.File(".").getCanonicalPath();
+
+	if ( java.lang.System.getProperty("os.name").indexOf("Windows") === -1 ) {
+		windows = false;
+		// does current browser config have a path?
+		var path = get_browser_location("firefox");
+		if ( path ) {
+			firefox_location = "*firefox " + path;
+		}
+	}
+
+	steal.system = {
+		windows: windows,
+		firefox: firefox_location,
+		filesystemPath: filesystemPath
+	};
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/generate/templates/app/(application_name).css.ejs b/browserid/static/dialog/steal/generate/templates/app/(application_name).css.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..9d859b93c8595a8681604c1c0038dc0f31a61afa
--- /dev/null
+++ b/browserid/static/dialog/steal/generate/templates/app/(application_name).css.ejs
@@ -0,0 +1,10 @@
+body {font-family: verdana;
+  font-size: 1.4em;
+}
+h1 {
+	padding: 10px;
+}
+p {
+	padding: 10px;
+	margin: 10px;
+}
diff --git a/browserid/static/dialog/steal/generate/templates/app/(application_name).html.ejs b/browserid/static/dialog/steal/generate/templates/app/(application_name).html.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..41ff70cd2618d44d4a418ad61372d11dd2a78d42
--- /dev/null
+++ b/browserid/static/dialog/steal/generate/templates/app/(application_name).html.ejs
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title><%= application_name %></title>
+	</head>
+	<body>
+	    <h1>Thanks for stealing StealJS!</h1>
+		<p>Don't worry, it's open source.  It's only stealing if you don't do something
+		awesome with it.
+		</p>
+        <div id='content'></div>
+		
+		<script type='text/javascript' 
+                src='<%= path_to_steal %>/steal/steal.js?<%= path %>/<%= application_name %>.js'>   
+        </script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/generate/templates/app/(application_name).js.ejs b/browserid/static/dialog/steal/generate/templates/app/(application_name).js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..0e410db7530e11332e6c7395122b81c0215e6391
--- /dev/null
+++ b/browserid/static/dialog/steal/generate/templates/app/(application_name).js.ejs
@@ -0,0 +1,10 @@
+steal( 'resources/example' )				// Loads 'resources/example.js'
+	.css( '<%= application_name %>' )			// Loads '<%= application_name %>.css'
+	.plugins(
+		'steal/less',
+		'steal/coffee' )					// Loads 'steal/less/less.js' and 'steal/coffee/coffee.js'
+	.then(function(){						// Adds a function to be called back once all prior files have been loaded and run 
+		steal.coffee('resources/example')	// Loads 'resources/example.coffee'
+			.less('resources/example');		// Loads 'resources/example.less'
+	});
+	 
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/generate/templates/app/docs/.ignore b/browserid/static/dialog/steal/generate/templates/app/docs/.ignore
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/browserid/static/dialog/steal/generate/templates/app/resources/.ignore b/browserid/static/dialog/steal/generate/templates/app/resources/.ignore
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/browserid/static/dialog/steal/generate/templates/app/resources/example.coffee.ejs b/browserid/static/dialog/steal/generate/templates/app/resources/example.coffee.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..5d985cc6ac390c3ddf8744a433b17814f17f7351
--- /dev/null
+++ b/browserid/static/dialog/steal/generate/templates/app/resources/example.coffee.ejs
@@ -0,0 +1,5 @@
+AddToContent "<ul>"
+AddToContent    "<li>Include plugins and files in <%= path %>/<%= application_name %>.</li>"
+AddToContent	"<li>Change to production mode by changing steal.js"
+AddToContent        " to steal.production.js in this file.</li>"
+AddToContent "</ul>"
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/generate/templates/app/resources/example.js.ejs b/browserid/static/dialog/steal/generate/templates/app/resources/example.js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..106a6fa17cd72f4c05ded890ba9ed3f96411425d
--- /dev/null
+++ b/browserid/static/dialog/steal/generate/templates/app/resources/example.js.ejs
@@ -0,0 +1,13 @@
+(function(){
+	var content = [];
+	
+	AddToContent = function(newContent){
+		content.push( newContent);
+	};
+	window.onload = function(){
+		document.getElementById('content').innerHTML 
+			= content.join("");
+	};
+	
+})();
+
diff --git a/browserid/static/dialog/steal/generate/templates/app/resources/example.less.ejs b/browserid/static/dialog/steal/generate/templates/app/resources/example.less.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..8d78587cebf38777ec906c27b6fb3e23187eaa2b
--- /dev/null
+++ b/browserid/static/dialog/steal/generate/templates/app/resources/example.less.ejs
@@ -0,0 +1,9 @@
+@brand_color: #4D926F;
+@box: 10px;
+h1 {
+  color: @brand_color;
+}
+ul {
+  margin: @box (2*@box);
+  width: (50*@box);
+}
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/generate/templates/app/scripts/build.html.ejs b/browserid/static/dialog/steal/generate/templates/app/scripts/build.html.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..35b326e7503eb2c13e6e41a6bba78303a66bee68
--- /dev/null
+++ b/browserid/static/dialog/steal/generate/templates/app/scripts/build.html.ejs
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title><%= application_name %> Build Page</title>
+	</head>
+	<body>
+	    <h1><%= application_name %> Build Page</h1>
+		<p>This is a dummy page that loads your app so steal can
+		   get all the files.  
+		</p>
+		<p>If you built your app
+		   to depend on HTML in the page before DOMContent loaded or 
+		   onload, you can add the HTML here, or you can change the
+		   build.js script to point to a better html file.
+		</p>
+		<script type='text/javascript' 
+	    src='../<%= path_to_steal %>/steal/steal.js?<%= path %>'>	 
+        </script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/generate/templates/app/scripts/build.js.ejs b/browserid/static/dialog/steal/generate/templates/app/scripts/build.js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..cb5672ac9ac9c121aa63bfefd02138c4a8883a11
--- /dev/null
+++ b/browserid/static/dialog/steal/generate/templates/app/scripts/build.js.ejs
@@ -0,0 +1,6 @@
+//steal/js <%= path %>/scripts/compress.js
+
+load("steal/rhino/steal.js");
+steal.plugins('steal/build','steal/build/scripts','steal/build/styles',function(){
+	steal.build('<%= path %>/scripts/build.html',{to: '<%= path %>'});
+});
diff --git a/browserid/static/dialog/steal/generate/templates/app/scripts/clean.js.ejs b/browserid/static/dialog/steal/generate/templates/app/scripts/clean.js.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..31ea69c580e17d42a63ef0d716208c7614678d0b
--- /dev/null
+++ b/browserid/static/dialog/steal/generate/templates/app/scripts/clean.js.ejs
@@ -0,0 +1,6 @@
+//steal/js <%= path %>/scripts/compress.js
+
+load("steal/rhino/steal.js");
+steal.plugins('steal/clean',function(){
+	steal.clean('<%= path %>/<%= application_name %>.html',{indent_size: 1, indent_char: '\t'});
+});
diff --git a/browserid/static/dialog/steal/generate/templates/app/test/.ignore b/browserid/static/dialog/steal/generate/templates/app/test/.ignore
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/browserid/static/dialog/steal/generate/templates/page.ejs b/browserid/static/dialog/steal/generate/templates/page.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..932506c4ab28d4652656b2bc98995b09f2fae07d
--- /dev/null
+++ b/browserid/static/dialog/steal/generate/templates/page.ejs
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title><%= application_name %></title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .error {border: solid 1px red;}
+            .error_text { color: red; font-size: 10px;}
+            td {padding: 3px;}
+        </style>
+	</head>
+	<body>
+	    <h1>Welcome to JavaScriptMVC 3.0!</h1>
+        <ul>
+            <li>Steal plugins and files in <i><%= path %>/<%= application_name %>.js</i>.</li>
+            <li>Change to production mode by changing <i>development</i> to <i>production</i> in this file.</li>
+        </ul>
+		<script type='text/javascript' 
+                src='<%= path_to_steal ? path_to_steal +"/" : "" %>steal/steal.js?<%= path %>,development'>   
+        </script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/generate/test/run.js b/browserid/static/dialog/steal/generate/test/run.js
new file mode 100644
index 0000000000000000000000000000000000000000..e94fc3e45858f2ca8eba7280974e3a44992e09d8
--- /dev/null
+++ b/browserid/static/dialog/steal/generate/test/run.js
@@ -0,0 +1,28 @@
+load('steal/rhino/steal.js')
+load('steal/rhino/test.js');
+
+(function(rhinoSteal){
+	_S = steal.test;
+	
+	//turn off printing
+	STEALPRINT = false;
+	
+	print("==========================  steal/generate =============================")
+	
+	print("-- generate basic foo app --");
+	
+	steal("//steal/generate/generate",'//steal/generate/system', function(steal){
+		var	data = steal.extend({
+			path: "foo", 
+			application_name: "foo",
+			current_path: steal.File.cwdURL(),
+			path_to_steal: new steal.File("foo").pathToRoot()
+		}, steal.system);
+		steal.generate("steal/generate/templates/app","foo",data)
+	})
+	
+	
+	rhinoSteal.File("foo").removeDir();
+	
+	print("== complete ==\n")
+})(steal);
diff --git a/browserid/static/dialog/steal/get/get.js b/browserid/static/dialog/steal/get/get.js
new file mode 100644
index 0000000000000000000000000000000000000000..72b44e707a15fac07ad5b1ac8a47a00fcf21e37a
--- /dev/null
+++ b/browserid/static/dialog/steal/get/get.js
@@ -0,0 +1,162 @@
+steal("//steal/get/json", "//steal/rhino/prompt", function( steal ) {
+	/**
+	 * @parent stealjs
+	 * Downloads and installs a plugin from a url.  Normally this is run from the steal/getjs script.
+	 * 
+	 * <p>The following copies the mustache-javascript repo to a local mustache folder.</p>
+	 * 
+	 * @codestart text
+	 * js steal/getjs "ttp://github.com/tdreyno/mustache-javascriptmvc mustache
+	 * @codeend
+	 * <p>Get will:</p>
+	 * <ul>
+	 * 	<li>Download the files that comprise the plugin.</li>
+	 *  <li>Prompt you to install dependencies found in its dependencies.json file.</li>
+	 *  <li>Prompt you to run an install script.</li>
+	 * </ul>
+	 * <h2>Offical Plugins</h2>
+	 * <p>JavaScriptMVC maintains a list of offical plugins compatible with JavaScriptMVC 3.0.
+	 *   You can install these by simply typing there name.  This is the current list of
+	 *   offical plugins:
+	 * </p>
+	 * <ul>
+	 * 	<li><code>mustache</code> - mustache templates.</li>
+	 *  <li><code>steal</code> - script loader, and more.</li>
+	 *  <li><code>jquery</code> - jQuery 1.4.3 and the MVC components.</li>
+	 *  <li><code>funcunit</code> - Functional testing platform.</li>
+	 *  <li><code>mxui</code> - UI widgets.</li>
+	 *  <li><code>documentjs</code> - documentation engine.</li>
+	 * </ul>
+	 * <p>You can install these just by writing</p>
+	 * @codestart text
+	 * js steal/getjs funcunit
+	 * @codeend
+	 * <p>If you have something good, let us know on the forums and we can make your project official too!</p>
+	 * <h2>The Get function</h2>
+	 * get takes a url or official plugin name and installs it.
+	 * @param {String} url the path to a svn or github repo or a name of a recognized plugin.
+	 * @param {Object} options configure the download.  
+	 * <table class='options'>
+	 * 	  <tr>
+	 * 	      <th>Name</th><th>Description</th>
+	 * 	  </tr>
+	 * 	  <tr><td>name</td>
+	 * 	  	  <td>The name of the folder to put the download in.</td></tr>
+	 *    <tr><td>ignore</td>
+	 * 	  	  <td>An array of regexps that if the filename matches, these will be ignored.</td></tr>
+	 * 	</table>
+	 * 
+	 */
+	var get = (steal.get = function( url, options ) {
+		options = steal.opts(options, {
+			name: 1
+		});
+		var getter, name = options.name, dependenciesUrl;
+
+		if (!url.match(/^http/) ) {
+			name = url;
+			url = pluginList(name);
+		}
+		if (!url ) {
+			steal.print("There is no plugin named " + name);
+			return;
+		}
+		getter = url.indexOf("github.com") !== -1 ? get.github : get.getter;
+		if (!name ) {
+			name = guessName(url);
+		}
+		//make the folder for this plugin
+		new steal.File(name).mkdirs();
+
+		dependenciesUrl = getter.dependenciesUrl(url);
+
+		installDependencies(dependenciesUrl, name);
+
+		//get contents
+		var fetcher = new getter(url, name, options);
+		fetcher.quiet = options.quiet || true;
+
+		fetcher.fetch();
+
+		steal.print("\n  " + name + " plugin downloaded.");
+		runInstallScript(name);
+
+		}),
+		/**
+		 * @hide
+		 * looks for a url elsewhere
+		 * @param {Object} name
+		 */
+		pluginList = function( name ) {
+			steal.print("  Looking for plugin ...");
+
+			var plugin_list_source =
+				readUrl("https://github.com/jupiterjs/steal/raw/master/get/gets.json");
+			var plugin_list;
+			eval("plugin_list = " + plugin_list_source);
+			if ( plugin_list[name] ) {
+				return plugin_list[name];
+			}
+			steal.print("  Looking in gets.json for your own plugin list")
+			
+			plugin_list_source = readFile("gets.json");
+			if(plugin_list_source){
+				eval("plugin_list = " + plugin_list_source);
+				return plugin_list[name];
+			}
+			
+		},
+		//gets teh name from the url
+		guessName = function( url ) {
+			var name = new steal.File(url).basename();
+			if ( name === 'trunk' || !name ) {
+				name = new steal.File(new steal.File(url).dir()).basename();
+			}
+			return name;
+		},
+		// works for 
+		// https://github.com/jupiterjs/funcunit/raw/master/dependencies.json
+		installDependencies = function( depend_url, name ) {
+			steal.print("  Checking dependencies ...");
+			var depend_text, dependencies;
+			
+			try {
+				depend_text = readUrl(depend_url);
+			} catch (e) {}
+			
+			if (!depend_text ) {
+				steal.print("  No dependancies");
+				return;
+			}
+
+			try {
+				dependencies = JSONparse(depend_text);
+			} catch (e) {
+				steal.print("  No or mailformed dependencies");
+				return;
+			}
+
+			for ( var plug_name in dependencies ) {
+				if ( steal.prompt.yesno("Install dependency " + plug_name + "? (yN):") ) {
+					steal.print("Installing " + plug_name + "...");
+					steal.get(dependencies[plug_name], {
+						name: plug_name
+					});
+				}
+			}
+
+			steal.print("  Installed all dependencies for " + name);
+		},
+		runInstallScript = function( name ) {
+			if ( readFile(name + "/install.js") ) {
+
+				var res = steal.prompt.yesno("\n  " + name + " has an install script." + "\n    WARNING! Install scripts may be evil.  " + "\n    You can run it manually after reading the file by running:" + "\n      js " + name + "/install.js" + "\n\n  Would you like to run it now? (yN):");
+				if ( res ) {
+					steal.print("  running ...");
+					load(name + "/install.js");
+				}
+			}
+		};
+
+
+}, "//steal/get/getter", "//steal/get/github");
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/get/gets.json b/browserid/static/dialog/steal/get/gets.json
new file mode 100644
index 0000000000000000000000000000000000000000..85263219650bc75a009ee16f2c549d1ab570bb96
--- /dev/null
+++ b/browserid/static/dialog/steal/get/gets.json
@@ -0,0 +1,12 @@
+{
+  "mustache" : "http://github.com/tdreyno/mustache-javascriptmvc",
+  "steal" : "http://github.com/jupiterjs/steal",
+  "jquery" : "http://github.com/jupiterjs/jquerymx",
+  "funcunit" : "http://github.com/jupiterjs/funcunit",
+  "mxui" : "http://github.com/jupiterjs/mxui",
+  "documentjs" : "http://github.com/jupiterjs/documentjs",
+  "ss/state_machine" : "http://github.com/secondstory/secondstoryjs-statemachine",
+  "ss/router" : "http://github.com/secondstory/secondstoryjs-router",
+  "srchr" : "https://github.com/jupiterjs/srchr/tree/master/srchr/",
+  "mxutil" : "http://github.com/jupiterjs/mxutil"
+}
diff --git a/browserid/static/dialog/steal/get/getter.js b/browserid/static/dialog/steal/get/getter.js
new file mode 100644
index 0000000000000000000000000000000000000000..c9f3a8d09af019f7deefcef6de5c5e7722d11dda
--- /dev/null
+++ b/browserid/static/dialog/steal/get/getter.js
@@ -0,0 +1,136 @@
+/*  This is a port to JavaScript of Rail's plugin functionality.  It uses the following
+ * license:
+ *  This is Free Software, copyright 2005 by Ryan Tomayko (rtomayko@gmail.com) 
+     and is licensed MIT: (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+steal(function( steal ) {
+
+
+	steal.get.getter = function( url, where, options, level ) {
+		if ( url ) {
+			this.init.apply(this, arguments);
+		}
+	};
+	
+	steal.get.getter.dependenciesUrl = function( url ) {
+		var depUrl = url + 
+			(url.lastIndexOf("/") === url.length - 1 ? "" : "/") + "dependencies.json";
+		return depUrl;
+	};
+	
+	steal.get.getter.prototype = {
+		init: function( url, where, options, level ) {
+
+			this.url = url + (/\/$/.test(url) ? "" : "/");
+			this.level = level || -1;
+			this.cwd = where || ".";
+			this.quite = options.quite;
+			this.ignore = 
+				(options.ignore && 
+					(steal.isArray(options.ignore) ? 
+						options.ignore : 
+						[options.ignore] )) 
+				|| [];
+			this.ignore.push(/\.jar$/);
+		},
+		ls: function() {
+			var links = [],
+				rhf = this;
+
+
+			if ( this.url.match(/^svn:\/\/.*/) ) {
+				steal.print('not supported');
+			} else {
+				links.concat(rhf.links("", readUrl(this.url)));
+			}
+
+
+			return links;
+			//store and return flatten
+		},
+		//gets the links from a page
+		links: function( base_url, contents ) {
+			var links = [],
+				anchors = contents.match(/href\s*=\s*\"*[^\">]*/ig),
+				ignore = this.ignore;
+
+			anchors.forEach(function( link ) {
+				link = link.replace(/href="/i, "");
+
+				if (!/svnindex.xsl$/.test(link) && !/^(\w*:|)\/\//.test(link) && !/^\./.test(link) ) {
+					links.push((new steal.File(base_url)).join(link));
+				}
+
+			});
+
+			return links;
+		},
+		//pushes a directory to go into and check
+		push_d: function( dir ) {
+			this.cwd = (new steal.File(this.cwd)).join(dir);
+			new steal.File(this.cwd).mkdir();
+		},
+		//pops up to the parent directory
+		pop_d: function() {
+			this.cwd = new steal.File(this.cwd).dir();
+		},
+		//downloads content from a url
+		download: function( link ) {
+			
+			//var text = readUrl( link);
+			var bn = new steal.File(link).basename(),
+				f = new steal.File(this.cwd).join(bn),
+				oldsrc, newsrc, p = "   ";
+
+			for ( var i = 0; i < this.ignore.length; i++ ) {
+				if ( f.match(this.ignore[i]) ) {
+					steal.print("   I " + f);
+					return;
+				}
+			}
+
+			oldsrc = readFile(f);
+			
+			new steal.File(f).download_from(link, true);
+			
+			
+			newsrc = readFile(f);
+
+			if ( oldsrc ) {
+				if ( oldsrc == newsrc ) {
+					return;
+				}
+				steal.print(p + "U " + f);
+			} else {
+				steal.print(p + "A " + f);
+			}
+		},
+		//gets the url or the directory
+		fetch: function( links ) {
+			var auto_fetch = !links;
+			links = links || [this.url];
+			var rhf = this;
+			links.forEach(function( link ) {
+				//steal.print("FETCH  "+link+"\n")
+				link.match(/\/$/) || auto_fetch ? rhf.fetch_dir(link) : rhf.download(link);
+			});
+		},
+		//gets a directory
+		fetch_dir: function( url ) {
+			this.level++;
+			if ( this.level > 0 ){
+				this.push_d(new steal.File(url).basename());
+			}
+
+			var contents = readUrl(url);
+			this.fetch(this.links(url, contents));
+			
+			if ( this.level > 0 ){
+				this.pop_d();
+			}
+			
+			this.level--;
+		}
+	};
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/get/github.js b/browserid/static/dialog/steal/get/github.js
new file mode 100644
index 0000000000000000000000000000000000000000..9ceed0ea6a2b0950e8b411971e375b83cbc2ba78
--- /dev/null
+++ b/browserid/static/dialog/steal/get/github.js
@@ -0,0 +1,168 @@
+/*  This is a port to JavaScript of Rail's plugin functionality.  It uses the following
+ * license:
+ *  This is Free Software, copyright 2005 by Ryan Tomayko (rtomayko@gmail.com) 
+     and is licensed MIT: (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+steal(function( steal ) {
+
+	steal.get.github = function( url, where, options, level ) {
+		if ( url ) {
+			this.init.apply(this, arguments);
+		}
+	};
+	
+	steal.get.github.dependenciesUrl = function( url ) {
+		if(!/https/.test(url)) { // github requires https
+			url = url.replace(/http/, 'https');
+		}
+		var depUrl = url + 
+			(url.lastIndexOf("/") === url.length - 1 ? "" : "/") + 
+			"raw/master/dependencies.json";
+		return depUrl;
+	};
+
+	steal.get.github.prototype = new steal.get.getter();
+	steal.extend(steal.get.github.prototype, {
+		init: function( url, where, options, level ) {
+			// not the best way of doing this, but ok for now.
+			arguments[0] = url = url.replace("http:","https:");
+			steal.get.getter.prototype.init.apply(this, arguments);
+			this.orig_cwd = this.cwd;
+			
+			this.ignore.push(".gitignore", "dist");
+
+			var split = url.split("/");
+			this.username = split[3];
+			this.project = split[4];
+			this.branch = options.tag || "master";
+			
+			//we probably gave something like : http://github.com/secondstory/secondstoryjs-router instead
+			// of http://github.com/secondstory/secondstoryjs-router/tree/master/
+			if(! url.match(/\/tree\//) ){
+				this.url = this.url+"tree/master/"
+			}
+			
+		},
+		get_latest_commit: function() {
+			// http://github.com/api/v2/json/commits/list/jupiterjs/steal/master
+			// https://github.com/api/v2/json/commits/list/jupiterjs/steal/master
+			var latestCommitUrl = "https://github.com/api/v2/json/commits/list/" + this.username + "/" + this.project + "/" + this.branch,
+				commitsText = readUrl(latestCommitUrl);
+				eval("var c = " + commitsText),
+				commitId = c.commits[0].tree;
+			return commitId;
+		},
+		ls_top: function( link ) {
+			var id = this.get_latest_commit(),
+				browseUrl = "http://github.com/api/v2/json/tree/show/" + this.username + "/" + this.project + "/" + id,
+				browseText = readUrl(browseUrl);
+				eval("var tree = " + browseText);
+			var urls = [],
+				item;
+			for ( var i = 0; i < tree.tree.length; i++ ) {
+				item = tree.tree[i];
+				if ( item.type == "blob" ) {
+					urls.push(this.url + item.name);
+				}
+				else if ( item.type == "tree" ) {
+					urls.push(this.url + item.name + '/');
+				}
+			}
+			return urls;
+		},
+		//returns a bunch of links to folders
+		links: function( base_url, contents ) {
+			var links = [],
+				newLink, 
+				anchors = contents.match(/href\s*=\s*\"*[^\">]*/ig),
+				ignore = this.ignore,
+				self = this,
+				base = this.url + this.cwd.replace(this.orig_cwd + "/", "");
+			
+			anchors.forEach(function( link ) {
+				link = link.replace(/href="/i, "");
+				newLink = base_url + (/\/$/.test(base_url) ? "" : "/") + link;
+				links.push(newLink);
+			});
+			return links;
+		},
+		download: function( link ) {
+			// get real download link
+			// https://github.com/jupiterjs/srchr/tree/master/srchr/disabler/disabler.html  -->
+			// https://github.com/jupiterjs/srchr/raw/master/srchr/disabler/disabler.html
+			var rawUrl = link.replace("/tree/","/raw/"),
+				bn = new steal.File(link).basename(),
+				f = new steal.File(this.cwd).join(bn);
+
+			for ( var i = 0; i < this.ignore.length; i++ ) {
+				if ( f.match(this.ignore[i]) ) {
+					steal.print("   I " + f);
+					return;
+				}
+			}
+
+			var oldsrc = readFile(f),
+				tmp = new steal.File("tmp"),
+				newsrc = readFile("tmp"),
+				p = "   ",
+				pstar = "   ";
+			try{
+				tmp.download_from(rawUrl, true);
+			}catch(e){
+				steal.print(pstar+"Error "+f);
+				return;
+			}
+			
+			
+			
+				if ( oldsrc ) {
+					var trim = /\s+$/gm,
+						jar = /\.jar$/.test(f);
+
+
+						if ((!jar && oldsrc.replace(trim, '') == newsrc.replace(trim, '')) || (jar && oldsrc == newsrc)) {
+							tmp.remove();
+							return;
+						}
+						steal.print(pstar + "U " + f);
+					tmp.copyTo(f);
+				} else {
+					steal.print(pstar + "A " + f);
+					tmp.copyTo(f);
+				}
+				tmp.remove();
+		},
+		fetch_dir: function( url ) {
+
+			this.level++;
+			if ( this.level > 0 ) {
+				this.push_d(new steal.File(url).basename());
+			}
+			if ( /\/tree\/\w+\/$/.test(url) ) { //if the root of the repo
+				this.fetch(this.ls_top());
+			} else {
+				// change to the raw url
+				// http://github.com/jupiterjs/jquerymx/
+				// http://github.com/jupiterjs/jquerymx/tree/master/controller?raw=true
+				var rawUrl, 
+					contents;
+
+				if(url.match(/\/tree\/\w/)){
+					rawUrl  = url+"?raw=true"
+				}else{
+					rawUrl = this.url + "tree/" + this.branch + "/" + url.replace(this.url, "") + "?raw=true"
+				}
+		
+				contents = readUrl(rawUrl);
+				
+				this.fetch(this.links(url, contents));
+			}
+			if ( this.level > 0 ) {
+				this.pop_d();
+			}
+			this.level--;
+		}
+	});
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/get/json.js b/browserid/static/dialog/steal/get/json.js
new file mode 100644
index 0000000000000000000000000000000000000000..cb32a36c69ed8a2284e824c0a38e5252ddf04431
--- /dev/null
+++ b/browserid/static/dialog/steal/get/json.js
@@ -0,0 +1,172 @@
+(function() {
+	var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+		isArray = function( arr ) {
+			return Object.prototype.toString.call(arr) === "[object Array]";
+		};
+
+
+	JSONparse = function( text, reviver ) {
+
+			var j;
+
+			function walk(holder, key) {
+				var k, v, value = holder[key];
+				if ( value && typeof value === 'object' ) {
+					for ( k in value ) {
+						if ( Object.hasOwnProperty.call(value, k) ) {
+							v = walk(value, k);
+							if ( v !== undefined ) {
+								value[k] = v;
+							} else {
+								delete value[k];
+							}
+						}
+					}
+				}
+				return reviver.call(holder, key, value);
+			}
+
+			cx.lastIndex = 0;
+			if ( cx.test(text) ) {
+				text = text.replace(cx, function( a ) {
+					return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+				});
+			}
+			if (/^[\],:{}\s]*$/
+				.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
+				.replace(/["'][^"\\\n\r]*["']|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
+				.replace(/(?:^|:|,)(?:\s*\[)+/g, '')) ) {
+
+
+				j = eval('(' + text + ')');
+
+				// In the optional fourth stage, we recursively walk the new structure, passing
+				// each name/value pair to a reviver function for possible transformation.
+				return typeof reviver === 'function' ? walk({
+					'': j
+				}, '') : j;
+			}
+
+			// If the text is not JSON parseable, then a SyntaxError is thrown.
+			throw new SyntaxError('JSONparse');
+		};
+
+	// Format integers to have at least two digits.
+	var toIntegersAtLease = function( n )
+	{
+		return n < 10 ? '0' + n : n;
+	};
+
+	// Yes, it polutes the Date namespace, but we'll allow it here, as
+	// it's damned usefull.
+	Date.prototype.toJSON = function( date )
+	{
+		return this.getUTCFullYear() + '-' + toIntegersAtLease(this.getUTCMonth()) + '-' + toIntegersAtLease(this.getUTCDate());
+	};
+
+	var escapeable = /["\\\x00-\x1f\x7f-\x9f]/g;
+	var meta = { // table of character substitutions
+		'\b': '\\b',
+		'\t': '\\t',
+		'\n': '\\n',
+		'\f': '\\f',
+		'\r': '\\r',
+		'"': '\\"',
+		'\\': '\\\\'
+	};
+
+	var quoteString = function( string )
+	// Places quotes around a string, inteligently.
+	// If the string contains no control characters, no quote characters, and no
+	// backslash characters, then we can safely slap some quotes around it.
+	// Otherwise we must also replace the offending characters with safe escape
+	// sequences.
+	{
+		if ( escapeable.test(string) ) {
+			return '"' + string.replace(escapeable, function( a ) {
+				var c = meta[a];
+				if ( typeof c === 'string' ) {
+					return c;
+				}
+				c = a.charCodeAt();
+				return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
+			}) + '"';
+		}
+		return '"' + string + '"';
+	};
+	var vtoJSON = null;
+	var steal = steal;
+	vtoJSON = function( o, compact ) {
+		var type = typeof(o);
+
+		if ( type == "undefined" ){
+			return "undefined";
+		} else if ( type == "number" || type == "boolean" ) {
+			return o + "";
+		} else if ( o === null ){
+			return "null";
+		}
+
+		// Is it a string?
+		if ( type == "string" ) {
+			return quoteString(o);
+		}
+
+		// Does it have a .toJSON function?
+		if ( type == "object" && typeof o.toJSON == "function" ) {
+			return o.toJSON(compact);
+		}
+
+		// Is it an array?
+		if ( isArray(o) ) {
+			var ret = [];
+			for ( var i = 0; i < o.length; i++ ) {
+				ret.push(vtoJSON(o[i], compact));
+			}
+			if ( compact ) {
+				return "[" + ret.join(",") + "]";
+			}
+			else {
+				return "[" + ret.join(", ") + "]";
+			}
+		}
+
+		// If it's a function, we have to warn somebody!
+		if ( type == "function" ) {
+			throw new TypeError("Unable to convert object of type 'function' to json.");
+		}
+
+		// It's probably an object, then.
+		var ret = [];
+		for ( var k in o ) {
+			var name;
+			type = typeof(k);
+
+			if ( type == "number" ) {
+				name = '"' + k + '"';
+			}
+			else if ( type == "string" ) {
+				name = quoteString(k);
+			}
+			else {
+				continue; //skip non-string or number keys
+			}
+			
+			var val = vtoJSON(o[k], compact);
+			if ( typeof(val) != "string" ) {
+				// skip non-serializable values
+				continue;
+			}
+
+			if ( compact ) {
+				ret.push(name + ":" + val);
+			}
+			else {
+				ret.push(name + ": " + val);
+			}
+		}
+		return "{" + ret.join(", ") + "}";
+	};
+	toJSON = vtoJSON;
+
+})();
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/get/test/get_test.js b/browserid/static/dialog/steal/get/test/get_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..ffabbfbe7ffe709aff258961c5c74c5b2dba1305
--- /dev/null
+++ b/browserid/static/dialog/steal/get/test/get_test.js
@@ -0,0 +1,33 @@
+load('steal/rhino/steal.js')
+load('steal/rhino/test.js');
+
+steal('//steal/get/get',function(rhinoSteal){
+	_S = steal.test;
+	
+
+	
+	_S.module("steal/get")
+	STEALPRINT = false;
+	
+	_S.test("root repo" , function(t){
+		
+		rhinoSteal.get('ss/router',{});
+		
+		var license = readFile("ss/router/LICENSE");
+		
+		t.ok(license, "srchr downloaded");
+		rhinoSteal.File("ss").removeDir();
+	});
+	
+	_S.test("deep repo" , function(t){		
+		rhinoSteal.get('srchr',{});
+		
+		var srchr = readFile("srchr/srchr.html");
+		
+		t.ok(srchr, "srchr downloaded");
+		rhinoSteal.File("srchr").removeDir();
+	});
+	
+	
+});
+
diff --git a/browserid/static/dialog/steal/getjs b/browserid/static/dialog/steal/getjs
new file mode 100644
index 0000000000000000000000000000000000000000..f7e99fb0ca1e43558d34502425209c94b59a1aec
--- /dev/null
+++ b/browserid/static/dialog/steal/getjs
@@ -0,0 +1,5 @@
+load("steal/rhino/steal.js");
+steal('//steal/get/get', function () {
+    var url = _args.shift();
+    steal.get(url, _args);
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/js b/browserid/static/dialog/steal/js
new file mode 100755
index 0000000000000000000000000000000000000000..01c86b67685a49ffe3e7522c7c3fa90d88d1093b
--- /dev/null
+++ b/browserid/static/dialog/steal/js
@@ -0,0 +1,56 @@
+#!/bin/sh
+# This script checks for arguments, if they don't exist it opens the Rhino dialog
+# if arguments do exist, it loads the script in the first argument and passes the other arguments to the script
+# ie: ./js steal/script/controller Todo
+
+if [ $# -eq 0 ]
+then
+  java -cp steal/rhino/js.jar:funcunit/java/selenium-java-client-driver.jar org.mozilla.javascript.tools.shell.Main
+  exit 127
+fi
+if [ $1 = "-selenium" ]
+then
+  java -jar funcunit/java/selenium-server.jar
+  exit 127
+fi
+CP=funcunit/java/selenium-java-client-driver.jar:steal/rhino/js.jar
+if [ $1 = "-mail" ]
+then
+	CP=steal/rhino/mail.jar:funcunit/java/selenium-java-client-driver.jar:steal/rhino/js.jar
+	shift
+fi
+
+if [ $1 = "-h" -o $1 = "-?" -o $1 = "--help" ]
+then
+echo Load a command line Rhino JavaScript environment or run JavaScript script files in Rhino.
+echo Available commands:
+echo -e "./js\t\t\t\tOpens a command line JavaScript environment"
+echo -e "./js -d\t\t\t\tOpens the Rhino debugger"
+echo -e "./js [FILE]\t\t\tRuns FILE in the Rhino environment"
+echo -e ""
+echo  -e "JavaScriptMVC script usage:"
+echo  -e "./js steal/generate/app [NAME]\t\tCreates a new JavaScriptMVC application"
+echo  -e "./js steal/generate/page [APP] [PAGE]\tGenerates a page for the application"
+echo  -e "./js steal/generate/controller [NAME]\tGenerates a Controller file"
+echo  -e "./js steal/generate/model [TYPE] [NAME]\tGenerates a Model file"
+echo  -e "./js apps/[NAME]/compress.js\t\tCompress your application and generate documentation"
+  exit 127
+fi
+
+
+if [ $1 = "-d" ]
+then
+        java -classpath steal/rhino/js.jar:steal/rhino/selenium-java-client-driver.jar org.mozilla.javascript.tools.debugger.Main
+        exit 127
+fi
+
+ARGS=[
+for arg
+do
+  if [ $arg != $1 ]
+  then
+    ARGS=$ARGS"'$arg'",
+  fi
+done
+ARGS=$ARGS]
+java -Xss1024k -cp $CP org.mozilla.javascript.tools.shell.Main -e _args=$ARGS -opt -1 -e 'load('"'"$1"'"')'
diff --git a/browserid/static/dialog/steal/js.bat b/browserid/static/dialog/steal/js.bat
new file mode 100644
index 0000000000000000000000000000000000000000..8ff1f2b5d2185190b943ebe20f61e4317a54047f
--- /dev/null
+++ b/browserid/static/dialog/steal/js.bat
@@ -0,0 +1,59 @@
+:: This script checks for arguments, if they don't exist it opens the Rhino dialog
+:: if arguments do exist, it loads the script in the first argument and passes the other arguments to the script
+:: ie: js jmvc\script\controller Todo
+@echo off
+SETLOCAL ENABLEDELAYEDEXPANSION
+if "%1"=="" (
+	java -cp steal\rhino\js.jar org.mozilla.javascript.tools.shell.Main
+	GOTO END
+)
+if "%1"=="-h" GOTO PRINT_HELP
+if "%1"=="-?" GOTO PRINT_HELP
+if "%1"=="--help" GOTO PRINT_HELP
+
+if "%1"=="-d" (
+	java -classpath funcunit/java/selenium-java-client-driver.jar;steal/rhino/js.jar org.mozilla.javascript.tools.debugger.Main
+	GOTO END
+)
+if "%1"=="-selenium" (
+	java -jar funcunit\java\selenium-server.jar
+	GOTO END
+)
+SET CP=funcunit/java/selenium-java-client-driver.jar;steal\rhino\js.jar
+if "%1"=="-mail" (
+	SET CP=steal/rhino/mail.jar;funcunit/java/selenium-java-client-driver.jar;steal\rhino\js.jar
+	SHIFT /0
+)
+SET ARGS=[
+SET FILENAME=%1
+SET FILENAME=%FILENAME:\=/%
+::haven't seen any way to loop through all args yet, so for now this goes through arg 2-7
+for /f "tokens=2,3,4,5,6,7 delims= " %%a in ("%*") do SET ARGS=!ARGS!'%%a','%%b','%%c','%%d','%%e','%%f'
+::remove the empty args
+:: for %%a in (",''=") do ( call set ARGS=%%ARGS:%%~a%% )
+SET ARGS=%ARGS:,''=%
+::remove the spaces
+:: for /f "tokens=1*" %%A in ("%ARGS%") do SET ARGS=%%A
+SET ARGS=%ARGS: =%
+SET ARGS=%ARGS%]
+set ARGS=%ARGS:\=/%
+java -Xmx228m -Xss1024k -cp %CP% org.mozilla.javascript.tools.shell.Main -opt -1 -e _args=%ARGS% -e load('%FILENAME%')
+
+GOTO END
+
+:PRINT_HELP
+echo Load a command line Rhino JavaScript environment or run JavaScript script files in Rhino.
+echo Available commands:
+echo js				Opens a command line JavaScript environment
+echo js	-d			Opens the Rhino debugger
+echo js -selenium   Starts selenium server
+echo js [FILE]			Runs FILE in the Rhino environment
+
+echo JavaScriptMVC script usage:
+echo js steal/generate/app [NAME]	Creates a new JavaScriptMVC application
+echo js steal/generate/page [APP] [PAGE]	Generates a page for the application
+echo js steal/generate/controller [NAME]	Generates a Controller file
+echo js steal/generate/model [TYPE] [NAME]	Generates a Model file
+echo js apps/[NAME]/compress.js	Compress your application and generate documentation
+
+:END
diff --git a/browserid/static/dialog/steal/less/less.js b/browserid/static/dialog/steal/less/less.js
new file mode 100644
index 0000000000000000000000000000000000000000..c06c87130d0537083ae859ce1504b3f2e9b8522c
--- /dev/null
+++ b/browserid/static/dialog/steal/less/less.js
@@ -0,0 +1,123 @@
+/**
+ * @add steal.static
+ */
+steal({path: "less_engine.js",ignore: true},function(){
+	
+	/**
+	 * @function less
+	 * @plugin steal/less
+	 * <p>Lets you build and compile [http://lesscss.org/ Less ] css styles.</p>
+	 * <p>Less is an extension of CSS that adds variables, mixins, and quite a bit more.
+	 * You can write css like:
+	 * </p>
+	 * @codestart css
+	 * @@brand_color: #4D926F;
+	 * #header {
+	 *   color: @@brand_color;
+	 * }
+	 * h2 {
+	 *   color: @@brand_color;
+	 * }
+	 * @codeend
+	 * <h2>Use</h2>
+	 * <p>First, create a less file like:</p>
+	 * @codestart css
+	 * @@my_color red
+	 * 
+	 * body { color:  @@my_color; }
+	 * @codeend
+	 * <p>Save this in a file named <code>red.less</code>.</p>
+	 * <p>Next, you have to require the <code>steal/less</code> plugin and then use
+	 * steal.less to load your less style:
+	 * </p>
+	 * @codestart
+	 * steal.plugins('steal/less').then(function(){
+	 *   steal.less('red');
+	 * });
+	 * @codeend
+	 *
+	 * Loads Less files relative to the current file.  It's expected that all
+	 * Less files end with <code>less</code>.
+	 * @param {String+} path the relative path from the current file to the less file.
+	 * You can pass multiple paths.
+	 * @return {steal} returns the steal function.
+	 */
+	steal.less = function(){
+		//if production, 
+		if(steal.options.env == 'production'){
+			if(steal.loadedProductionCSS){
+				return steal;
+			}else{
+				var productionCssPath = steal.File( steal.options.production.replace(".js", ".css") ).normalize();
+				productionCssPath = steal.root.join( productionCssPath );
+				steal.createLink( productionCssPath );
+				loadedProductionCSS = true;
+				return steal;
+			}
+		}
+		//@steal-remove-start
+		var current, path;
+		for(var i=0; i < arguments.length; i++){
+			current = new steal.File(arguments[i]+".less").joinCurrent();
+			path = steal.root.join(current)
+			if(steal.browser.rhino){
+				//rhino will just look for this
+				steal.createLink(path, {
+					type : "text/less"
+				})
+			}else{
+				var src = steal.request(path);
+				if(!src){
+					steal.dev.warn("steal/less : There's no content at "+path+", or you're on the filesystem and it's in another folder.");
+					return steal;
+				}
+				// less needs the full path with http:// or file://
+				var newPath = location.href.replace(/[\w\.-]+$/, '')+
+					path.replace(/[\w\.-]+$/, '');
+				//get and insert stype
+				new (less.Parser)({
+	                optimization: less.optimization,
+	                paths: [newPath]
+	            }).parse(src, function (e, root) {
+	                var styles = root.toCSS(),
+						css  = document.createElement('style');
+			        
+					css.type = 'text/css';
+					css.id = steal.cleanId(path)
+			        
+					document.getElementsByTagName('head')[0].appendChild(css);
+				    
+				    if (css.styleSheet) { // IE
+			            css.styleSheet.cssText = styles;
+				    } else {
+				        (function (node) {
+				            if (css.childNodes.length > 0) {
+				                if (css.firstChild.nodeValue !== node.nodeValue) {
+				                    css.replaceChild(node, css.firstChild);
+				                }
+				            } else {
+				                css.appendChild(node);
+				            }
+				        })(document.createTextNode(styles));
+				    }
+
+	            });
+			}
+		}
+		//@steal-remove-end
+		return steal;
+	}
+	//@steal-remove-start
+	steal.build.types['text/less'] =  function(script, loadScriptText){
+		var text =   script.text || loadScriptText(script.href, script),
+			styles;
+		new (less.Parser)({
+	                optimization: less.optimization,
+	                paths: []
+	            }).parse(text, function (e, root) {
+					styles = root.toCSS();
+				});
+		return styles;
+	}
+	//@steal-remove-end
+})
diff --git a/browserid/static/dialog/steal/less/less.less b/browserid/static/dialog/steal/less/less.less
new file mode 100644
index 0000000000000000000000000000000000000000..0c9f06532e669c5dd333ff52a2f0dfb43a855558
--- /dev/null
+++ b/browserid/static/dialog/steal/less/less.less
@@ -0,0 +1,5 @@
+@brandWidth: 100px;
+
+#myElement {
+	width : @brandWidth;
+}
diff --git a/browserid/static/dialog/steal/less/less_engine.js b/browserid/static/dialog/steal/less/less_engine.js
new file mode 100644
index 0000000000000000000000000000000000000000..bef8789e3c5c2811554826dcbf4e431a7b497e7c
--- /dev/null
+++ b/browserid/static/dialog/steal/less/less_engine.js
@@ -0,0 +1,2612 @@
+//
+// LESS - Leaner CSS v1.0.40
+// http://lesscss.org
+// 
+// Copyright (c) 2010, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+    return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree;
+
+if (typeof(window) === 'undefined') {
+    less = exports,
+    tree = require('less/tree');
+} else {
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env && env.paths || [],  // Search paths, when importing
+        queue: [],                      // Files which haven't been imported yet
+        files: {},                      // Holds the imported parse trees
+        mime:  env && env.mime,         // MIME type of .less files
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (root) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+                that.files[path] = root;                        // Store the root
+
+                callback(root);
+
+                if (that.queue.length === 0) { finish() }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, c, index, endIndex, k;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            mem = i += length;
+            endIndex = i + chunks[j].length - length;
+
+            while (i < endIndex) {
+                c = input.charCodeAt(i);
+                if (! (c === 32 || c === 10 || c === 9)) { break }
+                i++;
+            }
+            chunks[j] = chunks[j].slice(length + (i - mem));
+            current = i;
+
+            if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            chunks = [];
+            input = str.replace(/\r\n/g, '\n');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /[^"'`\{\}\/]+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inString;
+
+                for (var i = 0, c, cc; i < input.length; i++) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = i;
+
+                    if (!inString && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    c = input.charAt(i);
+                                }
+                            }
+                        }
+                    }
+
+                    if        (c === '{' && !inString) { level ++;
+                        chunk.push(c);
+                    } else if (c === '}' && !inString) { level --;
+                        chunk.push(c);
+                        chunks[++j] = chunk = [];
+                    } else {
+                        if (c === '"' || c === "'" || c === '`') {
+                            if (! inString) {
+                                inString = c;
+                            } else {
+                                inString = inString === c ? false : inString;
+                            }
+                        }
+                        chunk.push(c);
+                    }
+                }
+                if (level > 0) {
+                    throw {
+                        type: 'Syntax',
+                        message: "Missing closing `}`",
+                        filename: env.filename
+                    };
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            root = new(tree.Ruleset)([], $(this.parsers.primary));
+            root.root = true;
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [];
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false });
+                    } catch (e) {
+                        lines = input.split('\n');
+                        line = getLine(e.index);
+
+                        for (var n = e.index, column = -1;
+                                 n >= 0 && input.charAt(n) !== '\n';
+                                 n--) { column++ }
+
+                        throw {
+                            type: e.type,
+                            message: e.message,
+                            filename: env.filename,
+                            index: e.index,
+                            line: typeof(line) === 'number' ? line + 1 : null,
+                            callLine: e.call && (getLine(e.call) + 1),
+                            callExtract: lines[getLine(e.call)],
+                            stack: e.stack,
+                            column: column,
+                            extract: [
+                                lines[line - 1],
+                                lines[line],
+                                lines[line + 1]
+                            ]
+                        };
+                    }
+                    if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+
+                    function getLine(index) {
+                        return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    name: "ParseError",
+                    message: "Syntax Error on line " + line,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function () { callback(error, root) };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str;
+                    if (input.charAt(i) !== '"' && input.charAt(i) !== "'") return;
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2]);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+                    if (k = $(/^[A-Za-z-]+/)) { return new(tree.Keyword)(k) }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, args;
+
+                    if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
+
+                    name = name[1].toLowerCase();
+
+                    if (name === 'url') { return null }
+                    else                { i += name.length + 1 }
+
+                    if (name === 'alpha') { return $(this.alpha) }
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted);
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?]+/) || "";
+                    if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+                    return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), imports.paths);
+                },
+
+                dataURI: function () {
+                    var obj;
+
+                    if ($(/^data:/)) {
+                        obj         = {};
+                        obj.mime    = $(/^[^\/]+\/[^,;)]+/)     || '';
+                        obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+                        obj.base64  = $(/^;\s*base64/)          || '';
+                        obj.data    = $(/^,\s*[^)]+/);
+
+                        if (obj.data) { return obj }
+                    }
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@[\w-]+/))) {
+                        return new(tree.Variable)(name, index);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    if ((c > 57 || c < 45) || c === 47) return;
+
+                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str;
+
+                    if (input.charAt(i) !== '`') { return }
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+                    if (s !== '.' && s !== '#') { return }
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e));
+                        c = $('>');
+                    }
+                    $('(') && (args = $(this.entities.arguments)) && $(')');
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index);
+                    }
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value;
+
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*(;|})/)) return;
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        while (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                 || $(this.entities.keyword)) {
+                            // Variable
+                            if (param instanceof tree.Variable) {
+                                if ($(':')) {
+                                    if (value = $(this.expression)) {
+                                        params.push({ name: param.name, value: value });
+                                    } else {
+                                        throw new(Error)("Expected value");
+                                    }
+                                } else {
+                                    params.push({ name: param.name });
+                                }
+                            } else {
+                                params.push({ value: param });
+                            }
+                            if (! $(',')) { break }
+                        }
+                        if (! $(')')) throw new(Error)("Expected )");
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset);
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t;
+
+                c = $(this.combinator);
+                e = $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) || $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+                if (e) { return new(tree.Element)(c, e) }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '&' || c === '+' || c === '~') {
+                    i++;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (c === ':' && input.charAt(i + 1) === ':') {
+                    i += 2;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)('::');
+                } else if (input.charAt(i - 1) === ' ') {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            tag: function () {
+                return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match;
+                save();
+
+                if (match = /^([.#: \w-]+)[\s\n]*\{/.exec(chunks[j])) {
+                    i += match[0].length - 1;
+                    selectors = [new(tree.Selector)([new(tree.Element)(null, match[1])])];
+                } else {
+                    while (s = $(this.selector)) {
+                        selectors.push(s);
+                        if (! $(',')) { break }
+                    }
+                    if (s) $(this.comment);
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    return new(tree.Ruleset)(selectors, rules);
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path;
+                if ($(/^@import\s+/) &&
+                    (path = $(this.entities.quoted) || $(this.entities.url)) &&
+                    $(';')) {
+                    return new(tree.Import)(path, imports);
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, types;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import'])) {
+                    return value;
+                } else if (name = $(/^@media|@page/)) {
+                    types = ($(/^[^{]+/) || '').trim();
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name + " " + types, rules);
+                    }
+                } else if (name = $(/^@[-a-z]+/)) {
+                    if (name === '@font-face') {
+                        if (rules = $(this.block)) {
+                            return new(tree.Directive)(name, rules);
+                        }
+                    } else if ((value = $(this.entity)) && $(';')) {
+                        return new(tree.Directive)(name, value);
+                    }
+                }
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                return $(this.sub) || $(this.entities.dimension) ||
+                       $(this.entities.color) || $(this.entities.variable) ||
+                       $(this.entities.call);
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (typeof(window) !== 'undefined') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (path.charAt(0) !== '/' && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return number(c) }),
+            a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%s/,    args[i].value)
+                     .replace(/%[da]/, args[i].toCSS());
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    }
+};
+
+function hsla(hsla) {
+    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args) {
+    this.name = name;
+    this.args = args;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            return tree.functions[this.name].apply(tree.functions, args);
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    }
+};
+
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+    this.name = name;
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        env.frames.unshift(this);
+        this.ruleset = this.ruleset && this.ruleset.eval(env);
+        env.frames.shift();
+        return this;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+    this.value = value.trim();
+};
+tree.Element.prototype.toCSS = function (env) {
+    return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        '&' : '',
+        ':' : ' :',
+        '::': '::',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > '
+    }[this.value];
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else {
+            return this.value[0].eval(env);
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(' ');
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+    var that = this;
+
+    this._path = path;
+
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /\.(le?|c)ss$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (root) {
+            if (! root) {
+                throw new(Error)("Error parsing " + that.path);
+            }
+            that.root = root;
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function () {
+        if (this.css) {
+            return "@import " + this._path.toCSS() + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset;
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype
+                         .splice
+                         .apply(ruleset.rules,
+                                [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+            return ruleset.rules;
+        }
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index) {
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    toCSS: function () {
+        return JSON.stringify(this.evaluated);
+    },
+    eval: function (env) {
+        var result,
+            expression = new(Function)('return (' + this.expression + ')'),
+            context = {};
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            this.evaluated = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        return this;
+    }
+};
+
+})(require('less/tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, rules = [], match = false;
+
+        for (var i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                for (var m = 0; m < mixins.length; m++) {
+                    if (mixins[m].match(this.arguments, env)) {
+                        try {
+                            Array.prototype.push.apply(
+                                  rules, mixins[m].eval(env, this.arguments).rules);
+                            match = true;
+                        } catch (e) {
+                            throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+                        }
+                    }
+                }
+                if (match) {
+                    return rules;
+                } else {
+                    throw { message: 'No matching definition was found for `' +
+                                      this.selector.toCSS().trim() + '('      +
+                                      this.arguments.map(function (a) {
+                                          return a.toCSS();
+                                      }).join(', ') + ")`",
+                            index:   this.index };
+                }
+            }
+        }
+        throw { message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index };
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (p.name && !p.value) { return count + 1 }
+        else                    { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function () { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    eval: function (env, args) {
+        var frame = new(tree.Ruleset)(null, []), context;
+
+        for (var i = 0, val; i < this.params.length; i++) {
+            if (this.params[i].name) {
+                if (val = (args && args[i]) || this.params[i].value) {
+                    frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+                } else {
+                    throw { message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                }
+            }
+        }
+        return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+            frames: [this, frame].concat(this.frames, env.frames)
+        });
+    },
+    match: function (args, env) {
+        var argsLength = (args && args.length) || 0, len;
+
+        if (argsLength < this.required) { return false }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name) {
+                if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content) {
+    this.value = content || '';
+    this.quote = str.charAt(0);
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        return this.quote + this.value + this.quote;
+    },
+    eval: function () {
+        return this;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + ";";
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+        ruleset.root = this.root;
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root) {
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype.splice
+                         .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                Array.prototype.splice
+                     .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+
+        return ruleset;
+    },
+    match: function (args) {
+        return !args || args.length === 0;
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > 1) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            rule;
+
+        if (! this.root) {
+            if (context.length === 0) {
+                paths = this.selectors.map(function (s) { return [s] });
+            } else {
+                for (var s = 0; s < this.selectors.length; s++) {
+                    for (var c = 0; c < context.length; c++) {
+                        paths.push(context[c].concat([this.selectors[s]]));
+                    }
+                }
+            }
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Directive)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+                css.push(selector,
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('') + (env.compress ? '\n' : '');
+    }
+};
+})(require('less/tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+    if (this.elements[0].combinator.value === "") {
+        this.elements[0].combinator.value = ' ';
+    }
+};
+tree.Selector.prototype.match = function (other) {
+    if (this.elements[0].value === other.elements[0].value) {
+        return true;
+    } else {
+        return false;
+    }
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+
+    return this._css = this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+    if (val.data) {
+        this.attrs = val;
+    } else {
+        // Add the base path if the URL is relative and we are in the browser
+        if (!/^(?:https?:\/|file:\/)?\//.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
+            val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+        }
+        this.value = val;
+        this.paths = paths;
+    }
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+                                    : this.value.toCSS()) + ")";
+    },
+    eval: function (ctx) {
+        return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { return variable }
+        else {
+            throw { message: "variable " + this.name + " is undefined",
+                    index: this.index };
+        }
+    }
+};
+
+})(require('less/tree'));
+require('less/tree').find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:'    ||
+                      location.protocol === 'chrome:'  ||
+                      location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+                        location.hostname == '0.0.0.0'   ||
+                        location.hostname == 'localhost' ||
+                        location.port.length > 0         ||
+                        isFileProtocol                   ? 'development'
+                                                         : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch   = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+    less.optimization = 0;
+
+    if (/!watch/.test(location.hash)) {
+        less.watch();
+    }
+    less.watchTimer = setInterval(function () {
+        if (less.watchMode) {
+            loadStyleSheets(function (root, sheet, env) {
+                if (root) {
+                    createCSS(root.toCSS(), sheet, env.lastModified);
+                }
+            });
+        }
+    }, less.poll);
+} else {
+    less.optimization = 3;
+}
+
+var cache;
+
+try {
+    cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+    cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+       (links[i].type.match(typePattern)))) {
+        less.sheets.push(links[i]);
+    }
+}
+
+
+less.refresh = function (reload) {
+    var startTime = endTime = new(Date);
+
+    loadStyleSheets(function (root, sheet, env) {
+        if (env.local) {
+            log("loading " + sheet.href + " from cache.");
+        } else {
+            log("parsed " + sheet.href + " successfully.");
+            createCSS(root.toCSS(), sheet, env.lastModified);
+        }
+        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+        endTime = new(Date);
+    }, reload);
+
+    loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+    var styles = document.getElementsByTagName('style');
+    for (var i = 0; i < styles.length; i++) {
+        if (styles[i].type.match(typePattern)) {
+            new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+                styles[i].type      = 'text/css';
+                styles[i].innerHTML = tree.toCSS();
+            });
+        }
+    }
+}
+
+function loadStyleSheets(callback, reload) {
+    for (var i = 0; i < less.sheets.length; i++) {
+        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+    }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var url       = window.location.href.replace(/[#?].*$/, '');
+    var href      = sheet.href.replace(/\?.*$/, '');
+    var css       = cache && cache.getItem(href);
+    var timestamp = cache && cache.getItem(href + ':timestamp');
+    var styles    = { css: css, timestamp: timestamp };
+
+    // Stylesheets in IE don't always return the full path
+    if (! /^(https?|file):/.test(href)) {
+        href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+    }
+
+    xhr(sheet.href, sheet.type, function (data, lastModified) {
+        if (!reload && styles && lastModified &&
+           (new(Date)(lastModified).valueOf() ===
+            new(Date)(styles.timestamp).valueOf())) {
+            // Use local copy
+            createCSS(styles.css, sheet);
+            callback(null, sheet, { local: true, remaining: remaining });
+        } else {
+            // Use remote copy (re-parse)
+            try {
+                new(less.Parser)({
+                    optimization: less.optimization,
+                    paths: [href.replace(/[\w\.-]+$/, '')],
+                    mime: sheet.type
+                }).parse(data, function (e, root) {
+                    if (e) { return error(e, href) }
+                    try {
+                        callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
+                    } catch (e) {
+                        error(e, href);
+                    }
+                });
+            } catch (e) {
+                error(e, href);
+            }
+        }
+    }, function (status, url) {
+        throw new(Error)("Couldn't load " + url + " (" + status + ")");
+    });
+}
+
+function extractId(href) {
+    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
+               .replace(/^\//,                 '' )  // Remove root /
+               .replace(/\?.*$/,               '' )  // Remove query
+               .replace(/\.[^\.\/]+$/,         '' )  // Remove file extension
+               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
+               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+    var css;
+
+    // Strip the query-string
+    var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+    // If there is no title set, use the filename, minus the extension
+    var id = 'less:' + (sheet.title || extractId(href));
+
+    // If the stylesheet doesn't exist, create a new node
+    if ((css = document.getElementById(id)) === null) {
+        css = document.createElement('style');
+        css.type = 'text/css';
+        css.media = sheet.media || 'screen';
+        css.id = id;
+        document.getElementsByTagName('head')[0].appendChild(css);
+    }
+
+    if (css.styleSheet) { // IE
+        try {
+            css.styleSheet.cssText = styles;
+        } catch (e) {
+            throw new(Error)("Couldn't reassign styleSheet.cssText.");
+        }
+    } else {
+        (function (node) {
+            if (css.childNodes.length > 0) {
+                if (css.firstChild.nodeValue !== node.nodeValue) {
+                    css.replaceChild(node, css.firstChild);
+                }
+            } else {
+                css.appendChild(node);
+            }
+        })(document.createTextNode(styles));
+    }
+
+    // Don't update the local store if the file wasn't modified
+    if (lastModified && cache) {
+        log('saving ' + href + ' to cache.');
+        cache.setItem(href, styles);
+        cache.setItem(href + ':timestamp', lastModified);
+    }
+}
+
+function xhr(url, type, callback, errback) {
+    var xhr = getXMLHttpRequest();
+    var async = isFileProtocol ? false : less.async;
+
+    if (typeof(xhr.overrideMimeType) === 'function') {
+        xhr.overrideMimeType('text/css');
+    }
+    xhr.open('GET', url, async);
+    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+    xhr.send(null);
+
+    if (isFileProtocol) {
+        if (xhr.status === 0) {
+            callback(xhr.responseText);
+        } else {
+            errback(xhr.status, url);
+        }
+    } else if (async) {
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                handleResponse(xhr, callback, errback);
+            }
+        };
+    } else {
+        handleResponse(xhr, callback, errback);
+    }
+
+    function handleResponse(xhr, callback, errback) {
+        if (xhr.status >= 200 && xhr.status < 300) {
+            callback(xhr.responseText,
+                     xhr.getResponseHeader("Last-Modified"));
+        } else if (typeof(errback) === 'function') {
+            errback(xhr.status, url);
+        }
+    }
+}
+
+function getXMLHttpRequest() {
+    if (window.XMLHttpRequest) {
+        return new(XMLHttpRequest);
+    } else {
+        try {
+            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+        } catch (e) {
+            log("browser doesn't support AJAX.");
+            return null;
+        }
+    }
+}
+
+function removeNode(node) {
+    return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+    var id = 'less-error-message:' + extractId(href);
+
+    var template = ['<ul>',
+                        '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
+                        '<li><label>[0]</label><pre>{current}</pre></li>',
+                        '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
+                    '</ul>'].join('\n');
+
+    var elem = document.createElement('div'), timer, content;
+
+    elem.id        = id;
+    elem.className = "less-error-message";
+
+    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
+              '</h3>' + '<p><a href="' + href   + '">' + href + "</a> ";
+
+    if (e.extract) {
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+            template.replace(/\[(-?\d)\]/g, function (_, i) {
+                return (parseInt(e.line) + parseInt(i)) || '';
+            }).replace(/\{(\d)\}/g, function (_, i) {
+                return e.extract[parseInt(i)] || '';
+            }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
+                                      e.extract[1].slice(e.column)    + '</span>');
+    }
+    elem.innerHTML = content;
+
+    // CSS for error messages
+    createCSS([
+        '.less-error-message ul, .less-error-message li {',
+            'list-style-type: none;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message label {',
+            'font-size: 12px;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'color: #cc7777;',
+        '}',
+        '.less-error-message pre {',
+            'color: #ee4444;',
+            'padding: 4px 0;',
+            'margin: 0;',
+            'display: inline-block;',
+        '}',
+        '.less-error-message pre.ctx {',
+            'color: #dd4444;',
+        '}',
+        '.less-error-message h3 {',
+            'font-size: 20px;',
+            'font-weight: bold;',
+            'padding: 15px 0 5px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message a {',
+            'color: #10a',
+        '}',
+        '.less-error-message .error {',
+            'color: red;',
+            'font-weight: bold;',
+            'padding-bottom: 2px;',
+            'border-bottom: 1px dashed red;',
+        '}'
+    ].join('\n'), { title: 'error-message' });
+
+    elem.style.cssText = [
+        "font-family: Arial, sans-serif",
+        "border: 1px solid #e00",
+        "background-color: #eee",
+        "border-radius: 5px",
+        "-webkit-border-radius: 5px",
+        "-moz-border-radius: 5px",
+        "color: #e00",
+        "padding: 15px",
+        "margin-bottom: 15px"
+    ].join(';');
+
+    if (less.env == 'development') {
+        timer = setInterval(function () {
+            if (document.body) {
+                if (document.getElementById(id)) {
+                    document.body.replaceChild(elem, document.getElementById(id));
+                } else {
+                    document.body.insertBefore(elem, document.body.firstChild);
+                }
+                clearInterval(timer);
+            }
+        }, 10);
+    }
+}
+
+})(window);
diff --git a/browserid/static/dialog/steal/less/less_test.js b/browserid/static/dialog/steal/less/less_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..1e85675742d89cca66bea2fa672f633be475ff21
--- /dev/null
+++ b/browserid/static/dialog/steal/less/less_test.js
@@ -0,0 +1,17 @@
+steal.plugins('funcunit/qunit','steal/less').then(
+function(){
+	steal.less('less')
+},
+function(){
+	module("steal/less",{
+		setup : function(){
+			
+		}
+	})
+	test("element has color", function(){
+		document.getElementById('qunit-test-area').innerHTML = 
+			"<div id='myElement'>FOO</div>";
+			
+		equals(document.getElementById("myElement").clientWidth,100, "Background COlor is red")
+	})
+})
diff --git a/browserid/static/dialog/steal/less/qunit.html b/browserid/static/dialog/steal/less/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..31a059e174133b7f51d241cecda16ac825ae07a0
--- /dev/null
+++ b/browserid/static/dialog/steal/less/qunit.html
@@ -0,0 +1,22 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../funcunit/qunit/qunit.css" />
+        <title>QUnit Test</title>
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+		<script type='text/javascript' src='../../steal/steal.js?steal/less/less_test.js'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">Steal Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/make.js b/browserid/static/dialog/steal/make.js
new file mode 100644
index 0000000000000000000000000000000000000000..ad2b488af64636c45242964e3abcbe96a23003b7
--- /dev/null
+++ b/browserid/static/dialog/steal/make.js
@@ -0,0 +1,4 @@
+load('steal/rhino/steal.js');
+
+steal.File('steal/js').copyTo('js')
+steal.File('steal/js.bat').copyTo('js.bat')
diff --git a/browserid/static/dialog/steal/pluginifyjs b/browserid/static/dialog/steal/pluginifyjs
new file mode 100644
index 0000000000000000000000000000000000000000..c5445b2b54d299ca2802e13b5df01debad6281fd
--- /dev/null
+++ b/browserid/static/dialog/steal/pluginifyjs
@@ -0,0 +1,8 @@
+load("steal/rhino/steal.js");
+steal.plugins('steal/build/pluginify', function () {
+    //check if args
+    var app = _args.shift();
+    
+	steal.build.pluginify(app, _args)
+
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/rhino/blank.html b/browserid/static/dialog/steal/rhino/blank.html
new file mode 100644
index 0000000000000000000000000000000000000000..6f3e1dc99ddc41094d0099ec8f0d48caba1acd8c
--- /dev/null
+++ b/browserid/static/dialog/steal/rhino/blank.html
@@ -0,0 +1,6 @@
+<html>
+    <head></head>
+    <body>
+        <script src='../steal.js' type='text/javascript'></script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/rhino/build.js b/browserid/static/dialog/steal/rhino/build.js
new file mode 100644
index 0000000000000000000000000000000000000000..9992da0d1705586ed42fb59ec42142276a341806
--- /dev/null
+++ b/browserid/static/dialog/steal/rhino/build.js
@@ -0,0 +1,30 @@
+load('steal/rhino/steal.js')
+
+// moves js scripts to framework
+// creates steal.production.js
+// creates the zip
+// copy js.bat and js to root
+new steal.File("steal/js.bat").copyTo("js.bat", [])
+new steal.File("steal/js").copyTo("js", [])
+
+// compress steal.js to steal.production.js
+load("steal/rhino/steal.js");
+steal.plugins('steal/build', 'steal/build/scripts', function() {
+	var script = readFile('steal/steal.js'),
+		text = steal.build.builders.scripts.clean(script),
+		compressed = steal.build.builders.scripts.compressors.localClosure()(text, true);
+	new steal.File("steal/steal.production.js").save(compressed);
+});
+
+new steal.File("../stealjs").removeDir()
+new steal.File("stealjs.zip").remove()
+new steal.File("../stealjs").mkdir()
+
+var ignore = [".git", ".gitignore", "dist", "js", "js.bat"]
+
+new steal.File("../stealjs/steal").mkdir()
+new steal.File("steal").copyTo("../stealjs/steal/", ignore)
+new steal.File("js").copyTo("../stealjs/js", [])
+new steal.File("js.bat").copyTo("../stealjs/js.bat", [])
+
+new steal.File("../stealjs").zipDir("stealjs.zip", "..\\stealjs\\")
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/rhino/docs.js b/browserid/static/dialog/steal/rhino/docs.js
new file mode 100644
index 0000000000000000000000000000000000000000..22faeeca503a6c838b7538043cbff43f67da98c1
--- /dev/null
+++ b/browserid/static/dialog/steal/rhino/docs.js
@@ -0,0 +1,68 @@
+/*
+@page stealjs StealJS
+@tag core
+<h1>StealJS</h1>
+<p>The StealJS project is a collection of comamnd and client based JavaScript utilities
+that make building, packaging, sharing and consuming JavaScript applications easy.</p>
+
+<h2>Tools</h2>
+
+<h3>Dependency Management</h3>
+The [steal steal script] (steal/steal.js) is a script loader and 
+dependency management tool.  Features:
+<ul>
+	<li>Loads JavaScript, CSS, Less, CoffeeScript, and a variety of client-side templates.</li>
+	<li>Only loads a file once.</li>
+	<li>Can load relative to the current file.</li>
+</ul>
+@codestart
+steal.plugins('jquery/controller','jquery/view/ejs');
+@codeend
+<h3>JS/CSS Concatenation and Compression</h3>
+The steal [steal.build build] plugin makes compressing an application into a single compressed 
+JavaScript and CSS file extremely easy.  Features:
+<ul>
+	<li>Works with any application, even ones not using the steal script.</li>
+	<li>Configurable compressors (defaults to Google Closure).</li>
+	<li>Compresses Less and CoffeeScript.</li>
+	<li>Pre-processes and compresses client-side templates (templates don't have to be parsed).</li>
+	<li>Expandable architecture makes it easy to build other resources.</li>
+</ul>
+@codestart text
+js steal/buildjs mypage.html
+@codeend
+
+<h3>Logging</h3>
+Steal [steal.dev dev] logs messages cross browser.  Messages are removed in production builds.
+@codestart
+steal.dev.log('something is happening');
+@codeend
+
+<h3>Code Generators</h3>
+Steal [steal.generate generate]  makes building code generators extremely easy.  Features:
+<ul>
+	<li>Pre-packaged JMVC style code generators.</li>
+	<li>Very easy to write custom generators.</li>
+</ul>
+@codestart text
+js steal/generate/app cookbook
+@codeend
+
+<h3>Package Management</h3>
+Steal [steal.get get] is a simple JavaScript version of [http://rubygems.org/ ruby gems].  Features:
+ <ul>
+	<li>Download and install plugins from remote SVN or GIT repositories.  </li>
+	<li>Installs dependencies.</li>
+</ul>
+
+@codestart text
+js steal/getjs http://github.com/jupiterjs/mxui/
+@codeend
+<h3>Code Cleaner</h3>
+Steal [steal.clean clean] cleans your code and checks it against JSLint. 
+
+@codestart text
+js steal/clean path/to/page.html
+@codeend
+ */
+//blah
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/rhino/empty.html b/browserid/static/dialog/steal/rhino/empty.html
new file mode 100644
index 0000000000000000000000000000000000000000..074d309395d6fadeebc6c57ecdaf91eff54fdac1
--- /dev/null
+++ b/browserid/static/dialog/steal/rhino/empty.html
@@ -0,0 +1,12 @@
+<html>
+    <head></head>
+    <body>
+        
+        <script src='../steal.js' type='text/javascript'></script>
+		<script type='text/javascript'>
+			rhinoLoader.callback(steal);
+			steal.start();
+		</script>
+        <div id='testarea'></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/rhino/env.js b/browserid/static/dialog/steal/rhino/env.js
new file mode 100644
index 0000000000000000000000000000000000000000..3a2565d3ca917b8ea45467488febb890db0ba5e7
--- /dev/null
+++ b/browserid/static/dialog/steal/rhino/env.js
@@ -0,0 +1,25363 @@
+/*
+ * Envjs core-env.1.2.35
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ */
+
+Envjs = function(){
+    var i,
+        name,
+        override = function(){
+            for(i=0;i<arguments.length;i++){
+                for ( name in arguments[i] ) {
+                    var g = arguments[i].__lookupGetter__(name),
+                        s = arguments[i].__lookupSetter__(name);
+                    if ( g || s ) {
+                        if ( g ) { Envjs.__defineGetter__(name, g); }
+                        if ( s ) { Envjs.__defineSetter__(name, s); }
+                    } else {
+                        Envjs[name] = arguments[i][name];
+                    }
+                }
+            }
+        };
+    if(arguments.length === 1 && typeof(arguments[0]) == 'string'){
+        window.location = arguments[0];
+    }else if (arguments.length === 1 && typeof(arguments[0]) == "object"){
+        override(arguments[0]);
+    }else if(arguments.length === 2 && typeof(arguments[0]) == 'string'){
+        override(arguments[1]);
+        window.location = arguments[0];
+    }
+	if (Envjs.dontPrintUserAgent !== true && Envjs.printedUserAgent !== true) {
+		Envjs.printedUserAgent = true;
+		console.log('[ %s ]', window.navigator.userAgent);
+	}
+    return;
+},
+__this__ = this;
+
+//eg "Mozilla"
+Envjs.appCodeName  = "Envjs";
+
+//eg "Gecko/20070309 Firefox/2.0.0.3"
+Envjs.appName      = "Netscape";
+
+Envjs.version = "1.6";//?
+Envjs.revision = '';
+/*
+ * Envjs core-env.1.2.35 
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ */
+
+//CLOSURE_START
+(function(){
+
+
+
+
+
+/**
+ * @author john resig
+ */
+// Helper method for extending one object with another.
+function __extend__(a,b) {
+    for ( var i in b ) {
+        var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
+        if ( g || s ) {
+            if ( g ) { a.__defineGetter__(i, g); }
+            if ( s ) { a.__defineSetter__(i, s); }
+        } else {
+            a[i] = b[i];
+        }
+    } return a;
+}
+
+/**
+ * @author ariel flesler
+ *    http://flesler.blogspot.com/2008/11/fast-trim-function-for-javascript.html
+ * @param {Object} str
+ */
+function __trim__( str ){
+    return (str || "").replace( /^\s+|\s+$/g, "" );
+}
+
+
+/**
+ * Writes message to system out
+ * @param {String} message
+ */
+Envjs.log = function(message){};
+
+/**
+ * Constants providing enumerated levels for logging in modules
+ */
+Envjs.DEBUG = 1;
+Envjs.INFO = 2;
+Envjs.WARN = 3;
+Envjs.ERROR = 3;
+Envjs.NONE = 3;
+
+/**
+ * Writes error info out to console
+ * @param {Error} e
+ */
+Envjs.lineSource = function(e){};
+
+    
+/**
+ * TODO: used in ./event/eventtarget.js
+ * @param {Object} event
+ */
+Envjs.defaultEventBehaviors = {
+	'submit': function(event) {
+        var target = event.target,
+			serialized,
+		    method,
+		    action;
+        while (target && target.nodeName !== 'FORM') {
+            target = target.parentNode;
+        }
+        if (target && target.nodeName === 'FORM') {
+            serialized = Envjs.serializeForm(target);
+			//console.log('serialized %s', serialized);
+		    method = target.method?target.method.toUpperCase():"GET";
+			
+		    action = Envjs.uri(
+		        target.action !== ""?target.action:target.ownerDocument.baseURI,
+		        target.ownerDocument.baseURI
+		    );
+			if(method=='GET' && !action.match(/^file:/)){
+				action = action + "?" + serialized;
+			}
+			//console.log('replacing document with form submission %s', action);
+			target.ownerDocument.location.replace(
+				action, method, serialized
+			);
+        }
+    },
+    
+    'click': function(event) {
+		//console.log("handling default behavior for click %s", event.target);
+        var target = event.target,
+			url,
+			form,
+			inputs;
+        while (target && target.nodeName !== 'A' && target.nodeName !== 'INPUT') {
+            target = target.parentNode;
+        }
+        if (target && target.nodeName === 'A') {
+			//console.log('target is a link');
+            if(target.href && !target.href.match(/^#/)){
+			    url = Envjs.uri(target.href, target.ownerDocument.baseURI);
+				target.ownerDocument.location.replace(url);
+            }
+        }else if (target && target.nodeName === 'INPUT') {
+            if(target.type.toLowerCase() === 'submit'){
+				if(!target.value){
+					target.value = 'submit';
+				}
+				//console.log('submit click %s %s', target.name, target.value);
+				form = target.parentNode;
+			    while (form && form.nodeName !== 'FORM' ) {
+		            form = form.parentNode;
+		        }
+				if(form && form.nodeName === 'FORM'){
+					//disable other submit buttons before serializing
+					inputs = form.getElementsByTagName('input');
+					for(var i=0;i<inputs.length;i++){
+						if(inputs[i].type == 'submit' && inputs[i]!=target){
+							//console.log('disabling the non-relevant submit button %s', inputs[i].value);
+							inputs[i].disabled = true;
+							inputs[i].value = null;
+						}
+					}
+					form.submit();
+				}
+            }
+        }
+    }
+};
+
+Envjs.exchangeHTMLDocument = function(doc, text, url, frame) {
+    var html, head, title, body, 
+		event, 
+		frame = doc.__ownerFrame__, 
+		i;
+    try {
+        doc.baseURI = url;
+        //console.log('parsing document for window exchange %s', url); 
+        HTMLParser.parseDocument(text, doc);
+        //console.log('finsihed parsing document for window exchange %s', url); 
+        Envjs.wait();
+        /*console.log('finished wait after parse/exchange %s...( frame ? %s )', 
+            doc.baseURI, 
+            top.document.baseURI
+        );*/
+		//if this document is inside a frame make sure to trigger
+		//a new load event on the frame
+        if(frame){
+            event = doc.createEvent('HTMLEvents');
+            event.initEvent('load', false, false);
+            frame.dispatchEvent( event, false );
+        }
+    } catch (e) {
+        console.log('parsererror %s', e);
+        try {
+            console.log('document \n %s', doc.documentElement.outerHTML);
+        } catch (e) {
+            // swallow
+        }
+        doc = new HTMLDocument(new DOMImplementation(), doc.ownerWindow);
+        html =    doc.createElement('html');
+        head =    doc.createElement('head');
+        title =   doc.createElement('title');
+        body =    doc.createElement('body');
+        title.appendChild(doc.createTextNode('Error'));
+        body.appendChild(doc.createTextNode('' + e));
+        head.appendChild(title);
+        html.appendChild(head);
+        html.appendChild(body);
+        doc.appendChild(html);
+        //console.log('default error document \n %s', doc.documentElement.outerHTML);
+
+        //DOMContentLoaded event
+        if (doc.createEvent) {
+            event = doc.createEvent('Event');
+            event.initEvent('DOMContentLoaded', false, false);
+            doc.dispatchEvent( event, false );
+
+            event = doc.createEvent('HTMLEvents');
+            event.initEvent('load', false, false);
+            doc.dispatchEvent( event, false );
+        }
+
+        //finally fire the window.onload event
+        //TODO: this belongs in window.js which is a event
+        //      event handler for DOMContentLoaded on document
+
+        try {
+            if (doc === window.document) {
+                console.log('triggering window.load');
+                event = doc.createEvent('HTMLEvents');
+                event.initEvent('load', false, false);
+                window.dispatchEvent( event, false );
+            }
+        } catch (e) {
+            //console.log('window load event failed %s', e);
+            //swallow
+        }
+    };  /* closes return {... */
+};
+
+/**
+ * describes which script src values will trigger Envjs to load
+ * the script like a browser would
+ */
+Envjs.scriptTypes = {
+	"": false, //anonymous/inline
+    "text/javascript"   :false,
+    "text/envjs"        :true
+};
+
+/**
+ * will be called when loading a script throws an error
+ * @param {Object} script
+ * @param {Object} e
+ */
+Envjs.onScriptLoadError = function(script, e){
+    console.log('error loading script %s %s', script, e);
+};
+
+/**
+ * load and execute script tag text content
+ * @param {Object} script
+ */
+Envjs.loadInlineScript = function(script){
+    if(script.ownerDocument.ownerWindow){	
+		//console.log('evaulating inline in script.ownerDocument.ownerWindow %s', 
+		//	script.ownerDocument.ownerWindow);
+        Envjs.eval(
+            script.ownerDocument.ownerWindow,
+            script.text,
+            'eval('+script.text.substring(0,16)+'...):'+new Date().getTime()
+        );
+    }else{
+		//console.log('evaulating inline in global %s',  __this__);
+        Envjs.eval(
+            __this__,
+            script.text,
+            'eval('+script.text.substring(0,16)+'...):'+new Date().getTime()
+        );
+    }
+	if ( Envjs.afterInlineScriptLoad ) {
+		Envjs.afterInlineScriptLoad(script)
+	}
+    //console.log('evaluated at scope %s \n%s',
+    //    script.ownerDocument.ownerWindow.guid, script.text);
+};
+
+/**
+ * Should evaluate script in some context
+ * @param {Object} context
+ * @param {Object} source
+ * @param {Object} name
+ */
+Envjs.eval = function(context, source, name){};
+
+
+/**
+ * Executes a script tag
+ * @param {Object} script
+ * @param {Object} parser
+ */
+Envjs.loadLocalScript = function(script){
+    //console.log("loading script type %s \n source %s", script.type, script.src||script.text.substring(0,32));
+    var types,
+        src,
+        i,
+        base,
+        filename,
+        xhr;
+
+    if(script.type){
+        types = script.type.split(";");
+        for(i=0;i<types.length;i++){
+            if(Envjs.scriptTypes[types[i].toLowerCase()]){
+                //ok this script type is allowed
+                break;
+            }
+            if(i+1 == types.length){
+                //console.log('wont load script type %s', script.type);
+                return false;
+            }
+        }
+    }else if(!Envjs.scriptTypes['']){	
+        //console.log('wont load anonymous script type ""');
+        return false;
+    }
+
+    try{
+        //console.log('handling inline scripts %s %s', script.src, Envjs.scriptTypes[""] );
+        if(!script.src.length ){
+			if(Envjs.scriptTypes[""]){
+            	Envjs.loadInlineScript(script);
+	            return true;
+			}else{
+				return false;
+			}
+        }
+    }catch(e){
+        console.log("Error loading script. %s", e);
+        Envjs.onScriptLoadError(script, e);
+        return false;
+    }
+
+
+    //console.log("loading allowed external script %s", script.src);
+
+    //lets you register a function to execute
+    //before the script is loaded
+    if(Envjs.beforeScriptLoad){
+        for(src in Envjs.beforeScriptLoad){
+            if(script.src.match(src)){
+                Envjs.beforeScriptLoad[src](script);
+            }
+        }
+    }
+    base = "" + script.ownerDocument.location;
+    //filename = Envjs.uri(script.src.match(/([^\?#]*)/)[1], base );
+    //console.log('loading script from base %s', base);
+    filename = Envjs.uri(script.src, base);
+    try {
+        xhr = new XMLHttpRequest();
+        xhr.open("GET", filename, false/*syncronous*/);
+        //console.log("loading external script %s", filename);
+        xhr.onreadystatechange = function(){
+            //console.log("readyState %s", xhr.readyState);
+            if(xhr.readyState === 4){
+                Envjs.eval(
+                    script.ownerDocument.ownerWindow,
+                    xhr.responseText,
+                    filename
+                );
+            }
+        };
+        xhr.send(null, false);
+    } catch(e) {
+        console.log("could not load script %s \n %s", filename, e );
+        Envjs.onScriptLoadError(script, e);
+        return false;
+    }
+    //lets you register a function to execute
+    //after the script is loaded
+    if(Envjs.afterScriptLoad){
+        for(src in Envjs.afterScriptLoad){
+            if(script.src.match(src)){
+                Envjs.afterScriptLoad[src](script);
+            }
+        }
+    }
+    return true;
+};
+
+
+/**
+ * An 'image' was requested by the document.
+ *
+ * - During inital parse of a <link>
+ * - Via an innerHTML parse of a <link>
+ * - A modificiation of the 'src' attribute of an Image/HTMLImageElement
+ *
+ * NOTE: this is optional API.  If this doesn't exist then the default
+ * 'loaded' event occurs.
+ *
+ * @param node {Object} the <img> node
+ * @param node the src value
+ * @return 'true' to indicate the 'load' succeed, false otherwise
+ */
+Envjs.loadImage = function(node, src) {
+    return true;
+};
+
+
+/**
+ * A 'link'  was requested by the document.  Typically this occurs when:
+ * - During inital parse of a <link>
+ * - Via an innerHTML parse of a <link>
+ * - A modificiation of the 'href' attribute on a <link> node in the tree
+ *
+ * @param node {Object} is the link node in question
+ * @param href {String} is the href.
+ *
+ * Return 'true' to indicate that the 'load' was successful, or false
+ * otherwise.  The appropriate event is then triggered.
+ *
+ * NOTE: this is optional API.  If this doesn't exist then the default
+ *   'loaded' event occurs
+ */
+Envjs.loadLink = function(node, href) {
+    return true;
+};
+
+(function(){
+
+
+/*
+ *  cookie handling
+ *  Private internal helper class used to save/retreive cookies
+ */
+
+/**
+ * Specifies the location of the cookie file
+ */
+Envjs.cookieFile = function(){
+    return 'file://'+Envjs.homedir+'/.cookies';
+};
+
+/**
+ * saves cookies to a local file
+ * @param {Object} htmldoc
+ */
+Envjs.saveCookies = function(){
+    var cookiejson = JSON.stringify(Envjs.cookies.persistent,null,'\t');
+    //console.log('persisting cookies %s', cookiejson);
+    Envjs.writeToFile(cookiejson, Envjs.cookieFile());
+};
+
+/**
+ * loads cookies from a local file
+ * @param {Object} htmldoc
+ */
+Envjs.loadCookies = function(){
+    var cookiejson,
+        js;
+    try{
+        cookiejson = Envjs.readFromFile(Envjs.cookieFile())
+        js = JSON.parse(cookiejson, null, '\t');
+    }catch(e){
+        //console.log('failed to load cookies %s', e);
+        js = {};
+    }
+    return js;
+};
+
+Envjs.cookies = {
+    persistent:{
+        //domain - key on domain name {
+            //path - key on path {
+                //name - key on name {
+                     //value : cookie value
+                     //other cookie properties
+                //}
+            //}
+        //}
+        //expire - provides a timestamp for expiring the cookie
+        //cookie - the cookie!
+    },
+    temporary:{//transient is a reserved word :(
+        //like above
+    }
+};
+
+var __cookies__;
+
+//HTMLDocument cookie
+Envjs.setCookie = function(url, cookie){
+    var i,
+        index,
+        name,
+        value,
+        properties = {},
+        attr,
+        attrs;
+    url = Envjs.urlsplit(url);
+    if(cookie)
+        attrs = cookie.split(";");
+    else
+        return;
+    
+    //for now the strategy is to simply create a json object
+    //and post it to a file in the .cookies.js file.  I hate parsing
+    //dates so I decided not to implement support for 'expires' 
+    //(which is deprecated) and instead focus on the easier 'max-age'
+    //(which succeeds 'expires') 
+    cookie = {};//keyword properties of the cookie
+    cookie['domain'] = url.hostname;
+    cookie['path'] = url.path||'/';
+    for(i=0;i<attrs.length;i++){
+        index = attrs[i].indexOf("=");
+        if(index > -1){
+            name = __trim__(attrs[i].slice(0,index));
+            value = __trim__(attrs[i].slice(index+1));
+            if(name.toLowerCase() == 'max-age'){
+                //we'll have to when to check these
+                //and garbage collect expired cookies
+                cookie[name] = parseInt(value, 10);
+            } else if( name.toLowerCase() == 'domain' ){
+                if(__domainValid__(url, value)){
+                    cookie['domain'] = value;
+                }
+            } else if( name.toLowerCase() == 'path' ){
+                //not sure of any special logic for path
+                cookie['path'] = value;
+            } else {
+                //its not a cookie keyword so store it in our array of properties
+                //and we'll serialize individually in a moment
+                properties[name] = value;
+            }
+        }else{
+            if( attrs[i].toLowerCase() == 'secure' ){
+                cookie[attrs[i]] = true;
+            }
+        }
+    }
+    if(!('max-age' in cookie)){
+        //it's a transient cookie so it only lasts as long as 
+        //the window.location remains the same (ie in-memory cookie)
+        __mergeCookie__(Envjs.cookies.temporary, cookie, properties);
+    }else{
+        //the cookie is persistent
+        __mergeCookie__(Envjs.cookies.persistent, cookie, properties);
+        Envjs.saveCookies();
+    }
+};
+
+function __domainValid__(url, value){
+    var i,
+        domainParts = url.hostname.split('.').reverse(),
+        newDomainParts = value.split('.').reverse();
+    if(newDomainParts.length > 1){
+        for(i=0;i<newDomainParts.length;i++){
+            if(!(newDomainParts[i] == domainParts[i])){
+                return false;
+            }
+        }
+        return true;
+    }
+    return false;
+};
+
+Envjs.getCookies = function(url){
+    //The cookies that are returned must belong to the same domain
+    //and be at or below the current window.location.path.  Also
+    //we must check to see if the cookie was set to 'secure' in which
+    //case we must check our current location.protocol to make sure it's
+    //https:
+    var persisted;
+    url = Envjs.urlsplit(url);
+    if(!__cookies__){
+        try{
+            __cookies__ = true;
+            try{
+                persisted = Envjs.loadCookies();
+            }catch(e){
+                //fail gracefully
+                //console.log('%s', e);
+            }   
+            if(persisted){
+                __extend__(Envjs.cookies.persistent, persisted);
+            }
+            //console.log('set cookies for doc %s', doc.baseURI);
+        }catch(e){
+            console.log('cookies not loaded %s', e)
+        };
+    }
+    var temporary = __cookieString__(Envjs.cookies.temporary, url),
+        persistent =  __cookieString__(Envjs.cookies.persistent, url);
+    //console.log('temporary cookies: %s', temporary);  
+    //console.log('persistent cookies: %s', persistent);  
+    return  temporary + persistent;
+};
+
+function __cookieString__(cookies, url) {
+    var cookieString = "",
+        domain, 
+        path,
+        name,
+        i=0;
+    for (domain in cookies) {
+        // check if the cookie is in the current domain (if domain is set)
+        // console.log('cookie domain %s', domain);
+        if (domain == "" || domain == url.hostname) {
+            for (path in cookies[domain]) {
+                // console.log('cookie domain path %s', path);
+                // make sure path is at or below the window location path
+                if (path == "/" || url.path.indexOf(path) > -1) {
+                    for (name in cookies[domain][path]) {
+                        // console.log('cookie domain path name %s', name);
+                        cookieString += 
+                            ((i++ > 0)?'; ':'') +
+                            name + "=" + 
+                            cookies[domain][path][name].value;
+                    }
+                }
+            }
+        }
+    }
+    return cookieString;
+};
+
+function __mergeCookie__(target, cookie, properties){
+    var name, now;
+    if(!target[cookie.domain]){
+        target[cookie.domain] = {};
+    }
+    if(!target[cookie.domain][cookie.path]){
+        target[cookie.domain][cookie.path] = {};
+    }
+    for(name in properties){
+        now = new Date().getTime();
+        target[cookie.domain][cookie.path][name] = {
+            "value":properties[name],
+            "secure":cookie.secure,
+            "max-age":cookie['max-age'],
+            "date-created":now,
+            "expiration":(cookie['max-age']===0) ? 
+                0 :
+                now + cookie['max-age']
+        };
+        //console.log('cookie is %o',target[cookie.domain][cookie.path][name]);
+    }
+};
+
+})();//end cookies
+
+
+Envjs.serializeForm = __formSerialize__;
+/**
+ * Form Submissions
+ *
+ * This code is borrow largely from jquery.params and jquery.form.js
+ *
+ * formToArray() gathers form element data into an array of objects that can
+ * be passed to any of the following ajax functions: $.get, $.post, or load.
+ * Each object in the array has both a 'name' and 'value' property.  An example of
+ * an array for a simple login form might be:
+ *
+ * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
+ *
+ * It is this array that is passed to pre-submit callback functions provided to the
+ * ajaxSubmit() and ajaxForm() methods.
+ *
+ * The semantic argument can be used to force form serialization in semantic order.
+ * This is normally true anyway, unless the form contains input elements of type='image'.
+ * If your form must be submitted with name/value pairs in semantic order and your form
+ * contains an input of type='image" then pass true for this arg, otherwise pass false
+ * (or nothing) to avoid the overhead for this logic.
+ *
+ *
+ * @name formToArray
+ * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
+ * @type Array<Object>
+ */
+function __formToArray__(form, semantic) {
+    var array = [],
+        elements = semantic ? form.getElementsByTagName('*') : form.elements,
+        element,
+        i,j,imax, jmax,
+        name,
+        value;
+
+    if (!elements) {
+        return array;
+    }
+
+    imax = elements.length;
+    for(i=0; i < imax; i++) {
+        element = elements[i];
+        name = element.name;
+        if (!name) {
+            continue;
+        }
+		//console.log('serializing input %s', name);
+        if (semantic && form.clk && element.type === "image") {
+            // handle image inputs on the fly when semantic == true
+            if(!element.disabled && form.clk == element) {
+                array.push({
+                    name: name+'.x',
+                    value: form.clk_x
+                },{
+                    name: name+'.y',
+                    value: form.clk_y
+                });
+            }
+            continue;
+        }
+
+        value = __fieldValue__(element, true);
+		//console.log('input value is %s', value);
+        if (value && value.constructor == Array) {
+            jmax = value.length;
+            for(j=0; j < jmax; j++){
+                array.push({name: name, value: value[j]});
+            }
+        } else if (value !== null && typeof value != 'undefined'){
+			//console.log('serializing form %s %s', name, value);
+            array.push({name: name, value: value});
+        }
+    }
+
+    if (!semantic && form.clk) {
+        // input type=='image' are not found in elements array! handle them here
+        elements = form.getElementsByTagName("input");
+        imax = imax=elements.length;
+        for(i=0; i < imax; i++) {
+            element = elements[i];
+            name = element.name;
+            if(name && !element.disabled && element.type == "image" && form.clk == input) {
+                array.push(
+                    {name: name+'.x', value: form.clk_x},
+                    {name: name+'.y', value: form.clk_y});
+            }
+        }
+    }
+    return array;
+};
+
+
+/**
+ * Serializes form data into a 'submittable' string. This method will return a string
+ * in the format: name1=value1&amp;name2=value2
+ *
+ * The semantic argument can be used to force form serialization in semantic order.
+ * If your form must be submitted with name/value pairs in semantic order then pass
+ * true for this arg, otherwise pass false (or nothing) to avoid the overhead for
+ * this logic (which can be significant for very large forms).
+ *
+ *
+ * @name formSerialize
+ * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
+ * @type String
+ */
+function __formSerialize__(form, semantic) {
+    //hand off to param for proper encoding
+    return __param__(__formToArray__(form, semantic));
+};
+
+
+/**
+ * Serializes all field elements inputs Array into a query string.
+ * This method will return a string in the format: name1=value1&amp;name2=value2
+ *
+ * The successful argument controls whether or not serialization is limited to
+ * 'successful' controls (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
+ * The default value of the successful argument is true.
+ *
+ *
+ * @name fieldSerialize
+ * @param successful true if only successful controls should be serialized (default is true)
+ * @type String
+ */
+function __fieldSerialize__(inputs, successful) {
+    var array = [],
+        input,
+        name,
+        value,
+        i,j, imax, jmax;
+
+    imax = inputs.length;
+    for(i=0; i<imax; i++){
+        input = inputs[i];
+        name = input.name;
+        if (!name) {
+            return '';
+        }
+        value = __fieldValue__(input, successful);
+        if (value && value.constructor == Array) {
+            jmax = value.length;
+            for (j=0; j < jmax; j++){
+                array.push({
+                    name: name,
+                    value: value[j]
+                });
+            }
+        }else if (value !== null && typeof value != 'undefined'){
+            array.push({
+                name: input.name,
+                value: value
+            });
+        }
+    }
+
+    //hand off  for proper encoding
+    return __param__(array);
+};
+
+
+/**
+ * Returns the value(s) of the element in the matched set.  For example, consider the following form:
+ *
+ *
+ * The successful argument controls whether or not the field element must be 'successful'
+ * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
+ * The default value of the successful argument is true.  If this value is false the value(s)
+ * for each element is returned.
+ *
+ * Note: This method *always* returns an array.  If no valid value can be determined the
+ *       array will be empty, otherwise it will contain one or more values.
+ *
+ *
+ * @name fieldValue
+ * @param Boolean successful true if only the values for successful controls
+ *        should be returned (default is true)
+ * @type Array<String>
+ */
+ function __fieldValues__(inputs, successful) {
+    var i,
+        imax = inputs.length,
+        element,
+        values = [],
+        value;
+    for (i=0; i < imax; i++) {
+        element = inputs[i];
+        value = __fieldValue__(element, successful);
+        if (value === null || typeof value == 'undefined' ||
+            (value.constructor == Array && !value.length)) {
+            continue;
+        }
+        if (value.constructor == Array) {
+            Array.prototype.push(values, value);
+        } else {
+            values.push(value);
+        }
+    }
+    return values;
+};
+
+/**
+ * Returns the value of the field element.
+ *
+ * The successful argument controls whether or not the field element must be 'successful'
+ * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
+ * The default value of the successful argument is true.  If the given element is not
+ * successful and the successful arg is not false then the returned value will be null.
+ *
+ * Note: If the successful flag is true (default) but the element is not successful, the return will be null
+ * Note: The value returned for a successful select-multiple element will always be an array.
+ * Note: If the element has no value the return value will be undefined.
+ *
+ * @name fieldValue
+ * @param Element el The DOM element for which the value will be returned
+ * @param Boolean successful true if value returned must be for a successful controls (default is true)
+ * @type String or Array<String> or null or undefined
+ */
+ function __fieldValue__(element, successful) {
+    var name = element.name,
+        type = element.type,
+        tag = element.tagName.toLowerCase(),
+        index,
+        array,
+        options,
+        option,
+        one,
+        i, imax,
+        value;
+
+    if (typeof successful == 'undefined')  {
+        successful = true;
+    }
+
+    if (successful && (!name || element.disabled || type == 'reset' || type == 'button' ||
+             (type == 'checkbox' || type == 'radio') &&  !element.checked ||
+			/*thatcher - submit buttons should count?*/
+             (/*type == 'submit' || */type == 'image') &&
+             element.form && element.form.clk != element || tag === 'select' &&
+             element.selectedIndex === -1)) {
+            return null;
+    }
+
+    if (tag === 'select') {
+        index = element.selectedIndex;
+        if (index < 0) {
+            return null;
+        }
+        array = [];
+        options = element.options;
+        one = (type == 'select-one');
+        imax = (one ? index+1 : options.length);
+        i = (one ? index : 0);
+        for( i; i < imax; i++) {
+            option = options[i];
+            if (option.selected) {
+                value = option.value;
+                if (one) {
+                    return value;
+                }
+                array.push(value);
+            }
+        }
+        return array;
+    }
+    return element.value;
+};
+
+
+/**
+ * Clears the form data.  Takes the following actions on the form's input fields:
+ *  - input text fields will have their 'value' property set to the empty string
+ *  - select elements will have their 'selectedIndex' property set to -1
+ *  - checkbox and radio inputs will have their 'checked' property set to false
+ *  - inputs of type submit, button, reset, and hidden will *not* be effected
+ *  - button elements will *not* be effected
+ *
+ *
+ * @name clearForm
+ */
+ function __clearForm__(form) {
+    var i,
+        j, jmax,
+        elements,
+        resetable = ['input','select','textarea'];
+    for(i=0; i<resetable.length; i++){
+        elements = form.getElementsByTagName(resetable[i]);
+        jmax = elements.length;
+        for(j=0;j<jmax;j++){
+            __clearField__(elements[j]);
+        }
+    }
+};
+
+/**
+ * Clears the selected form element.  Takes the following actions on the element:
+ *  - input text fields will have their 'value' property set to the empty string
+ *  - select elements will have their 'selectedIndex' property set to -1
+ *  - checkbox and radio inputs will have their 'checked' property set to false
+ *  - inputs of type submit, button, reset, and hidden will *not* be effected
+ *  - button elements will *not* be effected
+ *
+ * @name clearFields
+ */
+ function __clearField__(element) {
+    var type = element.type,
+        tag = element.tagName.toLowerCase();
+    if (type == 'text' || type == 'password' || tag === 'textarea') {
+        element.value = '';
+    } else if (type == 'checkbox' || type == 'radio') {
+        element.checked = false;
+    } else if (tag === 'select') {
+        element.selectedIndex = -1;
+    }
+};
+
+
+// Serialize an array of key/values into a query string
+function __param__( array ) {
+    var i, serialized = [];
+
+    // Serialize the key/values
+    for(i=0; i<array.length; i++){
+        serialized[ serialized.length ] =
+            encodeURIComponent(array[i].name) + '=' +
+            encodeURIComponent(array[i].value);
+    }
+
+    // Return the resulting serialization
+    return serialized.join("&").replace(/%20/g, "+");
+};
+/*
+    http://www.JSON.org/json2.js
+    2008-07-15
+
+    Public Domain.
+
+    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+    See http://www.JSON.org/js.html
+
+   
+    This code should be minified before deployment.
+    See http://javascript.crockford.com/jsmin.html
+
+    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+    NOT CONTROL.
+*/
+try{ JSON; }catch(e){ 
+JSON = function () {
+
+    function f(n) {
+        // Format integers to have at least two digits.
+        return n < 10 ? '0' + n : n;
+    }
+
+    Date.prototype.toJSON = function (key) {
+
+        return this.getUTCFullYear()   + '-' +
+             f(this.getUTCMonth() + 1) + '-' +
+             f(this.getUTCDate())      + 'T' +
+             f(this.getUTCHours())     + ':' +
+             f(this.getUTCMinutes())   + ':' +
+             f(this.getUTCSeconds())   + 'Z';
+    };
+
+    String.prototype.toJSON = function (key) {
+        return String(this);
+    };
+    Number.prototype.toJSON =
+    Boolean.prototype.toJSON = function (key) {
+        return this.valueOf();
+    };
+
+    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        escapeable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        gap,
+        indent,
+        meta = {    // table of character substitutions
+            '\b': '\\b',
+            '\t': '\\t',
+            '\n': '\\n',
+            '\f': '\\f',
+            '\r': '\\r',
+            '"' : '\\"',
+            '\\': '\\\\'
+        },
+        rep;
+
+
+    function quote(string) {
+        
+        escapeable.lastIndex = 0;
+        return escapeable.test(string) ?
+            '"' + string.replace(escapeable, function (a) {
+                var c = meta[a];
+                if (typeof c === 'string') {
+                    return c;
+                }
+                return '\\u' + ('0000' +
+                        (+(a.charCodeAt(0))).toString(16)).slice(-4);
+            }) + '"' :
+            '"' + string + '"';
+    }
+
+
+    function str(key, holder) {
+
+        var i,          // The loop counter.
+            k,          // The member key.
+            v,          // The member value.
+            length,
+            mind = gap,
+            partial,
+            value = holder[key];
+
+        if (value && typeof value === 'object' &&
+                typeof value.toJSON === 'function') {
+            value = value.toJSON(key);
+        }
+        if (typeof rep === 'function') {
+            value = rep.call(holder, key, value);
+        }
+
+        switch (typeof value) {
+        case 'string':
+            return quote(value);
+
+        case 'number':
+            return isFinite(value) ? String(value) : 'null';
+
+        case 'boolean':
+        case 'null':
+
+            return String(value);
+            
+        case 'object':
+
+            if (!value) {
+                return 'null';
+            }
+            gap += indent;
+            partial = [];
+
+            if (typeof value.length === 'number' &&
+                    !(value.propertyIsEnumerable('length'))) {
+
+                length = value.length;
+                for (i = 0; i < length; i += 1) {
+                    partial[i] = str(i, value) || 'null';
+                }
+                
+                v = partial.length === 0 ? '[]' :
+                    gap ? '[\n' + gap +
+                            partial.join(',\n' + gap) + '\n' +
+                                mind + ']' :
+                          '[' + partial.join(',') + ']';
+                gap = mind;
+                return v;
+            }
+
+            if (rep && typeof rep === 'object') {
+                length = rep.length;
+                for (i = 0; i < length; i += 1) {
+                    k = rep[i];
+                    if (typeof k === 'string') {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            } else {
+
+                for (k in value) {
+                    if (Object.hasOwnProperty.call(value, k)) {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            }
+
+            v = partial.length === 0 ? '{}' :
+                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+                        mind + '}' : '{' + partial.join(',') + '}';
+            gap = mind;
+            return v;
+        }
+    }
+
+    return {
+        stringify: function (value, replacer, space) {
+
+            var i;
+            gap = '';
+            indent = '';
+
+            if (typeof space === 'number') {
+                for (i = 0; i < space; i += 1) {
+                    indent += ' ';
+                }
+
+            } else if (typeof space === 'string') {
+                indent = space;
+            }
+
+            rep = replacer;
+            if (replacer && typeof replacer !== 'function' &&
+                    (typeof replacer !== 'object' ||
+                     typeof replacer.length !== 'number')) {
+                throw new Error('JSON.stringify');
+            }
+
+            return str('', {'': value});
+        },
+
+
+        parse: function (text, reviver) {
+            var j;
+            function walk(holder, key) {
+                var k, v, value = holder[key];
+                if (value && typeof value === 'object') {
+                    for (k in value) {
+                        if (Object.hasOwnProperty.call(value, k)) {
+                            v = walk(value, k);
+                            if (v !== undefined) {
+                                value[k] = v;
+                            } else {
+                                delete value[k];
+                            }
+                        }
+                    }
+                }
+                return reviver.call(holder, key, value);
+            }
+
+            cx.lastIndex = 0;
+            if (cx.test(text)) {
+                text = text.replace(cx, function (a) {
+                    return '\\u' + ('0000' +
+                            (+(a.charCodeAt(0))).toString(16)).slice(-4);
+                });
+            }
+
+
+            if (/^[\],:{}\s]*$/.
+test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
+replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
+replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+        
+                j = eval('(' + text + ')');
+
+                return typeof reviver === 'function' ?
+                    walk({'': j}, '') : j;
+            }
+
+            throw new SyntaxError('JSON.parse');
+        }
+    };
+}();
+
+}
+
+/**
+ * synchronizes thread modifications
+ * @param {Function} fn
+ */
+Envjs.sync = function(fn){};
+
+/**
+ * sleep thread for specified duration
+ * @param {Object} millseconds
+ */
+Envjs.sleep = function(millseconds){};
+
+/**
+ * Interval to wait on event loop when nothing is happening
+ */
+Envjs.WAIT_INTERVAL = 100;//milliseconds
+
+/*
+ * Copyright (c) 2010 Nick Galbreath
+ * http://code.google.com/p/stringencoders/source/browse/#svn/trunk/javascript
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * url processing in the spirit of python's urlparse module
+ * see `pydoc urlparse` or
+ * http://docs.python.org/library/urlparse.html
+ *
+ *  urlsplit: break apart a URL into components
+ *  urlunsplit:  reconsistute a URL from componets
+ *  urljoin: join an absolute and another URL
+ *  urldefrag: remove the fragment from a URL
+ *
+ * Take a look at the tests in urlparse-test.html
+ *
+ * On URL Normalization:
+ *
+ * urlsplit only does minor normalization the components Only scheme
+ * and hostname are lowercased urljoin does a bit more, normalizing
+ * paths with "."  and "..".
+
+ * urlnormalize adds additional normalization
+ *
+ *   * removes default port numbers
+ *     http://abc.com:80/ -> http://abc.com/, etc
+ *   * normalizes path
+ *     http://abc.com -> http://abc.com/
+ *     and other "." and ".." cleanups
+ *   * if file, remove query and fragment
+ *
+ * It does not do:
+ *   * normalizes escaped hex values
+ *     http://abc.com/%7efoo -> http://abc.com/%7Efoo
+ *   * normalize '+' <--> '%20'
+ *
+ * Differences with Python
+ *
+ * The javascript urlsplit returns a normal object with the following
+ * properties: scheme, netloc, hostname, port, path, query, fragment.
+ * All properties are read-write.
+ *
+ * In python, the resulting object is not a dict, but a specialized,
+ * read-only, and has alternative tuple interface (e.g. obj[0] ==
+ * obj.scheme).  It's not clear why such a simple function requires
+ * a unique datastructure.
+ *
+ * urlunsplit in javascript takes an duck-typed object,
+ *  { scheme: 'http', netloc: 'abc.com', ...}
+ *  while in  * python it takes a list-like object.
+ *  ['http', 'abc.com'... ]
+ *
+ * For all functions, the javascript version use
+ * hostname+port if netloc is missing.  In python
+ * hostname+port were always ignored.
+ *
+ * Similar functionality in different languages:
+ *
+ *   http://php.net/manual/en/function.parse-url.php
+ *   returns assocative array but cannot handle relative URL
+ *
+ * TODO: test allowfragments more
+ * TODO: test netloc missing, but hostname present
+ */
+
+var urlparse = {};
+
+// Unlike to be useful standalone
+//
+// NORMALIZE PATH with "../" and "./"
+//   http://en.wikipedia.org/wiki/URL_normalization
+//   http://tools.ietf.org/html/rfc3986#section-5.2.3
+//
+urlparse.normalizepath = function(path)
+{
+    if (!path || path === '/') {
+        return '/';
+    }
+
+    var parts = path.split('/');
+
+    var newparts = [];
+    // make sure path always starts with '/'
+    if (parts[0]) {
+        newparts.push('');
+    }
+
+    for (var i = 0; i < parts.length; ++i) {
+        if (parts[i] === '..') {
+            if (newparts.length > 1) {
+                newparts.pop();
+            } else {
+                newparts.push(parts[i]);
+            }
+        } else if (parts[i] != '.') {
+            newparts.push(parts[i]);
+        }
+    }
+
+    path = newparts.join('/');
+    if (!path) {
+        path = '/';
+    }
+    return path;
+};
+
+//
+// Does many of the normalizations that the stock
+//  python urlsplit/urlunsplit/urljoin neglects
+//
+// Doesn't do hex-escape normalization on path or query
+//   %7e -> %7E
+// Nor, '+' <--> %20 translation
+//
+urlparse.urlnormalize = function(url)
+{
+    var parts = urlparse.urlsplit(url);
+    switch (parts.scheme) {
+    case 'file':
+        // files can't have query strings
+        //  and we don't bother with fragments
+        parts.query = '';
+        parts.fragment = '';
+        break;
+    case 'http':
+    case 'https':
+        // remove default port
+        if ((parts.scheme === 'http' && parts.port == 80) ||
+            (parts.scheme === 'https' && parts.port == 443)) {
+            parts.port = null;
+            // hostname is already lower case
+            parts.netloc = parts.hostname;
+        }
+        break;
+    default:
+        // if we don't have specific normalizations for this
+        // scheme, return the original url unmolested
+        return url;
+    }
+
+    // for [file|http|https].  Not sure about other schemes
+    parts.path = urlparse.normalizepath(parts.path);
+
+    return urlparse.urlunsplit(parts);
+};
+
+urlparse.urldefrag = function(url)
+{
+    var idx = url.indexOf('#');
+    if (idx == -1) {
+        return [ url, '' ];
+    } else {
+        return [ url.substr(0,idx), url.substr(idx+1) ];
+    }
+};
+
+urlparse.urlsplit = function(url, default_scheme, allow_fragments)
+{
+    var leftover;
+
+    if (typeof allow_fragments === 'undefined') {
+        allow_fragments = true;
+    }
+
+    // scheme (optional), host, port
+    var fullurl = /^([A-Za-z]+)?(:?\/\/)([0-9.\-A-Za-z]*)(?::(\d+))?(.*)$/;
+    // path, query, fragment
+    var parse_leftovers = /([^?#]*)?(?:\?([^#]*))?(?:#(.*))?$/;
+
+    var o = {};
+
+    var parts = url.match(fullurl);
+    if (parts) {
+        o.scheme = parts[1] || default_scheme || '';
+        o.hostname = parts[3].toLowerCase() || '';
+        o.port = parseInt(parts[4],10) || '';
+        // Probably should grab the netloc from regexp
+        //  and then parse again for hostname/port
+
+        o.netloc = parts[3];
+        if (parts[4]) {
+            o.netloc += ':' + parts[4];
+        }
+
+        leftover = parts[5];
+    } else {
+        o.scheme = default_scheme || '';
+        o.netloc = '';
+        o.hostname = '';
+        leftover = url;
+    }
+    o.scheme = o.scheme.toLowerCase();
+
+    parts = leftover.match(parse_leftovers);
+
+    o.path =  parts[1] || '';
+    o.query = parts[2] || '';
+
+    if (allow_fragments) {
+        o.fragment = parts[3] || '';
+    } else {
+        o.fragment = '';
+    }
+
+    return o;
+};
+
+urlparse.urlunsplit = function(o) {
+    var s = '';
+    if (o.scheme) {
+        s += o.scheme + '://';
+    }
+
+    if (o.netloc) {
+        if (s == '') {
+            s += '//';
+        }
+        s +=  o.netloc;
+    } else if (o.hostname) {
+        // extension.  Python only uses netloc
+        if (s == '') {
+            s += '//';
+        }
+        s += o.hostname;
+        if (o.port) {
+            s += ':' + o.port;
+        }
+    }
+
+    if (o.path) {
+        s += o.path;
+    }
+
+    if (o.query) {
+        s += '?' + o.query;
+    }
+    if (o.fragment) {
+        s += '#' + o.fragment;
+    }
+    return s;
+};
+
+urlparse.urljoin = function(base, url, allow_fragments)
+{
+    if (typeof allow_fragments === 'undefined') {
+        allow_fragments = true;
+    }
+
+    var url_parts = urlparse.urlsplit(url);
+
+    // if url parts has a scheme (i.e. absolute)
+    // then nothing to do
+    if (url_parts.scheme) {
+        if (! allow_fragments) {
+            return url;
+        } else {
+            return urlparse.urldefrag(url)[0];
+        }
+    }
+    var base_parts = urlparse.urlsplit(base);
+
+    // copy base, only if not present
+    if (!base_parts.scheme) {
+        base_parts.scheme = url_parts.scheme;
+    }
+
+    // copy netloc, only if not present
+    if (!base_parts.netloc || !base_parts.hostname) {
+        base_parts.netloc = url_parts.netloc;
+        base_parts.hostname = url_parts.hostname;
+        base_parts.port = url_parts.port;
+    }
+
+    // paths
+    if (url_parts.path.length > 0) {
+        if (url_parts.path.charAt(0) == '/') {
+            base_parts.path = url_parts.path;
+        } else {
+            // relative path.. get rid of "current filename" and
+            //   replace.  Same as var parts =
+            //   base_parts.path.split('/'); parts[parts.length-1] =
+            //   url_parts.path; base_parts.path = parts.join('/');
+            var idx = base_parts.path.lastIndexOf('/');
+            if (idx == -1) {
+                base_parts.path = url_parts.path;
+            } else {
+                base_parts.path = base_parts.path.substr(0,idx) + '/' +
+                    url_parts.path;
+            }
+        }
+    }
+
+    // clean up path
+    base_parts.path = urlparse.normalizepath(base_parts.path);
+
+    // copy query string
+    base_parts.query = url_parts.query;
+
+    // copy fragments
+    if (allow_fragments) {
+        base_parts.fragment = url_parts.fragment;
+    } else {
+        base_parts.fragment = '';
+    }
+
+    return urlparse.urlunsplit(base_parts);
+};
+
+/**
+ * getcwd - named after posix call of same name (see 'man 2 getcwd')
+ *
+ */
+Envjs.getcwd = function() {
+    return '.';
+};
+
+/**
+ * resolves location relative to doc location
+ *
+ * @param {Object} path  Relative or absolute URL
+ * @param {Object} base  (semi-optional)  The base url used in resolving "path" above
+ */
+Envjs.uri = function(path, base) {
+	path = path.replace(/\\/g, '/');
+    //console.log('constructing uri from path %s and base %s', path, base);
+
+    // Semi-common trick is to make an iframe with src='javascript:false'
+    //  (or some equivalent).  By returning '', the load is skipped
+    if (path.indexOf('javascript:') === 0) {
+        return '';
+    }
+
+    // if path is absolute, then just normalize and return
+    if (path.match('^[a-zA-Z]+://')) {
+        return urlparse.urlnormalize(path);
+    }
+
+    // if path is a Windows style absolute path (C:\foo\bar\index.html)
+	// make it a file: URL
+    if (path.match('^[a-zA-Z]+:/')) {
+        return 'file:///' + urlparse.urlnormalize(path);
+    }
+
+    // interesting special case, a few very large websites use
+    // '//foo/bar/' to mean 'http://foo/bar'
+    if (path.match('^//')) {
+        path = 'http:' + path;
+    }
+
+    // if base not passed in, try to get it from document
+    // Ideally I would like the caller to pass in document.baseURI to
+    //  make this more self-sufficient and testable
+    if (!base && document) {
+        base = document.baseURI;
+    }
+
+    // about:blank doesn't count
+    if (base === 'about:blank'){
+        base = '';
+    }
+
+    // if base is still empty, then we are in QA mode loading local
+    // files.  Get current working directory
+    if (!base) {
+        base = 'file:///' + (""+Envjs.getcwd()).replace(/\\/g, '/') + '/';
+    }
+    // handles all cases if path is abosulte or relative to base
+    // 3rd arg is "false" --> remove fragments
+    var newurl = urlparse.urlnormalize(urlparse.urljoin(base, path, false));
+	//console.log('uri %s %s = %s', base, path, newurl);
+    return newurl;
+};
+
+
+
+/**
+ * Used in the XMLHttpRquest implementation to run a
+ * request in a seperate thread
+ * @param {Object} fn
+ */
+Envjs.runAsync = function(fn){};
+
+
+/**
+ * Used to write to a local file
+ * @param {Object} text
+ * @param {Object} url
+ */
+Envjs.writeToFile = function(text, url){};
+
+
+/**
+ * Used to write to a local file
+ * @param {Object} text
+ * @param {Object} suffix
+ */
+Envjs.writeToTempFile = function(text, suffix){};
+
+/**
+ * Used to read the contents of a local file
+ * @param {Object} url
+ */
+Envjs.readFromFile = function(url){};
+
+/**
+ * Used to delete a local file
+ * @param {Object} url
+ */
+Envjs.deleteFile = function(url){};
+
+/**
+ * establishes connection and calls responsehandler
+ * @param {Object} xhr
+ * @param {Object} responseHandler
+ * @param {Object} data
+ */
+Envjs.connection = function(xhr, responseHandler, data){};
+
+
+__extend__(Envjs, urlparse);
+/**
+ * Makes an object window-like by proxying object accessors
+ * @param {Object} scope
+ * @param {Object} parent
+ */
+Envjs.proxy = function(scope, parent, aliasList){
+    return (function(){return this;})();
+};
+
+Envjs.javaEnabled = false;
+
+Envjs.homedir        = '';
+Envjs.tmpdir         = '';
+Envjs.os_name        = '';
+Envjs.os_arch        = '';
+Envjs.os_version     = '';
+Envjs.lang           = '';
+Envjs.platform       = '';
+
+//some common user agents as constants so you can emulate them
+Envjs.userAgents = {
+	firefox3: 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.7) Gecko/2009021910 Firefox/3.0.7'
+}
+
+var __windows__ = {};
+
+Envjs.windows = function(uuid, scope){
+	var w;
+	if(arguments.length === 0){
+		/*for(w in __windows__){
+			console.log('window uuid => %s', w);
+			console.log('window document => %s', __windows__[w].document.baseURI);
+		}*/
+		return __windows__;
+	}else if(arguments.length === 1){
+		return (uuid in __windows__) ? __windows__[uuid] : null
+	}else if(arguments.length === 2){
+		__windows__[uuid] = scope;
+		if(scope === null){
+            delete __windows__[uuid];
+		}
+	}
+};
+/**
+ *
+ * @param {Object} frameElement
+ * @param {Object} url
+ */
+Envjs.loadFrame = function(frame, url){	
+    try {
+        //console.log('loading frame %s', url);
+        if(frame.contentWindow && frame.contentWindow.close){
+            //mark for garbage collection
+            frame.contentWindow.close();
+        }
+
+        //create a new scope for the window proxy
+        //platforms will need to override this function
+        //to make sure the scope is global-like
+        frame.contentWindow = Envjs.proxy({});
+		//console.log("frame.ownerDocument %s subframe %s", 
+		//	frame.ownerDocument.location,
+		//	frame.ownerDocument.__ownerFrame__);
+		if(frame.ownerDocument&&frame.ownerDocument.__ownerFrame__){
+			//console.log('frame is parent %s', frame.ownerDocument.__ownerFrame__.contentWindow.guid);
+			new Window(frame.contentWindow, frame.ownerDocument.__ownerFrame__.contentWindow);
+		}else{
+			//console.log("window is parent %s", window.guid);
+			new Window(frame.contentWindow, window);
+		}
+
+        //I dont think frames load asynchronously in firefox
+        //and I think the tests have verified this but for
+        //some reason I'm less than confident... Are there cases?
+        frame.contentDocument = frame.contentWindow.document;
+        frame.contentDocument.async = false;
+        frame.contentDocument.__ownerFrame__ = frame;
+        if(url){
+            //console.log('envjs.loadFrame async %s', frame.contentDocument.async);
+            frame.contentDocument.location.assign(Envjs.uri(url, frame.ownerDocument.location.toString()));
+        }
+    } catch(e) {
+        console.log("failed to load frame content: from %s %s", url, e);
+    }
+};
+
+
+/**
+ * unloadFrame
+ * @param {Object} frame
+ */
+Envjs.unloadFrame = function(frame){
+    var all, length, i;
+    try{
+        //TODO: probably self-referencing structures within a document tree
+        //preventing it from being entirely garbage collected once orphaned.
+        //Should have code to walk tree and break all links between contained
+        //objects.
+        frame.contentDocument = null;
+        if(frame.contentWindow){
+			//console.log('closing window %s', frame.contentWindow);
+            frame.contentWindow.close();
+        }
+        Envjs.gc();
+    }catch(e){
+        console.log(e);
+    }
+};
+
+/**
+ * Platform clean up hook if it ever makes sense - see Envjs.unloadFrame for example
+ */
+Envjs.gc = function(){};
+/**
+ * @author john resig & the envjs team
+ * @uri http://www.envjs.com/
+ * @copyright 2008-2010
+ * @license MIT
+ */
+//CLOSURE_END
+}());
+/*
+ * Envjs rhino-env.1.2.35
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ */
+
+__context__ = Packages.org.mozilla.javascript.Context.getCurrentContext();
+
+Envjs.platform       = "Rhino";
+Envjs.revision       = "1.7.0.rc2";
+
+/*
+ * Envjs rhino-env.1.2.35 
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ */
+
+//CLOSURE_START
+(function(){
+
+
+
+
+
+/**
+ * @author john resig
+ */
+// Helper method for extending one object with another.
+function __extend__(a,b) {
+    for ( var i in b ) {
+        var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
+        if ( g || s ) {
+            if ( g ) { a.__defineGetter__(i, g); }
+            if ( s ) { a.__defineSetter__(i, s); }
+        } else {
+            a[i] = b[i];
+        }
+    } return a;
+}
+
+/**
+ * Writes message to system out.
+ *
+ * Some sites redefine 'print' as in 'window.print', so instead of
+ * printing to stdout, you are popping open a new window, which might
+ * call print, etc, etc,etc This can cause infinite loops and can
+ * exhausing all memory.
+ *
+ * By defining this upfront now, Envjs.log will always call the native 'print'
+ * function
+ *
+ * @param {Object} message
+ */
+Envjs.log = print;
+
+Envjs.lineSource = function(e){
+    return e&&e.rhinoException?e.rhinoException.lineSource():"(line ?)";
+};
+Envjs.eval = function(context, source, name){
+    __context__.evaluateString(
+        context,
+        source,
+        name,
+        0,
+        null
+    );
+};
+Envjs.renderSVG = function(svgstring, url){
+    //console.log("svg template url %s", templateSVG);
+    // Create a JPEG transcoder
+    var t = new Packages.org.apache.batik.transcoder.image.JPEGTranscoder();
+
+    // Set the transcoding hints.
+    t.addTranscodingHint(
+        Packages.org.apache.batik.transcoder.image.JPEGTranscoder.KEY_QUALITY,
+        new java.lang.Float(1.0));
+    // Create the transcoder input.
+    var input = new Packages.org.apache.batik.transcoder.TranscoderInput(
+        new java.io.StringReader(svgstring));
+
+    // Create the transcoder output.
+    var ostream = new java.io.ByteArrayOutputStream();
+    var output = new Packages.org.apache.batik.transcoder.TranscoderOutput(ostream);
+
+    // Save the image.
+    t.transcode(input, output);
+
+    // Flush and close the stream.
+    ostream.flush();
+    ostream.close();
+    
+	var out = new java.io.FileOutputStream(new java.io.File(new java.net.URI(url.toString())));
+	try{
+    	out.write( ostream.toByteArray() );
+	}catch(e){
+		
+	}finally{
+    	out.flush();
+    	out.close();
+    }
+};
+//Temporary patch for parser module
+Packages.org.mozilla.javascript.Context.
+    getCurrentContext().setOptimizationLevel(-1);
+
+Envjs.shell = new Packages.java.util.Scanner(Packages.java.lang.System['in']);
+/**
+ * Rhino provides a very succinct 'sync'
+ * @param {Function} fn
+ */
+try{
+    Envjs.sync = sync;
+    Envjs.spawn = spawn;
+} catch(e){
+    //sync unavailable on AppEngine
+    Envjs.sync = function(fn){
+        //console.log('Threadless platform, sync is safe');
+        return fn;
+    };
+
+    Envjs.spawn = function(fn){
+        //console.log('Threadless platform, spawn shares main thread.');
+        return fn();
+    };
+}
+
+/**
+ * sleep thread for specified duration
+ * @param {Object} millseconds
+ */
+Envjs.sleep = function(millseconds){
+    try{
+        java.lang.Thread.currentThread().sleep(millseconds);
+    }catch(e){
+        console.log('Threadless platform, cannot sleep.');
+    }
+};
+
+/**
+ * provides callback hook for when the system exits
+ */
+Envjs.onExit = function(callback){
+    var rhino = Packages.org.mozilla.javascript,
+        contextFactory =  __context__.getFactory(),
+        listener = new rhino.ContextFactory.Listener({
+            contextReleased: function(context){
+                if(context === __context__)
+                    console.log('context released', context);
+                contextFactory.removeListener(this);
+                if(callback)
+                    callback();
+            }
+        });
+    contextFactory.addListener(listener);
+};
+
+/**
+ * Get 'Current Working Directory'
+ */
+Envjs.getcwd = function() {
+    return java.lang.System.getProperty('user.dir');
+}
+
+/**
+ *
+ * @param {Object} fn
+ * @param {Object} onInterupt
+ */
+Envjs.runAsync = function(fn, onInterupt){
+    ////Envjs.debug("running async");
+    var running = true,
+        run;
+
+    try{
+        run = Envjs.sync(function(){
+            fn();
+            Envjs.wait();
+        });
+        Envjs.spawn(run);
+    }catch(e){
+        console.log("error while running async operation", e);
+        try{if(onInterrupt)onInterrupt(e)}catch(ee){};
+    }
+};
+
+/**
+ * Used to write to a local file
+ * @param {Object} text
+ * @param {Object} url
+ */
+Envjs.writeToFile = function(text, url){
+    //Envjs.debug("writing text to url : " + url);
+    var out = new java.io.FileWriter(
+        new java.io.File(
+            new java.net.URI(url.toString())));
+    out.write( text, 0, text.length );
+    out.flush();
+    out.close();
+};
+
+/**
+ * Used to write to a local file
+ * @param {Object} text
+ * @param {Object} suffix
+ */
+Envjs.writeToTempFile = function(text, suffix){
+    //Envjs.debug("writing text to temp url : " + suffix);
+    // Create temp file.
+    var temp = java.io.File.createTempFile("envjs-tmp", suffix);
+
+    // Delete temp file when program exits.
+    temp.deleteOnExit();
+
+    // Write to temp file
+    var out = new java.io.FileWriter(temp);
+    out.write(text, 0, text.length);
+    out.close();
+    return temp.getAbsolutePath().toString()+'';
+};
+
+
+/**
+ * Used to read the contents of a local file
+ * @param {Object} url
+ */
+Envjs.readFromFile = function( url ){
+    var fileReader = new java.io.FileReader(
+        new java.io.File( 
+            new java.net.URI( url )));
+            
+    var stringwriter = new java.io.StringWriter(),
+        buffer = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 1024),
+        length;
+
+    while ((length = fileReader.read(buffer, 0, 1024)) != -1) {
+        stringwriter.write(buffer, 0, length);
+    }
+
+    stringwriter.close();
+    return stringwriter.toString()+"";
+};
+    
+
+/**
+ * Used to delete a local file
+ * @param {Object} url
+ */
+Envjs.deleteFile = function(url){
+    var file = new java.io.File( new java.net.URI( url ) );
+    file["delete"]();
+};
+
+/**
+ * establishes connection and calls responsehandler
+ * @param {Object} xhr
+ * @param {Object} responseHandler
+ * @param {Object} data
+ */
+Envjs.connection = function(xhr, responseHandler, data){
+    var url = java.net.URL(xhr.url),
+        connection,
+        header,
+        outstream,
+        buffer,
+        length,
+        binary = false,
+        name, value,
+        contentEncoding,
+        instream,
+        responseXML,
+        i;
+    
+        
+    if ( /^file\:/.test(url) ) {
+        try{
+            if ( "PUT" == xhr.method || "POST" == xhr.method ) {
+                data =  data || "" ;
+                Envjs.writeToFile(data, url);
+                xhr.readyState = 4;
+                //could be improved, I just cant recall the correct http codes
+                xhr.status = 200;
+                xhr.statusText = "";
+            } else if ( xhr.method == "DELETE" ) {
+                Envjs.deleteFile(url);
+                xhr.readyState = 4;
+                //could be improved, I just cant recall the correct http codes
+                xhr.status = 200;
+                xhr.statusText = "";
+            } else {
+                //try to add some canned headers that make sense
+                xhr.readyState = 4;
+                xhr.statusText = "ok";
+                xhr.responseText = Envjs.readFromFile(xhr.url);
+                try{
+                    if(xhr.url.match(/html$/)){
+                        xhr.responseHeaders["Content-Type"] = 'text/html';
+                    }else if(xhr.url.match(/.xml$/)){
+                        xhr.responseHeaders["Content-Type"] = 'text/xml';
+                    }else if(xhr.url.match(/.js$/)){
+                        xhr.responseHeaders["Content-Type"] = 'text/javascript';
+                    }else if(xhr.url.match(/.json$/)){
+                        xhr.responseHeaders["Content-Type"] = 'application/json';
+                    }else{
+                        xhr.responseHeaders["Content-Type"] = 'text/plain';
+                    }
+                    //xhr.responseHeaders['Last-Modified'] = connection.getLastModified();
+                    //xhr.responseHeaders['Content-Length'] = headerValue+'';
+                    //xhr.responseHeaders['Date'] = new Date()+'';*/
+                }catch(e){
+                    console.log('failed to load response headers',e);
+                }
+            }
+        }catch(e){
+            console.log('failed to open file %s %s', url, e);
+            connection = null;
+            xhr.readyState = 4;
+            xhr.statusText = "Local File Protocol Error";
+            xhr.responseText = "<html><head/><body><p>"+ e+ "</p></body></html>";
+        }
+    } else {
+        connection = url.openConnection();
+        //handle redirects manually since cookie support sucks out of the box
+        connection.setFollowRedirects(false);
+        connection.setRequestMethod( xhr.method );
+
+        // Add headers to Java connection
+        for (header in xhr.headers){
+            connection.addRequestProperty(header+'', xhr.headers[header]+'');
+        }
+        connection.addRequestProperty("Accept-Encoding", 'gzip');
+        connection.addRequestProperty("Agent", 'gzip');
+
+        //write data to output stream if required
+        if(data){
+            if(data instanceof Document){
+                if ( xhr.method == "PUT" || xhr.method == "POST" ) {
+                    connection.setDoOutput(true);
+                    outstream = connection.getOutputStream(),
+                    xml = (new XMLSerializer()).serializeToString(data);
+                    buffer = new java.lang.String(xml).getBytes('UTF-8');
+                    outstream.write(buffer, 0, buffer.length);
+                    outstream.close();
+                }
+            }else if(data.length&&data.length>0){
+                if ( xhr.method == "PUT" || xhr.method == "POST" ) {
+                    connection.setDoOutput(true);
+                    outstream = connection.getOutputStream();
+                    buffer = new java.lang.String(data).getBytes('UTF-8');
+                    outstream.write(buffer, 0, buffer.length);
+                    outstream.close();
+                }
+            }
+            connection.connect();
+        }else{
+            connection.connect();
+        }
+    }
+
+    if(connection){
+        try{
+            length = connection.getHeaderFields().size();
+            // Stick the response headers into responseHeaders
+            for (i = 0; i < length; i++) {
+                name = connection.getHeaderFieldKey(i);
+                value = connection.getHeaderField(i);
+                if (name)
+                    xhr.responseHeaders[name+''] = value+'';
+            }
+        }catch(e){
+            console.log('failed to load response headers \n%s',e);
+        }
+
+        xhr.readyState = 4;
+        xhr.status = parseInt(connection.responseCode,10) || undefined;
+        xhr.statusText = connection.responseMessage || "";
+
+        contentEncoding = connection.getContentEncoding() || "utf-8";
+        instream = null;
+        responseXML = null;
+        
+        try{
+            //console.log('contentEncoding %s', contentEncoding);
+            if( contentEncoding.equalsIgnoreCase("gzip") ||
+                contentEncoding.equalsIgnoreCase("decompress")){
+                //zipped content
+                binary = true;
+                outstream = new java.io.ByteArrayOutputStream();
+                buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 1024);
+                instream = new java.util.zip.GZIPInputStream(connection.getInputStream())
+            }else{
+                //this is a text file
+                outstream = new java.io.StringWriter();
+                buffer = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 1024);
+                instream = new java.io.InputStreamReader(connection.getInputStream());
+            }
+        }catch(e){
+            if (connection.getResponseCode() == 404){
+                console.log('failed to open connection stream \n %s %s',
+                            e.toString(), e);
+            }else{
+                console.log('failed to open connection stream \n %s %s',
+                            e.toString(), e);
+            }
+            instream = connection.getErrorStream();
+        }
+
+        while ((length = instream.read(buffer, 0, 1024)) != -1) {
+            outstream.write(buffer, 0, length);
+        }
+
+        outstream.close();
+        instream.close();
+        
+        if(binary){
+            xhr.responseText = new java.lang.String(outstream.toByteArray(), 'UTF-8')+'';
+        }else{
+            xhr.responseText = outstream.toString()+'';
+        }
+
+    }
+    if(responseHandler){
+        //Envjs.debug('calling ajax response handler');
+        responseHandler();
+    }
+};
+
+//Since we're running in rhino I guess we can safely assume
+//java is 'enabled'.  I'm sure this requires more thought
+//than I've given it here
+Envjs.javaEnabled = true;
+
+Envjs.homedir        = java.lang.System.getProperty("user.home");
+Envjs.tmpdir         = java.lang.System.getProperty("java.io.tmpdir");
+Envjs.os_name        = java.lang.System.getProperty("os.name");
+Envjs.os_arch        = java.lang.System.getProperty("os.arch");
+Envjs.os_version     = java.lang.System.getProperty("os.version");
+Envjs.lang           = java.lang.System.getProperty("user.lang");
+
+
+Envjs.gc = function(){ gc(); };
+
+/**
+ * Makes an object window-like by proxying object accessors
+ * @param {Object} scope
+ * @param {Object} parent
+ */
+Envjs.proxy = function(scope, parent) {
+    try{
+        if(scope+'' == '[object global]'){
+            return scope
+        }else{
+            return  __context__.initStandardObjects();
+        }
+    }catch(e){
+        console.log('failed to init standard objects %s %s \n%s', scope, parent, e);
+    }
+
+};
+
+/**
+ * @author john resig & the envjs team
+ * @uri http://www.envjs.com/
+ * @copyright 2008-2010
+ * @license MIT
+ */
+//CLOSURE_END
+}());
+
+/**
+ * @author envjs team
+ */
+/*var Console,
+    console;*/
+
+/*
+ * Envjs console.1.2.35 
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ */
+
+//CLOSURE_START
+(function(){
+
+
+
+
+
+/**
+ * @author envjs team
+ * borrowed 99%-ish with love from firebug-lite
+ *
+ * http://wiki.commonjs.org/wiki/Console
+ */
+Console = function(module){
+    var $level,
+    $logger,
+    $null = function(){};
+
+
+    if(Envjs[module] && Envjs[module].loglevel){
+        $level = Envjs.module.loglevel;
+        $logger = {
+            log: function(level){
+                logFormatted(arguments, (module)+" ");
+            },
+            debug: $level>1 ? $null: function() {
+                logFormatted(arguments, (module)+" debug");
+            },
+            info: $level>2 ? $null:function(){
+                logFormatted(arguments, (module)+" info");
+            },
+            warn: $level>3 ? $null:function(){
+                logFormatted(arguments, (module)+" warning");
+            },
+            error: $level>4 ? $null:function(){
+                logFormatted(arguments, (module)+" error");
+            }
+        };
+    } else {
+        $logger = {
+            log: function(level){
+                logFormatted(arguments, "");
+            },
+            debug: $null,
+            info: $null,
+            warn: $null,
+            error: $null
+        };
+    }
+
+    return $logger;
+};
+
+console = new Console("console",1);
+
+function logFormatted(objects, className)
+{
+    var html = [];
+
+    var format = objects[0];
+    var objIndex = 0;
+
+    if (typeof(format) != "string")
+    {
+        format = "";
+        objIndex = -1;
+    }
+
+    var parts = parseFormat(format);
+    for (var i = 0; i < parts.length; ++i)
+    {
+        var part = parts[i];
+        if (part && typeof(part) == "object")
+        {
+            var object = objects[++objIndex];
+            part.appender(object, html);
+        }
+        else {
+            appendText(part, html);
+	}
+    }
+
+    for (var i = objIndex+1; i < objects.length; ++i)
+    {
+        appendText(" ", html);
+
+        var object = objects[i];
+        if (typeof(object) == "string") {
+            appendText(object, html);
+        } else {
+            appendObject(object, html);
+	}
+    }
+
+    Envjs.log(html.join(' '));
+}
+
+function parseFormat(format)
+{
+    var parts = [];
+
+    var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
+    var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat};
+
+    for (var m = reg.exec(format); m; m = reg.exec(format))
+    {
+        var type = m[8] ? m[8] : m[5];
+        var appender = type in appenderMap ? appenderMap[type] : appendObject;
+        var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);
+
+        parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
+        parts.push({appender: appender, precision: precision});
+
+        format = format.substr(m.index+m[0].length);
+    }
+
+    parts.push(format);
+
+    return parts;
+}
+
+function escapeHTML(value)
+{
+    return value;
+}
+
+function objectToString(object)
+{
+    try
+    {
+        return object+"";
+    }
+    catch (exc)
+    {
+        return null;
+    }
+}
+
+// ********************************************************************************************
+
+function appendText(object, html)
+{
+    html.push(escapeHTML(objectToString(object)));
+}
+
+function appendNull(object, html)
+{
+    html.push(escapeHTML(objectToString(object)));
+}
+
+function appendString(object, html)
+{
+    html.push(escapeHTML(objectToString(object)));
+}
+
+function appendInteger(object, html)
+{
+    html.push(escapeHTML(objectToString(object)));
+}
+
+function appendFloat(object, html)
+{
+    html.push(escapeHTML(objectToString(object)));
+}
+
+function appendFunction(object, html)
+{
+    var reName = /function ?(.*?)\(/;
+    var m = reName.exec(objectToString(object));
+    var name = m ? m[1] : "function";
+    html.push(escapeHTML(name));
+}
+
+function appendObject(object, html)
+{
+    try
+    {
+        if (object == undefined) {
+            appendNull("undefined", html);
+        } else if (object == null) {
+            appendNull("null", html);
+        } else if (typeof object == "string") {
+            appendString(object, html);
+	} else if (typeof object == "number") {
+            appendInteger(object, html);
+	} else if (typeof object == "function") {
+            appendFunction(object, html);
+        } else if (object.nodeType == 1) {
+            appendSelector(object, html);
+        } else if (typeof object == "object") {
+            appendObjectFormatted(object, html);
+        } else {
+            appendText(object, html);
+	}
+    }
+    catch (exc)
+    {
+    }
+}
+
+function appendObjectFormatted(object, html)
+{
+    var text = objectToString(object);
+    var reObject = /\[object (.*?)\]/;
+
+    var m = reObject.exec(text);
+    html.push( m ? m[1] : text);
+}
+
+function appendSelector(object, html)
+{
+
+    html.push(escapeHTML(object.nodeName.toLowerCase()));
+    if (object.id) {
+        html.push(escapeHTML(object.id));
+    }
+    if (object.className) {
+        html.push(escapeHTML(object.className));
+    }
+}
+
+function appendNode(node, html)
+{
+    if (node.nodeType == 1)
+    {
+        html.push( node.nodeName.toLowerCase());
+
+        for (var i = 0; i < node.attributes.length; ++i)
+        {
+            var attr = node.attributes[i];
+            if (!attr.specified) {
+                continue;
+	    }
+
+            html.push( attr.nodeName.toLowerCase(),escapeHTML(attr.nodeValue));
+        }
+
+        if (node.firstChild)
+        {
+            for (var child = node.firstChild; child; child = child.nextSibling) {
+                appendNode(child, html);
+	    }
+
+            html.push( node.nodeName.toLowerCase());
+        }
+    }
+    else if (node.nodeType === 3)
+    {
+        html.push(escapeHTML(node.nodeValue));
+    }
+};
+
+/**
+ * @author john resig & the envjs team
+ * @uri http://www.envjs.com/
+ * @copyright 2008-2010
+ * @license MIT
+ */
+//CLOSURE_END
+}());
+/*
+ * Envjs dom.1.2.35 
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ * 
+ * Parts of the implementation were originally written by:\
+ * and Jon van Noort   (jon@webarcana.com.au) \
+ * and David Joham     (djoham@yahoo.com)",\ 
+ * and Scott Severtson
+ * 
+ * This file simply provides the global definitions we need to \
+ * be able to correctly implement to core browser DOM interfaces."
+ */
+
+/*var Attr,
+    CDATASection,
+    CharacterData,
+    Comment,
+    Document,
+    DocumentFragment,
+    DocumentType,
+    DOMException,
+    DOMImplementation,
+    Element,
+    Entity,
+    EntityReference,
+    NamedNodeMap,
+    Namespace,
+    Node,
+    NodeList,
+    Notation,
+    ProcessingInstruction,
+    Text,
+    Range,
+    XMLSerializer,
+    DOMParser;
+*/
+
+
+/*
+ * Envjs dom.1.2.35 
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ */
+
+//CLOSURE_START
+(function(){
+
+
+
+
+
+/**
+ * @author john resig
+ */
+// Helper method for extending one object with another.
+function __extend__(a,b) {
+    for ( var i in b ) {
+        var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
+        if ( g || s ) {
+            if ( g ) { a.__defineGetter__(i, g); }
+            if ( s ) { a.__defineSetter__(i, s); }
+        } else {
+            a[i] = b[i];
+        }
+    } return a;
+}
+
+/**
+ * @author john resig
+ */
+//from jQuery
+function __setArray__( target, array ) {
+    // Resetting the length to 0, then using the native Array push
+    // is a super-fast way to populate an object with array-like properties
+    target.length = 0;
+    Array.prototype.push.apply( target, array );
+}
+
+/**
+ * @class  NodeList -
+ *      provides the abstraction of an ordered collection of nodes
+ *
+ * @param  ownerDocument : Document - the ownerDocument
+ * @param  parentNode    : Node - the node that the NodeList is attached to (or null)
+ */
+NodeList = function(ownerDocument, parentNode) {
+    this.length = 0;
+    this.parentNode = parentNode;
+    this.ownerDocument = ownerDocument;
+    this._readonly = false;
+    __setArray__(this, []);
+};
+
+__extend__(NodeList.prototype, {
+    item : function(index) {
+        var ret = null;
+        if ((index >= 0) && (index < this.length)) {
+            // bounds check
+            ret = this[index];
+        }
+        // if the index is out of bounds, default value null is returned
+        return ret;
+    },
+    get xml() {
+        var ret = "",
+            i;
+
+        // create string containing the concatenation of the string values of each child
+        for (i=0; i < this.length; i++) {
+            if(this[i]){
+                if(this[i].nodeType == Node.TEXT_NODE && i>0 &&
+                   this[i-1].nodeType == Node.TEXT_NODE){
+                    //add a single space between adjacent text nodes
+                    ret += " "+this[i].xml;
+                }else{
+                    ret += this[i].xml;
+                }
+            }
+        }
+        return ret;
+    },
+    toArray: function () {
+        var children = [],
+            i;
+        for ( i=0; i < this.length; i++) {
+            children.push (this[i]);
+        }
+        return children;
+    },
+    toString: function(){
+        return "[object NodeList]";
+    }
+});
+
+
+/**
+ * @method __findItemIndex__
+ *      find the item index of the node
+ * @author Jon van Noort (jon@webarcana.com.au)
+ * @param  node : Node
+ * @return : int
+ */
+var __findItemIndex__ = function (nodelist, node) {
+    var ret = -1, i;
+    for (i=0; i<nodelist.length; i++) {
+        // compare id to each node's _id
+        if (nodelist[i] === node) {
+            // found it!
+            ret = i;
+            break;
+        }
+    }
+    // if node is not found, default value -1 is returned
+    return ret;
+};
+
+/**
+ * @method __insertBefore__
+ *      insert the specified Node into the NodeList before the specified index
+ *      Used by Node.insertBefore(). Note: Node.insertBefore() is responsible
+ *      for Node Pointer surgery __insertBefore__ simply modifies the internal
+ *      data structure (Array).
+ * @param  newChild      : Node - the Node to be inserted
+ * @param  refChildIndex : int     - the array index to insert the Node before
+ */
+var __insertBefore__ = function(nodelist, newChild, refChildIndex) {
+    if ((refChildIndex >= 0) && (refChildIndex <= nodelist.length)) {
+        // bounds check
+        if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
+            // node is a DocumentFragment
+            // append the children of DocumentFragment
+            Array.prototype.splice.apply(nodelist,
+                [refChildIndex, 0].concat(newChild.childNodes.toArray()));
+        }
+        else {
+            // append the newChild
+            Array.prototype.splice.apply(nodelist,[refChildIndex, 0, newChild]);
+        }
+    }
+};
+
+/**
+ * @method __replaceChild__
+ *      replace the specified Node in the NodeList at the specified index
+ *      Used by Node.replaceChild(). Note: Node.replaceChild() is responsible
+ *      for Node Pointer surgery __replaceChild__ simply modifies the internal
+ *      data structure (Array).
+ *
+ * @param  newChild      : Node - the Node to be inserted
+ * @param  refChildIndex : int     - the array index to hold the Node
+ */
+var __replaceChild__ = function(nodelist, newChild, refChildIndex) {
+    var ret = null;
+
+    // bounds check
+    if ((refChildIndex >= 0) && (refChildIndex < nodelist.length)) {
+        // preserve old child for return
+        ret = nodelist[refChildIndex];
+
+        if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
+            // node is a DocumentFragment
+            // get array containing children prior to refChild
+            Array.prototype.splice.apply(nodelist,
+                [refChildIndex, 1].concat(newChild.childNodes.toArray()));
+        }
+        else {
+            // simply replace node in array (links between Nodes are
+            // made at higher level)
+            nodelist[refChildIndex] = newChild;
+        }
+    }
+    // return replaced node
+    return ret;
+};
+
+/**
+ * @method __removeChild__
+ *      remove the specified Node in the NodeList at the specified index
+ *      Used by Node.removeChild(). Note: Node.removeChild() is responsible
+ *      for Node Pointer surgery __removeChild__ simply modifies the internal
+ *      data structure (Array).
+ * @param  refChildIndex : int - the array index holding the Node to be removed
+ */
+var __removeChild__ = function(nodelist, refChildIndex) {
+    var ret = null;
+
+    if (refChildIndex > -1) {
+        // found it!
+        // return removed node
+        ret = nodelist[refChildIndex];
+
+        // rebuild array without removed child
+        Array.prototype.splice.apply(nodelist,[refChildIndex, 1]);
+    }
+    // return removed node
+    return ret;
+};
+
+/**
+ * @method __appendChild__
+ *      append the specified Node to the NodeList. Used by Node.appendChild().
+ *      Note: Node.appendChild() is responsible for Node Pointer surgery
+ *      __appendChild__ simply modifies the internal data structure (Array).
+ * @param  newChild      : Node - the Node to be inserted
+ */
+var __appendChild__ = function(nodelist, newChild) {
+    if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
+        // node is a DocumentFragment
+        // append the children of DocumentFragment
+        Array.prototype.push.apply(nodelist, newChild.childNodes.toArray() );
+    } else {
+        // simply add node to array (links between Nodes are made at higher level)
+        Array.prototype.push.apply(nodelist, [newChild]);
+    }
+
+};
+
+/**
+ * @method __cloneNodes__ -
+ *      Returns a NodeList containing clones of the Nodes in this NodeList
+ * @param  deep : boolean -
+ *      If true, recursively clone the subtree under each of the nodes;
+ *      if false, clone only the nodes themselves (and their attributes,
+ *      if it is an Element).
+ * @param  parentNode : Node - the new parent of the cloned NodeList
+ * @return : NodeList - NodeList containing clones of the Nodes in this NodeList
+ */
+var __cloneNodes__ = function(nodelist, deep, parentNode) {
+    var cloneNodeList = new NodeList(nodelist.ownerDocument, parentNode);
+
+    // create list containing clones of each child
+    for (var i=0; i < nodelist.length; i++) {
+        __appendChild__(cloneNodeList, nodelist[i].cloneNode(deep));
+    }
+
+    return cloneNodeList;
+};
+
+
+var __ownerDocument__ = function(node){
+    return (node.nodeType == Node.DOCUMENT_NODE)?node:node.ownerDocument;
+};
+
+/**
+ * @class  Node -
+ *      The Node interface is the primary datatype for the entire
+ *      Document Object Model. It represents a single node in the
+ *      document tree.
+ * @param  ownerDocument : Document - The Document object associated with this node.
+ */
+
+Node = function(ownerDocument) {
+    this.baseURI = 'about:blank';
+    this.namespaceURI = null;
+    this.nodeName = "";
+    this.nodeValue = null;
+
+    // A NodeList that contains all children of this node. If there are no
+    // children, this is a NodeList containing no nodes.  The content of the
+    // returned NodeList is "live" in the sense that, for instance, changes to
+    // the children of the node object that it was created from are immediately
+    // reflected in the nodes returned by the NodeList accessors; it is not a
+    // static snapshot of the content of the node. This is true for every
+    // NodeList, including the ones returned by the getElementsByTagName method.
+    this.childNodes      = new NodeList(ownerDocument, this);
+
+    // The first child of this node. If there is no such node, this is null
+    this.firstChild      = null;
+    // The last child of this node. If there is no such node, this is null.
+    this.lastChild       = null;
+    // The node immediately preceding this node. If there is no such node,
+    // this is null.
+    this.previousSibling = null;
+    // The node immediately following this node. If there is no such node,
+    // this is null.
+    this.nextSibling     = null;
+
+    this.attributes = null;
+    // The namespaces in scope for this node
+    this._namespaces = new NamespaceNodeMap(ownerDocument, this);
+    this._readonly = false;
+
+    //IMPORTANT: These must come last so rhino will not iterate parent
+    //           properties before child properties.  (qunit.equiv issue)
+
+    // The parent of this node. All nodes, except Document, DocumentFragment,
+    // and Attr may have a parent.  However, if a node has just been created
+    // and not yet added to the tree, or if it has been removed from the tree,
+    // this is null
+    this.parentNode      = null;
+    // The Document object associated with this node
+    this.ownerDocument = ownerDocument;
+
+};
+
+// nodeType constants
+Node.ELEMENT_NODE                = 1;
+Node.ATTRIBUTE_NODE              = 2;
+Node.TEXT_NODE                   = 3;
+Node.CDATA_SECTION_NODE          = 4;
+Node.ENTITY_REFERENCE_NODE       = 5;
+Node.ENTITY_NODE                 = 6;
+Node.PROCESSING_INSTRUCTION_NODE = 7;
+Node.COMMENT_NODE                = 8;
+Node.DOCUMENT_NODE               = 9;
+Node.DOCUMENT_TYPE_NODE          = 10;
+Node.DOCUMENT_FRAGMENT_NODE      = 11;
+Node.NOTATION_NODE               = 12;
+Node.NAMESPACE_NODE              = 13;
+
+Node.DOCUMENT_POSITION_EQUAL        = 0x00;
+Node.DOCUMENT_POSITION_DISCONNECTED = 0x01;
+Node.DOCUMENT_POSITION_PRECEDING    = 0x02;
+Node.DOCUMENT_POSITION_FOLLOWING    = 0x04;
+Node.DOCUMENT_POSITION_CONTAINS     = 0x08;
+Node.DOCUMENT_POSITION_CONTAINED_BY = 0x10;
+Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC      = 0x20;
+
+
+__extend__(Node.prototype, {
+    get localName(){
+        return this.prefix?
+            this.nodeName.substring(this.prefix.length+1, this.nodeName.length):
+            this.nodeName;
+    },
+    get prefix(){
+        return this.nodeName.split(':').length>1?
+            this.nodeName.split(':')[0]:
+            null;
+    },
+    set prefix(value){
+        if(value === null){
+            this.nodeName = this.localName;
+        }else{
+            this.nodeName = value+':'+this.localName;
+        }
+    },
+    hasAttributes : function() {
+        if (this.attributes.length == 0) {
+            return false;
+        }else{
+            return true;
+        }
+    },
+    get textContent(){
+        return __recursivelyGatherText__(this);
+    },
+    set textContent(newText){
+        while(this.firstChild != null){
+            this.removeChild( this.firstChild );
+        }
+        var text = this.ownerDocument.createTextNode(newText);
+        this.appendChild(text);
+    },
+    insertBefore : function(newChild, refChild) {
+        var prevNode;
+
+        if(newChild==null){
+            return newChild;
+        }
+        if(refChild==null){
+            this.appendChild(newChild);
+            return this.newChild;
+        }
+
+        // test for exceptions
+        if (__ownerDocument__(this).implementation.errorChecking) {
+            // throw Exception if Node is readonly
+            if (this._readonly) {
+                throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+            }
+
+            // throw Exception if newChild was not created by this Document
+            if (__ownerDocument__(this) != __ownerDocument__(newChild)) {
+                throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
+            }
+
+            // throw Exception if the node is an ancestor
+            if (__isAncestor__(this, newChild)) {
+                throw(new DOMException(DOMException.HIERARCHY_REQUEST_ERR));
+            }
+        }
+
+        // if refChild is specified, insert before it
+        if (refChild) {
+            // find index of refChild
+            var itemIndex = __findItemIndex__(this.childNodes, refChild);
+            // throw Exception if there is no child node with this id
+            if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) {
+                throw(new DOMException(DOMException.NOT_FOUND_ERR));
+            }
+
+            // if the newChild is already in the tree,
+            var newChildParent = newChild.parentNode;
+            if (newChildParent) {
+                // remove it
+                newChildParent.removeChild(newChild);
+            }
+
+            // insert newChild into childNodes
+            __insertBefore__(this.childNodes, newChild, itemIndex);
+
+            // do node pointer surgery
+            prevNode = refChild.previousSibling;
+
+            // handle DocumentFragment
+            if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
+                if (newChild.childNodes.length > 0) {
+                    // set the parentNode of DocumentFragment's children
+                    for (var ind = 0; ind < newChild.childNodes.length; ind++) {
+                        newChild.childNodes[ind].parentNode = this;
+                    }
+
+                    // link refChild to last child of DocumentFragment
+                    refChild.previousSibling = newChild.childNodes[newChild.childNodes.length-1];
+                }
+            }else {
+                // set the parentNode of the newChild
+                newChild.parentNode = this;
+                // link refChild to newChild
+                refChild.previousSibling = newChild;
+            }
+
+        }else {
+            // otherwise, append to end
+            prevNode = this.lastChild;
+            this.appendChild(newChild);
+        }
+
+        if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
+            // do node pointer surgery for DocumentFragment
+            if (newChild.childNodes.length > 0) {
+                if (prevNode) {
+                    prevNode.nextSibling = newChild.childNodes[0];
+                }else {
+                    // this is the first child in the list
+                    this.firstChild = newChild.childNodes[0];
+                }
+                newChild.childNodes[0].previousSibling = prevNode;
+                newChild.childNodes[newChild.childNodes.length-1].nextSibling = refChild;
+            }
+        }else {
+            // do node pointer surgery for newChild
+            if (prevNode) {
+                prevNode.nextSibling = newChild;
+            }else {
+                // this is the first child in the list
+                this.firstChild = newChild;
+            }
+            newChild.previousSibling = prevNode;
+            newChild.nextSibling     = refChild;
+        }
+
+        return newChild;
+    },
+    replaceChild : function(newChild, oldChild) {
+        var ret = null;
+
+        if(newChild==null || oldChild==null){
+            return oldChild;
+        }
+
+        // test for exceptions
+        if (__ownerDocument__(this).implementation.errorChecking) {
+            // throw Exception if Node is readonly
+            if (this._readonly) {
+                throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+            }
+
+            // throw Exception if newChild was not created by this Document
+            if (__ownerDocument__(this) != __ownerDocument__(newChild)) {
+                throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
+            }
+
+            // throw Exception if the node is an ancestor
+            if (__isAncestor__(this, newChild)) {
+                throw(new DOMException(DOMException.HIERARCHY_REQUEST_ERR));
+            }
+        }
+
+        // get index of oldChild
+        var index = __findItemIndex__(this.childNodes, oldChild);
+
+        // throw Exception if there is no child node with this id
+        if (__ownerDocument__(this).implementation.errorChecking && (index < 0)) {
+            throw(new DOMException(DOMException.NOT_FOUND_ERR));
+        }
+
+        // if the newChild is already in the tree,
+        var newChildParent = newChild.parentNode;
+        if (newChildParent) {
+            // remove it
+            newChildParent.removeChild(newChild);
+        }
+
+        // add newChild to childNodes
+        ret = __replaceChild__(this.childNodes,newChild, index);
+
+
+        if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
+            // do node pointer surgery for Document Fragment
+            if (newChild.childNodes.length > 0) {
+                for (var ind = 0; ind < newChild.childNodes.length; ind++) {
+                    newChild.childNodes[ind].parentNode = this;
+                }
+
+                if (oldChild.previousSibling) {
+                    oldChild.previousSibling.nextSibling = newChild.childNodes[0];
+                } else {
+                    this.firstChild = newChild.childNodes[0];
+                }
+
+                if (oldChild.nextSibling) {
+                    oldChild.nextSibling.previousSibling = newChild;
+                } else {
+                    this.lastChild = newChild.childNodes[newChild.childNodes.length-1];
+                }
+
+                newChild.childNodes[0].previousSibling = oldChild.previousSibling;
+                newChild.childNodes[newChild.childNodes.length-1].nextSibling = oldChild.nextSibling;
+            }
+        } else {
+            // do node pointer surgery for newChild
+            newChild.parentNode = this;
+
+            if (oldChild.previousSibling) {
+                oldChild.previousSibling.nextSibling = newChild;
+            }else{
+                this.firstChild = newChild;
+            }
+            if (oldChild.nextSibling) {
+                oldChild.nextSibling.previousSibling = newChild;
+            }else{
+                this.lastChild = newChild;
+            }
+            newChild.previousSibling = oldChild.previousSibling;
+            newChild.nextSibling = oldChild.nextSibling;
+        }
+
+        return ret;
+    },
+    removeChild : function(oldChild) {
+        if(!oldChild){
+            return null;
+        }
+        // throw Exception if NamedNodeMap is readonly
+        if (__ownerDocument__(this).implementation.errorChecking &&
+            (this._readonly || oldChild._readonly)) {
+            throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+        }
+
+        // get index of oldChild
+        var itemIndex = __findItemIndex__(this.childNodes, oldChild);
+
+        // throw Exception if there is no child node with this id
+        if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) {
+            throw(new DOMException(DOMException.NOT_FOUND_ERR));
+        }
+
+        // remove oldChild from childNodes
+        __removeChild__(this.childNodes, itemIndex);
+
+        // do node pointer surgery
+        oldChild.parentNode = null;
+
+        if (oldChild.previousSibling) {
+            oldChild.previousSibling.nextSibling = oldChild.nextSibling;
+        }else {
+            this.firstChild = oldChild.nextSibling;
+        }
+        if (oldChild.nextSibling) {
+            oldChild.nextSibling.previousSibling = oldChild.previousSibling;
+        }else {
+            this.lastChild = oldChild.previousSibling;
+        }
+
+        oldChild.previousSibling = null;
+        oldChild.nextSibling = null;
+
+        return oldChild;
+    },
+    appendChild : function(newChild) {
+        if(!newChild){
+            return null;
+        }
+        // test for exceptions
+        if (__ownerDocument__(this).implementation.errorChecking) {
+            // throw Exception if Node is readonly
+            if (this._readonly) {
+                throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+            }
+
+            // throw Exception if arg was not created by this Document
+            if (__ownerDocument__(this) != __ownerDocument__(this)) {
+                throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
+            }
+
+            // throw Exception if the node is an ancestor
+            if (__isAncestor__(this, newChild)) {
+              throw(new DOMException(DOMException.HIERARCHY_REQUEST_ERR));
+            }
+        }
+
+        // if the newChild is already in the tree,
+        var newChildParent = newChild.parentNode;
+        if (newChildParent) {
+            // remove it
+           //console.debug('removing node %s', newChild);
+            newChildParent.removeChild(newChild);
+        }
+
+        // add newChild to childNodes
+        __appendChild__(this.childNodes, newChild);
+
+        if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
+            // do node pointer surgery for DocumentFragment
+            if (newChild.childNodes.length > 0) {
+                for (var ind = 0; ind < newChild.childNodes.length; ind++) {
+                    newChild.childNodes[ind].parentNode = this;
+                }
+
+                if (this.lastChild) {
+                    this.lastChild.nextSibling = newChild.childNodes[0];
+                    newChild.childNodes[0].previousSibling = this.lastChild;
+                    this.lastChild = newChild.childNodes[newChild.childNodes.length-1];
+                } else {
+                    this.lastChild = newChild.childNodes[newChild.childNodes.length-1];
+                    this.firstChild = newChild.childNodes[0];
+                }
+            }
+        } else {
+            // do node pointer surgery for newChild
+            newChild.parentNode = this;
+            if (this.lastChild) {
+                this.lastChild.nextSibling = newChild;
+                newChild.previousSibling = this.lastChild;
+                this.lastChild = newChild;
+            } else {
+                this.lastChild = newChild;
+                this.firstChild = newChild;
+            }
+       }
+       return newChild;
+    },
+    hasChildNodes : function() {
+        return (this.childNodes.length > 0);
+    },
+    cloneNode: function(deep) {
+        // use importNode to clone this Node
+        //do not throw any exceptions
+        try {
+            return __ownerDocument__(this).importNode(this, deep);
+        } catch (e) {
+            //there shouldn't be any exceptions, but if there are, return null
+            // may want to warn: $debug("could not clone node: "+e.code);
+            return null;
+        }
+    },
+    normalize : function() {
+        var i;
+        var inode;
+        var nodesToRemove = new NodeList();
+
+        if (this.nodeType == Node.ELEMENT_NODE || this.nodeType == Node.DOCUMENT_NODE) {
+            var adjacentTextNode = null;
+
+            // loop through all childNodes
+            for(i = 0; i < this.childNodes.length; i++) {
+                inode = this.childNodes.item(i);
+
+                if (inode.nodeType == Node.TEXT_NODE) {
+                    // this node is a text node
+                    if (inode.length < 1) {
+                        // this text node is empty
+                        // add this node to the list of nodes to be remove
+                        __appendChild__(nodesToRemove, inode);
+                    }else {
+                        if (adjacentTextNode) {
+                            // previous node was also text
+                            adjacentTextNode.appendData(inode.data);
+                            // merge the data in adjacent text nodes
+                            // add this node to the list of nodes to be removed
+                            __appendChild__(nodesToRemove, inode);
+                        } else {
+                            // remember this node for next cycle
+                            adjacentTextNode = inode;
+                        }
+                    }
+                } else {
+                    // (soon to be) previous node is not a text node
+                    adjacentTextNode = null;
+                    // normalize non Text childNodes
+                    inode.normalize();
+                }
+            }
+
+            // remove redundant Text Nodes
+            for(i = 0; i < nodesToRemove.length; i++) {
+                inode = nodesToRemove.item(i);
+                inode.parentNode.removeChild(inode);
+            }
+        }
+    },
+    isSupported : function(feature, version) {
+        // use Implementation.hasFeature to determine if this feature is supported
+        return __ownerDocument__(this).implementation.hasFeature(feature, version);
+    },
+    getElementsByTagName : function(tagname) {
+        // delegate to _getElementsByTagNameRecursive
+        // recurse childNodes
+        var nodelist = new NodeList(__ownerDocument__(this));
+        for (var i = 0; i < this.childNodes.length; i++) {
+            __getElementsByTagNameRecursive__(this.childNodes.item(i),
+                                              tagname,
+                                              nodelist);
+        }
+        return nodelist;
+    },
+    getElementsByTagNameNS : function(namespaceURI, localName) {
+        // delegate to _getElementsByTagNameNSRecursive
+        return __getElementsByTagNameNSRecursive__(this, namespaceURI, localName,
+            new NodeList(__ownerDocument__(this)));
+    },
+    importNode : function(importedNode, deep) {
+        var i;
+        var importNode;
+
+        //there is no need to perform namespace checks since everything has already gone through them
+        //in order to have gotten into the DOM in the first place. The following line
+        //turns namespace checking off in ._isValidNamespace
+        __ownerDocument__(this).importing = true;
+
+        if (importedNode.nodeType == Node.ELEMENT_NODE) {
+            if (!__ownerDocument__(this).implementation.namespaceAware) {
+                // create a local Element (with the name of the importedNode)
+                importNode = __ownerDocument__(this).createElement(importedNode.tagName);
+
+                // create attributes matching those of the importedNode
+                for(i = 0; i < importedNode.attributes.length; i++) {
+                    importNode.setAttribute(importedNode.attributes.item(i).name, importedNode.attributes.item(i).value);
+                }
+            } else {
+                // create a local Element (with the name & namespaceURI of the importedNode)
+                importNode = __ownerDocument__(this).createElementNS(importedNode.namespaceURI, importedNode.nodeName);
+
+                // create attributes matching those of the importedNode
+                for(i = 0; i < importedNode.attributes.length; i++) {
+                    importNode.setAttributeNS(importedNode.attributes.item(i).namespaceURI,
+                        importedNode.attributes.item(i).name, importedNode.attributes.item(i).value);
+                }
+
+                // create namespace definitions matching those of the importedNode
+                for(i = 0; i < importedNode._namespaces.length; i++) {
+                    importNode._namespaces[i] = __ownerDocument__(this).createNamespace(importedNode._namespaces.item(i).localName);
+                    importNode._namespaces[i].value = importedNode._namespaces.item(i).value;
+                }
+            }
+        } else if (importedNode.nodeType == Node.ATTRIBUTE_NODE) {
+            if (!__ownerDocument__(this).implementation.namespaceAware) {
+                // create a local Attribute (with the name of the importedAttribute)
+                importNode = __ownerDocument__(this).createAttribute(importedNode.name);
+            } else {
+                // create a local Attribute (with the name & namespaceURI of the importedAttribute)
+                importNode = __ownerDocument__(this).createAttributeNS(importedNode.namespaceURI, importedNode.nodeName);
+
+                // create namespace definitions matching those of the importedAttribute
+                for(i = 0; i < importedNode._namespaces.length; i++) {
+                    importNode._namespaces[i] = __ownerDocument__(this).createNamespace(importedNode._namespaces.item(i).localName);
+                    importNode._namespaces[i].value = importedNode._namespaces.item(i).value;
+                }
+            }
+
+            // set the value of the local Attribute to match that of the importedAttribute
+            importNode.value = importedNode.value;
+
+        } else if (importedNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
+            // create a local DocumentFragment
+            importNode = __ownerDocument__(this).createDocumentFragment();
+        } else if (importedNode.nodeType == Node.NAMESPACE_NODE) {
+            // create a local NamespaceNode (with the same name & value as the importedNode)
+            importNode = __ownerDocument__(this).createNamespace(importedNode.nodeName);
+            importNode.value = importedNode.value;
+        } else if (importedNode.nodeType == Node.TEXT_NODE) {
+            // create a local TextNode (with the same data as the importedNode)
+            importNode = __ownerDocument__(this).createTextNode(importedNode.data);
+        } else if (importedNode.nodeType == Node.CDATA_SECTION_NODE) {
+            // create a local CDATANode (with the same data as the importedNode)
+            importNode = __ownerDocument__(this).createCDATASection(importedNode.data);
+        } else if (importedNode.nodeType == Node.PROCESSING_INSTRUCTION_NODE) {
+            // create a local ProcessingInstruction (with the same target & data as the importedNode)
+            importNode = __ownerDocument__(this).createProcessingInstruction(importedNode.target, importedNode.data);
+        } else if (importedNode.nodeType == Node.COMMENT_NODE) {
+            // create a local Comment (with the same data as the importedNode)
+            importNode = __ownerDocument__(this).createComment(importedNode.data);
+        } else {  // throw Exception if nodeType is not supported
+            throw(new DOMException(DOMException.NOT_SUPPORTED_ERR));
+        }
+
+        if (deep) {
+            // recurse childNodes
+            for(i = 0; i < importedNode.childNodes.length; i++) {
+                importNode.appendChild(__ownerDocument__(this).importNode(importedNode.childNodes.item(i), true));
+            }
+        }
+
+        //reset importing
+        __ownerDocument__(this).importing = false;
+        return importNode;
+
+    },
+    contains : function(node){
+        while(node && node != this ){
+            node = node.parentNode;
+        }
+        return !!node;
+    },
+    compareDocumentPosition : function(b){
+        //console.log("comparing document position %s %s", this, b);
+        var i,
+            length,
+            a = this,
+            parent,
+            aparents,
+            bparents;
+        //handle a couple simpler case first
+        if(a === b) {
+            return Node.DOCUMENT_POSITION_EQUAL;
+        }
+        if(a.ownerDocument !== b.ownerDocument) {
+            return Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC|
+               Node.DOCUMENT_POSITION_FOLLOWING|
+               Node.DOCUMENT_POSITION_DISCONNECTED;
+        }
+        if(a.parentNode === b.parentNode){
+            length = a.parentNode.childNodes.length;
+            for(i=0;i<length;i++){
+                if(a.parentNode.childNodes[i] === a){
+                    return Node.DOCUMENT_POSITION_FOLLOWING;
+                }else if(a.parentNode.childNodes[i] === b){
+                    return Node.DOCUMENT_POSITION_PRECEDING;
+                }
+            }
+        }
+
+        if(a.contains(b)) {
+            return Node.DOCUMENT_POSITION_CONTAINED_BY|
+                   Node.DOCUMENT_POSITION_FOLLOWING;
+        }
+        if(b.contains(a)) {
+            return Node.DOCUMENT_POSITION_CONTAINS|
+                   Node.DOCUMENT_POSITION_PRECEDING;
+        }
+        aparents = [];
+        parent = a.parentNode;
+        while(parent){
+            aparents[aparents.length] = parent;
+            parent = parent.parentNode;
+        }
+
+        bparents = [];
+        parent = b.parentNode;
+        while(parent){
+            i = aparents.indexOf(parent);
+            if(i < 0){
+                bparents[bparents.length] = parent;
+                parent = parent.parentNode;
+            }else{
+                //i cant be 0 since we already checked for equal parentNode
+                if(bparents.length > aparents.length){
+                    return Node.DOCUMENT_POSITION_FOLLOWING;
+                }else if(bparents.length < aparents.length){
+                    return Node.DOCUMENT_POSITION_PRECEDING;
+                }else{
+                    //common ancestor diverge point
+                    if (i === 0) {
+                        return Node.DOCUMENT_POSITION_FOLLOWING;
+                    } else {
+                        parent = aparents[i-1];
+                    }
+                    return parent.compareDocumentPosition(bparents.pop());
+                }
+            }
+        }
+
+        return Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC|
+               Node.DOCUMENT_POSITION_DISCONNECTED;
+
+    },
+    toString : function() {
+        return '[object Node]';
+    }
+
+});
+
+
+
+/**
+ * @method __getElementsByTagNameRecursive__ - implements getElementsByTagName()
+ * @param  elem     : Element  - The element which are checking and then recursing into
+ * @param  tagname  : string      - The name of the tag to match on. The special value "*" matches all tags
+ * @param  nodeList : NodeList - The accumulating list of matching nodes
+ *
+ * @return : NodeList
+ */
+var __getElementsByTagNameRecursive__ = function (elem, tagname, nodeList) {
+
+    if (elem.nodeType == Node.ELEMENT_NODE || elem.nodeType == Node.DOCUMENT_NODE) {
+
+        if(elem.nodeType !== Node.DOCUMENT_NODE &&
+            ((elem.nodeName.toUpperCase() == tagname.toUpperCase()) ||
+                (tagname == "*")) ){
+            // add matching node to nodeList
+            __appendChild__(nodeList, elem);
+        }
+
+        // recurse childNodes
+        for(var i = 0; i < elem.childNodes.length; i++) {
+            nodeList = __getElementsByTagNameRecursive__(elem.childNodes.item(i), tagname, nodeList);
+        }
+    }
+
+    return nodeList;
+};
+
+/**
+ * @method __getElementsByTagNameNSRecursive__
+ *      implements getElementsByTagName()
+ *
+ * @param  elem     : Element  - The element which are checking and then recursing into
+ * @param  namespaceURI : string - the namespace URI of the required node
+ * @param  localName    : string - the local name of the required node
+ * @param  nodeList     : NodeList - The accumulating list of matching nodes
+ *
+ * @return : NodeList
+ */
+var __getElementsByTagNameNSRecursive__ = function(elem, namespaceURI, localName, nodeList) {
+    if (elem.nodeType == Node.ELEMENT_NODE || elem.nodeType == Node.DOCUMENT_NODE) {
+
+        if (((elem.namespaceURI == namespaceURI) || (namespaceURI == "*")) &&
+            ((elem.localName == localName) || (localName == "*"))) {
+            // add matching node to nodeList
+            __appendChild__(nodeList, elem);
+        }
+
+        // recurse childNodes
+        for(var i = 0; i < elem.childNodes.length; i++) {
+            nodeList = __getElementsByTagNameNSRecursive__(
+                elem.childNodes.item(i), namespaceURI, localName, nodeList);
+        }
+    }
+
+    return nodeList;
+};
+
+/**
+ * @method __isAncestor__ - returns true if node is ancestor of target
+ * @param  target         : Node - The node we are using as context
+ * @param  node         : Node - The candidate ancestor node
+ * @return : boolean
+ */
+var __isAncestor__ = function(target, node) {
+    // if this node matches, return true,
+    // otherwise recurse up (if there is a parentNode)
+    return ((target == node) || ((target.parentNode) && (__isAncestor__(target.parentNode, node))));
+};
+
+
+
+var __recursivelyGatherText__ = function(aNode) {
+    var accumulateText = "",
+        idx,
+        node;
+    for (idx=0;idx < aNode.childNodes.length;idx++){
+        node = aNode.childNodes.item(idx);
+        if(node.nodeType == Node.TEXT_NODE)
+            accumulateText += node.data;
+        else
+            accumulateText += __recursivelyGatherText__(node);
+    }
+    return accumulateText;
+};
+
+/**
+ * function __escapeXML__
+ * @param  str : string - The string to be escaped
+ * @return : string - The escaped string
+ */
+var escAmpRegEx = /&(?!(amp;|lt;|gt;|quot|apos;))/g;
+var escLtRegEx = /</g;
+var escGtRegEx = />/g;
+var quotRegEx = /"/g;
+var aposRegEx = /'/g;
+
+function __escapeXML__(str) {
+    str = str.replace(escAmpRegEx, "&amp;").
+            replace(escLtRegEx, "&lt;").
+            replace(escGtRegEx, "&gt;").
+            replace(quotRegEx, "&quot;").
+            replace(aposRegEx, "&apos;");
+
+    return str;
+};
+
+/*
+function __escapeHTML5__(str) {
+    str = str.replace(escAmpRegEx, "&amp;").
+            replace(escLtRegEx, "&lt;").
+            replace(escGtRegEx, "&gt;");
+
+    return str;
+};
+function __escapeHTML5Atribute__(str) {
+    str = str.replace(escAmpRegEx, "&amp;").
+            replace(escLtRegEx, "&lt;").
+            replace(escGtRegEx, "&gt;").
+            replace(quotRegEx, "&quot;").
+            replace(aposRegEx, "&apos;");
+
+    return str;
+};
+*/
+
+/**
+ * function __unescapeXML__
+ * @param  str : string - The string to be unescaped
+ * @return : string - The unescaped string
+ */
+var unescAmpRegEx = /&amp;/g;
+var unescLtRegEx = /&lt;/g;
+var unescGtRegEx = /&gt;/g;
+var unquotRegEx = /&quot;/g;
+var unaposRegEx = /&apos;/g;
+function __unescapeXML__(str) {
+    str = str.replace(unescAmpRegEx, "&").
+            replace(unescLtRegEx, "<").
+            replace(unescGtRegEx, ">").
+            replace(unquotRegEx, "\"").
+            replace(unaposRegEx, "'");
+
+    return str;
+};
+
+/**
+ * @class  NamedNodeMap -
+ *      used to represent collections of nodes that can be accessed by name
+ *      typically a set of Element attributes
+ *
+ * @extends NodeList -
+ *      note W3C spec says that this is not the case, but we need an item()
+ *      method identical to NodeList's, so why not?
+ * @param  ownerDocument : Document - the ownerDocument
+ * @param  parentNode    : Node - the node that the NamedNodeMap is attached to (or null)
+ */
+NamedNodeMap = function(ownerDocument, parentNode) {
+    NodeList.apply(this, arguments);
+    __setArray__(this, []);
+};
+NamedNodeMap.prototype = new NodeList();
+__extend__(NamedNodeMap.prototype, {
+    add: function(name){
+        this[this.length] = name;
+    },
+    getNamedItem : function(name) {
+        var ret = null;
+        //console.log('NamedNodeMap getNamedItem %s', name);
+        // test that Named Node exists
+        var itemIndex = __findNamedItemIndex__(this, name);
+
+        if (itemIndex > -1) {
+            // found it!
+            ret = this[itemIndex];
+        }
+        // if node is not found, default value null is returned
+        return ret;
+    },
+    setNamedItem : function(arg) {
+      //console.log('setNamedItem %s', arg);
+      // test for exceptions
+      if (__ownerDocument__(this).implementation.errorChecking) {
+            // throw Exception if arg was not created by this Document
+            if (this.ownerDocument != arg.ownerDocument) {
+              throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
+            }
+
+            // throw Exception if DOMNamedNodeMap is readonly
+            if (this._readonly || (this.parentNode && this.parentNode._readonly)) {
+              throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+            }
+
+            // throw Exception if arg is already an attribute of another Element object
+            if (arg.ownerElement && (arg.ownerElement != this.parentNode)) {
+              throw(new DOMException(DOMException.INUSE_ATTRIBUTE_ERR));
+            }
+      }
+
+     //console.log('setNamedItem __findNamedItemIndex__ ');
+      // get item index
+      var itemIndex = __findNamedItemIndex__(this, arg.name);
+      var ret = null;
+
+     //console.log('setNamedItem __findNamedItemIndex__ %s', itemIndex);
+      if (itemIndex > -1) {                          // found it!
+            ret = this[itemIndex];                // use existing Attribute
+
+            // throw Exception if DOMAttr is readonly
+            if (__ownerDocument__(this).implementation.errorChecking && ret._readonly) {
+              throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+            } else {
+              this[itemIndex] = arg;                // over-write existing NamedNode
+              this[arg.name.toLowerCase()] = arg;
+            }
+      } else {
+            // add new NamedNode
+           //console.log('setNamedItem add new named node map (by index)');
+            Array.prototype.push.apply(this, [arg]);
+           //console.log('setNamedItem add new named node map (by name) %s %s', arg, arg.name);
+            this[arg.name] = arg;
+           //console.log('finsished setNamedItem add new named node map (by name) %s', arg.name);
+
+      }
+
+     //console.log('setNamedItem parentNode');
+      arg.ownerElement = this.parentNode;            // update ownerElement
+      // return old node or new node
+     //console.log('setNamedItem exit');
+      return ret;
+    },
+    removeNamedItem : function(name) {
+          var ret = null;
+          // test for exceptions
+          // throw Exception if NamedNodeMap is readonly
+          if (__ownerDocument__(this).implementation.errorChecking &&
+                (this._readonly || (this.parentNode && this.parentNode._readonly))) {
+              throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+          }
+
+          // get item index
+          var itemIndex = __findNamedItemIndex__(this, name);
+
+          // throw Exception if there is no node named name in this map
+          if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) {
+            throw(new DOMException(DOMException.NOT_FOUND_ERR));
+          }
+
+          // get Node
+          var oldNode = this[itemIndex];
+          //this[oldNode.name] = undefined;
+
+          // throw Exception if Node is readonly
+          if (__ownerDocument__(this).implementation.errorChecking && oldNode._readonly) {
+            throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+          }
+
+          // return removed node
+          return __removeChild__(this, itemIndex);
+    },
+    getNamedItemNS : function(namespaceURI, localName) {
+        var ret = null;
+
+        // test that Named Node exists
+        var itemIndex = __findNamedItemNSIndex__(this, namespaceURI, localName);
+
+        if (itemIndex > -1) {
+            // found it! return NamedNode
+            ret = this[itemIndex];
+        }
+        // if node is not found, default value null is returned
+        return ret;
+    },
+    setNamedItemNS : function(arg) {
+        //console.log('setNamedItemNS %s', arg);
+        // test for exceptions
+        if (__ownerDocument__(this).implementation.errorChecking) {
+            // throw Exception if NamedNodeMap is readonly
+            if (this._readonly || (this.parentNode && this.parentNode._readonly)) {
+                throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+            }
+
+            // throw Exception if arg was not created by this Document
+            if (__ownerDocument__(this) != __ownerDocument__(arg)) {
+                throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
+            }
+
+            // throw Exception if arg is already an attribute of another Element object
+            if (arg.ownerElement && (arg.ownerElement != this.parentNode)) {
+                throw(new DOMException(DOMException.INUSE_ATTRIBUTE_ERR));
+            }
+        }
+
+        // get item index
+        var itemIndex = __findNamedItemNSIndex__(this, arg.namespaceURI, arg.localName);
+        var ret = null;
+
+        if (itemIndex > -1) {
+            // found it!
+            // use existing Attribute
+            ret = this[itemIndex];
+            // throw Exception if Attr is readonly
+            if (__ownerDocument__(this).implementation.errorChecking && ret._readonly) {
+                throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+            } else {
+                // over-write existing NamedNode
+                this[itemIndex] = arg;
+            }
+        }else {
+            // add new NamedNode
+            Array.prototype.push.apply(this, [arg]);
+        }
+        arg.ownerElement = this.parentNode;
+
+        // return old node or null
+        return ret;
+        //console.log('finished setNamedItemNS %s', arg);
+    },
+    removeNamedItemNS : function(namespaceURI, localName) {
+          var ret = null;
+
+          // test for exceptions
+          // throw Exception if NamedNodeMap is readonly
+          if (__ownerDocument__(this).implementation.errorChecking && (this._readonly || (this.parentNode && this.parentNode._readonly))) {
+            throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+          }
+
+          // get item index
+          var itemIndex = __findNamedItemNSIndex__(this, namespaceURI, localName);
+
+          // throw Exception if there is no matching node in this map
+          if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) {
+            throw(new DOMException(DOMException.NOT_FOUND_ERR));
+          }
+
+          // get Node
+          var oldNode = this[itemIndex];
+
+          // throw Exception if Node is readonly
+          if (__ownerDocument__(this).implementation.errorChecking && oldNode._readonly) {
+            throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+          }
+
+          return __removeChild__(this, itemIndex);             // return removed node
+    },
+    get xml() {
+          var ret = "";
+
+          // create string containing concatenation of all (but last) Attribute string values (separated by spaces)
+          for (var i=0; i < this.length -1; i++) {
+            ret += this[i].xml +" ";
+          }
+
+          // add last Attribute to string (without trailing space)
+          if (this.length > 0) {
+            ret += this[this.length -1].xml;
+          }
+
+          return ret;
+    },
+    toString : function(){
+        return "[object NamedNodeMap]";
+    }
+
+});
+
+/**
+ * @method __findNamedItemIndex__
+ *      find the item index of the node with the specified name
+ *
+ * @param  name : string - the name of the required node
+ * @param  isnsmap : if its a NamespaceNodeMap
+ * @return : int
+ */
+var __findNamedItemIndex__ = function(namednodemap, name, isnsmap) {
+    var ret = -1;
+    // loop through all nodes
+    for (var i=0; i<namednodemap.length; i++) {
+        // compare name to each node's nodeName
+        if(namednodemap[i].localName && name && isnsmap){
+            if (namednodemap[i].localName.toLowerCase() == name.toLowerCase()) {
+                // found it!
+                ret = i;
+                break;
+            }
+        }else{
+            if(namednodemap[i].name && name){
+                if (namednodemap[i].name.toLowerCase() == name.toLowerCase()) {
+                    // found it!
+                    ret = i;
+                    break;
+                }
+            }
+        }
+    }
+    // if node is not found, default value -1 is returned
+    return ret;
+};
+
+/**
+ * @method __findNamedItemNSIndex__
+ *      find the item index of the node with the specified
+ *      namespaceURI and localName
+ *
+ * @param  namespaceURI : string - the namespace URI of the required node
+ * @param  localName    : string - the local name of the required node
+ * @return : int
+ */
+var __findNamedItemNSIndex__ = function(namednodemap, namespaceURI, localName) {
+    var ret = -1;
+    // test that localName is not null
+    if (localName) {
+        // loop through all nodes
+        for (var i=0; i<namednodemap.length; i++) {
+            if(namednodemap[i].namespaceURI && namednodemap[i].localName){
+                // compare name to each node's namespaceURI and localName
+                if ((namednodemap[i].namespaceURI.toLowerCase() == namespaceURI.toLowerCase()) &&
+                    (namednodemap[i].localName.toLowerCase() == localName.toLowerCase())) {
+                    // found it!
+                    ret = i;
+                    break;
+                }
+            }
+        }
+    }
+    // if node is not found, default value -1 is returned
+    return ret;
+};
+
+/**
+ * @method __hasAttribute__
+ *      Returns true if specified node exists
+ *
+ * @param  name : string - the name of the required node
+ * @return : boolean
+ */
+var __hasAttribute__ = function(namednodemap, name) {
+    var ret = false;
+    // test that Named Node exists
+    var itemIndex = __findNamedItemIndex__(namednodemap, name);
+        if (itemIndex > -1) {
+        // found it!
+        ret = true;
+    }
+    // if node is not found, default value false is returned
+    return ret;
+}
+
+/**
+ * @method __hasAttributeNS__
+ *      Returns true if specified node exists
+ *
+ * @param  namespaceURI : string - the namespace URI of the required node
+ * @param  localName    : string - the local name of the required node
+ * @return : boolean
+ */
+var __hasAttributeNS__ = function(namednodemap, namespaceURI, localName) {
+    var ret = false;
+    // test that Named Node exists
+    var itemIndex = __findNamedItemNSIndex__(namednodemap, namespaceURI, localName);
+    if (itemIndex > -1) {
+        // found it!
+        ret = true;
+    }
+    // if node is not found, default value false is returned
+    return ret;
+}
+
+/**
+ * @method __cloneNamedNodes__
+ *      Returns a NamedNodeMap containing clones of the Nodes in this NamedNodeMap
+ *
+ * @param  parentNode : Node - the new parent of the cloned NodeList
+ * @param  isnsmap : bool - is this a NamespaceNodeMap
+ * @return NamedNodeMap containing clones of the Nodes in this NamedNodeMap
+ */
+var __cloneNamedNodes__ = function(namednodemap, parentNode, isnsmap) {
+    var cloneNamedNodeMap = isnsmap?
+        new NamespaceNodeMap(namednodemap.ownerDocument, parentNode):
+        new NamedNodeMap(namednodemap.ownerDocument, parentNode);
+
+    // create list containing clones of all children
+    for (var i=0; i < namednodemap.length; i++) {
+        __appendChild__(cloneNamedNodeMap, namednodemap[i].cloneNode(false));
+    }
+
+    return cloneNamedNodeMap;
+};
+
+
+/**
+ * @class  NamespaceNodeMap -
+ *      used to represent collections of namespace nodes that can be
+ *      accessed by name typically a set of Element attributes
+ *
+ * @extends NamedNodeMap
+ *
+ * @param  ownerDocument : Document - the ownerDocument
+ * @param  parentNode    : Node - the node that the NamespaceNodeMap is attached to (or null)
+ */
+var NamespaceNodeMap = function(ownerDocument, parentNode) {
+    this.NamedNodeMap = NamedNodeMap;
+    this.NamedNodeMap(ownerDocument, parentNode);
+    __setArray__(this, []);
+};
+NamespaceNodeMap.prototype = new NamedNodeMap();
+__extend__(NamespaceNodeMap.prototype, {
+    get xml() {
+        var ret = "",
+            ns,
+            ind;
+        // identify namespaces declared local to this Element (ie, not inherited)
+        for (ind = 0; ind < this.length; ind++) {
+            // if namespace declaration does not exist in the containing node's, parentNode's namespaces
+            ns = null;
+            try {
+                var ns = this.parentNode.parentNode._namespaces.
+                    getNamedItem(this[ind].localName);
+            }catch (e) {
+                //breaking to prevent default namespace being inserted into return value
+                break;
+            }
+            if (!(ns && (""+ ns.nodeValue == ""+ this[ind].nodeValue))) {
+                // display the namespace declaration
+                ret += this[ind].xml +" ";
+            }
+        }
+        return ret;
+    }
+});
+
+/**
+ * @class  Namespace -
+ *      The Namespace interface represents an namespace in an Element object
+ *
+ * @param  ownerDocument : The Document object associated with this node.
+ */
+Namespace = function(ownerDocument) {
+    Node.apply(this, arguments);
+    // the name of this attribute
+    this.name      = "";
+
+    // If this attribute was explicitly given a value in the original document,
+    // this is true; otherwise, it is false.
+    // Note that the implementation is in charge of this attribute, not the user.
+    // If the user changes the value of the attribute (even if it ends up having
+    // the same value as the default value) then the specified flag is
+    // automatically flipped to true
+    this.specified = false;
+};
+Namespace.prototype = new Node();
+__extend__(Namespace.prototype, {
+    get value(){
+        // the value of the attribute is returned as a string
+        return this.nodeValue;
+    },
+    set value(value){
+        this.nodeValue = value+'';
+    },
+    get nodeType(){
+        return Node.NAMESPACE_NODE;
+    },
+    get xml(){
+        var ret = "";
+
+          // serialize Namespace Declaration
+          if (this.nodeName != "") {
+            ret += this.nodeName +"=\""+ __escapeXML__(this.nodeValue) +"\"";
+          }
+          else {  // handle default namespace
+            ret += "xmlns=\""+ __escapeXML__(this.nodeValue) +"\"";
+          }
+
+          return ret;
+    },
+    toString: function(){
+        return '[object Namespace]';
+    }
+});
+
+
+/**
+ * @class  CharacterData - parent abstract class for Text and Comment
+ * @extends Node
+ * @param  ownerDocument : The Document object associated with this node.
+ */
+CharacterData = function(ownerDocument) {
+    Node.apply(this, arguments);
+};
+CharacterData.prototype = new Node();
+__extend__(CharacterData.prototype,{
+    get data(){
+        return this.nodeValue;
+    },
+    set data(data){
+        this.nodeValue = data;
+    },
+    get textContent(){
+        return this.nodeValue;
+    },
+    set textContent(newText){
+        this.nodeValue = newText;
+    },
+    get length(){return this.nodeValue.length;},
+    appendData: function(arg){
+        // throw Exception if CharacterData is readonly
+        if (__ownerDocument__(this).implementation.errorChecking && this._readonly) {
+            throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+        }
+        // append data
+        this.data = "" + this.data + arg;
+    },
+    deleteData: function(offset, count){
+        // throw Exception if CharacterData is readonly
+        if (__ownerDocument__(this).implementation.errorChecking && this._readonly) {
+            throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+        }
+        if (this.data) {
+            // throw Exception if offset is negative or greater than the data length,
+            if (__ownerDocument__(this).implementation.errorChecking &&
+                ((offset < 0) || (offset >  this.data.length) || (count < 0))) {
+                throw(new DOMException(DOMException.INDEX_SIZE_ERR));
+            }
+
+            // delete data
+            if(!count || (offset + count) > this.data.length) {
+              this.data = this.data.substring(0, offset);
+            }else {
+              this.data = this.data.substring(0, offset).
+                concat(this.data.substring(offset + count));
+            }
+        }
+    },
+    insertData: function(offset, arg){
+        // throw Exception if CharacterData is readonly
+        if(__ownerDocument__(this).implementation.errorChecking && this._readonly){
+            throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+        }
+
+        if(this.data){
+            // throw Exception if offset is negative or greater than the data length,
+            if (__ownerDocument__(this).implementation.errorChecking &&
+                ((offset < 0) || (offset >  this.data.length))) {
+                throw(new DOMException(DOMException.INDEX_SIZE_ERR));
+            }
+
+            // insert data
+            this.data =  this.data.substring(0, offset).concat(arg, this.data.substring(offset));
+        }else {
+            // throw Exception if offset is negative or greater than the data length,
+            if (__ownerDocument__(this).implementation.errorChecking && (offset !== 0)) {
+               throw(new DOMException(DOMException.INDEX_SIZE_ERR));
+            }
+
+            // set data
+            this.data = arg;
+        }
+    },
+    replaceData: function(offset, count, arg){
+        // throw Exception if CharacterData is readonly
+        if (__ownerDocument__(this).implementation.errorChecking && this._readonly) {
+            throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+        }
+
+        if (this.data) {
+            // throw Exception if offset is negative or greater than the data length,
+            if (__ownerDocument__(this).implementation.errorChecking &&
+                ((offset < 0) || (offset >  this.data.length) || (count < 0))) {
+                throw(new DOMException(DOMException.INDEX_SIZE_ERR));
+            }
+
+            // replace data
+            this.data = this.data.substring(0, offset).
+                concat(arg, this.data.substring(offset + count));
+        }else {
+            // set data
+            this.data = arg;
+        }
+    },
+    substringData: function(offset, count){
+        var ret = null;
+        if (this.data) {
+            // throw Exception if offset is negative or greater than the data length,
+            // or the count is negative
+            if (__ownerDocument__(this).implementation.errorChecking &&
+                ((offset < 0) || (offset > this.data.length) || (count < 0))) {
+                throw(new DOMException(DOMException.INDEX_SIZE_ERR));
+            }
+            // if count is not specified
+            if (!count) {
+                ret = this.data.substring(offset); // default to 'end of string'
+            }else{
+                ret = this.data.substring(offset, offset + count);
+            }
+        }
+        return ret;
+    },
+    toString : function(){
+        return "[object CharacterData]";
+    }
+});
+
+/**
+ * @class  Text
+ *      The Text interface represents the textual content (termed
+ *      character data in XML) of an Element or Attr.
+ *      If there is no markup inside an element's content, the text is
+ *      contained in a single object implementing the Text interface that
+ *      is the only child of the element. If there is markup, it is
+ *      parsed into a list of elements and Text nodes that form the
+ *      list of children of the element.
+ * @extends CharacterData
+ * @param  ownerDocument The Document object associated with this node.
+ */
+Text = function(ownerDocument) {
+    CharacterData.apply(this, arguments);
+    this.nodeName  = "#text";
+};
+Text.prototype = new CharacterData();
+__extend__(Text.prototype,{
+    get localName(){
+        return null;
+    },
+    // Breaks this Text node into two Text nodes at the specified offset,
+    // keeping both in the tree as siblings. This node then only contains
+    // all the content up to the offset point.  And a new Text node, which
+    // is inserted as the next sibling of this node, contains all the
+    // content at and after the offset point.
+    splitText : function(offset) {
+        var data,
+            inode;
+        // test for exceptions
+        if (__ownerDocument__(this).implementation.errorChecking) {
+            // throw Exception if Node is readonly
+            if (this._readonly) {
+              throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+            }
+            // throw Exception if offset is negative or greater than the data length,
+            if ((offset < 0) || (offset > this.data.length)) {
+              throw(new DOMException(DOMException.INDEX_SIZE_ERR));
+            }
+        }
+        if (this.parentNode) {
+            // get remaining string (after offset)
+            data  = this.substringData(offset);
+            // create new TextNode with remaining string
+            inode = __ownerDocument__(this).createTextNode(data);
+            // attach new TextNode
+            if (this.nextSibling) {
+              this.parentNode.insertBefore(inode, this.nextSibling);
+            } else {
+              this.parentNode.appendChild(inode);
+            }
+            // remove remaining string from original TextNode
+            this.deleteData(offset);
+        }
+        return inode;
+    },
+    get nodeType(){
+        return Node.TEXT_NODE;
+    },
+    get xml(){
+        return __escapeXML__(""+ this.nodeValue);
+    },
+    toString: function(){
+        return "[object Text]";
+    }
+});
+
+/**
+ * @class CDATASection 
+ *      CDATA sections are used to escape blocks of text containing 
+ *      characters that would otherwise be regarded as markup.
+ *      The only delimiter that is recognized in a CDATA section is 
+ *      the "\]\]\>" string that ends the CDATA section
+ * @extends Text
+ * @param  ownerDocument : The Document object associated with this node.
+ */
+CDATASection = function(ownerDocument) {
+    Text.apply(this, arguments);
+    this.nodeName = '#cdata-section';
+};
+CDATASection.prototype = new Text();
+__extend__(CDATASection.prototype,{
+    get nodeType(){
+        return Node.CDATA_SECTION_NODE;
+    },
+    get xml(){
+        return "<![CDATA[" + this.nodeValue + "]]>";
+    },
+    toString : function(){
+        return "[object CDATASection]";
+    }
+});
+/**
+ * @class  Comment
+ *      This represents the content of a comment, i.e., all the
+ *      characters between the starting '<!--' and ending '-->'
+ * @extends CharacterData
+ * @param  ownerDocument :  The Document object associated with this node.
+ */
+Comment = function(ownerDocument) {
+    CharacterData.apply(this, arguments);
+    this.nodeName  = "#comment";
+};
+Comment.prototype = new CharacterData();
+__extend__(Comment.prototype, {
+    get localName(){
+        return null;
+    },
+    get nodeType(){
+        return Node.COMMENT_NODE;
+    },
+    get xml(){
+        return "<!--" + this.nodeValue + "-->";
+    },
+    toString : function(){
+        return "[object Comment]";
+    }
+});
+
+
+/**
+ * @author envjs team
+ * @param {Document} onwnerDocument
+ */
+DocumentType = function(ownerDocument) {
+    Node.apply(this, arguments);
+    this.systemId = null;
+    this.publicId = null;
+};
+DocumentType.prototype = new Node();
+__extend__({
+    get name(){
+        return this.nodeName;
+    },
+    get entities(){
+        return null;
+    },
+    get internalSubsets(){
+        return null;
+    },
+    get notations(){
+        return null;
+    },
+    toString : function(){
+        return "[object DocumentType]";
+    }
+});
+
+/**
+ * @class  Attr
+ *      The Attr interface represents an attribute in an Element object
+ * @extends Node
+ * @param  ownerDocument : The Document object associated with this node.
+ */
+Attr = function(ownerDocument) {
+    Node.apply(this, arguments);
+    // set when Attr is added to NamedNodeMap
+    this.ownerElement = null;
+    //TODO: our implementation of Attr is incorrect because we don't
+    //      treat the value of the attribute as a child text node.
+};
+Attr.prototype = new Node();
+__extend__(Attr.prototype, {
+    // the name of this attribute
+    get name(){
+        return this.nodeName;
+    },
+    // the value of the attribute is returned as a string
+    get value(){
+        return this.nodeValue||'';
+    },
+    set value(value){
+        // throw Exception if Attribute is readonly
+        if (__ownerDocument__(this).implementation.errorChecking && this._readonly) {
+            throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+        }
+        // delegate to node
+        this.nodeValue = value;
+    },
+    get textContent(){
+        return this.nodeValue;
+    },
+    set textContent(newText){
+        this.nodeValue = newText;
+    },
+    get specified(){
+        return (this !== null && this !== undefined);
+    },
+    get nodeType(){
+        return Node.ATTRIBUTE_NODE;
+    },
+    get xml() {
+        if (this.nodeValue) {
+            return  __escapeXML__(this.nodeValue+"");
+        } else {
+            return '';
+        }
+    },
+    toString : function() {
+        return '[object Attr]';
+    }
+});
+
+
+/**
+ * @class  Element -
+ *      By far the vast majority of objects (apart from text)
+ *      that authors encounter when traversing a document are
+ *      Element nodes.
+ * @extends Node
+ * @param  ownerDocument : The Document object associated with this node.
+ */
+Element = function(ownerDocument) {
+    Node.apply(this, arguments);
+    this.attributes = new NamedNodeMap(this.ownerDocument, this);
+};
+Element.prototype = new Node();
+__extend__(Element.prototype, {
+    // The name of the element.
+    get tagName(){
+        return this.nodeName;
+    },
+
+    getAttribute: function(name) {
+        var ret = null;
+        // if attribute exists, use it
+        var attr = this.attributes.getNamedItem(name);
+        if (attr) {
+            ret = attr.value;
+        }
+        // if Attribute exists, return its value, otherwise, return null
+        return ret;
+    },
+    setAttribute : function (name, value) {
+        // if attribute exists, use it
+        var attr = this.attributes.getNamedItem(name);
+       //console.log('attr %s', attr);
+        //I had to add this check because as the script initializes
+        //the id may be set in the constructor, and the html element
+        //overrides the id property with a getter/setter.
+        if(__ownerDocument__(this)){
+            if (attr===null||attr===undefined) {
+                // otherwise create it
+                attr = __ownerDocument__(this).createAttribute(name);
+               //console.log('attr %s', attr);
+            }
+
+
+            // test for exceptions
+            if (__ownerDocument__(this).implementation.errorChecking) {
+                // throw Exception if Attribute is readonly
+                if (attr._readonly) {
+                    throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+                }
+
+                // throw Exception if the value string contains an illegal character
+                if (!__isValidString__(value+'')) {
+                    throw(new DOMException(DOMException.INVALID_CHARACTER_ERR));
+                }
+            }
+
+            // assign values to properties (and aliases)
+            attr.value     = value + '';
+
+            // add/replace Attribute in NamedNodeMap
+            this.attributes.setNamedItem(attr);
+           //console.log('element setNamedItem %s', attr);
+        }else{
+           console.warn('Element has no owner document '+this.tagName+
+                '\n\t cant set attribute ' + name + ' = '+value );
+        }
+    },
+    removeAttribute : function removeAttribute(name) {
+        // delegate to NamedNodeMap.removeNamedItem
+        return this.attributes.removeNamedItem(name);
+    },
+    getAttributeNode : function getAttributeNode(name) {
+        // delegate to NamedNodeMap.getNamedItem
+        return this.attributes.getNamedItem(name);
+    },
+    setAttributeNode: function(newAttr) {
+        // if this Attribute is an ID
+        if (__isIdDeclaration__(newAttr.name)) {
+            this.id = newAttr.value;  // cache ID for getElementById()
+        }
+        // delegate to NamedNodeMap.setNamedItem
+        return this.attributes.setNamedItem(newAttr);
+    },
+    removeAttributeNode: function(oldAttr) {
+      // throw Exception if Attribute is readonly
+      if (__ownerDocument__(this).implementation.errorChecking && oldAttr._readonly) {
+        throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+      }
+
+      // get item index
+      var itemIndex = this.attributes._findItemIndex(oldAttr._id);
+
+      // throw Exception if node does not exist in this map
+      if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) {
+        throw(new DOMException(DOMException.NOT_FOUND_ERR));
+      }
+
+      return this.attributes._removeChild(itemIndex);
+    },
+    getAttributeNS : function(namespaceURI, localName) {
+        var ret = "";
+        // delegate to NAmedNodeMap.getNamedItemNS
+        var attr = this.attributes.getNamedItemNS(namespaceURI, localName);
+        if (attr) {
+            ret = attr.value;
+        }
+        return ret;  // if Attribute exists, return its value, otherwise return ""
+    },
+    setAttributeNS : function(namespaceURI, qualifiedName, value) {
+        // call NamedNodeMap.getNamedItem
+        //console.log('setAttributeNS %s %s %s', namespaceURI, qualifiedName, value);
+        var attr = this.attributes.getNamedItem(namespaceURI, qualifiedName);
+
+        if (!attr) {  // if Attribute exists, use it
+            // otherwise create it
+            attr = __ownerDocument__(this).createAttributeNS(namespaceURI, qualifiedName);
+        }
+
+        value = '' + value;
+
+        // test for exceptions
+        if (__ownerDocument__(this).implementation.errorChecking) {
+            // throw Exception if Attribute is readonly
+            if (attr._readonly) {
+                throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+            }
+
+            // throw Exception if the Namespace is invalid
+            if (!__isValidNamespace__(this.ownerDocument, namespaceURI, qualifiedName, true)) {
+                throw(new DOMException(DOMException.NAMESPACE_ERR));
+            }
+
+            // throw Exception if the value string contains an illegal character
+            if (!__isValidString__(value)) {
+                throw(new DOMException(DOMException.INVALID_CHARACTER_ERR));
+            }
+        }
+
+        // if this Attribute is an ID
+        //if (__isIdDeclaration__(name)) {
+        //    this.id = value;
+        //}
+
+        // assign values to properties (and aliases)
+        attr.value     = value;
+        attr.nodeValue = value;
+
+        // delegate to NamedNodeMap.setNamedItem
+        this.attributes.setNamedItemNS(attr);
+    },
+    removeAttributeNS : function(namespaceURI, localName) {
+        // delegate to NamedNodeMap.removeNamedItemNS
+        return this.attributes.removeNamedItemNS(namespaceURI, localName);
+    },
+    getAttributeNodeNS : function(namespaceURI, localName) {
+        // delegate to NamedNodeMap.getNamedItemNS
+        return this.attributes.getNamedItemNS(namespaceURI, localName);
+    },
+    setAttributeNodeNS : function(newAttr) {
+        // if this Attribute is an ID
+        if ((newAttr.prefix == "") &&  __isIdDeclaration__(newAttr.name)) {
+            this.id = newAttr.value+'';  // cache ID for getElementById()
+        }
+
+        // delegate to NamedNodeMap.setNamedItemNS
+        return this.attributes.setNamedItemNS(newAttr);
+    },
+    hasAttribute : function(name) {
+        // delegate to NamedNodeMap._hasAttribute
+        return __hasAttribute__(this.attributes,name);
+    },
+    hasAttributeNS : function(namespaceURI, localName) {
+        // delegate to NamedNodeMap._hasAttributeNS
+        return __hasAttributeNS__(this.attributes, namespaceURI, localName);
+    },
+    get nodeType(){
+        return Node.ELEMENT_NODE;
+    },
+    get xml() {
+        var ret = "",
+            ns = "",
+            attrs,
+            attrstring,
+            i;
+
+        // serialize namespace declarations
+        if (this.namespaceURI ){
+            if((this === this.ownerDocument.documentElement) ||
+               (!this.parentNode)||
+               (this.parentNode && (this.parentNode.namespaceURI !== this.namespaceURI))) {
+                ns = ' xmlns' + (this.prefix?(':'+this.prefix):'') +
+                    '="' + this.namespaceURI + '"';
+            }
+        }
+
+        // serialize Attribute declarations
+        attrs = this.attributes;
+        attrstring = "";
+        for(i=0;i< attrs.length;i++){
+            if(attrs[i].name.match('xmlns:')) {
+                attrstring += " "+attrs[i].name+'="'+attrs[i].xml+'"';
+            }
+        }
+        for(i=0;i< attrs.length;i++){
+            if(!attrs[i].name.match('xmlns:')) {
+                attrstring += " "+attrs[i].name+'="'+attrs[i].xml+'"';
+            }
+        }
+
+        if(this.hasChildNodes()){
+            // serialize this Element
+            ret += "<" + this.tagName + ns + attrstring +">";
+            ret += this.childNodes.xml;
+            ret += "</" + this.tagName + ">";
+        }else{
+            ret += "<" + this.tagName + ns + attrstring +"/>";
+        }
+
+        return ret;
+    },
+    toString : function(){
+        return '[object Element]';
+    }
+});
+/**
+ * @class  DOMException - raised when an operation is impossible to perform
+ * @author Jon van Noort (jon@webarcana.com.au)
+ * @param  code : int - the exception code (one of the DOMException constants)
+ */
+DOMException = function(code) {
+    this.code = code;
+};
+
+// DOMException constants
+// Introduced in DOM Level 1:
+DOMException.INDEX_SIZE_ERR                 = 1;
+DOMException.DOMSTRING_SIZE_ERR             = 2;
+DOMException.HIERARCHY_REQUEST_ERR          = 3;
+DOMException.WRONG_DOCUMENT_ERR             = 4;
+DOMException.INVALID_CHARACTER_ERR          = 5;
+DOMException.NO_DATA_ALLOWED_ERR            = 6;
+DOMException.NO_MODIFICATION_ALLOWED_ERR    = 7;
+DOMException.NOT_FOUND_ERR                  = 8;
+DOMException.NOT_SUPPORTED_ERR              = 9;
+DOMException.INUSE_ATTRIBUTE_ERR            = 10;
+
+// Introduced in DOM Level 2:
+DOMException.INVALID_STATE_ERR              = 11;
+DOMException.SYNTAX_ERR                     = 12;
+DOMException.INVALID_MODIFICATION_ERR       = 13;
+DOMException.NAMESPACE_ERR                  = 14;
+DOMException.INVALID_ACCESS_ERR             = 15;
+
+/**
+ * @class  DocumentFragment -
+ *      DocumentFragment is a "lightweight" or "minimal" Document object.
+ * @extends Node
+ * @param  ownerDocument :  The Document object associated with this node.
+ */
+DocumentFragment = function(ownerDocument) {
+    Node.apply(this, arguments);
+    this.nodeName  = "#document-fragment";
+};
+DocumentFragment.prototype = new Node();
+__extend__(DocumentFragment.prototype,{
+    get nodeType(){
+        return Node.DOCUMENT_FRAGMENT_NODE;
+    },
+    get xml(){
+        var xml = "",
+        count = this.childNodes.length;
+
+        // create string concatenating the serialized ChildNodes
+        for (var i = 0; i < count; i++) {
+            xml += this.childNodes.item(i).xml;
+        }
+
+        return xml;
+    },
+    toString : function(){
+        return "[object DocumentFragment]";
+    },
+    get localName(){
+        return null;
+    }
+});
+
+
+/**
+ * @class  ProcessingInstruction -
+ *      The ProcessingInstruction interface represents a
+ *      "processing instruction", used in XML as a way to
+ *      keep processor-specific information in the text of
+ *      the document
+ * @extends Node
+ * @author Jon van Noort (jon@webarcana.com.au)
+ * @param  ownerDocument :  The Document object associated with this node.
+ */
+ProcessingInstruction = function(ownerDocument) {
+    Node.apply(this, arguments);
+};
+ProcessingInstruction.prototype = new Node();
+__extend__(ProcessingInstruction.prototype, {
+    get data(){
+        return this.nodeValue;
+    },
+    set data(data){
+        // throw Exception if Node is readonly
+        if (__ownerDocument__(this).errorChecking && this._readonly) {
+            throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+        }
+        this.nodeValue = data;
+    },
+    get textContent(){
+        return this.data;
+    },
+    get localName(){
+        return null;
+    },
+    get target(){
+      // The target of this processing instruction.
+      // XML defines this as being the first token following the markup that begins the processing instruction.
+      // The content of this processing instruction.
+        return this.nodeName;
+    },
+    set target(value){
+      // The target of this processing instruction.
+      // XML defines this as being the first token following the markup that begins the processing instruction.
+      // The content of this processing instruction.
+        this.nodeName = value;
+    },
+    get nodeType(){
+        return Node.PROCESSING_INSTRUCTION_NODE;
+    },
+    get xml(){
+        return "<?" + this.nodeName +" "+ this.nodeValue + "?>";
+    },
+    toString : function(){
+        return "[object ProcessingInstruction]";
+    }
+});
+
+
+/**
+ * @author envjs team
+ */
+
+Entity = function() {
+    throw new Error("Entity Not Implemented" );
+};
+
+Entity.constants = {
+        // content taken from W3C "HTML 4.01 Specification"
+        //                        "W3C Recommendation 24 December 1999"
+
+    nbsp: "\u00A0",
+    iexcl: "\u00A1",
+    cent: "\u00A2",
+    pound: "\u00A3",
+    curren: "\u00A4",
+    yen: "\u00A5",
+    brvbar: "\u00A6",
+    sect: "\u00A7",
+    uml: "\u00A8",
+    copy: "\u00A9",
+    ordf: "\u00AA",
+    laquo: "\u00AB",
+    not: "\u00AC",
+    shy: "\u00AD",
+    reg: "\u00AE",
+    macr: "\u00AF",
+    deg: "\u00B0",
+    plusmn: "\u00B1",
+    sup2: "\u00B2",
+    sup3: "\u00B3",
+    acute: "\u00B4",
+    micro: "\u00B5",
+    para: "\u00B6",
+    middot: "\u00B7",
+    cedil: "\u00B8",
+    sup1: "\u00B9",
+    ordm: "\u00BA",
+    raquo: "\u00BB",
+    frac14: "\u00BC",
+    frac12: "\u00BD",
+    frac34: "\u00BE",
+    iquest: "\u00BF",
+    Agrave: "\u00C0",
+    Aacute: "\u00C1",
+    Acirc: "\u00C2",
+    Atilde: "\u00C3",
+    Auml: "\u00C4",
+    Aring: "\u00C5",
+    AElig: "\u00C6",
+    Ccedil: "\u00C7",
+    Egrave: "\u00C8",
+    Eacute: "\u00C9",
+    Ecirc: "\u00CA",
+    Euml: "\u00CB",
+    Igrave: "\u00CC",
+    Iacute: "\u00CD",
+    Icirc: "\u00CE",
+    Iuml: "\u00CF",
+    ETH: "\u00D0",
+    Ntilde: "\u00D1",
+    Ograve: "\u00D2",
+    Oacute: "\u00D3",
+    Ocirc: "\u00D4",
+    Otilde: "\u00D5",
+    Ouml: "\u00D6",
+    times: "\u00D7",
+    Oslash: "\u00D8",
+    Ugrave: "\u00D9",
+    Uacute: "\u00DA",
+    Ucirc: "\u00DB",
+    Uuml: "\u00DC",
+    Yacute: "\u00DD",
+    THORN: "\u00DE",
+    szlig: "\u00DF",
+    agrave: "\u00E0",
+    aacute: "\u00E1",
+    acirc: "\u00E2",
+    atilde: "\u00E3",
+    auml: "\u00E4",
+    aring: "\u00E5",
+    aelig: "\u00E6",
+    ccedil: "\u00E7",
+    egrave: "\u00E8",
+    eacute: "\u00E9",
+    ecirc: "\u00EA",
+    euml: "\u00EB",
+    igrave: "\u00EC",
+    iacute: "\u00ED",
+    icirc: "\u00EE",
+    iuml: "\u00EF",
+    eth: "\u00F0",
+    ntilde: "\u00F1",
+    ograve: "\u00F2",
+    oacute: "\u00F3",
+    ocirc: "\u00F4",
+    otilde: "\u00F5",
+    ouml: "\u00F6",
+    divide: "\u00F7",
+    oslash: "\u00F8",
+    ugrave: "\u00F9",
+    uacute: "\u00FA",
+    ucirc: "\u00FB",
+    uuml: "\u00FC",
+    yacute: "\u00FD",
+    thorn: "\u00FE",
+    yuml: "\u00FF",
+    fnof: "\u0192",
+    Alpha: "\u0391",
+    Beta: "\u0392",
+    Gamma: "\u0393",
+    Delta: "\u0394",
+    Epsilon: "\u0395",
+    Zeta: "\u0396",
+    Eta: "\u0397",
+    Theta: "\u0398",
+    Iota: "\u0399",
+    Kappa: "\u039A",
+    Lambda: "\u039B",
+    Mu: "\u039C",
+    Nu: "\u039D",
+    Xi: "\u039E",
+    Omicron: "\u039F",
+    Pi: "\u03A0",
+    Rho: "\u03A1",
+    Sigma: "\u03A3",
+    Tau: "\u03A4",
+    Upsilon: "\u03A5",
+    Phi: "\u03A6",
+    Chi: "\u03A7",
+    Psi: "\u03A8",
+    Omega: "\u03A9",
+    alpha: "\u03B1",
+    beta: "\u03B2",
+    gamma: "\u03B3",
+    delta: "\u03B4",
+    epsilon: "\u03B5",
+    zeta: "\u03B6",
+    eta: "\u03B7",
+    theta: "\u03B8",
+    iota: "\u03B9",
+    kappa: "\u03BA",
+    lambda: "\u03BB",
+    mu: "\u03BC",
+    nu: "\u03BD",
+    xi: "\u03BE",
+    omicron: "\u03BF",
+    pi: "\u03C0",
+    rho: "\u03C1",
+    sigmaf: "\u03C2",
+    sigma: "\u03C3",
+    tau: "\u03C4",
+    upsilon: "\u03C5",
+    phi: "\u03C6",
+    chi: "\u03C7",
+    psi: "\u03C8",
+    omega: "\u03C9",
+    thetasym: "\u03D1",
+    upsih: "\u03D2",
+    piv: "\u03D6",
+    bull: "\u2022",
+    hellip: "\u2026",
+    prime: "\u2032",
+    Prime: "\u2033",
+    oline: "\u203E",
+    frasl: "\u2044",
+    weierp: "\u2118",
+    image: "\u2111",
+    real: "\u211C",
+    trade: "\u2122",
+    alefsym: "\u2135",
+    larr: "\u2190",
+    uarr: "\u2191",
+    rarr: "\u2192",
+    darr: "\u2193",
+    harr: "\u2194",
+    crarr: "\u21B5",
+    lArr: "\u21D0",
+    uArr: "\u21D1",
+    rArr: "\u21D2",
+    dArr: "\u21D3",
+    hArr: "\u21D4",
+    forall: "\u2200",
+    part: "\u2202",
+    exist: "\u2203",
+    empty: "\u2205",
+    nabla: "\u2207",
+    isin: "\u2208",
+    notin: "\u2209",
+    ni: "\u220B",
+    prod: "\u220F",
+    sum: "\u2211",
+    minus: "\u2212",
+    lowast: "\u2217",
+    radic: "\u221A",
+    prop: "\u221D",
+    infin: "\u221E",
+    ang: "\u2220",
+    and: "\u2227",
+    or: "\u2228",
+    cap: "\u2229",
+    cup: "\u222A",
+    intXX: "\u222B",
+    there4: "\u2234",
+    sim: "\u223C",
+    cong: "\u2245",
+    asymp: "\u2248",
+    ne: "\u2260",
+    equiv: "\u2261",
+    le: "\u2264",
+    ge: "\u2265",
+    sub: "\u2282",
+    sup: "\u2283",
+    nsub: "\u2284",
+    sube: "\u2286",
+    supe: "\u2287",
+    oplus: "\u2295",
+    otimes: "\u2297",
+    perp: "\u22A5",
+    sdot: "\u22C5",
+    lceil: "\u2308",
+    rceil: "\u2309",
+    lfloor: "\u230A",
+    rfloor: "\u230B",
+    lang: "\u2329",
+    rang: "\u232A",
+    loz: "\u25CA",
+    spades: "\u2660",
+    clubs: "\u2663",
+    hearts: "\u2665",
+    diams: "\u2666",
+    quot: "\u0022",
+    amp: "\u0026",
+    lt: "\u003C",
+    gt: "\u003E",
+    OElig: "\u0152",
+    oelig: "\u0153",
+    Scaron: "\u0160",
+    scaron: "\u0161",
+    Yuml: "\u0178",
+    circ: "\u02C6",
+    tilde: "\u02DC",
+    ensp: "\u2002",
+    emsp: "\u2003",
+    thinsp: "\u2009",
+    zwnj: "\u200C",
+    zwj: "\u200D",
+    lrm: "\u200E",
+    rlm: "\u200F",
+    ndash: "\u2013",
+    mdash: "\u2014",
+    lsquo: "\u2018",
+    rsquo: "\u2019",
+    sbquo: "\u201A",
+    ldquo: "\u201C",
+    rdquo: "\u201D",
+    bdquo: "\u201E",
+    dagger: "\u2020",
+    Dagger: "\u2021",
+    permil: "\u2030",
+    lsaquo: "\u2039",
+    rsaquo: "\u203A",
+    euro: "\u20AC",
+
+    // non-standard entities
+    apos: "'"
+};
+
+/**
+ * @author envjs team
+ */
+
+EntityReference = function() {
+    throw new Error("EntityReference Not Implemented" );
+};
+
+/**
+ * @class  DOMImplementation -
+ *      provides a number of methods for performing operations
+ *      that are independent of any particular instance of the
+ *      document object model.
+ *
+ * @author Jon van Noort (jon@webarcana.com.au)
+ */
+DOMImplementation = function() {
+    this.preserveWhiteSpace = false;  // by default, ignore whitespace
+    this.namespaceAware = true;       // by default, handle namespaces
+    this.errorChecking  = true;      // by default, test for exceptions
+};
+
+__extend__(DOMImplementation.prototype,{
+    // @param  feature : string - The package name of the feature to test.
+    //      the legal only values are "XML" and "CORE" (case-insensitive).
+    // @param  version : string - This is the version number of the package
+    //       name to test. In Level 1, this is the string "1.0".*
+    // @return : boolean
+    hasFeature : function(feature, version) {
+        var ret = false;
+        if (feature.toLowerCase() == "xml") {
+            ret = (!version || (version == "1.0") || (version == "2.0"));
+        }
+        else if (feature.toLowerCase() == "core") {
+            ret = (!version || (version == "2.0"));
+        }
+        else if (feature == "http://www.w3.org/TR/SVG11/feature#BasicStructure") {
+            ret = (version == "1.1");
+        }
+        return ret;
+    },
+    createDocumentType : function(qname, publicId, systemId){
+        var doctype = new DocumentType();
+        doctype.nodeName = qname?qname.toUpperCase():null;
+        doctype.publicId = publicId?publicId:null;
+        doctype.systemId = systemId?systemId:null;
+        return doctype;
+    },
+    createDocument : function(nsuri, qname, doctype){
+
+        var doc = null, documentElement;
+
+        doc = new Document(this, null);
+        if(doctype){
+            doc.doctype = doctype;
+        }
+
+        if(nsuri && qname){
+            documentElement = doc.createElementNS(nsuri, qname);
+        }else if(qname){
+            documentElement = doc.createElement(qname);
+        }
+        if(documentElement){
+            doc.appendChild(documentElement);
+        }
+        return doc;
+    },
+    createHTMLDocument : function(title){
+        var doc = new HTMLDocument($implementation, null, "");
+        var html = doc.createElement("html"); doc.appendChild(html);
+        var head = doc.createElement("head"); html.appendChild(head);
+        var body = doc.createElement("body"); html.appendChild(body);
+        var t = doc.createElement("title"); head.appendChild(t);
+        if( title) {
+            t.appendChild(doc.createTextNode(title));
+        }
+        return doc;
+    },
+    translateErrCode : function(code) {
+        //convert DOMException Code to human readable error message;
+      var msg = "";
+
+      switch (code) {
+        case DOMException.INDEX_SIZE_ERR :                // 1
+           msg = "INDEX_SIZE_ERR: Index out of bounds";
+           break;
+
+        case DOMException.DOMSTRING_SIZE_ERR :            // 2
+           msg = "DOMSTRING_SIZE_ERR: The resulting string is too long to fit in a DOMString";
+           break;
+
+        case DOMException.HIERARCHY_REQUEST_ERR :         // 3
+           msg = "HIERARCHY_REQUEST_ERR: The Node can not be inserted at this location";
+           break;
+
+        case DOMException.WRONG_DOCUMENT_ERR :            // 4
+           msg = "WRONG_DOCUMENT_ERR: The source and the destination Documents are not the same";
+           break;
+
+        case DOMException.INVALID_CHARACTER_ERR :         // 5
+           msg = "INVALID_CHARACTER_ERR: The string contains an invalid character";
+           break;
+
+        case DOMException.NO_DATA_ALLOWED_ERR :           // 6
+           msg = "NO_DATA_ALLOWED_ERR: This Node / NodeList does not support data";
+           break;
+
+        case DOMException.NO_MODIFICATION_ALLOWED_ERR :   // 7
+           msg = "NO_MODIFICATION_ALLOWED_ERR: This object cannot be modified";
+           break;
+
+        case DOMException.NOT_FOUND_ERR :                 // 8
+           msg = "NOT_FOUND_ERR: The item cannot be found";
+           break;
+
+        case DOMException.NOT_SUPPORTED_ERR :             // 9
+           msg = "NOT_SUPPORTED_ERR: This implementation does not support function";
+           break;
+
+        case DOMException.INUSE_ATTRIBUTE_ERR :           // 10
+           msg = "INUSE_ATTRIBUTE_ERR: The Attribute has already been assigned to another Element";
+           break;
+
+        // Introduced in DOM Level 2:
+        case DOMException.INVALID_STATE_ERR :             // 11
+           msg = "INVALID_STATE_ERR: The object is no longer usable";
+           break;
+
+        case DOMException.SYNTAX_ERR :                    // 12
+           msg = "SYNTAX_ERR: Syntax error";
+           break;
+
+        case DOMException.INVALID_MODIFICATION_ERR :      // 13
+           msg = "INVALID_MODIFICATION_ERR: Cannot change the type of the object";
+           break;
+
+        case DOMException.NAMESPACE_ERR :                 // 14
+           msg = "NAMESPACE_ERR: The namespace declaration is incorrect";
+           break;
+
+        case DOMException.INVALID_ACCESS_ERR :            // 15
+           msg = "INVALID_ACCESS_ERR: The object does not support this function";
+           break;
+
+        default :
+           msg = "UNKNOWN: Unknown Exception Code ("+ code +")";
+      }
+
+      return msg;
+    },
+    toString : function(){
+        return "[object DOMImplementation]";
+    }
+});
+
+
+
+/**
+ * @method DOMImplementation._isNamespaceDeclaration - Return true, if attributeName is a namespace declaration
+ * @author Jon van Noort (jon@webarcana.com.au)
+ * @param  attributeName : string - the attribute name
+ * @return : boolean
+ */
+function __isNamespaceDeclaration__(attributeName) {
+  // test if attributeName is 'xmlns'
+  return (attributeName.indexOf('xmlns') > -1);
+}
+
+/**
+ * @method DOMImplementation._isIdDeclaration - Return true, if attributeName is an id declaration
+ * @author Jon van Noort (jon@webarcana.com.au)
+ * @param  attributeName : string - the attribute name
+ * @return : boolean
+ */
+function __isIdDeclaration__(attributeName) {
+  // test if attributeName is 'id' (case insensitive)
+  return attributeName?(attributeName.toLowerCase() == 'id'):false;
+}
+
+/**
+ * @method DOMImplementation._isValidName - Return true,
+ *   if name contains no invalid characters
+ * @author Jon van Noort (jon@webarcana.com.au)
+ * @param  name : string - the candidate name
+ * @return : boolean
+ */
+function __isValidName__(name) {
+  // test if name contains only valid characters
+  return name.match(re_validName);
+}
+var re_validName = /^[a-zA-Z_:][a-zA-Z0-9\.\-_:]*$/;
+
+/**
+ * @method DOMImplementation._isValidString - Return true, if string does not contain any illegal chars
+ *  All of the characters 0 through 31 and character 127 are nonprinting control characters.
+ *  With the exception of characters 09, 10, and 13, (Ox09, Ox0A, and Ox0D)
+ *  Note: different from _isValidName in that ValidStrings may contain spaces
+ * @author Jon van Noort (jon@webarcana.com.au)
+ * @param  name : string - the candidate string
+ * @return : boolean
+ */
+function __isValidString__(name) {
+  // test that string does not contains invalid characters
+  return (name.search(re_invalidStringChars) < 0);
+}
+var re_invalidStringChars = /\x01|\x02|\x03|\x04|\x05|\x06|\x07|\x08|\x0B|\x0C|\x0E|\x0F|\x10|\x11|\x12|\x13|\x14|\x15|\x16|\x17|\x18|\x19|\x1A|\x1B|\x1C|\x1D|\x1E|\x1F|\x7F/;
+
+/**
+ * @method DOMImplementation._parseNSName - parse the namespace name.
+ *  if there is no colon, the
+ * @author Jon van Noort (jon@webarcana.com.au)
+ * @param  qualifiedName : string - The qualified name
+ * @return : NSName - [
+         .prefix        : string - The prefix part of the qname
+         .namespaceName : string - The namespaceURI part of the qname
+    ]
+ */
+function __parseNSName__(qualifiedName) {
+    var resultNSName = {};
+    // unless the qname has a namespaceName, the prefix is the entire String
+    resultNSName.prefix          = qualifiedName;
+    resultNSName.namespaceName   = "";
+    // split on ':'
+    var delimPos = qualifiedName.indexOf(':');
+    if (delimPos > -1) {
+        // get prefix
+        resultNSName.prefix        = qualifiedName.substring(0, delimPos);
+        // get namespaceName
+        resultNSName.namespaceName = qualifiedName.substring(delimPos +1, qualifiedName.length);
+    }
+    return resultNSName;
+}
+
+/**
+ * @method DOMImplementation._parseQName - parse the qualified name
+ * @author Jon van Noort (jon@webarcana.com.au)
+ * @param  qualifiedName : string - The qualified name
+ * @return : QName
+ */
+function __parseQName__(qualifiedName) {
+    var resultQName = {};
+    // unless the qname has a prefix, the local name is the entire String
+    resultQName.localName = qualifiedName;
+    resultQName.prefix    = "";
+    // split on ':'
+    var delimPos = qualifiedName.indexOf(':');
+    if (delimPos > -1) {
+        // get prefix
+        resultQName.prefix    = qualifiedName.substring(0, delimPos);
+        // get localName
+        resultQName.localName = qualifiedName.substring(delimPos +1, qualifiedName.length);
+    }
+    return resultQName;
+}
+/**
+ * @author envjs team
+ */
+Notation = function() {
+    throw new Error("Notation Not Implemented" );
+};/**
+ * @author thatcher
+ */
+Range = function(){
+
+};
+
+__extend__(Range.prototype, {
+    get startContainer(){
+
+    },
+    get endContainer(){
+
+    },
+    get startOffset(){
+
+    },
+    get endOffset(){
+
+    },
+    get collapsed(){
+
+    },
+    get commonAncestorContainer(){
+
+    },
+    setStart: function(refNode, offset){//throws RangeException
+
+    },
+    setEnd: function(refNode, offset){//throws RangeException
+    
+    },
+    setStartBefore: function(refNode){//throws RangeException
+    
+    },
+    setStartAfter: function(refNode){//throws RangeException
+    
+    },
+    setEndBefore: function(refNode){//throws RangeException
+    
+    },
+    setEndAfter: function(refNode){//throws RangeException
+    
+    },
+    collapse: function(toStart){//throws RangeException
+    
+    },
+    selectNode: function(refNode){//throws RangeException
+    
+    },
+    selectNodeContents: function(refNode){//throws RangeException
+    
+    },
+    compareBoundaryPoints: function(how, sourceRange){
+
+    },
+    deleteContents: function(){
+
+    },
+    extractContents: function(){
+
+    },
+    cloneContents: function(){
+
+    },
+    insertNode: function(newNode){
+
+    },
+    surroundContents: function(newParent){
+
+    },
+    cloneRange: function(){
+
+    },
+    toString: function(){
+        return '[object Range]';
+    },
+    detach: function(){
+
+    }
+});
+
+
+  // CompareHow
+Range.START_TO_START                 = 0;
+Range.START_TO_END                   = 1;
+Range.END_TO_END                     = 2;
+Range.END_TO_START                   = 3;
+  
+/*
+ * Forward declarations
+ */
+var __isValidNamespace__;
+
+/**
+ * @class  Document - The Document interface represents the entire HTML
+ *      or XML document. Conceptually, it is the root of the document tree,
+ *      and provides the primary access to the document's data.
+ *
+ * @extends Node
+ * @param  implementation : DOMImplementation - the creator Implementation
+ */
+Document = function(implementation, docParentWindow) {
+    Node.apply(this, arguments);
+
+    //TODO: Temporary!!! Cnage back to true!!!
+    this.async = true;
+    // The Document Type Declaration (see DocumentType) associated with this document
+    this.doctype = null;
+    // The DOMImplementation object that handles this document.
+    this.implementation = implementation;
+
+    this.nodeName  = "#document";
+    // initially false, set to true by parser
+    this.parsing = false;
+    this.baseURI = 'about:blank';
+
+    this.ownerDocument = null;
+
+    this.importing = false;
+};
+
+Document.prototype = new Node();
+__extend__(Document.prototype,{
+    get localName(){
+        return null;
+    },
+    get textContent(){
+        return null;
+    },
+    get all(){
+        return this.getElementsByTagName("*");
+    },
+    get documentElement(){
+        var i, length = this.childNodes?this.childNodes.length:0;
+        for(i=0;i<length;i++){
+            if(this.childNodes[i].nodeType === Node.ELEMENT_NODE){
+                return this.childNodes[i];
+            }
+        }
+        return null;
+    },
+    get documentURI(){
+        return this.baseURI;
+    },
+    createExpression: function(xpath, nsuriMap){
+        return new XPathExpression(xpath, nsuriMap);
+    },
+    createDocumentFragment: function() {
+        var node = new DocumentFragment(this);
+        return node;
+    },
+    createTextNode: function(data) {
+        var node = new Text(this);
+        node.data = data;
+        return node;
+    },
+    createComment: function(data) {
+        var node = new Comment(this);
+        node.data = data;
+        return node;
+    },
+    createCDATASection : function(data) {
+        var node = new CDATASection(this);
+        node.data = data;
+        return node;
+    },
+    createProcessingInstruction: function(target, data) {
+        // throw Exception if the target string contains an illegal character
+        if (__ownerDocument__(this).implementation.errorChecking &&
+            (!__isValidName__(target))) {
+            throw(new DOMException(DOMException.INVALID_CHARACTER_ERR));
+        }
+
+        var node = new ProcessingInstruction(this);
+        node.target = target;
+        node.data = data;
+        return node;
+    },
+    createElement: function(tagName) {
+        // throw Exception if the tagName string contains an illegal character
+        if (__ownerDocument__(this).implementation.errorChecking &&
+            (!__isValidName__(tagName))) {
+            throw(new DOMException(DOMException.INVALID_CHARACTER_ERR));
+        }
+        var node = new Element(this);
+        node.nodeName = tagName;
+        return node;
+    },
+    createElementNS : function(namespaceURI, qualifiedName) {
+        //we use this as a parser flag to ignore the xhtml
+        //namespace assumed by the parser
+        //console.log('creating element %s %s', namespaceURI, qualifiedName);
+        if(this.baseURI === 'http://envjs.com/xml' &&
+            namespaceURI === 'http://www.w3.org/1999/xhtml'){
+            return this.createElement(qualifiedName);
+        }
+        //console.log('createElementNS %s %s', namespaceURI, qualifiedName);
+        if (__ownerDocument__(this).implementation.errorChecking) {
+            // throw Exception if the Namespace is invalid
+            if (!__isValidNamespace__(this, namespaceURI, qualifiedName)) {
+                throw(new DOMException(DOMException.NAMESPACE_ERR));
+            }
+
+            // throw Exception if the qualifiedName string contains an illegal character
+            if (!__isValidName__(qualifiedName)) {
+                throw(new DOMException(DOMException.INVALID_CHARACTER_ERR));
+            }
+        }
+        var node  = new Element(this);
+        var qname = __parseQName__(qualifiedName);
+        node.namespaceURI = namespaceURI;
+        node.prefix       = qname.prefix;
+        node.nodeName     = qualifiedName;
+
+        //console.log('created element %s %s', namespaceURI, qualifiedName);
+        return node;
+    },
+    createAttribute : function(name) {
+        //console.log('createAttribute %s ', name);
+        // throw Exception if the name string contains an illegal character
+        if (__ownerDocument__(this).implementation.errorChecking &&
+            (!__isValidName__(name))) {
+            throw(new DOMException(DOMException.INVALID_CHARACTER_ERR));
+        }
+        var node = new Attr(this);
+        node.nodeName = name;
+        return node;
+    },
+    createAttributeNS : function(namespaceURI, qualifiedName) {
+        //we use this as a parser flag to ignore the xhtml
+        //namespace assumed by the parser
+        if(this.baseURI === 'http://envjs.com/xml' &&
+            namespaceURI === 'http://www.w3.org/1999/xhtml'){
+            return this.createAttribute(qualifiedName);
+        }
+        //console.log('createAttributeNS %s %s', namespaceURI, qualifiedName);
+        // test for exceptions
+        if (this.implementation.errorChecking) {
+            // throw Exception if the Namespace is invalid
+            if (!__isValidNamespace__(this, namespaceURI, qualifiedName, true)) {
+                throw(new DOMException(DOMException.NAMESPACE_ERR));
+            }
+
+            // throw Exception if the qualifiedName string contains an illegal character
+            if (!__isValidName__(qualifiedName)) {
+                throw(new DOMException(DOMException.INVALID_CHARACTER_ERR));
+            }
+        }
+        var node  = new Attr(this);
+        var qname = __parseQName__(qualifiedName);
+        node.namespaceURI = namespaceURI === '' ? null : namespaceURI;
+        node.prefix       = qname.prefix;
+        node.nodeName     = qualifiedName;
+        node.nodeValue    = "";
+        //console.log('attribute %s %s %s', node.namespaceURI, node.prefix, node.nodeName);
+        return node;
+    },
+    createNamespace : function(qualifiedName) {
+        //console.log('createNamespace %s', qualifiedName);
+        // create Namespace specifying 'this' as ownerDocument
+        var node  = new Namespace(this);
+        var qname = __parseQName__(qualifiedName);
+
+        // assign values to properties (and aliases)
+        node.prefix       = qname.prefix;
+        node.localName    = qname.localName;
+        node.name         = qualifiedName;
+        node.nodeValue    = "";
+
+        return node;
+    },
+
+    createRange: function(){
+        return new Range();
+    },
+
+    evaluate: function(xpathText, contextNode, nsuriMapper, resultType, result){
+        //return new XPathExpression().evaluate();
+        throw Error('Document.evaluate not supported yet!');
+    },
+
+    getElementById : function(elementId) {
+        var retNode = null,
+            node;
+        // loop through all Elements
+        var all = this.getElementsByTagName('*');
+        for (var i=0; i < all.length; i++) {
+            node = all[i];
+            // if id matches
+            if (node.id == elementId) {
+                //found the node
+                retNode = node;
+                break;
+            }
+        }
+        return retNode;
+    },
+    normalizeDocument: function(){
+        this.normalize();
+    },
+    get nodeType(){
+        return Node.DOCUMENT_NODE;
+    },
+    get xml(){
+        return this.documentElement.xml;
+    },
+    toString: function(){
+        return "[object XMLDocument]";
+    },
+    get defaultView(){
+        return { getComputedStyle: function(elem){
+            return window.getComputedStyle(elem);
+        }};
+    },
+});
+
+/*
+ * Helper function
+ *
+ */
+__isValidNamespace__ = function(doc, namespaceURI, qualifiedName, isAttribute) {
+
+    if (doc.importing === true) {
+        //we're doing an importNode operation (or a cloneNode) - in both cases, there
+        //is no need to perform any namespace checking since the nodes have to have been valid
+        //to have gotten into the DOM in the first place
+        return true;
+    }
+
+    var valid = true;
+    // parse QName
+    var qName = __parseQName__(qualifiedName);
+
+
+    //only check for namespaces if we're finished parsing
+    if (this.parsing === false) {
+
+        // if the qualifiedName is malformed
+        if (qName.localName.indexOf(":") > -1 ){
+            valid = false;
+        }
+
+        if ((valid) && (!isAttribute)) {
+            // if the namespaceURI is not null
+            if (!namespaceURI) {
+                valid = false;
+            }
+        }
+
+        // if the qualifiedName has a prefix
+        if ((valid) && (qName.prefix === "")) {
+            valid = false;
+        }
+    }
+
+    // if the qualifiedName has a prefix that is "xml" and the namespaceURI is
+    //  different from "http://www.w3.org/XML/1998/namespace" [Namespaces].
+    if ((valid) && (qName.prefix === "xml") && (namespaceURI !== "http://www.w3.org/XML/1998/namespace")) {
+        valid = false;
+    }
+
+    return valid;
+};
+/**
+ *
+ * This file only handles XML parser.
+ * It is extended by parser/domparser.js (and parser/htmlparser.js)
+ *
+ * This depends on e4x, which some engines may not have.
+ *
+ * @author thatcher
+ */
+DOMParser = function(principle, documentURI, baseURI) {
+    // TODO: why/what should these 3 args do?
+};
+__extend__(DOMParser.prototype,{
+    parseFromString: function(xmlstring, mimetype){
+        var doc = new Document(new DOMImplementation()),
+            e4;
+
+        // The following are e4x directives.
+        // Full spec is here:
+        // http://www.ecma-international.org/publications/standards/Ecma-357.htm
+        //
+        // that is pretty gross, so checkout this summary
+        // http://rephrase.net/days/07/06/e4x
+        //
+        // also see the Mozilla Developer Center:
+        // https://developer.mozilla.org/en/E4X
+        //
+        XML.ignoreComments = false;
+        XML.ignoreProcessingInstructions = false;
+        XML.ignoreWhitespace = false;
+
+        // for some reason e4x can't handle initial xml declarations
+        // https://bugzilla.mozilla.org/show_bug.cgi?id=336551
+        // The official workaround is the big regexp below
+        // but simpler one seems to be ok
+        // xmlstring = xmlstring.replace(/^<\?xml\s+version\s*=\s*(["'])[^\1]+\1[^?]*\?>/, "");
+        //
+        xmlstring = xmlstring.replace(/<\?xml.*\?>/, '');
+
+        e4 = new XMLList(xmlstring);
+
+        __toDomNode__(e4, doc, doc);
+
+        //console.log('xml \n %s', doc.documentElement.xml);
+        return doc;
+    }
+});
+
+var __toDomNode__ = function(e4, parent, doc){
+    var xnode,
+        domnode,
+        children,
+        target,
+        value,
+        length,
+        element,
+        kind,
+        item;
+    //console.log('converting e4x node list \n %s', e4)
+
+    // not using the for each(item in e4) since some engines can't
+    // handle the syntax (i.e. says syntax error)
+    //
+    // for each(xnode in e4) {
+    for (item in e4) {
+        // NO do not do this if (e4.hasOwnProperty(item)) {
+        // breaks spidermonkey
+        xnode = e4[item];
+
+        kind = xnode.nodeKind();
+        //console.log('treating node kind %s', kind);
+        switch(kind){
+        case 'element':
+            // add node
+            //console.log('creating element %s %s', xnode.localName(), xnode.namespace());
+            if(xnode.namespace() && (xnode.namespace()+'') !== ''){
+                //console.log('createElementNS %s %s',xnode.namespace()+'', xnode.localName() );
+                domnode = doc.createElementNS(xnode.namespace()+'', xnode.localName());
+            }else{
+                domnode = doc.createElement(xnode.name()+'');
+            }
+            parent.appendChild(domnode);
+
+            // add attributes
+            __toDomNode__(xnode.attributes(), domnode, doc);
+
+            // add children
+            children = xnode.children();
+            length = children.length();
+            //console.log('recursing? %s', length ? 'yes' : 'no');
+            if (length > 0) {
+                __toDomNode__(children, domnode, doc);
+            }
+            break;
+        case 'attribute':
+            // console.log('setting attribute %s %s %s',
+            //       xnode.localName(), xnode.namespace(), xnode.valueOf());
+
+            //
+            // cross-platform alert.  The original code used
+            //  xnode.text() to get the attribute value
+            //  This worked in Rhino, but did not in Spidermonkey
+            //  valueOf seemed to work in both
+            //
+            if(xnode.namespace() && xnode.namespace().prefix){
+                //console.log("%s", xnode.namespace().prefix);
+                parent.setAttributeNS(xnode.namespace()+'',
+                                      xnode.namespace().prefix+':'+xnode.localName(),
+                                      xnode.valueOf());
+            }else if((xnode.name()+'').match('http://www.w3.org/2000/xmlns/::')){
+                if(xnode.localName()!=='xmlns'){
+                    parent.setAttributeNS('http://www.w3.org/2000/xmlns/',
+                                          'xmlns:'+xnode.localName(),
+                                          xnode.valueOf());
+                }
+            }else{
+                parent.setAttribute(xnode.localName()+'', xnode.valueOf());
+            }
+            break;
+        case 'text':
+            //console.log('creating text node : %s', xnode);
+            domnode = doc.createTextNode(xnode+'');
+            parent.appendChild(domnode);
+            break;
+        case 'comment':
+            //console.log('creating comment node : %s', xnode);
+            value = xnode+'';
+            domnode = doc.createComment(value.substring(4,value.length-3));
+            parent.appendChild(domnode);
+            break;
+        case 'processing-instruction':
+            //console.log('creating processing-instruction node : %s', xnode);
+            value = xnode+'';
+            target = value.split(' ')[0].substring(2);
+            value = value.split(' ').splice(1).join(' ').replace('?>','');
+            //console.log('creating processing-instruction data : %s', value);
+            domnode = doc.createProcessingInstruction(target, value);
+            parent.appendChild(domnode);
+            break;
+        default:
+            console.log('e4x DOM ERROR');
+            throw new Error("Assertion failed in xml parser");
+        }
+    }
+};
+/**
+ * @author envjs team
+ * @class XMLSerializer
+ */
+
+XMLSerializer = function() {};
+
+__extend__(XMLSerializer.prototype, {
+    serializeToString: function(node){
+        return node.xml;
+    },
+    toString : function(){
+        return "[object XMLSerializer]";
+    }
+});
+
+/**
+ * @author john resig & the envjs team
+ * @uri http://www.envjs.com/
+ * @copyright 2008-2010
+ * @license MIT
+ */
+//CLOSURE_END
+}());
+/*
+ * Envjs event.1.2.35
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ *
+ * This file simply provides the global definitions we need to
+ * be able to correctly implement to core browser DOM Event interfaces.
+ */
+/*var Event,
+    MouseEvent,
+    UIEvent,
+    KeyboardEvent,
+    MutationEvent,
+    DocumentEvent,
+    EventTarget,
+    EventException,
+    //nonstandard but very useful for implementing mutation events
+    //among other things like general profiling
+    Aspect;*/
+/*
+ * Envjs event.1.2.35 
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ */
+
+//CLOSURE_START
+(function(){
+
+
+
+
+
+/**
+ * @author john resig
+ */
+// Helper method for extending one object with another.
+function __extend__(a,b) {
+    for ( var i in b ) {
+        var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
+        if ( g || s ) {
+            if ( g ) { a.__defineGetter__(i, g); }
+            if ( s ) { a.__defineSetter__(i, s); }
+        } else {
+            a[i] = b[i];
+        }
+    } return a;
+}
+
+/**
+ * @author john resig
+ */
+//from jQuery
+function __setArray__( target, array ) {
+    // Resetting the length to 0, then using the native Array push
+    // is a super-fast way to populate an object with array-like properties
+    target.length = 0;
+    Array.prototype.push.apply( target, array );
+}
+/**
+ * Borrowed with love from:
+ * 
+ * jQuery AOP - jQuery plugin to add features of aspect-oriented programming (AOP) to jQuery.
+ * http://jquery-aop.googlecode.com/
+ *
+ * Licensed under the MIT license:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * Version: 1.1
+ */
+(function() {
+
+	var _after	= 1;
+	var _before	= 2;
+	var _around	= 3;
+	var _intro  = 4;
+	var _regexEnabled = true;
+
+	/**
+	 * Private weaving function.
+	 */
+	var weaveOne = function(source, method, advice) {
+
+		var old = source[method];
+
+		var aspect;
+		if (advice.type == _after)
+			aspect = function() {
+				var returnValue = old.apply(this, arguments);
+				return advice.value.apply(this, [returnValue, method]);
+			};
+		else if (advice.type == _before)
+			aspect = function() {
+				advice.value.apply(this, [arguments, method]);
+				return old.apply(this, arguments);
+			};
+		else if (advice.type == _intro)
+			aspect = function() {
+				return advice.value.apply(this, arguments);
+			};
+		else if (advice.type == _around) {
+			aspect = function() {
+				var invocation = { object: this, args: arguments };
+				return advice.value.apply(invocation.object, [{ arguments: invocation.args, method: method, proceed : 
+					function() {
+						return old.apply(invocation.object, invocation.args);
+					}
+				}] );
+			};
+		}
+
+		aspect.unweave = function() { 
+			source[method] = old;
+			pointcut = source = aspect = old = null;
+		};
+
+		source[method] = aspect;
+
+		return aspect;
+
+	};
+
+
+	/**
+	 * Private weaver and pointcut parser.
+	 */
+	var weave = function(pointcut, advice)
+	{
+
+		var source = (typeof(pointcut.target.prototype) != 'undefined') ? pointcut.target.prototype : pointcut.target;
+		var advices = [];
+
+		// If it's not an introduction and no method was found, try with regex...
+		if (advice.type != _intro && typeof(source[pointcut.method]) == 'undefined')
+		{
+
+			for (var method in source)
+			{
+				if (source[method] != null && source[method] instanceof Function && method.match(pointcut.method))
+				{
+					advices[advices.length] = weaveOne(source, method, advice);
+				}
+			}
+
+			if (advices.length == 0)
+				throw 'No method: ' + pointcut.method;
+
+		} 
+		else
+		{
+			// Return as an array of one element
+			advices[0] = weaveOne(source, pointcut.method, advice);
+		}
+
+		return _regexEnabled ? advices : advices[0];
+
+	};
+
+	Aspect = 
+	{
+		/**
+		 * Creates an advice after the defined point-cut. The advice will be executed after the point-cut method 
+		 * has completed execution successfully, and will receive one parameter with the result of the execution.
+		 * This function returns an array of weaved aspects (Function).
+		 *
+		 * @example jQuery.aop.after( {target: window, method: 'MyGlobalMethod'}, function(result) { alert('Returned: ' + result); } );
+		 * @result Array<Function>
+		 *
+		 * @example jQuery.aop.after( {target: String, method: 'indexOf'}, function(index) { alert('Result found at: ' + index + ' on:' + this); } );
+		 * @result Array<Function>
+		 *
+		 * @name after
+		 * @param Map pointcut Definition of the point-cut to apply the advice. A point-cut is the definition of the object/s and method/s to be weaved.
+		 * @option Object target Target object to be weaved. 
+		 * @option String method Name of the function to be weaved. Regex are supported, but not on built-in objects.
+		 * @param Function advice Function containing the code that will get called after the execution of the point-cut. It receives one parameter
+		 *                        with the result of the point-cut's execution.
+		 *
+		 * @type Array<Function>
+		 * @cat Plugins/General
+		 */
+		after : function(pointcut, advice)
+		{
+			return weave( pointcut, { type: _after, value: advice } );
+		},
+
+		/**
+		 * Creates an advice before the defined point-cut. The advice will be executed before the point-cut method 
+		 * but cannot modify the behavior of the method, or prevent its execution.
+		 * This function returns an array of weaved aspects (Function).
+		 *
+		 * @example jQuery.aop.before( {target: window, method: 'MyGlobalMethod'}, function() { alert('About to execute MyGlobalMethod'); } );
+		 * @result Array<Function>
+		 *
+		 * @example jQuery.aop.before( {target: String, method: 'indexOf'}, function(index) { alert('About to execute String.indexOf on: ' + this); } );
+		 * @result Array<Function>
+		 *
+		 * @name before
+		 * @param Map pointcut Definition of the point-cut to apply the advice. A point-cut is the definition of the object/s and method/s to be weaved.
+		 * @option Object target Target object to be weaved. 
+		 * @option String method Name of the function to be weaved. Regex are supported, but not on built-in objects.
+		 * @param Function advice Function containing the code that will get called before the execution of the point-cut.
+		 *
+		 * @type Array<Function>
+		 * @cat Plugins/General
+		 */
+		before : function(pointcut, advice)
+		{
+			return weave( pointcut, { type: _before, value: advice } );
+		},
+
+
+		/**
+		 * Creates an advice 'around' the defined point-cut. This type of advice can control the point-cut method execution by calling
+		 * the functions '.proceed()' on the 'invocation' object, and also, can modify the arguments collection before sending them to the function call.
+		 * This function returns an array of weaved aspects (Function).
+		 *
+		 * @example jQuery.aop.around( {target: window, method: 'MyGlobalMethod'}, function(invocation) {
+		 *                alert('# of Arguments: ' + invocation.arguments.length); 
+		 *                return invocation.proceed(); 
+		 *          } );
+		 * @result Array<Function>
+		 *
+		 * @example jQuery.aop.around( {target: String, method: 'indexOf'}, function(invocation) { 
+		 *                alert('Searching: ' + invocation.arguments[0] + ' on: ' + this); 
+		 *                return invocation.proceed(); 
+		 *          } );
+		 * @result Array<Function>
+		 *
+		 * @example jQuery.aop.around( {target: window, method: /Get(\d+)/}, function(invocation) {
+		 *                alert('Executing ' + invocation.method); 
+		 *                return invocation.proceed(); 
+		 *          } );
+		 * @desc Matches all global methods starting with 'Get' and followed by a number.
+		 * @result Array<Function>
+		 *
+		 *
+		 * @name around
+		 * @param Map pointcut Definition of the point-cut to apply the advice. A point-cut is the definition of the object/s and method/s to be weaved.
+		 * @option Object target Target object to be weaved. 
+		 * @option String method Name of the function to be weaved. Regex are supported, but not on built-in objects.
+		 * @param Function advice Function containing the code that will get called around the execution of the point-cut. This advice will be called with one
+		 *                        argument containing one function '.proceed()', the collection of arguments '.arguments', and the matched method name '.method'.
+		 *
+		 * @type Array<Function>
+		 * @cat Plugins/General
+		 */
+		around : function(pointcut, advice)
+		{
+			return weave( pointcut, { type: _around, value: advice } );
+		},
+
+		/**
+		 * Creates an introduction on the defined point-cut. This type of advice replaces any existing methods with the same
+		 * name. To restore them, just unweave it.
+		 * This function returns an array with only one weaved aspect (Function).
+		 *
+		 * @example jQuery.aop.introduction( {target: window, method: 'MyGlobalMethod'}, function(result) { alert('Returned: ' + result); } );
+		 * @result Array<Function>
+		 *
+		 * @example jQuery.aop.introduction( {target: String, method: 'log'}, function() { alert('Console: ' + this); } );
+		 * @result Array<Function>
+		 *
+		 * @name introduction
+		 * @param Map pointcut Definition of the point-cut to apply the advice. A point-cut is the definition of the object/s and method/s to be weaved.
+		 * @option Object target Target object to be weaved. 
+		 * @option String method Name of the function to be weaved.
+		 * @param Function advice Function containing the code that will be executed on the point-cut. 
+		 *
+		 * @type Array<Function>
+		 * @cat Plugins/General
+		 */
+		introduction : function(pointcut, advice)
+		{
+			return weave( pointcut, { type: _intro, value: advice } );
+		},
+		
+		/**
+		 * Configures global options.
+		 *
+		 * @name setup
+		 * @param Map settings Configuration options.
+		 * @option Boolean regexMatch Enables/disables regex matching of method names.
+		 *
+		 * @example jQuery.aop.setup( { regexMatch: false } );
+		 * @desc Disable regex matching.
+		 *
+		 * @type Void
+		 * @cat Plugins/General
+		 */
+		setup: function(settings)
+		{
+			_regexEnabled = settings.regexMatch;
+		}
+	};
+
+})();
+
+
+
+
+/**
+ * @name EventTarget
+ * @w3c:domlevel 2
+ * @uri -//TODO: paste dom event level 2 w3c spc uri here
+ */
+EventTarget = function(){};
+EventTarget.prototype.addEventListener = function(type, fn, phase){
+    __addEventListener__(this, type, fn, phase);
+};
+EventTarget.prototype.removeEventListener = function(type, fn){
+    __removeEventListener__(this, type, fn);
+};
+EventTarget.prototype.dispatchEvent = function(event, bubbles){
+    __dispatchEvent__(this, event, bubbles);
+};
+
+__extend__(Node.prototype, EventTarget.prototype);
+
+
+var $events = [{}];
+
+function __addEventListener__(target, type, fn, phase){
+    phase = !!phase?"CAPTURING":"BUBBLING";
+    if ( !target.uuid ) {
+        //console.log('event uuid %s %s', target, target.uuid);
+        target.uuid = $events.length+'';
+    }
+    if ( !$events[target.uuid] ) {
+        //console.log('creating listener for target: %s %s', target, target.uuid);
+        $events[target.uuid] = {};
+    }
+    if ( !$events[target.uuid][type] ){
+        //console.log('creating listener for type: %s %s %s', target, target.uuid, type);
+        $events[target.uuid][type] = {
+            CAPTURING:[],
+            BUBBLING:[]
+        };
+    }
+    if ( $events[target.uuid][type][phase].indexOf( fn ) < 0 ){
+        //console.log('adding event listener %s %s %s %s %s %s', target, target.uuid, type, phase,
+        //    $events[target.uuid][type][phase].length, $events[target.uuid][type][phase].indexOf( fn ));
+        //console.log('creating listener for function: %s %s %s', target, target.uuid, phase);
+        $events[target.uuid][type][phase].push( fn );
+        //console.log('adding event listener %s %s %s %s %s %s', target, target.uuid, type, phase,
+        //    $events[target.uuid][type][phase].length, $events[target.uuid][type][phase].indexOf( fn ));
+    }
+    //console.log('registered event listeners %s', $events.length);
+}
+
+function __removeEventListener__(target, type, fn, phase){
+
+    phase = !!phase?"CAPTURING":"BUBBLING";
+    if ( !target.uuid ) {
+        return;
+    }
+    if ( !$events[target.uuid] ) {
+        return;
+    }
+    if(type == '*'){
+        //used to clean all event listeners for a given node
+        //console.log('cleaning all event listeners for node %s %s',target, target.uuid);
+        delete $events[target.uuid];
+        return;
+    }else if ( !$events[target.uuid][type] ){
+        return;
+    }
+    $events[target.uuid][type][phase] =
+    $events[target.uuid][type][phase].filter(function(f){
+        //console.log('removing event listener %s %s %s %s', target, type, phase, fn);
+        return f != fn;
+    });
+}
+
+var __eventuuid__ = 0;
+function __dispatchEvent__(target, event, bubbles){
+
+    if (!event.uuid) {
+        event.uuid = __eventuuid__++;
+    }
+    //the window scope defines the $event object, for IE(^^^) compatibility;
+    //$event = event;
+    //console.log('dispatching event %s', event.uuid);
+    if (bubbles === undefined || bubbles === null) {
+        bubbles = true;
+    }
+
+    if (!event.target) {
+        event.target = target;
+    }
+
+    //console.log('dispatching? %s %s %s', target, event.type, bubbles);
+    if ( event.type && (target.nodeType || target === window )) {
+
+        //console.log('dispatching event %s %s %s', target, event.type, bubbles);
+        __captureEvent__(target, event);
+
+        event.eventPhase = Event.AT_TARGET;
+        if ( target.uuid && $events[target.uuid] && $events[target.uuid][event.type] ) {
+            event.currentTarget = target;
+            //console.log('dispatching %s %s %s %s', target, event.type,
+            //  $events[target.uuid][event.type]['CAPTURING'].length);
+            $events[target.uuid][event.type].CAPTURING.forEach(function(fn){
+                //console.log('AT_TARGET (CAPTURING) event %s', fn);
+                var returnValue = fn( event );
+                //console.log('AT_TARGET (CAPTURING) return value %s', returnValue);
+                if(returnValue === false){
+                    event.stopPropagation();
+                }
+            });
+            //console.log('dispatching %s %s %s %s', target, event.type,
+            //  $events[target.uuid][event.type]['BUBBLING'].length);
+            $events[target.uuid][event.type].BUBBLING.forEach(function(fn){
+                //console.log('AT_TARGET (BUBBLING) event %s', fn);
+                var returnValue = fn( event );
+                //console.log('AT_TARGET (BUBBLING) return value %s', returnValue);
+                if(returnValue === false){
+                    event.stopPropagation();
+                }
+            });
+        }
+        if (target["on" + event.type]) {
+            target["on" + event.type](event);
+        }
+        if (bubbles && !event.cancelled){
+            __bubbleEvent__(target, event);
+        }
+        if(!event._preventDefault){
+            //At this point I'm guessing that just HTMLEvents are concerned
+            //with default behavior being executed in a browser but I could be
+            //wrong as usual.  The goal is much more to filter at this point
+            //what events have no need to be handled
+            //console.log('triggering default behavior for %s', event.type);
+            if(event.type in Envjs.defaultEventBehaviors){
+                Envjs.defaultEventBehaviors[event.type](event);
+            }
+        }
+        //console.log('deleting event %s', event.uuid);
+        event.target = null;
+        event = null;
+    }else{
+        throw new EventException(EventException.UNSPECIFIED_EVENT_TYPE_ERR);
+    }
+}
+
+function __captureEvent__(target, event){
+    var ancestorStack = [],
+        parent = target.parentNode;
+
+    event.eventPhase = Event.CAPTURING_PHASE;
+    while(parent){
+        if(parent.uuid && $events[parent.uuid] && $events[parent.uuid][event.type]){
+            ancestorStack.push(parent);
+        }
+        parent = parent.parentNode;
+    }
+    while(ancestorStack.length && !event.cancelled){
+        event.currentTarget = ancestorStack.pop();
+        if($events[event.currentTarget.uuid] && $events[event.currentTarget.uuid][event.type]){
+            $events[event.currentTarget.uuid][event.type].CAPTURING.forEach(function(fn){
+                var returnValue = fn( event );
+                if(returnValue === false){
+                    event.stopPropagation();
+                }
+            });
+        }
+    }
+}
+
+function __bubbleEvent__(target, event){
+    var parent = target.parentNode;
+    event.eventPhase = Event.BUBBLING_PHASE;
+    while(parent){
+        if(parent.uuid && $events[parent.uuid] && $events[parent.uuid][event.type] ){
+            event.currentTarget = parent;
+            $events[event.currentTarget.uuid][event.type].BUBBLING.forEach(function(fn){
+                var returnValue = fn( event );
+                if(returnValue === false){
+                    event.stopPropagation();
+                }
+            });
+        }
+        parent = parent.parentNode;
+    }
+}
+
+/**
+ * @class Event
+ */
+Event = function(options){
+    // event state is kept read-only by forcing
+    // a new object for each event.  This may not
+    // be appropriate in the long run and we'll
+    // have to decide if we simply dont adhere to
+    // the read-only restriction of the specification
+    this._bubbles = true;
+    this._cancelable = true;
+    this._cancelled = false;
+    this._currentTarget = null;
+    this._target = null;
+    this._eventPhase = Event.AT_TARGET;
+    this._timeStamp = new Date().getTime();
+    this._preventDefault = false;
+    this._stopPropogation = false;
+};
+
+__extend__(Event.prototype,{
+    get bubbles(){return this._bubbles;},
+    get cancelable(){return this._cancelable;},
+    get currentTarget(){return this._currentTarget;},
+    set currentTarget(currentTarget){ this._currentTarget = currentTarget; },
+    get eventPhase(){return this._eventPhase;},
+    set eventPhase(eventPhase){this._eventPhase = eventPhase;},
+    get target(){return this._target;},
+    set target(target){ this._target = target;},
+    get timeStamp(){return this._timeStamp;},
+    get type(){return this._type;},
+    initEvent: function(type, bubbles, cancelable){
+        this._type=type?type:'';
+        this._bubbles=!!bubbles;
+        this._cancelable=!!cancelable;
+    },
+    preventDefault: function(){
+        this._preventDefault = true;
+    },
+    stopPropagation: function(){
+        if(this._cancelable){
+            this._cancelled = true;
+            this._bubbles = false;
+        }
+    },
+    get cancelled(){
+        return this._cancelled;
+    },
+    toString: function(){
+        return '[object Event]';
+    }
+});
+
+__extend__(Event,{
+    CAPTURING_PHASE : 1,
+    AT_TARGET       : 2,
+    BUBBLING_PHASE  : 3
+});
+
+
+
+/**
+ * @name UIEvent
+ * @param {Object} options
+ */
+UIEvent = function(options) {
+    this._view = null;
+    this._detail = 0;
+};
+
+UIEvent.prototype = new Event();
+__extend__(UIEvent.prototype,{
+    get view(){
+        return this._view;
+    },
+    get detail(){
+        return this._detail;
+    },
+    initUIEvent: function(type, bubbles, cancelable, windowObject, detail){
+        this.initEvent(type, bubbles, cancelable);
+        this._detail = 0;
+        this._view = windowObject;
+    }
+});
+
+var $onblur,
+    $onfocus,
+    $onresize;
+
+
+/**
+ * @name MouseEvent
+ * @w3c:domlevel 2 
+ * @uri http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html
+ */
+MouseEvent = function(options) {
+    this._screenX= 0;
+    this._screenY= 0;
+    this._clientX= 0;
+    this._clientY= 0;
+    this._ctrlKey= false;
+    this._metaKey= false;
+    this._altKey= false;
+    this._button= null;
+    this._relatedTarget= null;
+};
+MouseEvent.prototype = new UIEvent();
+__extend__(MouseEvent.prototype,{
+    get screenX(){
+        return this._screenX;
+    },
+    get screenY(){
+        return this._screenY;
+    },
+    get clientX(){
+        return this._clientX;
+    },
+    get clientY(){
+        return this._clientY;
+    },
+    get ctrlKey(){
+        return this._ctrlKey;
+    },
+    get altKey(){
+        return this._altKey;
+    },
+    get shiftKey(){
+        return this._shiftKey;
+    },
+    get metaKey(){
+        return this._metaKey;
+    },
+    get button(){
+        return this._button;
+    },
+    get relatedTarget(){
+        return this._relatedTarget;
+    },
+    initMouseEvent: function(type, bubbles, cancelable, windowObject, detail,
+            screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, 
+            metaKey, button, relatedTarget){
+        this.initUIEvent(type, bubbles, cancelable, windowObject, detail);
+        this._screenX = screenX;
+        this._screenY = screenY;
+        this._clientX = clientX;
+        this._clientY = clientY;
+        this._ctrlKey = ctrlKey;
+        this._altKey = altKey;
+        this._shiftKey = shiftKey;
+        this._metaKey = metaKey;
+        this._button = button;
+        this._relatedTarget = relatedTarget;
+    }
+});
+
+/**
+ * Interface KeyboardEvent (introduced in DOM Level 3)
+ */
+KeyboardEvent = function(options) {
+    this._keyIdentifier = 0;
+    this._keyLocation = 0;
+    this._ctrlKey = false;
+    this._metaKey = false;
+    this._altKey = false;
+    this._metaKey = false;
+};
+KeyboardEvent.prototype = new UIEvent();
+
+__extend__(KeyboardEvent.prototype,{
+
+    get ctrlKey(){
+        return this._ctrlKey;
+    },
+    get altKey(){
+        return this._altKey;
+    },
+    get shiftKey(){
+        return this._shiftKey;
+    },
+    get metaKey(){
+        return this._metaKey;
+    },
+    get button(){
+        return this._button;
+    },
+    get relatedTarget(){
+        return this._relatedTarget;
+    },
+    getModifiersState: function(keyIdentifier){
+
+    },
+    initMouseEvent: function(type, bubbles, cancelable, windowObject,
+            keyIdentifier, keyLocation, modifiersList, repeat){
+        this.initUIEvent(type, bubbles, cancelable, windowObject, 0);
+        this._keyIdentifier = keyIdentifier;
+        this._keyLocation = keyLocation;
+        this._modifiersList = modifiersList;
+        this._repeat = repeat;
+    }
+});
+
+KeyboardEvent.DOM_KEY_LOCATION_STANDARD      = 0;
+KeyboardEvent.DOM_KEY_LOCATION_LEFT          = 1;
+KeyboardEvent.DOM_KEY_LOCATION_RIGHT         = 2;
+KeyboardEvent.DOM_KEY_LOCATION_NUMPAD        = 3;
+KeyboardEvent.DOM_KEY_LOCATION_MOBILE        = 4;
+KeyboardEvent.DOM_KEY_LOCATION_JOYSTICK      = 5;
+
+
+
+//We dont fire mutation events until someone has registered for them
+var __supportedMutations__ = /DOMSubtreeModified|DOMNodeInserted|DOMNodeRemoved|DOMAttrModified|DOMCharacterDataModified/;
+
+var __fireMutationEvents__ = Aspect.before({
+    target: EventTarget,
+    method: 'addEventListener'
+}, function(target, type){
+    if(type && type.match(__supportedMutations__)){
+        //unweaving removes the __addEventListener__ aspect
+        __fireMutationEvents__.unweave();
+        // These two methods are enough to cover all dom 2 manipulations
+        Aspect.around({
+            target: Node,
+            method:"removeChild"
+        }, function(invocation){
+            var event,
+                node = invocation.arguments[0];
+            event = node.ownerDocument.createEvent('MutationEvents');
+            event.initEvent('DOMNodeRemoved', true, false, node.parentNode, null, null, null, null);
+            node.dispatchEvent(event, false);
+            return invocation.proceed();
+
+        });
+        Aspect.around({
+            target: Node,
+            method:"appendChild"
+        }, function(invocation) {
+            var event,
+                node = invocation.proceed();
+            event = node.ownerDocument.createEvent('MutationEvents');
+            event.initEvent('DOMNodeInserted', true, false, node.parentNode, null, null, null, null);
+            node.dispatchEvent(event, false);
+            return node;
+        });
+    }
+});
+
+/**
+ * @name MutationEvent
+ * @param {Object} options
+ */
+MutationEvent = function(options) {
+    this._cancelable = false;
+    this._timeStamp = 0;
+};
+
+MutationEvent.prototype = new Event();
+__extend__(MutationEvent.prototype,{
+    get relatedNode(){
+        return this._relatedNode;
+    },
+    get prevValue(){
+        return this._prevValue;
+    },
+    get newValue(){
+        return this._newValue;
+    },
+    get attrName(){
+        return this._attrName;
+    },
+    get attrChange(){
+        return this._attrChange;
+    },
+    initMutationEvent: function( type, bubbles, cancelable,
+            relatedNode, prevValue, newValue, attrName, attrChange ){
+        this._relatedNode = relatedNode;
+        this._prevValue = prevValue;
+        this._newValue = newValue;
+        this._attrName = attrName;
+        this._attrChange = attrChange;
+        switch(type){
+            case "DOMSubtreeModified":
+                this.initEvent(type, true, false);
+                break;
+            case "DOMNodeInserted":
+                this.initEvent(type, true, false);
+                break;
+            case "DOMNodeRemoved":
+                this.initEvent(type, true, false);
+                break;
+            case "DOMNodeRemovedFromDocument":
+                this.initEvent(type, false, false);
+                break;
+            case "DOMNodeInsertedIntoDocument":
+                this.initEvent(type, false, false);
+                break;
+            case "DOMAttrModified":
+                this.initEvent(type, true, false);
+                break;
+            case "DOMCharacterDataModified":
+                this.initEvent(type, true, false);
+                break;
+            default:
+                this.initEvent(type, bubbles, cancelable);
+        }
+    }
+});
+
+// constants
+MutationEvent.ADDITION = 0;
+MutationEvent.MODIFICATION = 1;
+MutationEvent.REMOVAL = 2;
+
+
+/**
+ * @name EventException
+ */
+EventException = function(code) {
+  this.code = code;
+};
+EventException.UNSPECIFIED_EVENT_TYPE_ERR = 0;
+/**
+ *
+ * DOM Level 2: http://www.w3.org/TR/DOM-Level-2-Events/events.html
+ * DOM Level 3: http://www.w3.org/TR/DOM-Level-3-Events/
+ *
+ * interface DocumentEvent {
+ *   Event createEvent (in DOMString eventType)
+ *      raises (DOMException);
+ * };
+ *
+ * Firefox (3.6) exposes DocumentEvent
+ * Safari (4) does NOT.
+ */
+
+/**
+ * TODO: Not sure we need a full prototype.  We not just an regular object?
+ */
+DocumentEvent = function(){};
+DocumentEvent.prototype.__EventMap__ = {
+    // Safari4: singular and plural forms accepted
+    // Firefox3.6: singular and plural forms accepted
+    'Event'          : Event,
+    'Events'         : Event,
+    'UIEvent'        : UIEvent,
+    'UIEvents'       : UIEvent,
+    'MouseEvent'     : MouseEvent,
+    'MouseEvents'    : MouseEvent,
+    'MutationEvent'  : MutationEvent,
+    'MutationEvents' : MutationEvent,
+
+    // Safari4: accepts HTMLEvents, but not HTMLEvent
+    // Firefox3.6: accepts HTMLEvents, but not HTMLEvent
+    'HTMLEvent'      : Event,
+    'HTMLEvents'     : Event,
+
+    // Safari4: both not accepted
+    // Firefox3.6, only KeyEvents is accepted
+    'KeyEvent'       : KeyboardEvent,
+    'KeyEvents'      : KeyboardEvent,
+
+    // Safari4: both accepted
+    // Firefox3.6: none accepted
+    'KeyboardEvent'  : KeyboardEvent,
+    'KeyboardEvents' : KeyboardEvent
+};
+
+DocumentEvent.prototype.createEvent = function(eventType) {
+    var Clazz = this.__EventMap__[eventType];
+    if (Clazz) {
+        return new Clazz();
+    }
+    throw(new DOMException(DOMException.NOT_SUPPORTED_ERR));
+};
+
+__extend__(Document.prototype, DocumentEvent.prototype);
+
+/**
+ * @author john resig & the envjs team
+ * @uri http://www.envjs.com/
+ * @copyright 2008-2010
+ * @license MIT
+ */
+//CLOSURE_END
+}());
+
+/*
+ * Envjs timer.1.2.35 
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ * 
+ * Parts of the implementation were originally written by:\
+ * Steven Parkes
+ * 
+ * requires Envjs.wait, Envjs.sleep, Envjs.WAIT_INTERVAL
+ */
+/*var setTimeout,
+    clearTimeout,
+    setInterval,
+    clearInterval;
+*/
+
+    
+/*
+ * Envjs timer.1.2.35 
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ */
+
+//CLOSURE_START
+(function(){
+
+
+
+
+/*
+*       timer.js
+*   implementation provided by Steven Parkes
+*/
+
+//private
+var $timers = [],
+    EVENT_LOOP_RUNNING = false;
+
+$timers.lock = function(fn){
+    Envjs.sync(fn)();
+};
+
+Envjs.clear = function(){
+    $timers.lock(function(){
+		for(var i=0; i<$timers.length; i++) {
+			if ( !$timers[i] ) {
+				continue;
+			}
+            $timers[i].stop();
+            delete $timers[i];
+        }
+    });
+}
+
+//private internal class
+var Timer = function(fn, interval){
+    this.fn = fn;
+    this.interval = interval;
+    this.at = Date.now() + interval;
+    // allows for calling wait() from callbacks
+    this.running = false;
+};
+
+Timer.prototype.start = function(){};
+Timer.prototype.stop = function(){};
+
+//static
+Timer.normalize = function(time) {
+    time = time*1;
+    if ( isNaN(time) || time < 0 ) {
+        time = 0;
+    }
+
+    if ( EVENT_LOOP_RUNNING && time < Timer.MIN_TIME ) {
+        time = Timer.MIN_TIME;
+    }
+    return time;
+};
+// html5 says this should be at least 4, but the parser is using
+// a setTimeout for the SAX stuff which messes up the world
+Timer.MIN_TIME = /* 4 */ 0;
+
+/**
+ * @function setTimeout
+ * @param {Object} fn
+ * @param {Object} time
+ */
+setTimeout = function(fn, time){
+    var num;
+    time = Timer.normalize(time);
+    $timers.lock(function(){
+        num = $timers.length+1;
+        var tfn;
+        if (typeof fn == 'string') {
+            tfn = function() {
+                try {
+                    // eval in global scope
+                    eval(fn, null);
+                } catch (e) {
+                    console.log('timer error %s %s', fn, e);
+                } finally {
+                    clearInterval(num);
+                }
+            };
+        } else {
+            tfn = function() {
+                try {
+                    fn();
+                } catch (e) {
+                    console.log('timer error %s %s', fn, e);
+                } finally {
+                    clearInterval(num);
+                }
+            };
+        }
+        //console.log("Creating timer number %s", num);
+        $timers[num] = new Timer(tfn, time);
+        $timers[num].start();
+    });
+    return num;
+};
+
+/**
+ * @function setInterval
+ * @param {Object} fn
+ * @param {Object} time
+ */
+setInterval = function(fn, time){
+    //console.log('setting interval %s %s', time, fn.toString().substring(0,64));
+    time = Timer.normalize(time);
+    if ( time < 10 ) {
+        time = 10;
+    }
+    if (typeof fn == 'string') {
+        var fnstr = fn;
+        fn = function() {
+            eval(fnstr);
+        };
+    }
+    var num;
+    $timers.lock(function(){
+        num = $timers.length+1;
+        //Envjs.debug("Creating timer number "+num);
+        $timers[num] = new Timer(fn, time);
+        $timers[num].start();
+    });
+    return num;
+};
+
+/**
+ * clearInterval
+ * @param {Object} num
+ */
+clearInterval = clearTimeout = function(num){
+    //console.log("clearing interval "+num);
+    $timers.lock(function(){
+        if ( $timers[num] ) {
+            $timers[num].stop();
+            delete $timers[num];
+        }
+    });
+};
+
+// wait === null/undefined: execute any timers as they fire,
+//  waiting until there are none left
+// wait(n) (n > 0): execute any timers as they fire until there
+//  are none left waiting at least n ms but no more, even if there
+//  are future events/current threads
+// wait(0): execute any immediately runnable timers and return
+// wait(-n): keep sleeping until the next event is more than n ms
+//  in the future
+//
+// TODO: make a priority queue ...
+
+Envjs.wait = function(wait) {
+    //console.log('wait %s', wait);
+    var delta_wait,
+        start = Date.now(),
+        was_running = EVENT_LOOP_RUNNING;
+
+    if (wait < 0) {
+        delta_wait = -wait;
+        wait = 0;
+    }
+    EVENT_LOOP_RUNNING = true;
+    if (wait !== 0 && wait !== null && wait !== undefined){
+        wait += Date.now();
+    }
+
+    var earliest,
+        timer,
+        sleep,
+        index,
+        goal,
+        now,
+        nextfn,
+		commandline;
+
+    for (;;) {
+        /*console.log('timer loop');
+		try{
+		commandline = Envjs.shell.next(' ');
+		}catch(e){console.log(e);}
+	    console.log('commandline %s', commandline);*/
+        earliest = sleep = goal = now = nextfn = null;
+        $timers.lock(function(){
+            for(index in $timers){
+                if( isNaN(index*0) ) {
+                    continue;
+                }
+                timer = $timers[index];
+                // determine timer with smallest run-at time that is
+                // not already running
+                if( !timer.running && ( !earliest || timer.at < earliest.at) ) {
+                    earliest = timer;
+                }
+            }
+        });
+        //next sleep time
+        sleep = earliest && earliest.at - Date.now();
+		/*console.log('timer loop earliest %s sleep %s', earliest, sleep);*/
+        if ( earliest && sleep <= 0 ) {
+            nextfn = earliest.fn;
+            try {
+                /*console.log('running stack %s', nextfn.toString().substring(0,64));*/
+                earliest.running = true;
+                nextfn();
+            } catch (e) {
+                console.log('timer error %s %s', nextfn, e);
+            } finally {
+                earliest.running = false;
+            }
+            goal = earliest.at + earliest.interval;
+            now = Date.now();
+            if ( goal < now ) {
+                earliest.at = now;
+            } else {
+                earliest.at = goal;
+            }
+            continue;
+        }
+
+        // bunch of subtle cases here ...
+        if ( !earliest ) {
+            // no events in the queue (but maybe XHR will bring in events, so ...
+            if ( !wait || wait < Date.now() ) {
+                // Loop ends if there are no events and a wait hasn't been
+                // requested or has expired
+                break;
+            }
+        // no events, but a wait requested: fall through to sleep
+        } else {
+            // there are events in the queue, but they aren't firable now
+            /*if ( delta_wait && sleep <= delta_wait ) {
+                //TODO: why waste a check on a tight
+                // loop if it just falls through?
+            // if they will happen within the next delta, fall through to sleep
+            } else */if ( wait === 0 || ( wait > 0 && wait < Date.now () ) ) {
+                // loop ends even if there are events but the user
+                // specifcally asked not to wait too long
+                break;
+            }
+            // there are events and the user wants to wait: fall through to sleep
+        }
+
+        // Related to ajax threads ... hopefully can go away ..
+        var interval =  Envjs.WAIT_INTERVAL || 100;
+        if ( !sleep || sleep > interval ) {
+            sleep = interval;
+        }
+        //console.log('sleeping %s', sleep);
+        Envjs.sleep(sleep);
+
+    }
+    EVENT_LOOP_RUNNING = was_running;
+};
+
+
+/**
+ * @author john resig & the envjs team
+ * @uri http://www.envjs.com/
+ * @copyright 2008-2010
+ * @license MIT
+ */
+//CLOSURE_END
+}());
+/*
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ *
+ * This file simply provides the global definitions we need to
+ * be able to correctly implement to core browser DOM HTML interfaces.
+ */
+/*var HTMLDocument,
+    HTMLElement,
+    HTMLCollection,
+    HTMLAnchorElement,
+    HTMLAreaElement,
+    HTMLBaseElement,
+    HTMLQuoteElement,
+    HTMLBodyElement,
+    HTMLBRElement,
+    HTMLButtonElement,
+    CanvasRenderingContext2D,
+    HTMLCanvasElement,
+    HTMLTableColElement,
+    HTMLModElement,
+    HTMLDivElement,
+    HTMLDListElement,
+    HTMLFieldSetElement,
+    HTMLFormElement,
+    HTMLFrameElement,
+    HTMLFrameSetElement,
+    HTMLHeadElement,
+    HTMLHeadingElement,
+    HTMLHRElement,
+    HTMLHtmlElement,
+    HTMLIFrameElement,
+    HTMLImageElement,
+    HTMLInputElement,
+    HTMLLabelElement,
+    HTMLLegendElement,
+    HTMLLIElement,
+    HTMLLinkElement,
+    HTMLMapElement,
+    HTMLMetaElement,
+    HTMLObjectElement,
+    HTMLOListElement,
+    HTMLOptGroupElement,
+    HTMLOptionElement,
+    HTMLParagraphElement,
+    HTMLParamElement,
+    HTMLPreElement,
+    HTMLScriptElement,
+    HTMLSelectElement,
+    HTMLSpanElement,
+    HTMLStyleElement,
+    HTMLTableElement,
+    HTMLTableSectionElement,
+    HTMLTableCellElement,
+    HTMLTableDataCellElement,
+    HTMLTableHeaderCellElement,
+    HTMLTableRowElement,
+    HTMLTextAreaElement,
+    HTMLTitleElement,
+    HTMLUListElement,
+    HTMLUnknownElement,
+    Image,
+    Option,
+    __loadImage__,
+    __loadLink__;
+*/
+/*
+ * Envjs html.1.2.35 
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ */
+
+//CLOSURE_START
+(function(){
+
+
+
+
+
+/**
+ * @author ariel flesler
+ *    http://flesler.blogspot.com/2008/11/fast-trim-function-for-javascript.html
+ * @param {Object} str
+ */
+function __trim__( str ){
+    return (str || "").replace( /^\s+|\s+$/g, "" );
+}
+
+
+/**
+ * @author john resig
+ */
+// Helper method for extending one object with another.
+function __extend__(a,b) {
+    for ( var i in b ) {
+        var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
+        if ( g || s ) {
+            if ( g ) { a.__defineGetter__(i, g); }
+            if ( s ) { a.__defineSetter__(i, s); }
+        } else {
+            a[i] = b[i];
+        }
+    } return a;
+}
+
+/**
+ * @author john resig
+ */
+//from jQuery
+function __setArray__( target, array ) {
+    // Resetting the length to 0, then using the native Array push
+    // is a super-fast way to populate an object with array-like properties
+    target.length = 0;
+    Array.prototype.push.apply( target, array );
+}
+
+/**
+ * @class  HTMLDocument
+ *      The Document interface represents the entire HTML or XML document.
+ *      Conceptually, it is the root of the document tree, and provides
+ *      the primary access to the document's data.
+ *
+ * @extends Document
+ */
+HTMLDocument = function(implementation, ownerWindow, referrer) {
+    Document.apply(this, arguments);
+    this.referrer = referrer || '';
+    this.baseURI = "about:blank";
+    this.ownerWindow = ownerWindow;
+};
+
+HTMLDocument.prototype = new Document();
+
+__extend__(HTMLDocument.prototype, {
+    createElement: function(tagName){
+        var node;
+        tagName = tagName.toUpperCase();
+        // create Element specifying 'this' as ownerDocument
+        // This is an html document so we need to use explicit interfaces per the
+        //TODO: would be much faster as a big switch
+        switch(tagName){
+        case "A":
+            node = new HTMLAnchorElement(this);break;
+        case "AREA":
+            node = new HTMLAreaElement(this);break;
+        case "BASE":
+            node = new HTMLBaseElement(this);break;
+        case "BLOCKQUOTE":
+            node = new HTMLQuoteElement(this);break;
+        case "CANVAS":
+            node = new HTMLCanvasElement(this);break;
+        case "Q":
+            node = new HTMLQuoteElement(this);break;
+        case "BODY":
+            node = new HTMLBodyElement(this);break;
+        case "BR":
+            node = new HTMLBRElement(this);break;
+        case "BUTTON":
+            node = new HTMLButtonElement(this);break;
+        case "CAPTION":
+            node = new HTMLElement(this);break;
+        case "COL":
+            node = new HTMLTableColElement(this);break;
+        case "COLGROUP":
+            node = new HTMLTableColElement(this);break;
+        case "DEL":
+            node = new HTMLModElement(this);break;
+        case "INS":
+            node = new HTMLModElement(this);break;
+        case "DIV":
+            node = new HTMLDivElement(this);break;
+        case "DL":
+            node = new HTMLDListElement(this);break;
+        case "DT":
+            node = new HTMLElement(this); break;
+        case "FIELDSET":
+            node = new HTMLFieldSetElement(this);break;
+        case "FORM":
+            node = new HTMLFormElement(this);break;
+        case "FRAME":
+            node = new HTMLFrameElement(this);break;
+        case "FRAMESET":
+            node = new HTMLFrameSetElement(this);break;
+        case "H1":
+            node = new HTMLHeadingElement(this);break;
+        case "H2":
+            node = new HTMLHeadingElement(this);break;
+        case "H3":
+            node = new HTMLHeadingElement(this);break;
+        case "H4":
+            node = new HTMLHeadingElement(this);break;
+        case "H5":
+            node = new HTMLHeadingElement(this);break;
+        case "H6":
+            node = new HTMLHeadingElement(this);break;
+        case "HEAD":
+            node = new HTMLHeadElement(this);break;
+        case "HR":
+            node = new HTMLHRElement(this);break;
+        case "HTML":
+            node = new HTMLHtmlElement(this);break;
+        case "IFRAME":
+            node = new HTMLIFrameElement(this);break;
+        case "IMG":
+            node = new HTMLImageElement(this);break;
+        case "INPUT":
+            node = new HTMLInputElement(this);break;
+        case "LABEL":
+            node = new HTMLLabelElement(this);break;
+        case "LEGEND":
+            node = new HTMLLegendElement(this);break;
+        case "LI":
+            node = new HTMLLIElement(this);break;
+        case "LINK":
+            node = new HTMLLinkElement(this);break;
+        case "MAP":
+            node = new HTMLMapElement(this);break;
+        case "META":
+            node = new HTMLMetaElement(this);break;
+        case "NOSCRIPT":
+            node = new HTMLElement(this);break;
+        case "OBJECT":
+            node = new HTMLObjectElement(this);break;
+        case "OPTGROUP":
+            node = new HTMLOptGroupElement(this);break;
+        case "OL":
+            node = new HTMLOListElement(this); break;
+        case "OPTION":
+            node = new HTMLOptionElement(this);break;
+        case "P":
+            node = new HTMLParagraphElement(this);break;
+        case "PARAM":
+            node = new HTMLParamElement(this);break;
+        case "PRE":
+            node = new HTMLPreElement(this);break;
+        case "SCRIPT":
+            node = new HTMLScriptElement(this);break;
+        case "SELECT":
+            node = new HTMLSelectElement(this);break;
+        case "SMALL":
+            node = new HTMLElement(this);break;
+        case "SPAN":
+            node = new HTMLSpanElement(this);break;
+        case "STRONG":
+            node = new HTMLElement(this);break;
+        case "STYLE":
+            node = new HTMLStyleElement(this);break;
+        case "TABLE":
+            node = new HTMLTableElement(this);break;
+        case "TBODY":
+            node = new HTMLTableSectionElement(this);break;
+        case "TFOOT":
+            node = new HTMLTableSectionElement(this);break;
+        case "THEAD":
+            node = new HTMLTableSectionElement(this);break;
+        case "TD":
+            node = new HTMLTableDataCellElement(this);break;
+        case "TH":
+            node = new HTMLTableHeaderCellElement(this);break;
+        case "TEXTAREA":
+            node = new HTMLTextAreaElement(this);break;
+        case "TITLE":
+            node = new HTMLTitleElement(this);break;
+        case "TR":
+            node = new HTMLTableRowElement(this);break;
+        case "UL":
+            node = new HTMLUListElement(this);break;
+        default:
+            node = new HTMLUnknownElement(this);
+        }
+        // assign values to properties (and aliases)
+        node.nodeName  = tagName;
+        return node;
+    },
+    createElementNS : function (uri, local) {
+        //print('createElementNS :'+uri+" "+local);
+        if(!uri){
+            return this.createElement(local);
+        }else if ("http://www.w3.org/1999/xhtml" == uri) {
+            return this.createElement(local);
+        } else if ("http://www.w3.org/1998/Math/MathML" == uri) {
+            return this.createElement(local);
+        } else if ("http://www.w3.org/2000/svg" == uri) {
+ 			return this.createElement(local);
+		} else {
+            return Document.prototype.createElementNS.apply(this,[uri, local]);
+        }
+    },
+    get anchors(){
+        return new HTMLCollection(this.getElementsByTagName('a'));
+    },
+    get applets(){
+        return new HTMLCollection(this.getElementsByTagName('applet'));
+    },
+    get documentElement(){
+        var html = Document.prototype.__lookupGetter__('documentElement').apply(this,[]);
+        if( html === null){
+            html = this.createElement('html');
+            this.appendChild(html);
+            html.appendChild(this.createElement('head'));
+            html.appendChild(this.createElement('body'));
+        }
+        return html;
+    },
+    //document.head is non-standard
+    get head(){
+        //console.log('get head');
+        if (!this.documentElement) {
+            this.appendChild(this.createElement('html'));
+        }
+        var element = this.documentElement,
+        	length = element.childNodes.length,
+	        i;
+        //check for the presence of the head element in this html doc
+        for(i=0;i<length;i++){
+            if(element.childNodes[i].nodeType === Node.ELEMENT_NODE){
+                if(element.childNodes[i].tagName.toLowerCase() === 'head'){
+                    return element.childNodes[i];
+                }
+            }
+        }
+        //no head?  ugh bad news html.. I guess we'll force the issue?
+        var head = element.appendChild(this.createElement('head'));
+        return head;
+    },
+    get title(){
+        //console.log('get title');
+        if (!this.documentElement) {
+            this.appendChild(this.createElement('html'));
+        }
+        var title,
+        	head = this.head,
+	        length = head.childNodes.length,
+	        i;
+        //check for the presence of the title element in this head element
+        for(i=0;i<length;i++){
+            if(head.childNodes[i].nodeType === Node.ELEMENT_NODE){
+                if(head.childNodes[i].tagName.toLowerCase() === 'title'){
+                    return head.childNodes[i].textContent;
+                }
+            }
+        }
+        //no title?  ugh bad news html.. I guess we'll force the issue?
+        title = head.appendChild(this.createElement('title'));
+        return title.appendChild(this.createTextNode('Untitled Document')).nodeValue;
+    },
+    set title(titleStr){
+        //console.log('set title %s', titleStr);
+        if (!this.documentElement) {
+            this.appendChild(this.createElement('html'));
+        }
+        var title = this.title;
+        title.textContent = titleStr;
+    },
+
+    get body() {
+        var element = this.documentElement,
+            length = element.childNodes.length,
+            i;
+        for (i=0; i<length; i++) {
+            if (element.childNodes[i].nodeType === Node.ELEMENT_NODE &&
+                (element.childNodes[i].tagName === 'BODY' || 
+				 element.childNodes[i].tagName === 'FRAMESET')) {
+                return element.childNodes[i];
+            }
+        }
+        return null;
+    },
+    set body() {
+        /* in firefox this is a benevolent do nothing*/
+        console.log('set body');
+    },
+
+    get cookie(){
+        return Envjs.getCookies(this.location+'');
+    },
+    set cookie(cookie){
+        return Envjs.setCookie(this.location+'', cookie);
+    },
+
+    /**
+     * document.location
+     *
+     * should be identical to window.location
+     *
+     * HTML5:
+     * http://dev.w3.org/html5/spec/Overview.html#the-location-interface
+     *
+     * Mozilla MDC:
+     * https://developer.mozilla.org/en/DOM/document.location
+     *
+     */
+    get location() {
+        if (this.ownerWindow) {
+            return this.ownerWindow.location;
+        } else {
+            return this.baseURI;
+        }
+    },
+    set location(url) {
+        this.baseURI = url;
+        if (this.ownerWindow) {
+            this.ownerWindow.location = url;
+        }
+    },
+
+    /**
+     * document.URL (read-only)
+     *
+     * HTML DOM Level 2:
+     * http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-46183437
+     *
+     * HTML5:
+     * http://dev.w3.org/html5/spec/Overview.html#dom-document-url
+     *
+     * Mozilla MDC:
+     * https://developer.mozilla.org/en/DOM/document.URL
+     */
+    get URL() {
+        return this.location.href;
+    },
+
+    /**
+     * document.domain
+     *
+     * HTML5 Spec:
+     * http://dev.w3.org/html5/spec/Overview.html#dom-document-domain
+     *
+     * Mozilla MDC:
+     * https://developer.mozilla.org/en/DOM/document.domain
+     *
+     */
+    get domain(){
+        var HOSTNAME = new RegExp('\/\/([^\:\/]+)'),
+        matches = HOSTNAME.exec(this.baseURI);
+        return matches&&matches.length>1?matches[1]:"";
+    },
+    set domain(value){
+        var i,
+        domainParts = this.domain.split('.').reverse(),
+        newDomainParts = value.split('.').reverse();
+        if(newDomainParts.length > 1){
+            for(i=0;i<newDomainParts.length;i++){
+                if(!(newDomainParts[i] === domainParts[i])){
+                    return;
+                }
+            }
+            this.baseURI = this.baseURI.replace(domainParts.join('.'), value);
+        }
+    },
+
+    get forms(){
+        return new HTMLCollection(this.getElementsByTagName('form'));
+    },
+    get images(){
+        return new HTMLCollection(this.getElementsByTagName('img'));
+    },
+    get lastModified(){
+        /* TODO */
+        return this._lastModified;
+    },
+    get links(){
+        return new HTMLCollection(this.getElementsByTagName('a'));
+    },
+    getElementsByName : function(name){
+        //returns a real Array + the NodeList
+        var retNodes = __extend__([],new NodeList(this, this.documentElement)),
+        node;
+        // loop through all Elements
+        var all = this.getElementsByTagName('*');
+        for (var i=0; i < all.length; i++) {
+            node = all[i];
+            if (node.nodeType === Node.ELEMENT_NODE &&
+                node.getAttribute('name') == name) {
+                retNodes.push(node);
+            }
+        }
+        return retNodes;
+    },
+    toString: function(){
+        return "[object HTMLDocument]";
+    },
+    get innerHTML(){
+        return this.documentElement.outerHTML;
+    }
+});
+
+
+
+Aspect.around({
+    target: Node,
+    method:"appendChild"
+}, function(invocation) {
+    var event,
+        okay,
+        node = invocation.proceed(),
+        doc = node.ownerDocument,
+		target;
+
+    //console.log('element appended: %s %s %s', node+'', node.nodeName, node.namespaceURI);
+    if((node.nodeType !== Node.ELEMENT_NODE)){
+        //for now we are only handling element insertions.  probably
+        //we will need to handle text node changes to script tags and
+        //changes to src attributes
+        return node;
+    }
+	
+	if(node.tagName&&node.tagName.toLowerCase()=="input"){
+		target = node.parentNode;
+		//console.log('adding named map for input');
+		while(target&&target.tagName&&target.tagName.toLowerCase()!="form"){
+			//console.log('possible target for named map for input is %s', target);
+			target = target.parentNode;
+		}
+		if(target){
+			//console.log('target for named map for input is %s', target);
+			__addNamedMap__(target, node);
+		}
+	}
+    //console.log('appended html element %s %s %s', node.namespaceURI, node.nodeName, node);
+    switch(doc.parsing){
+        case true:
+
+        /**
+         * Very special case.  While in parsing mode, in head, a
+         * script can add another script tag to the head, and it will
+         * be evaluated.  This is tested in 'ant fulldoc-spec' tests.
+         *
+         * Not quite sure if the require that the new script tag must
+         * be in the head is correct or not.  NamespaceURI == null
+         * might also need to corrected too.
+         */
+        if (node.tagName.toLowerCase() === 'script' && 
+			(node.namespaceURI === "" || 
+			 node.namespaceURI === "http://www.w3.org/1999/xhtml" || 
+			 node.namespaceURI === null) ) {
+            //console.log('appending script while parsing');
+            if((this.nodeName.toLowerCase() === 'head')){
+                try{
+                    okay = Envjs.loadLocalScript(node, null);
+                    //console.log('loaded script? %s %s', node.uuid, okay);
+                    // only fire event if we actually had something to load
+                    if (node.src && node.src.length > 0){
+                        event = doc.createEvent('HTMLEvents');
+                        event.initEvent( okay ? "load" : "error", false, false );
+                        node.dispatchEvent( event, false );
+                    }
+                }catch(e){
+                    console.log('error loading html element %s %e', node, e.toString());
+                }
+            }
+        }
+        break;
+        case false:
+            switch(node.namespaceURI){
+                case null:
+                    //fall through
+                case "":
+                    //fall through
+                case "http://www.w3.org/1999/xhtml":
+                    switch(node.tagName.toLowerCase()){
+                    case 'style':
+                        document.styleSheets.push(CSSStyleSheet(node));
+                        break;
+                    case 'script':
+                        //console.log('appending script %s', node.src);
+                        if((this.nodeName.toLowerCase() === 'head')){
+                            try{
+                                okay = Envjs.loadLocalScript(node, null);
+                                //console.log('loaded script? %s %s', node.uuid, okay);
+                                // only fire event if we actually had something to load
+                                if (node.src && node.src.length > 0){
+                                    event = doc.createEvent('HTMLEvents');
+                                    event.initEvent( okay ? "load" : "error", false, false );
+                                    node.dispatchEvent( event, false );
+                                }
+                            }catch(e){
+                                console.log('error loading html element %s %e', node, e.toString());
+                            }
+                        }
+                        break;
+                    case 'frame':
+                    case 'iframe':
+                        node.contentWindow = { };
+                        node.contentDocument = new HTMLDocument(new DOMImplementation(), node.contentWindow);
+                        node.contentWindow.document = node.contentDocument;
+                        try{
+                            Window;
+                        }catch(e){
+                            node.contentDocument.addEventListener('DOMContentLoaded', function(){
+                                event = node.contentDocument.createEvent('HTMLEvents');
+                                event.initEvent("load", false, false);
+                                node.dispatchEvent( event, false );
+                            });
+                            console.log('error loading html element %s %e', node, e.toString());
+                        }
+                        try{
+                            if (node.src && node.src.length > 0){
+                                //console.log("trigger load on frame from appendChild %s", node.src);
+                                Envjs.loadFrame(node, Envjs.uri(node.src, doc.location+''));
+                            }else{
+                                Envjs.loadFrame(node);
+                            }
+                        }catch(e){
+                            console.log('error loading html element %s %e', node, e.toString());
+                        }
+                        break;
+
+                    case 'link':
+                        if (node.href && node.href.length > 0) {
+                            __loadLink__(node, node.href);
+                        }
+                        break;
+                        /*
+                          case 'img':
+                          if (node.src && node.src.length > 0){
+                          // don't actually load anything, so we're "done" immediately:
+                          event = doc.createEvent('HTMLEvents');
+                          event.initEvent("load", false, false);
+                          node.dispatchEvent( event, false );
+                          }
+                          break;
+                        */
+                    case 'option':
+                        node._updateoptions();
+                        break;
+                    default:
+                        if(node.getAttribute('onload')){
+                            //console.log('calling attribute onload %s | %s', node.onload, node.tagName);
+                            node.onload();
+                        }
+                        break;
+                    }//switch on name
+                default:
+                    break;
+            }//switch on ns
+            break;
+        default:
+            // console.log('element appended: %s %s', node+'', node.namespaceURI);
+    }//switch on doc.parsing
+    return node;
+
+});
+
+Aspect.around({
+    target: Node,
+    method:"removeChild"
+}, function(invocation) {
+    var event,
+        okay,
+        node = invocation.proceed(),
+        doc = node.ownerDocument;
+    if((node.nodeType !== Node.ELEMENT_NODE)){
+        //for now we are only handling element insertions.  probably we will need
+        //to handle text node changes to script tags and changes to src
+        //attributes
+        if(node.nodeType !== Node.DOCUMENT_NODE && node.uuid){
+            //console.log('removing event listeners, %s', node, node.uuid);
+            node.removeEventListener('*', null, null);
+        }
+        return node;
+    }
+    //console.log('appended html element %s %s %s', node.namespaceURI, node.nodeName, node);
+	if(node.tagName&&node.tagName.toLowerCase()=="input"){
+		target = node.parentNode;
+		//console.log('adding named map for input');
+		while(target&&target.tagName&&target.tagName.toLowerCase()!="form"){
+			//console.log('possible target for named map for input is %s', target);
+			target = target.parentNode;
+		}
+		if(target){
+			//console.log('target for named map for input is %s', target);
+			__removeNamedMap__(target, node);
+		}
+	}
+    switch(doc.parsing){
+        case true:
+            //handled by parser if included
+            break;
+        case false:
+            switch(node.namespaceURI){
+            case null:
+                //fall through
+            case "":
+                //fall through
+            case "http://www.w3.org/1999/xhtml":
+                //this is interesting dillema since our event engine is
+                //storing the registered events in an array accessed
+                //by the uuid property of the node.  unforunately this
+                //means listeners hang out way after(forever ;)) the node
+                //has been removed and gone out of scope.
+                //console.log('removing event listeners, %s', node, node.uuid);
+                node.removeEventListener('*', null, null);
+                switch(node.tagName.toLowerCase()){
+                case 'frame':
+                case 'iframe':
+                    try{
+                        //console.log('removing iframe document');
+                        try{
+                            Envjs.unloadFrame(node);
+                        }catch(e){
+                            console.log('error freeing resources from frame %s', e);
+                        }
+                        node.contentWindow = null;
+                        node.contentDocument = null;
+                    }catch(e){
+                        console.log('error unloading html element %s %e', node, e.toString());
+                    }
+                    break;
+                default:
+                    break;
+                }//switch on name
+            default:
+                break;
+            }//switch on ns
+            break;
+        default:
+            console.log('element appended: %s %s', node+'', node.namespaceURI);
+    }//switch on doc.parsing
+    return node;
+
+});
+
+
+
+/**
+ * Named Element Support
+ *
+ *
+ */
+
+/*
+ *
+ * @returns 'name' if the node has a appropriate name
+ *          null if node does not have a name
+ */
+
+var __isNamedElement__ = function(node) {
+    if (node.nodeType !== Node.ELEMENT_NODE) {
+        return null;
+    }
+    var tagName = node.tagName.toLowerCase();
+    var nodename = null;
+
+    switch (tagName) {
+        case 'embed':
+        case 'form':
+        case 'iframe':
+		case 'input':
+            nodename = node.getAttribute('name');
+            break;
+        case 'applet':
+            nodename = node.id;
+            break;
+        case 'object':
+            // TODO: object needs to be 'fallback free'
+            nodename = node.id;
+            break;
+        case 'img':
+            nodename = node.id;
+            if (!nodename || ! node.getAttribute('name')) {
+                nodename = null;
+            }
+            break;
+    }
+    return (nodename) ? nodename : null;
+};
+
+
+var __addNamedMap__ = function(target, node) {
+    var nodename = __isNamedElement__(node);
+    if (nodename) {
+       	target.__defineGetter__(nodename, function() {
+            return node;
+        });	
+		target.__defineSetter__(nodename, function(value) {
+	        return value;
+	    });
+    }
+};
+
+var __removeNamedMap__ = function(target, node) {
+    if (!node) {
+        return;
+    }
+    var nodename = __isNamedElement__(node);
+    if (nodename) {
+		delete target[nodename];
+    }
+};
+
+/**
+ * @name HTMLEvents
+ * @w3c:domlevel 2
+ * @uri http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html
+ */
+
+var __eval__ = function(script, node){
+    if (!script == "" && Envjs.scriptTypes['']){
+        // don't assemble environment if no script...
+        try{
+            Envjs.eval(node.ownerDocument.ownerWindow, script, script+" ("+node+")");
+        }catch(e){
+            console.log('error evaluating %s', e);
+        }
+    }
+};
+
+var HTMLEvents= function(){};
+HTMLEvents.prototype = {
+    onload: function(event){
+        __eval__(this.getAttribute('onload')||'', this);
+    },
+    onunload: function(event){
+        __eval__(this.getAttribute('onunload')||'', this);
+    },
+    onabort: function(event){
+        __eval__(this.getAttribute('onabort')||'', this);
+    },
+    onerror: function(event){
+        __eval__(this.getAttribute('onerror')||'', this);
+    },
+    onselect: function(event){
+        __eval__(this.getAttribute('onselect')||'', this);
+    },
+    onchange: function(event){
+        __eval__(this.getAttribute('onchange')||'', this);
+    },
+    onsubmit: function(event){
+        if (__eval__(this.getAttribute('onsubmit')||'', this)) {
+            this.submit();
+        }
+    },
+    onreset: function(event){
+        __eval__(this.getAttribute('onreset')||'', this);
+    },
+    onfocus: function(event){
+        __eval__(this.getAttribute('onfocus')||'', this);
+    },
+    onblur: function(event){
+        __eval__(this.getAttribute('onblur')||'', this);
+    },
+    onresize: function(event){
+        __eval__(this.getAttribute('onresize')||'', this);
+    },
+    onscroll: function(event){
+        __eval__(this.getAttribute('onscroll')||'', this);
+    }
+};
+
+//HTMLDocument, HTMLFramesetElement, HTMLObjectElement
+var  __load__ = function(element){
+    var event = new Event('HTMLEvents');
+    event.initEvent("load", false, false);
+    element.dispatchEvent(event);
+    return event;
+};
+
+//HTMLFramesetElement, HTMLBodyElement
+var  __unload__ = function(element){
+    var event = new Event('HTMLEvents');
+    event.initEvent("unload", false, false);
+    element.dispatchEvent(event);
+    return event;
+};
+
+//HTMLObjectElement
+var  __abort__ = function(element){
+    var event = new Event('HTMLEvents');
+    event.initEvent("abort", true, false);
+    element.dispatchEvent(event);
+    return event;
+};
+
+//HTMLFramesetElement, HTMLObjectElement, HTMLBodyElement
+var  __error__ = function(element){
+    var event = new Event('HTMLEvents');
+    event.initEvent("error", true, false);
+    element.dispatchEvent(event);
+    return event;
+};
+
+//HTMLInputElement, HTMLTextAreaElement
+var  __select__ = function(element){
+    var event = new Event('HTMLEvents');
+    event.initEvent("select", true, false);
+    element.dispatchEvent(event);
+    return event;
+};
+
+//HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement
+var  __change__ = function(element){
+    var event = new Event('HTMLEvents');
+    event.initEvent("change", true, false);
+    element.dispatchEvent(event);
+    return event;
+};
+
+//HtmlFormElement
+var __submit__ = function(element){
+    var event = new Event('HTMLEvents');
+    event.initEvent("submit", true, true);
+    element.dispatchEvent(event);
+    return event;
+};
+
+//HtmlFormElement
+var  __reset__ = function(element){
+    var event = new Event('HTMLEvents');
+    event.initEvent("reset", false, false);
+    element.dispatchEvent(event);
+    return event;
+};
+
+//LABEL, INPUT, SELECT, TEXTAREA, and BUTTON
+var __focus__ = function(element){
+    var event = new Event('HTMLEvents');
+    event.initEvent("focus", false, false);
+    element.dispatchEvent(event);
+    return event;
+};
+
+//LABEL, INPUT, SELECT, TEXTAREA, and BUTTON
+var __blur__ = function(element){
+    var event = new Event('HTMLEvents');
+    event.initEvent("blur", false, false);
+    element.dispatchEvent(event);
+    return event;
+};
+
+//Window
+var __resize__ = function(element){
+    var event = new Event('HTMLEvents');
+    event.initEvent("resize", true, false);
+    element.dispatchEvent(event);
+    return event;
+};
+
+//Window
+var __scroll__ = function(element){
+    var event = new Event('HTMLEvents');
+    event.initEvent("scroll", true, false);
+    element.dispatchEvent(event);
+    return event;
+};
+
+/**
+ * @name KeyboardEvents
+ * @w3c:domlevel 2 
+ * @uri http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html
+ */
+var KeyboardEvents= function(){};
+KeyboardEvents.prototype = {
+    onkeydown: function(event){
+        __eval__(this.getAttribute('onkeydown')||'', this);
+    },
+    onkeypress: function(event){
+        __eval__(this.getAttribute('onkeypress')||'', this);
+    },
+    onkeyup: function(event){
+        __eval__(this.getAttribute('onkeyup')||'', this);
+    }
+};
+
+
+var __registerKeyboardEventAttrs__ = function(elm){
+    if(elm.hasAttribute('onkeydown')){ 
+        elm.addEventListener('keydown', elm.onkeydown, false); 
+    }
+    if(elm.hasAttribute('onkeypress')){ 
+        elm.addEventListener('keypress', elm.onkeypress, false); 
+    }
+    if(elm.hasAttribute('onkeyup')){ 
+        elm.addEventListener('keyup', elm.onkeyup, false); 
+    }
+    return elm;
+};
+
+//HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement
+var  __keydown__ = function(element){
+    var event = new Event('KeyboardEvents');
+    event.initEvent("keydown", false, false);
+    element.dispatchEvent(event);
+};
+
+//HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement
+var  __keypress__ = function(element){
+    var event = new Event('KeyboardEvents');
+    event.initEvent("keypress", false, false);
+    element.dispatchEvent(event);
+};
+
+//HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement
+var  __keyup__ = function(element){
+    var event = new Event('KeyboardEvents');
+    event.initEvent("keyup", false, false);
+    element.dispatchEvent(event);
+};
+
+/**
+ * @name MaouseEvents
+ * @w3c:domlevel 2 
+ * @uri http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html
+ */
+var MouseEvents= function(){};
+MouseEvents.prototype = {
+    onclick: function(event){
+        __eval__(this.getAttribute('onclick')||'', this);
+    },
+    ondblclick: function(event){
+        __eval__(this.getAttribute('ondblclick')||'', this);
+    },
+    onmousedown: function(event){
+        __eval__(this.getAttribute('onmousedown')||'', this);
+    },
+    onmousemove: function(event){
+        __eval__(this.getAttribute('onmousemove')||'', this);
+    },
+    onmouseout: function(event){
+        __eval__(this.getAttribute('onmouseout')||'', this);
+    },
+    onmouseover: function(event){
+        __eval__(this.getAttribute('onmouseover')||'', this);
+    },
+    onmouseup: function(event){
+        __eval__(this.getAttribute('onmouseup')||'', this);
+    }  
+};
+
+var __registerMouseEventAttrs__ = function(elm){
+    if(elm.hasAttribute('onclick')){ 
+        elm.addEventListener('click', elm.onclick, false); 
+    }
+    if(elm.hasAttribute('ondblclick')){ 
+        elm.addEventListener('dblclick', elm.ondblclick, false); 
+    }
+    if(elm.hasAttribute('onmousedown')){ 
+        elm.addEventListener('mousedown', elm.onmousedown, false); 
+    }
+    if(elm.hasAttribute('onmousemove')){ 
+        elm.addEventListener('mousemove', elm.onmousemove, false); 
+    }
+    if(elm.hasAttribute('onmouseout')){ 
+        elm.addEventListener('mouseout', elm.onmouseout, false); 
+    }
+    if(elm.hasAttribute('onmouseover')){ 
+        elm.addEventListener('mouseover', elm.onmouseover, false); 
+    }
+    if(elm.hasAttribute('onmouseup')){ 
+        elm.addEventListener('mouseup', elm.onmouseup, false); 
+    }
+    return elm;
+};
+
+
+var  __click__ = function(element){
+    var event = new Event('MouseEvents');
+    event.initEvent("click", true, true, null, 0,
+                0, 0, 0, 0, false, false, false, 
+                false, null, null);
+    element.dispatchEvent(event);
+};
+var  __mousedown__ = function(element){
+    var event = new Event('MouseEvents');
+    event.initEvent("mousedown", true, true, null, 0,
+                0, 0, 0, 0, false, false, false, 
+                false, null, null);
+    element.dispatchEvent(event);
+};
+var  __mouseup__ = function(element){
+    var event = new Event('MouseEvents');
+    event.initEvent("mouseup", true, true, null, 0,
+                0, 0, 0, 0, false, false, false, 
+                false, null, null);
+    element.dispatchEvent(event);
+};
+var  __mouseover__ = function(element){
+    var event = new Event('MouseEvents');
+    event.initEvent("mouseover", true, true, null, 0,
+                0, 0, 0, 0, false, false, false, 
+                false, null, null);
+    element.dispatchEvent(event);
+};
+var  __mousemove__ = function(element){
+    var event = new Event('MouseEvents');
+    event.initEvent("mousemove", true, true, null, 0,
+                0, 0, 0, 0, false, false, false, 
+                false, null, null);
+    element.dispatchEvent(event);
+};
+var  __mouseout__ = function(element){
+    var event = new Event('MouseEvents');
+    event.initEvent("mouseout", true, true, null, 0,
+                0, 0, 0, 0, false, false, false, 
+                false, null, null);
+    element.dispatchEvent(event);
+};
+
+/**
+ * HTMLElement - DOM Level 2
+ */
+
+
+/* Hack for http://www.prototypejs.org/
+ *
+ * Prototype 1.6 (the library) creates a new global Element, which causes
+ * envjs to use the wrong Element.
+ *
+ * http://envjs.lighthouseapp.com/projects/21590/tickets/108-prototypejs-wont-load-due-it-clobbering-element
+ *
+ * Options:
+ *  (1) Rename the dom/element to something else
+ *       rejected: been done before. people want Element.
+ *  (2) merge dom+html and not export Element to global namespace
+ *      (meaning we would use a local var Element in a closure, so prototype
+ *      can do what ever it wants)
+ *       rejected: want dom and html separate
+ *  (3) use global namespace (put everything under Envjs = {})
+ *       rejected: massive change
+ *  (4) use commonjs modules (similar to (3) in spirit)
+ *       rejected: massive change
+ *
+ *  or
+ *
+ *  (5) take a reference to Element during initial loading ("compile
+ *      time"), and use the reference instead of "Element".  That's
+ *      what the next line does.  We use __DOMElement__ if we need to
+ *      reference the parent class.  Only this file explcity uses
+ *      Element so this should work, and is the most minimal change I
+ *      could think of with no external API changes.
+ *
+ */
+var  __DOMElement__ = Element;
+
+HTMLElement = function(ownerDocument) {
+    __DOMElement__.apply(this, arguments);
+};
+
+HTMLElement.prototype = new Element();
+__extend__(HTMLElement.prototype, HTMLEvents.prototype);
+__extend__(HTMLElement.prototype, {
+    get className() {
+        return this.getAttribute("class")||'';
+    },
+    set className(value) {
+        return this.setAttribute("class",__trim__(value));
+    },
+    get dir() {
+        return this.getAttribute("dir")||"ltr";
+    },
+    set dir(val) {
+        return this.setAttribute("dir",val);
+    },
+    get id(){
+        return this.getAttribute('id') || '';
+    },
+    set id(id){
+        this.setAttribute('id', id);
+    },
+    get innerHTML(){
+        var ret = "",
+        i;
+
+        // create string containing the concatenation of the string
+        // values of each child
+        for (i=0; i < this.childNodes.length; i++) {
+            if(this.childNodes[i]){
+                if(this.childNodes[i].nodeType === Node.ELEMENT_NODE){
+                    ret += this.childNodes[i].xhtml;
+                } else if (this.childNodes[i].nodeType === Node.TEXT_NODE && i>0 &&
+                           this.childNodes[i-1].nodeType === Node.TEXT_NODE){
+                    //add a single space between adjacent text nodes
+                    ret += " "+this.childNodes[i].xml;
+                }else{
+                    ret += this.childNodes[i].xml;
+                }
+            }
+        }
+        return ret;
+    },
+    get lang() {
+        return this.getAttribute("lang");
+    },
+    set lang(val) {
+        return this.setAttribute("lang",val);
+    },
+    get offsetHeight(){
+        return Number((this.style.height || '').replace("px",""));
+    },
+    get offsetWidth(){
+        return Number((this.style.width || '').replace("px",""));
+    },
+    offsetLeft: 0,
+    offsetRight: 0,
+    get offsetParent(){
+        /* TODO */
+        return;
+    },
+    set offsetParent(element){
+        /* TODO */
+        return;
+    },
+    scrollHeight: 0,
+    scrollWidth: 0,
+    scrollLeft: 0,
+    scrollRight: 0,
+    get style(){
+        return this.getAttribute('style')||'';
+    },
+    get title() {
+        return this.getAttribute("title");
+    },
+    set title(value) {
+        return this.setAttribute("title", value);
+    },
+    get tabIndex(){
+        var tabindex = this.getAttribute('tabindex');
+        if(tabindex!==null){
+            return Number(tabindex);
+        } else {
+            return 0;
+        }
+    },
+    set tabIndex(value){
+        if (value === undefined || value === null) {
+            value = 0;
+        }
+        this.setAttribute('tabindex',Number(value));
+    },
+    get outerHTML(){
+        //Not in the specs but I'll leave it here for now.
+        return this.xhtml;
+    },
+    scrollIntoView: function(){
+        /*TODO*/
+        return;
+    },
+    toString: function(){
+        return '[object HTMLElement]';
+    },
+    get xhtml() {
+        // HTMLDocument.xhtml is non-standard
+        // This is exactly like Document.xml except the tagName has to be
+        // lower cased.  I dont like to duplicate this but its really not
+        // a simple work around between xml and html serialization via
+        // XMLSerializer (which uppercases html tags) and innerHTML (which
+        // lowercases tags)
+
+        var ret = "",
+            ns = "",
+            name = (this.tagName+"").toLowerCase(),
+            attrs,
+            attrstring = "",
+			style = false,
+            i;
+
+        // serialize namespace declarations
+        if (this.namespaceURI){
+            if((this === this.ownerDocument.documentElement) ||
+               (!this.parentNode) ||
+               (this.parentNode &&
+                (this.parentNode.namespaceURI !== this.namespaceURI))) {
+                ns = ' xmlns' + (this.prefix ? (':' + this.prefix) : '') +
+                    '="' + this.namespaceURI + '"';
+            }
+        }
+
+        // serialize Attribute declarations
+        attrs = this.attributes;
+        for(i=0;i< attrs.length;i++){
+            attrstring += " "+attrs[i].name+'="'+attrs[i].xml+'"';
+			if(attrs[i].name == 'style'){
+				style = true;
+			}
+        }
+		if(!style ){
+			style = this.getAttribute('style');
+			if(style)
+				attrstring += ' style="'+style+'"';
+		}
+
+        if(this.hasChildNodes()){
+            // serialize this Element
+	        //console.log('serializing childNodes for %s', name);
+            ret += "<" + name + ns + attrstring +">";
+            for(i=0;i< this.childNodes.length;i++){
+                console.debug('xhtml for '+ this);
+                ret += 'xhtml' in this.childNodes[i] ?
+                    this.childNodes[i].xhtml :
+                    this.childNodes[i].xml;
+            }
+            ret += "</" + name + ">";
+        }else{	
+            //console.log('no childNodes to serialize for %s', name);
+            switch(name){
+            case 'script':
+            case 'noscript':
+                ret += "<" + name + ns + attrstring +"></"+name+">";
+                break;
+            default:
+                ret += "<" + name + ns + attrstring +"/>";
+            }
+        }
+
+        return ret;
+    },
+
+    /**
+     * setAttribute use a dispatch table that other tags can set to
+     *  "listen" to various values being set.  The dispatch table
+     * and registration functions are at the end of the file.
+     *
+     */
+
+    setAttribute: function(name, value) {
+        var result = __DOMElement__.prototype.setAttribute.apply(this, arguments);
+        __addNamedMap__(this.ownerDocument, this);
+        var tagname = this.tagName;
+        var callback = HTMLElement.getAttributeCallback('set', tagname, name);
+        if (callback) {
+            callback(this, value);
+        }
+    },
+    setAttributeNS: function(namespaceURI, name, value) {
+        var result = __DOMElement__.prototype.setAttributeNS.apply(this, arguments);
+        __addNamedMap__(this.ownerDocument, this);
+        var tagname = this.tagName;
+        var callback = HTMLElement.getAttributeCallback('set', tagname, name);
+        if (callback) {
+            callback(this, value);
+        }
+
+        return result;
+    },
+    setAttributeNode: function(newnode) {
+        var result = __DOMElement__.prototype.setAttributeNode.apply(this, arguments);
+        __addNamedMap__(this.ownerDocument, this);
+        var tagname = this.tagName;
+        var callback = HTMLElement.getAttributeCallback('set', tagname, newnode.name);
+        if (callback) {
+            callback(this, node.value);
+        }
+        return result;
+    },
+    setAttributeNodeNS: function(newnode) {
+        var result = __DOMElement__.prototype.setAttributeNodeNS.apply(this, arguments);
+        __addNamedMap__(this.ownerDocument, this);
+        var tagname = this.tagName;
+        var callback = HTMLElement.getAttributeCallback('set', tagname, newnode.name);
+        if (callback) {
+            callback(this, node.value);
+        }
+        return result;
+    },
+    removeAttribute: function(name) {
+        __removeNamedMap__(this.ownerDocument, this);
+        return __DOMElement__.prototype.removeAttribute.apply(this, arguments);
+    },
+    removeAttributeNS: function(namespace, localname) {
+        __removeNamedMap__(this.ownerDocument, this);
+        return __DOMElement__.prototype.removeAttributeNS.apply(this, arguments);
+    },
+    removeAttributeNode: function(name) {
+        __removeNamedMap__(this.ownerDocument, this);
+        return __DOMElement__.prototype.removeAttribute.apply(this, arguments);
+    },
+    removeChild: function(oldChild) {
+        __removeNamedMap__(this.ownerDocument, oldChild);
+        return __DOMElement__.prototype.removeChild.apply(this, arguments);
+    },
+    importNode: function(othernode, deep) {
+        var newnode = __DOMElement__.prototype.importNode.apply(this, arguments);
+        __addNamedMap__(this.ownerDocument, newnode);
+        return newnode;
+    },
+
+    // not actually sure if this is needed or not
+    replaceNode: function(newchild, oldchild) {
+        var newnode = __DOMElement__.prototype.replaceNode.apply(this, arguments);
+        __removeNamedMap__(this.ownerDocument, oldchild);
+        __addNamedMap__(this.ownerDocument, newnode);
+                return newnode;
+    }
+});
+
+
+HTMLElement.attributeCallbacks = {};
+HTMLElement.registerSetAttribute = function(tag, attrib, callbackfn) {
+    HTMLElement.attributeCallbacks[tag + ':set:' + attrib] = callbackfn;
+};
+HTMLElement.registerRemoveAttribute = function(tag, attrib, callbackfn) {
+    HTMLElement.attributeCallbacks[tag + ':remove:' + attrib] = callbackfn;
+};
+
+/**
+ * This is really only useful internally
+ *
+ */
+HTMLElement.getAttributeCallback = function(type, tag, attrib) {
+    return HTMLElement.attributeCallbacks[tag + ':' + type + ':' + attrib] || null;
+};
+/*
+ * HTMLCollection
+ *
+ * HTML5 -- 2.7.2.1 HTMLCollection
+ * http://dev.w3.org/html5/spec/Overview.html#htmlcollection
+ * http://dev.w3.org/html5/spec/Overview.html#collections
+ */
+HTMLCollection = function(nodelist, type) {
+
+    __setArray__(this, []);
+    var n;
+    for (var i=0; i<nodelist.length; i++) {
+        this[i] = nodelist[i];
+        n = nodelist[i].name;
+        if (n) {
+            this[n] = nodelist[i];
+        }
+        n = nodelist[i].id;
+        if (n) {
+            this[n] = nodelist[i];
+        }
+    }
+
+    this.length = nodelist.length;
+};
+
+HTMLCollection.prototype = {
+
+    item: function (idx) {
+        return  ((idx >= 0) && (idx < this.length)) ? this[idx] : null;
+    },
+
+    namedItem: function (name) {
+        return this[name] || null;
+    },
+
+    toString: function() {
+        return '[object HTMLCollection]';
+    }
+};
+/*
+ *  a set of convenience classes to centralize implementation of
+ * properties and methods across multiple in-form elements
+ *
+ *  the hierarchy of related HTML elements and their members is as follows:
+ *
+ * Condensed Version
+ *
+ *  HTMLInputCommon
+ *     * legent (no value attr)
+ *     * fieldset (no value attr)
+ *     * label (no value attr)
+ *     * option (custom value)
+ *  HTMLTypeValueInputs (extends InputCommon)
+ *     * select  (custom value)
+ *     * button (just sets value)
+ *  HTMLInputAreaCommon (extends TypeValueIput)
+ *     * input  (custom)
+ *     * textarea (just sets value)
+ *
+ * -----------------------
+ *    HTMLInputCommon:  common to all elements
+ *       .form
+ *
+ *    <legend>
+ *          [common plus:]
+ *       .align
+ *
+ *    <fieldset>
+ *          [identical to "legend" plus:]
+ *       .margin
+ *
+ *
+ *  ****
+ *
+ *    <label>
+ *          [common plus:]
+ *       .dataFormatAs
+ *       .htmlFor
+ *       [plus data properties]
+ *
+ *    <option>
+ *          [common plus:]
+ *       .defaultSelected
+ *       .index
+ *       .label
+ *       .selected
+ *       .text
+ *       .value   // unique implementation, not duplicated
+ *       .form    // unique implementation, not duplicated
+ *  ****
+ *
+ *    HTMLTypeValueInputs:  common to remaining elements
+ *          [common plus:]
+ *       .name
+ *       .type
+ *       .value
+ *       [plus data properties]
+ *
+ *
+ *    <select>
+ *       .length
+ *       .multiple
+ *       .options[]
+ *       .selectedIndex
+ *       .add()
+ *       .remove()
+ *       .item()                                       // unimplemented
+ *       .namedItem()                                  // unimplemented
+ *       [plus ".onchange"]
+ *       [plus focus events]
+ *       [plus data properties]
+ *       [plus ".size"]
+ *
+ *    <button>
+ *       .dataFormatAs   // duplicated from above, oh well....
+ *       [plus ".status", ".createTextRange()"]
+ *
+ *  ****
+ *
+ *    HTMLInputAreaCommon:  common to remaining elements
+ *       .defaultValue
+ *       .readOnly
+ *       .handleEvent()                                // unimplemented
+ *       .select()
+ *       .onselect
+ *       [plus ".size"]
+ *       [plus ".status", ".createTextRange()"]
+ *       [plus focus events]
+ *       [plus ".onchange"]
+ *
+ *    <textarea>
+ *       .cols
+ *       .rows
+ *       .wrap                                         // unimplemented
+ *       .onscroll                                     // unimplemented
+ *
+ *    <input>
+ *       .alt
+ *       .accept                                       // unimplemented
+ *       .checked
+ *       .complete                                     // unimplemented
+ *       .defaultChecked
+ *       .dynsrc                                       // unimplemented
+ *       .height
+ *       .hspace                                       // unimplemented
+ *       .indeterminate                                // unimplemented
+ *       .loop                                         // unimplemented
+ *       .lowsrc                                       // unimplemented
+ *       .maxLength
+ *       .src
+ *       .start                                        // unimplemented
+ *       .useMap
+ *       .vspace                                       // unimplemented
+ *       .width
+ *       .onclick
+ *       [plus ".size"]
+ *       [plus ".status", ".createTextRange()"]
+
+ *    [data properties]                                // unimplemented
+ *       .dataFld
+ *       .dataSrc
+
+ *    [status stuff]                                   // unimplemented
+ *       .status
+ *       .createTextRange()
+
+ *    [focus events]
+ *       .onblur
+ *       .onfocus
+
+ */
+
+
+
+var inputElements_dataProperties = {};
+var inputElements_status = {};
+
+var inputElements_onchange = {
+    onchange: function(event){
+        __eval__(this.getAttribute('onchange')||'', this);
+    }
+};
+
+var inputElements_size = {
+    get size(){
+        return Number(this.getAttribute('size'));
+    },
+    set size(value){
+        this.setAttribute('size',value);
+    }
+};
+
+var inputElements_focusEvents = {
+    blur: function(){
+        __blur__(this);
+
+        if (this._oldValue != this.value){
+            var event = document.createEvent("HTMLEvents");
+            event.initEvent("change", true, true);
+            this.dispatchEvent( event );
+        }
+    },
+    focus: function(){
+        __focus__(this);
+        this._oldValue = this.value;
+    }
+};
+
+
+/*
+* HTMLInputCommon - convenience class, not DOM
+*/
+var HTMLInputCommon = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLInputCommon.prototype = new HTMLElement();
+__extend__(HTMLInputCommon.prototype, {
+    get form() {
+        // parent can be null if element is outside of a form
+        // or not yet added to the document
+        var parent = this.parentNode;
+        while (parent && parent.nodeName.toLowerCase() !== 'form') {
+            parent = parent.parentNode;
+        }
+        return parent;
+    },
+    get accessKey(){
+        return this.getAttribute('accesskey');
+    },
+    set accessKey(value){
+        this.setAttribute('accesskey',value);
+    },
+    get access(){
+        return this.getAttribute('access');
+    },
+    set access(value){
+        this.setAttribute('access', value);
+    },
+    get disabled(){
+        return (this.getAttribute('disabled') === 'disabled');
+    },
+    set disabled(value){
+        this.setAttribute('disabled', (value ? 'disabled' :''));
+    }
+});
+
+
+
+
+/*
+* HTMLTypeValueInputs - convenience class, not DOM
+*/
+var HTMLTypeValueInputs = function(ownerDocument) {
+
+    HTMLInputCommon.apply(this, arguments);
+
+    this._oldValue = "";
+};
+HTMLTypeValueInputs.prototype = new HTMLInputCommon();
+__extend__(HTMLTypeValueInputs.prototype, inputElements_size);
+__extend__(HTMLTypeValueInputs.prototype, inputElements_status);
+__extend__(HTMLTypeValueInputs.prototype, inputElements_dataProperties);
+__extend__(HTMLTypeValueInputs.prototype, {
+    get name(){
+        return this.getAttribute('name')||'';
+    },
+    set name(value){
+        this.setAttribute('name',value);
+    },
+});
+
+
+/*
+* HTMLInputAreaCommon - convenience class, not DOM
+*/
+var HTMLInputAreaCommon = function(ownerDocument) {
+    HTMLTypeValueInputs.apply(this, arguments);
+};
+HTMLInputAreaCommon.prototype = new HTMLTypeValueInputs();
+__extend__(HTMLInputAreaCommon.prototype, inputElements_focusEvents);
+__extend__(HTMLInputAreaCommon.prototype, inputElements_onchange);
+__extend__(HTMLInputAreaCommon.prototype, {
+    get readOnly(){
+        return (this.getAttribute('readonly')=='readonly');
+    },
+    set readOnly(value){
+        this.setAttribute('readonly', (value ? 'readonly' :''));
+    },
+    select:function(){
+        __select__(this);
+
+    }
+});
+
+
+var __updateFormForNamedElement__ = function(node, value) {
+    if (node.form) {
+        // to check for ID or NAME attribute too
+        // not, then nothing to do
+        node.form._updateElements();
+    }
+};
+
+/**
+ * HTMLAnchorElement - DOM Level 2
+ *
+ * HTML5: 4.6.1 The a element
+ * http://dev.w3.org/html5/spec/Overview.html#the-a-element
+ */
+HTMLAnchorElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLAnchorElement.prototype = new HTMLElement();
+__extend__(HTMLAnchorElement.prototype, {
+    get accessKey() {
+        return this.getAttribute("accesskey")||'';
+    },
+    set accessKey(val) {
+        return this.setAttribute("accesskey",val);
+    },
+    get charset() {
+        return this.getAttribute("charset")||'';
+    },
+    set charset(val) {
+        return this.setAttribute("charset",val);
+    },
+    get coords() {
+        return this.getAttribute("coords")||'';
+    },
+    set coords(val) {
+        return this.setAttribute("coords",val);
+    },
+    get href() {
+        var link = this.getAttribute('href');
+        if (!link) {
+            return '';
+        }
+        return Envjs.uri(link, this.ownerDocument.location.toString());
+    },
+    set href(val) {
+        return this.setAttribute("href", val);
+    },
+    get hreflang() {
+        return this.getAttribute("hreflang")||'';
+    },
+    set hreflang(val) {
+        this.setAttribute("hreflang",val);
+    },
+    get name() {
+        return this.getAttribute("name")||'';
+    },
+    set name(val) {
+        this.setAttribute("name",val);
+    },
+    get rel() {
+        return this.getAttribute("rel")||'';
+    },
+    set rel(val) {
+        return this.setAttribute("rel", val);
+    },
+    get rev() {
+        return this.getAttribute("rev")||'';
+    },
+    set rev(val) {
+        return this.setAttribute("rev",val);
+    },
+    get shape() {
+        return this.getAttribute("shape")||'';
+    },
+    set shape(val) {
+        return this.setAttribute("shape",val);
+    },
+    get target() {
+        return this.getAttribute("target")||'';
+    },
+    set target(val) {
+        return this.setAttribute("target",val);
+    },
+    get type() {
+        return this.getAttribute("type")||'';
+    },
+    set type(val) {
+        return this.setAttribute("type",val);
+    },
+    blur: function() {
+        __blur__(this);
+    },
+    focus: function() {
+        __focus__(this);
+    },
+	click: function(){
+		__click__(this);
+	},
+    /**
+     * Unlike other elements, toString returns the href
+     */
+    toString: function() {
+        return this.href;
+    }
+});
+
+/*
+ * HTMLAreaElement - DOM Level 2
+ *
+ * HTML5: 4.8.13 The area element
+ * http://dev.w3.org/html5/spec/Overview.html#the-area-element
+ */
+HTMLAreaElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLAreaElement.prototype = new HTMLElement();
+__extend__(HTMLAreaElement.prototype, {
+    get accessKey(){
+        return this.getAttribute('accesskey');
+    },
+    set accessKey(value){
+        this.setAttribute('accesskey',value);
+    },
+    get alt(){
+        return this.getAttribute('alt') || '';
+    },
+    set alt(value){
+        this.setAttribute('alt',value);
+    },
+    get coords(){
+        return this.getAttribute('coords');
+    },
+    set coords(value){
+        this.setAttribute('coords',value);
+    },
+    get href(){
+        return this.getAttribute('href') || '';
+    },
+    set href(value){
+        this.setAttribute('href',value);
+    },
+    get noHref(){
+        return this.hasAttribute('href');
+    },
+    get shape(){
+        //TODO
+        return 0;
+    },
+    /*get tabIndex(){
+      return this.getAttribute('tabindex');
+      },
+      set tabIndex(value){
+      this.setAttribute('tabindex',value);
+      },*/
+    get target(){
+        return this.getAttribute('target');
+    },
+    set target(value){
+        this.setAttribute('target',value);
+    },
+
+    /**
+     * toString like <a>, returns the href
+     */
+    toString: function() {
+        return this.href;
+    }
+});
+
+
+/*
+ * HTMLBaseElement - DOM Level 2
+ *
+ * HTML5: 4.2.3 The base element
+ * http://dev.w3.org/html5/spec/Overview.html#the-base-element
+ */
+HTMLBaseElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLBaseElement.prototype = new HTMLElement();
+__extend__(HTMLBaseElement.prototype, {
+    get href(){
+        return this.getAttribute('href');
+    },
+    set href(value){
+        this.setAttribute('href',value);
+    },
+    get target(){
+        return this.getAttribute('target');
+    },
+    set target(value){
+        this.setAttribute('target',value);
+    },
+    toString: function() {
+        return '[object HTMLBaseElement]';
+    }
+});
+
+
+/*
+ * HTMLQuoteElement - DOM Level 2
+ * HTML5: 4.5.5 The blockquote element
+ * http://dev.w3.org/html5/spec/Overview.html#htmlquoteelement
+ */
+HTMLQuoteElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+__extend__(HTMLQuoteElement.prototype, HTMLElement.prototype);
+__extend__(HTMLQuoteElement.prototype, {
+    /**
+     * Quoth the spec:
+     * """
+     * If the cite attribute is present, it must be a valid URL. To
+     * obtain the corresponding citation link, the value of the
+     * attribute must be resolved relative to the element. User agents
+     * should allow users to follow such citation links.
+     * """
+     *
+     * TODO: normalize
+     *
+     */
+    get cite() {
+        return this.getAttribute('cite') || '';
+    },
+
+    set cite(value) {
+        this.setAttribute('cite', value);
+    },
+    toString: function() {
+        return '[object HTMLQuoteElement]';
+    }
+});
+
+/*
+ * HTMLBodyElement - DOM Level 2
+ * HTML5: http://dev.w3.org/html5/spec/Overview.html#the-body-element-0
+ */
+HTMLBodyElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLBodyElement.prototype = new HTMLElement();
+__extend__(HTMLBodyElement.prototype, {
+    onload: function(event){
+        __eval__(this.getAttribute('onload')||'', this);
+    },
+    onunload: function(event){
+        __eval__(this.getAttribute('onunload')||'', this);
+    },
+    toString: function() {
+        return '[object HTMLBodyElement]';
+    }
+});
+
+/*
+ * HTMLBRElement
+ * HTML5: 4.5.3 The hr Element
+ * http://dev.w3.org/html5/spec/Overview.html#the-br-element
+ */
+HTMLBRElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+
+HTMLBRElement.prototype = new HTMLElement();
+__extend__(HTMLBRElement.prototype, {
+
+    // no additional properties or elements
+
+    toString: function() {
+        return '[object HTMLBRElement]';
+    }
+});
+
+
+/*
+ * HTMLButtonElement - DOM Level 2
+ *
+ * HTML5: 4.10.6 The button element
+ * http://dev.w3.org/html5/spec/Overview.html#the-button-element
+ */
+HTMLButtonElement = function(ownerDocument) {
+    HTMLTypeValueInputs.apply(this, arguments);
+};
+HTMLButtonElement.prototype = new HTMLTypeValueInputs();
+__extend__(HTMLButtonElement.prototype, inputElements_status);
+__extend__(HTMLButtonElement.prototype, {
+    get dataFormatAs(){
+        return this.getAttribute('dataFormatAs');
+    },
+    set dataFormatAs(value){
+        this.setAttribute('dataFormatAs',value);
+    },
+    get type() {
+        return this.getAttribute('type') || 'submit';
+    },
+    set type(value) {
+        this.setAttribute('type', value);
+    },
+    get value() {
+        return this.getAttribute('value') || '';
+    },
+    set value(value) {
+        this.setAttribute('value', value);
+    },
+    toString: function() {
+        return '[object HTMLButtonElement]';
+    }
+});
+
+// Named Element Support
+HTMLElement.registerSetAttribute('BUTTON', 'name',
+                                 __updateFormForNamedElement__);
+
+/*
+ * HTMLCanvasElement - DOM Level 2
+ * HTML5: 4.8.11 The canvas element
+ * http://dev.w3.org/html5/spec/Overview.html#the-canvas-element
+ */
+
+
+/*
+ * This is a "non-Abstract Base Class". For an implmentation that actually
+ * did something, all these methods would need to over-written
+ */
+CanvasRenderingContext2D = function() {
+    // NOP
+};
+
+var nullfunction = function() {};
+
+CanvasRenderingContext2D.prototype = {
+    addColorStop: nullfunction,
+    arc: nullfunction,
+    beginPath: nullfunction,
+    bezierCurveTo: nullfunction,
+    clearRect: nullfunction,
+    clip: nullfunction,
+    closePath: nullfunction,
+    createLinearGradient: nullfunction,
+    createPattern: nullfunction,
+    createRadialGradient: nullfunction,
+    drawImage: nullfunction,
+    fill: nullfunction,
+    fillRect:  nullfunction,
+    lineTo: nullfunction,
+    moveTo: nullfunction,
+    quadraticCurveTo: nullfunction,
+    rect: nullfunction,
+    restore: nullfunction,
+    rotate: nullfunction,
+    save: nullfunction,
+    scale: nullfunction,
+    setTranform: nullfunction,
+    stroke: nullfunction,
+    strokeRect: nullfunction,
+    transform: nullfunction,
+    translate: nullfunction,
+
+    toString: function() {
+        return '[object CanvasRenderingContext2D]';
+    }
+};
+
+HTMLCanvasElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLCanvasElement.prototype = new HTMLElement();
+__extend__(HTMLCanvasElement.prototype, {
+
+    getContext: function(ctxtype) {
+        if (ctxtype === '2d') {
+            return new CanvasRenderingContext2D();
+        }
+        throw new Error("Unknown context type of '" + ctxtype + '"');
+    },
+
+    get height(){
+        return Number(this.getAttribute('height')|| 150);
+    },
+    set height(value){
+        this.setAttribute('height', value);
+    },
+
+    get width(){
+        return Number(this.getAttribute('width')|| 300);
+    },
+    set width(value){
+        this.setAttribute('width', value);
+    },
+
+    toString: function() {
+        return '[object HTMLCanvasElement]';
+    }
+
+});
+
+
+/*
+* HTMLTableColElement - DOM Level 2
+*
+* HTML5: 4.9.3 The colgroup element
+* http://dev.w3.org/html5/spec/Overview.html#the-colgroup-element
+*/
+HTMLTableColElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLTableColElement.prototype = new HTMLElement();
+__extend__(HTMLTableColElement.prototype, {
+    get align(){
+        return this.getAttribute('align');
+    },
+    set align(value){
+        this.setAttribute('align', value);
+    },
+    get ch(){
+        return this.getAttribute('ch');
+    },
+    set ch(value){
+        this.setAttribute('ch', value);
+    },
+    get chOff(){
+        return this.getAttribute('ch');
+    },
+    set chOff(value){
+        this.setAttribute('ch', value);
+    },
+    get span(){
+        return this.getAttribute('span');
+    },
+    set span(value){
+        this.setAttribute('span', value);
+    },
+    get vAlign(){
+        return this.getAttribute('valign');
+    },
+    set vAlign(value){
+        this.setAttribute('valign', value);
+    },
+    get width(){
+        return this.getAttribute('width');
+    },
+    set width(value){
+        this.setAttribute('width', value);
+    },
+    toString: function() {
+        return '[object HTMLTableColElement]';
+    }
+});
+
+
+/*
+ * HTMLModElement - DOM Level 2
+ * http://dev.w3.org/html5/spec/Overview.html#htmlmodelement
+ */
+HTMLModElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLModElement.prototype = new HTMLElement();
+__extend__(HTMLModElement.prototype, {
+    get cite(){
+        return this.getAttribute('cite');
+    },
+    set cite(value){
+        this.setAttribute('cite', value);
+    },
+    get dateTime(){
+        return this.getAttribute('datetime');
+    },
+    set dateTime(value){
+        this.setAttribute('datetime', value);
+    },
+    toString: function() {
+        return '[object HTMLModElement]';
+    }
+});
+
+/*
+ * HTMLDivElement - DOM Level 2
+ * HTML5: 4.5.12 The Div Element
+ * http://dev.w3.org/html5/spec/Overview.html#the-div-element
+ */
+HTMLDivElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+
+HTMLDivElement.prototype = new HTMLElement();
+__extend__(HTMLDivElement.prototype, {
+    get align(){
+        return this.getAttribute('align') || 'left';
+    },
+    set align(value){
+        this.setAttribute('align', value);
+    },
+    toString: function() {
+        return '[object HTMLDivElement]';
+    }
+});
+
+
+/*
+ * HTMLDListElement
+ * HTML5: 4.5.7 The dl Element
+ * http://dev.w3.org/html5/spec/Overview.html#the-dl-element
+ */
+HTMLDListElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+
+HTMLDListElement.prototype = new HTMLElement();
+__extend__(HTMLDListElement.prototype, {
+
+    // no additional properties or elements
+
+    toString: function() {
+        return '[object HTMLDListElement]';
+    }
+});
+
+
+/**
+ * HTMLLegendElement - DOM Level 2
+ *
+ * HTML5: 4.10.3 The legend element
+ * http://dev.w3.org/html5/spec/Overview.html#the-legend-element
+ */
+HTMLLegendElement = function(ownerDocument) {
+    HTMLInputCommon.apply(this, arguments);
+};
+HTMLLegendElement.prototype = new HTMLInputCommon();
+__extend__(HTMLLegendElement.prototype, {
+    get align(){
+        return this.getAttribute('align');
+    },
+    set align(value){
+        this.setAttribute('align',value);
+    }
+});
+
+
+/*
+ * HTMLFieldSetElement - DOM Level 2
+ *
+ * HTML5: 4.10.2 The fieldset element
+ * http://dev.w3.org/html5/spec/Overview.html#the-fieldset-element
+ */
+HTMLFieldSetElement = function(ownerDocument) {
+    HTMLLegendElement.apply(this, arguments);
+};
+HTMLFieldSetElement.prototype = new HTMLLegendElement();
+__extend__(HTMLFieldSetElement.prototype, {
+    get margin(){
+        return this.getAttribute('margin');
+    },
+    set margin(value){
+        this.setAttribute('margin',value);
+    },
+    toString: function() {
+        return '[object HTMLFieldSetElement]';
+    }
+});
+
+// Named Element Support
+HTMLElement.registerSetAttribute('FIELDSET', 'name', __updateFormForNamedElement__);
+/*
+ * HTMLFormElement - DOM Level 2
+ *
+ * HTML5: http://dev.w3.org/html5/spec/Overview.html#the-form-element
+ */
+HTMLFormElement = function(ownerDocument){
+    HTMLElement.apply(this, arguments);
+
+    //TODO: on __elementPopped__ from the parser
+    //      we need to determine all the forms default
+    //      values
+};
+HTMLFormElement.prototype = new HTMLElement();
+__extend__(HTMLFormElement.prototype,{
+    get acceptCharset(){
+        return this.getAttribute('accept-charset');
+    },
+    set acceptCharset(acceptCharset) {
+        this.setAttribute('accept-charset', acceptCharset);
+    },
+    get action() {
+        return this.getAttribute('action');
+    },
+    set action(action){
+        this.setAttribute('action', action);
+    },
+
+    get enctype() {
+        return this.getAttribute('enctype');
+    },
+    set enctype(enctype) {
+        this.setAttribute('enctype', enctype);
+    },
+    get method() {
+        return this.getAttribute('method');
+    },
+    set method(method) {
+        this.setAttribute('method', method);
+    },
+    get name() {
+        return this.getAttribute("name");
+    },
+    set name(val) {
+        return this.setAttribute("name",val);
+    },
+    get target() {
+        return this.getAttribute("target");
+    },
+    set target(val) {
+        return this.setAttribute("target",val);
+    },
+
+    /**
+     * "Named Elements"
+     *
+     */
+    /**
+     * returns HTMLFormControlsCollection
+     * http://dev.w3.org/html5/spec/Overview.html#dom-form-elements
+     *
+     * button fieldset input keygen object output select textarea
+     */
+    get elements() {
+        var nodes = this.getElementsByTagName('*');
+        var alist = [];
+        var i, tmp;
+        for (i = 0; i < nodes.length; ++i) {
+            nodename = nodes[i].nodeName;
+            // would like to replace switch with something else
+            //  since it's redundant with the SetAttribute callbacks
+            switch (nodes[i].nodeName) {
+            case 'BUTTON':
+            case 'FIELDSET':
+            case 'INPUT':
+            case 'KEYGEN':
+            case 'OBJECT':
+            case 'OUTPUT':
+            case 'SELECT':
+            case 'TEXTAREA':
+                alist.push(nodes[i]);
+                this[i] = nodes[i];
+                tmp = nodes[i].name;
+                if (tmp) {
+                    this[tmp] = nodes[i];
+                }
+                tmp = nodes[i].id;
+                if (tmp) {
+                    this[tmp] = nodes[i];
+                }
+            }
+        }
+        return new HTMLCollection(alist);
+    },
+    _updateElements: function() {
+        this.elements;
+    },
+    get length() {
+        return this.elements.length;
+    },
+    item: function(idx) {
+        return this.elements[idx];
+    },
+    namedItem: function(aname) {
+        return this.elements.namedItem(aname);
+    },
+    toString: function() {
+        return '[object HTMLFormElement]';
+    },
+    submit: function() {
+        //TODO: this needs to perform the form inputs serialization
+        //      and submission
+        //  DONE: see xhr/form.js
+        var event = __submit__(this);
+
+    },
+    reset: function() {
+        //TODO: this needs to reset all values specified in the form
+        //      to those which where set as defaults
+        __reset__(this);
+
+    },
+    onsubmit: HTMLEvents.prototype.onsubmit,
+    onreset: HTMLEvents.prototype.onreset
+});
+
+/**
+ * HTMLFrameElement - DOM Level 2
+ */
+HTMLFrameElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+    // this is normally a getter but we need to be
+    // able to set it to correctly emulate behavior
+    this.contentDocument = null;
+    this.contentWindow = null;
+};
+HTMLFrameElement.prototype = new HTMLElement();
+__extend__(HTMLFrameElement.prototype, {
+
+    get frameBorder(){
+        return this.getAttribute('border')||"";
+    },
+    set frameBorder(value){
+        this.setAttribute('border', value);
+    },
+    get longDesc(){
+        return this.getAttribute('longdesc')||"";
+    },
+    set longDesc(value){
+        this.setAttribute('longdesc', value);
+    },
+    get marginHeight(){
+        return this.getAttribute('marginheight')||"";
+    },
+    set marginHeight(value){
+        this.setAttribute('marginheight', value);
+    },
+    get marginWidth(){
+        return this.getAttribute('marginwidth')||"";
+    },
+    set marginWidth(value){
+        this.setAttribute('marginwidth', value);
+    },
+    get name(){
+        return this.getAttribute('name')||"";
+    },
+    set name(value){
+        this.setAttribute('name', value);
+    },
+    get noResize(){
+        return this.getAttribute('noresize')||false;
+    },
+    set noResize(value){
+        this.setAttribute('noresize', value);
+    },
+    get scrolling(){
+        return this.getAttribute('scrolling')||"";
+    },
+    set scrolling(value){
+        this.setAttribute('scrolling', value);
+    },
+    get src(){
+        return this.getAttribute('src')||"";
+    },
+    set src(value){
+        this.setAttribute('src', value);
+    },
+    toString: function(){
+        return '[object HTMLFrameElement]';
+    },
+    onload: HTMLEvents.prototype.onload
+});
+
+/**
+ * HTMLFrameSetElement - DOM Level 2
+ *
+ * HTML5: 12.3.3 Frames
+ * http://dev.w3.org/html5/spec/Overview.html#frameset
+ */
+HTMLFrameSetElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLFrameSetElement.prototype = new HTMLElement();
+__extend__(HTMLFrameSetElement.prototype, {
+    get cols(){
+        return this.getAttribute('cols');
+    },
+    set cols(value){
+        this.setAttribute('cols', value);
+    },
+    get rows(){
+        return this.getAttribute('rows');
+    },
+    set rows(value){
+        this.setAttribute('rows', value);
+    },
+    toString: function() {
+        return '[object HTMLFrameSetElement]';
+    }
+});
+
+/*
+ * HTMLHeadingElement
+ * HTML5: 4.4.6 The h1, h2, h3, h4, h5, and h6 elements
+ * http://dev.w3.org/html5/spec/Overview.html#the-h1-h2-h3-h4-h5-and-h6-elements
+ */
+HTMLHeadingElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+
+HTMLHeadingElement.prototype = new HTMLElement();
+__extend__(HTMLHeadingElement.prototype, {
+    toString: function() {
+        return '[object HTMLHeadingElement]';
+    }
+});
+
+/**
+ * HTMLHeadElement - DOM Level 2
+ *
+ * HTML5: 4.2.1 The head element
+ * http://dev.w3.org/html5/spec/Overview.html#the-head-element-0
+ */
+HTMLHeadElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLHeadElement.prototype = new HTMLElement();
+__extend__(HTMLHeadElement.prototype, {
+    get profile(){
+        return this.getAttribute('profile');
+    },
+    set profile(value){
+        this.setAttribute('profile', value);
+    },
+    //we override this so we can apply browser behavior specific to head children
+    //like loading scripts
+    appendChild : function(newChild) {
+        newChild = HTMLElement.prototype.appendChild.apply(this,[newChild]);
+        //TODO: evaluate scripts which are appended to the head
+        //__evalScript__(newChild);
+        return newChild;
+    },
+    insertBefore : function(newChild, refChild) {
+        newChild = HTMLElement.prototype.insertBefore.apply(this,[newChild]);
+        //TODO: evaluate scripts which are appended to the head
+        //__evalScript__(newChild);
+        return newChild;
+    },
+    toString: function(){
+        return '[object HTMLHeadElement]';
+    }
+});
+
+
+/*
+ * HTMLHRElement
+ * HTML5: 4.5.2 The hr Element
+ * http://dev.w3.org/html5/spec/Overview.html#the-hr-element
+ */
+HTMLHRElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+
+HTMLHRElement.prototype = new HTMLElement();
+__extend__(HTMLHRElement.prototype, {
+
+    // no additional properties or elements
+
+    toString: function() {
+        return '[object HTMLHRElement]';
+    }
+});
+
+
+/*
+ * HTMLHtmlElement
+ * HTML5: 4.1.1 The Html Element
+ * http://dev.w3.org/html5/spec/Overview.html#htmlhtmlelement
+ */
+HTMLHtmlElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+
+HTMLHtmlElement.prototype = new HTMLElement();
+__extend__(HTMLHtmlElement.prototype, {
+
+    // no additional properties or elements
+
+    toString: function() {
+        return '[object HTMLHtmlElement]';
+    }
+});
+
+
+/*
+ * HTMLIFrameElement - DOM Level 2
+ *
+ * HTML5: 4.8.3 The iframe element
+ * http://dev.w3.org/html5/spec/Overview.html#the-iframe-element
+ */
+HTMLIFrameElement = function(ownerDocument) {
+    HTMLFrameElement.apply(this, arguments);
+};
+HTMLIFrameElement.prototype = new HTMLFrameElement();
+__extend__(HTMLIFrameElement.prototype, {
+    get height() {
+        return this.getAttribute("height") || "";
+    },
+    set height(val) {
+        return this.setAttribute("height",val);
+    },
+    get width() {
+        return this.getAttribute("width") || "";
+    },
+    set width(val) {
+        return this.setAttribute("width",val);
+    },
+    toString: function(){
+        return '[object HTMLIFrameElement]';
+    }
+});
+
+/**
+ * HTMLImageElement and Image
+ */
+
+
+HTMLImageElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLImageElement.prototype = new HTMLElement();
+__extend__(HTMLImageElement.prototype, {
+    get alt(){
+        return this.getAttribute('alt');
+    },
+    set alt(value){
+        this.setAttribute('alt', value);
+    },
+    get height(){
+        return parseInt(this.getAttribute('height'), 10) || 0;
+    },
+    set height(value){
+        this.setAttribute('height', value);
+    },
+    get isMap(){
+        return this.hasAttribute('map');
+    },
+    set useMap(value){
+        this.setAttribute('map', value);
+    },
+    get longDesc(){
+        return this.getAttribute('longdesc');
+    },
+    set longDesc(value){
+        this.setAttribute('longdesc', value);
+    },
+    get name(){
+        return this.getAttribute('name');
+    },
+    set name(value){
+        this.setAttribute('name', value);
+    },
+    get src(){
+        return this.getAttribute('src') || '';
+    },
+    set src(value){
+        this.setAttribute('src', value);
+    },
+    get width(){
+        return parseInt(this.getAttribute('width'), 10) || 0;
+    },
+    set width(value){
+        this.setAttribute('width', value);
+    },
+    toString: function(){
+        return '[object HTMLImageElement]';
+    }
+});
+
+/*
+ * html5 4.8.1
+ * http://dev.w3.org/html5/spec/Overview.html#the-img-element
+ */
+Image = function(width, height) {
+    // Not sure if "[global].document" satifies this requirement:
+    // "The element's document must be the active document of the
+    // browsing context of the Window object on which the interface
+    // object of the invoked constructor is found."
+
+    HTMLElement.apply(this, [document]);
+    // Note: firefox will throw an error if the width/height
+    //   is not an integer.  Safari just converts to 0 on error.
+    this.width = parseInt(width, 10) || 0;
+    this.height = parseInt(height, 10) || 0;
+    this.nodeName = 'IMG';
+};
+Image.prototype = new HTMLImageElement();
+
+
+/*
+ * Image.src attribute events.
+ *
+ * Not sure where this should live... in events/img.js? in parser/img.js?
+ * Split out to make it easy to move.
+ */
+
+/**
+ * HTMLImageElement && Image are a bit odd in that the 'src' attribute
+ * is 'active' -- changing it triggers loading of the image from the
+ * network.
+ *
+ * This can occur by
+ *   - Directly setting the Image.src =
+ *   - Using one of the Element.setAttributeXXX methods
+ *   - Node.importNode an image
+ *   - The initial creation and parsing of an <img> tag
+ *
+ * __onImageRequest__ is a function that handles eventing
+ *  and dispatches to a user-callback.
+ *
+ */
+__loadImage__ = function(node, value) {
+    var event;
+    if (value && (!Envjs.loadImage ||
+                  (Envjs.loadImage &&
+                   Envjs.loadImage(node, value)))) {
+        // value has to be something (easy)
+        // if the user-land API doesn't exist
+        // Or if the API exists and it returns true, then ok:
+        event = document.createEvent('Events');
+        event.initEvent('load');
+    } else {
+        // oops
+        event = document.createEvent('Events');
+        event.initEvent('error');
+    }
+    node.dispatchEvent(event, false);
+};
+
+__extend__(HTMLImageElement.prototype, {
+    onload: function(event){
+        __eval__(this.getAttribute('onload') || '', this);
+    }
+});
+
+
+/*
+ * Image Loading
+ *
+ * The difference between "owner.parsing" and "owner.fragment"
+ *
+ * If owner.parsing === true, then during the html5 parsing then,
+ *  __elementPopped__ is called when a compete tag (with attrs and
+ *  children) is full parsed and added the DOM.
+ *
+ *   For images, __elementPopped__ is called with everything the
+ *    tag has.  which in turn looks for a "src" attr and calls
+ *    __loadImage__
+ *
+ * If owner.parser === false (or non-existant), then we are not in
+ * a parsing step.  For images, perhaps someone directly modified
+ * a 'src' attribute of an existing image.
+ *
+ * 'innerHTML' is tricky since we first create a "fake document",
+ *  parse it, then import the right parts.  This may call
+ *  img.setAttributeNS twice.  once during the parse and once
+ *  during the clone of the node.  We want event to trigger on the
+ *  later and not during th fake doco.  "owner.fragment" is set by
+ *  the fake doco parser to indicate that events should not be
+ *  triggered on this.
+ *
+ * We coud make 'owner.parser' == [ 'none', 'full', 'fragment']
+ * and just use one variable That was not done since the patch is
+ * quite large as is.
+ *
+ * This same problem occurs with scripts.  innerHTML oddly does
+ * not eval any <script> tags inside.
+ */
+HTMLElement.registerSetAttribute('IMG', 'src', function(node, value) {
+    var owner = node.ownerDocument;
+    if (!owner.parsing && !owner.fragment) {
+        __loadImage__(node, value);
+    }
+});
+/**
+ * HTMLInputElement
+ *
+ * HTML5: 4.10.5 The input element
+ * http://dev.w3.org/html5/spec/Overview.html#the-input-element
+ */
+HTMLInputElement = function(ownerDocument) {
+    HTMLInputAreaCommon.apply(this, arguments);
+    this._dirty = false;
+    this._checked = null;
+    this._value = null;
+};
+HTMLInputElement.prototype = new HTMLInputAreaCommon();
+__extend__(HTMLInputElement.prototype, {
+    get alt(){
+        return this.getAttribute('alt') || '';
+    },
+    set alt(value){
+        this.setAttribute('alt', value);
+    },
+
+    /**
+     * 'checked' returns state, NOT the value of the attribute
+     */
+    get checked(){
+        if (this._checked === null) {
+            this._checked = this.defaultChecked;
+        }
+        return this._checked;
+    },
+    set checked(value){
+        // force to boolean value
+        this._checked = (value) ? true : false;
+    },
+
+    /**
+     * 'defaultChecked' actually reflects if the 'checked' attribute
+     * is present or not
+     */
+    get defaultChecked(){
+        return this.hasAttribute('checked');
+    },
+    set defaultChecked(val){
+        if (val) {
+            this.setAttribute('checked', '');
+        } else {
+            if (this.defaultChecked) {
+                this.removeAttribute('checked');
+            }
+        }
+    },
+    get defaultValue() {
+        return this.getAttribute('value') || '';
+    },
+    set defaultValue(value) {
+        this._dirty = true;
+        this.setAttribute('value', value);
+    },
+    get value() {
+        return (this._value === null) ? this.defaultValue : this._value;
+    },
+    set value(newvalue) {
+        this._value = newvalue;
+    },
+    /**
+     * Height is a string
+     */
+    get height(){
+        // spec says it is a string
+        return this.getAttribute('height') || '';
+    },
+    set height(value){
+        this.setAttribute('height',value);
+    },
+
+    /**
+     * MaxLength is a number
+     */
+    get maxLength(){
+        return Number(this.getAttribute('maxlength')||'-1');
+    },
+    set maxLength(value){
+        this.setAttribute('maxlength', value);
+    },
+
+    /**
+     * Src is a URL string
+     */
+    get src(){
+        return this.getAttribute('src') || '';
+    },
+    set src(value){
+        // TODO: make absolute any relative URLS
+        this.setAttribute('src', value);
+    },
+
+    get type() {
+        return this.getAttribute('type') || 'text';
+    },
+    set type(value) {
+        this.setAttribute('type', value);
+    },
+
+    get useMap(){
+        return this.getAttribute('map') || '';
+    },
+
+    /**
+     * Width: spec says it is a string
+     */
+    get width(){
+        return this.getAttribute('width') || '';
+    },
+    set width(value){
+        this.setAttribute('width',value);
+    },
+    click:function(){
+        __click__(this);
+    },
+    toString: function() {
+        return '[object HTMLInputElement]';
+    }
+});
+
+//http://dev.w3.org/html5/spec/Overview.html#dom-input-value
+// if someone directly modifies the value attribute, then the input's value
+// also directly changes.
+HTMLElement.registerSetAttribute('INPUT', 'value', function(node, value) {
+    if (!node._dirty) {
+        node._value = value;
+        node._dirty = true;
+    }
+});
+
+/*
+ *The checked content attribute is a boolean attribute that gives the
+ *default checkedness of the input element. When the checked content
+ *attribute is added, if the control does not have dirty checkedness,
+ *the user agent must set the checkedness of the element to true; when
+ *the checked content attribute is removed, if the control does not
+ *have dirty checkedness, the user agent must set the checkedness of
+ *the element to false.
+ */
+// Named Element Support
+HTMLElement.registerSetAttribute('INPUT', 'name',
+                                 __updateFormForNamedElement__);
+
+/**
+ * HTMLLabelElement - DOM Level 2
+ * HTML5 4.10.4 The label element
+ * http://dev.w3.org/html5/spec/Overview.html#the-label-element
+ */
+HTMLLabelElement = function(ownerDocument) {
+    HTMLInputCommon.apply(this, arguments);
+};
+HTMLLabelElement.prototype = new HTMLInputCommon();
+__extend__(HTMLLabelElement.prototype, inputElements_dataProperties);
+__extend__(HTMLLabelElement.prototype, {
+    get htmlFor() {
+        return this.getAttribute('for');
+    },
+    set htmlFor(value) {
+        this.setAttribute('for',value);
+    },
+    get dataFormatAs() {
+        return this.getAttribute('dataFormatAs');
+    },
+    set dataFormatAs(value) {
+        this.setAttribute('dataFormatAs',value);
+    },
+    toString: function() {
+        return '[object HTMLLabelElement]';
+    }
+});
+
+/*
+ * HTMLLIElement
+ * HTML5: 4.5.8 The li Element
+ * http://dev.w3.org/html5/spec/Overview.html#the-li-element
+ */
+HTMLLIElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+
+HTMLLIElement.prototype = new HTMLElement();
+__extend__(HTMLLIElement.prototype, {
+
+    // TODO: attribute long value;
+
+    toString: function() {
+        return '[object HTMLLIElement]';
+    }
+});
+
+
+/*
+ * HTMLLinkElement - DOM Level 2
+ *
+ * HTML5: 4.8.12 The map element
+ * http://dev.w3.org/html5/spec/Overview.html#the-map-element
+ */
+HTMLLinkElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLLinkElement.prototype = new HTMLElement();
+__extend__(HTMLLinkElement.prototype, {
+    get disabled(){
+        return this.getAttribute('disabled');
+    },
+    set disabled(value){
+        this.setAttribute('disabled',value);
+    },
+    get charset(){
+        return this.getAttribute('charset');
+    },
+    set charset(value){
+        this.setAttribute('charset',value);
+    },
+    get href(){
+        return this.getAttribute('href');
+    },
+    set href(value){
+        this.setAttribute('href',value);
+    },
+    get hreflang(){
+        return this.getAttribute('hreflang');
+    },
+    set hreflang(value){
+        this.setAttribute('hreflang',value);
+    },
+    get media(){
+        return this.getAttribute('media');
+    },
+    set media(value){
+        this.setAttribute('media',value);
+    },
+    get rel(){
+        return this.getAttribute('rel');
+    },
+    set rel(value){
+        this.setAttribute('rel',value);
+    },
+    get rev(){
+        return this.getAttribute('rev');
+    },
+    set rev(value){
+        this.setAttribute('rev',value);
+    },
+    get target(){
+        return this.getAttribute('target');
+    },
+    set target(value){
+        this.setAttribute('target',value);
+    },
+    get type(){
+        return this.getAttribute('type');
+    },
+    set type(value){
+        this.setAttribute('type',value);
+    },
+    toString: function() {
+        return '[object HTMLLinkElement]';
+    }
+});
+
+__loadLink__ = function(node, value) {
+    var event;
+    var owner = node.ownerDocument;
+
+    if (owner.fragment) {
+        /**
+         * if we are in an innerHTML fragment parsing step
+         * then ignore.  It will be handled once the fragment is
+         * added to the real doco
+         */
+        return;
+    }
+
+    if (node.parentNode === null) {
+        /*
+         * if a <link> is parentless (normally by create a new link
+         * via document.createElement('link'), then do *not* fire an
+         * event, even if it has a valid 'href' attribute.
+         */
+        return;
+    }
+    if (value != '' && (!Envjs.loadLink ||
+                        (Envjs.loadLink &&
+                         Envjs.loadLink(node, value)))) {
+        // value has to be something (easy)
+        // if the user-land API doesn't exist
+        // Or if the API exists and it returns true, then ok:
+        event = document.createEvent('Events');
+        event.initEvent('load');
+    } else {
+        // oops
+        event = document.createEvent('Events');
+        event.initEvent('error');
+    }
+    node.dispatchEvent(event, false);
+};
+
+
+HTMLElement.registerSetAttribute('LINK', 'href', function(node, value) {
+    __loadLink__(node, value);
+});
+
+/**
+ * Event stuff, not sure where it goes
+ */
+__extend__(HTMLLinkElement.prototype, {
+    onload: function(event){
+        __eval__(this.getAttribute('onload')||'', this);
+    },
+});
+
+/**
+ * HTMLMapElement
+ *
+ * 4.8.12 The map element
+ * http://dev.w3.org/html5/spec/Overview.html#the-map-element
+ */
+HTMLMapElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLMapElement.prototype = new HTMLElement();
+__extend__(HTMLMapElement.prototype, {
+    get areas(){
+        return this.getElementsByTagName('area');
+    },
+    get name(){
+        return this.getAttribute('name') || '';
+    },
+    set name(value){
+        this.setAttribute('name',value);
+    },
+    toString: function() {
+        return '[object HTMLMapElement]';
+    }
+});
+
+/**
+ * HTMLMetaElement - DOM Level 2
+ * HTML5: 4.2.5 The meta element
+ * http://dev.w3.org/html5/spec/Overview.html#meta
+ */
+HTMLMetaElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLMetaElement.prototype = new HTMLElement();
+__extend__(HTMLMetaElement.prototype, {
+    get content() {
+        return this.getAttribute('content') || '';
+    },
+    set content(value){
+        this.setAttribute('content',value);
+    },
+    get httpEquiv(){
+        return this.getAttribute('http-equiv') || '';
+    },
+    set httpEquiv(value){
+        this.setAttribute('http-equiv',value);
+    },
+    get name(){
+        return this.getAttribute('name') || '';
+    },
+    set name(value){
+        this.setAttribute('name',value);
+    },
+    get scheme(){
+        return this.getAttribute('scheme');
+    },
+    set scheme(value){
+        this.setAttribute('scheme',value);
+    },
+    toString: function() {
+        return '[object HTMLMetaElement]';
+    }
+});
+
+
+/**
+ * HTMLObjectElement - DOM Level 2
+ * HTML5: 4.8.5 The object element
+ * http://dev.w3.org/html5/spec/Overview.html#the-object-element
+ */
+HTMLObjectElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLObjectElement.prototype = new HTMLElement();
+__extend__(HTMLObjectElement.prototype, {
+    get code(){
+        return this.getAttribute('code');
+    },
+    set code(value){
+        this.setAttribute('code',value);
+    },
+    get archive(){
+        return this.getAttribute('archive');
+    },
+    set archive(value){
+        this.setAttribute('archive',value);
+    },
+    get codeBase(){
+        return this.getAttribute('codebase');
+    },
+    set codeBase(value){
+        this.setAttribute('codebase',value);
+    },
+    get codeType(){
+        return this.getAttribute('codetype');
+    },
+    set codeType(value){
+        this.setAttribute('codetype',value);
+    },
+    get data(){
+        return this.getAttribute('data');
+    },
+    set data(value){
+        this.setAttribute('data',value);
+    },
+    get declare(){
+        return this.getAttribute('declare');
+    },
+    set declare(value){
+        this.setAttribute('declare',value);
+    },
+    get height(){
+        return this.getAttribute('height');
+    },
+    set height(value){
+        this.setAttribute('height',value);
+    },
+    get standby(){
+        return this.getAttribute('standby');
+    },
+    set standby(value){
+        this.setAttribute('standby',value);
+    },
+    /*get tabIndex(){
+      return this.getAttribute('tabindex');
+      },
+      set tabIndex(value){
+      this.setAttribute('tabindex',value);
+      },*/
+    get type(){
+        return this.getAttribute('type');
+    },
+    set type(value){
+        this.setAttribute('type',value);
+    },
+    get useMap(){
+        return this.getAttribute('usemap');
+    },
+    set useMap(value){
+        this.setAttribute('usemap',value);
+    },
+    get width(){
+        return this.getAttribute('width');
+    },
+    set width(value){
+        this.setAttribute('width',value);
+    },
+    get contentDocument(){
+        return this.ownerDocument;
+    },
+    toString: function() {
+        return '[object HTMLObjectElement]';
+    }
+});
+
+// Named Element Support
+HTMLElement.registerSetAttribute('OBJECT', 'name',
+                                 __updateFormForNamedElement__);
+
+/*
+ * HTMLOListElement
+ * HTML5: 4.5.6 The ol Element
+ * http://dev.w3.org/html5/spec/Overview.html#the-ol-element
+ */
+HTMLOListElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+
+HTMLOListElement.prototype = new HTMLElement();
+__extend__(HTMLOListElement.prototype, {
+
+    // TODO: attribute boolean reversed;
+    // TODO:  attribute long start;
+
+    toString: function() {
+        return '[object HTMLOListElement]';
+    }
+});
+
+
+/**
+ * HTMLOptGroupElement - DOM Level 2
+ * HTML 5: 4.10.9 The optgroup element
+ * http://dev.w3.org/html5/spec/Overview.html#the-optgroup-element
+ */
+HTMLOptGroupElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLOptGroupElement.prototype = new HTMLElement();
+__extend__(HTMLOptGroupElement.prototype, {
+    get disabled(){
+        return this.getAttribute('disabled');
+    },
+    set disabled(value){
+        this.setAttribute('disabled',value);
+    },
+    get label(){
+        return this.getAttribute('label');
+    },
+    set label(value){
+        this.setAttribute('label',value);
+    },
+    appendChild: function(node){
+        var i,
+        length,
+        selected = false;
+        //make sure at least one is selected by default
+        if(node.nodeType === Node.ELEMENT_NODE && node.tagName === 'OPTION'){
+            length = this.childNodes.length;
+            for(i=0;i<length;i++){
+                if(this.childNodes[i].nodeType === Node.ELEMENT_NODE &&
+                   this.childNodes[i].tagName === 'OPTION'){
+                    //check if it is selected
+                    if(this.selected){
+                        selected = true;
+                        break;
+                    }
+                }
+            }
+            if(!selected){
+                node.selected = true;
+                this.value = node.value?node.value:'';
+            }
+        }
+        return HTMLElement.prototype.appendChild.apply(this, [node]);
+    },
+    toString: function() {
+        return '[object HTMLOptGroupElement]';
+    }
+});
+
+/**
+ * HTMLOptionElement, Option
+ * HTML5: 4.10.10 The option element
+ * http://dev.w3.org/html5/spec/Overview.html#the-option-element
+ */
+HTMLOptionElement = function(ownerDocument) {
+    HTMLInputCommon.apply(this, arguments);
+    this._selected = null;
+};
+HTMLOptionElement.prototype = new HTMLInputCommon();
+__extend__(HTMLOptionElement.prototype, {
+
+    /**
+     * defaultSelected actually reflects the presence of the
+     * 'selected' attribute.
+     */
+    get defaultSelected() {
+        return this.hasAttribute('selected');
+    },
+    set defaultSelected(value) {
+        if (value) {
+            this.setAttribute('selected','');
+        } else {
+            if (this.hasAttribute('selected')) {
+                this.removeAttribute('selected');
+            }
+        }
+    },
+
+    /*
+     * HTML5: The form IDL attribute's behavior depends on whether the
+     * option element is in a select element or not. If the option has
+     * a select element as its parent, or has a colgroup element as
+     * its parent and that colgroup element has a select element as
+     * its parent, then the form IDL attribute must return the same
+     * value as the form IDL attribute on that select
+     * element. Otherwise, it must return null.
+     */
+    _selectparent: function() {
+        var parent = this.parentNode;
+        if (!parent) {
+            return null;
+        }
+
+        if (parent.tagName === 'SELECT') {
+            return parent;
+        }
+        if (parent.tagName === 'COLGROUP') {
+            parent = parent.parentNode;
+            if (parent && parent.tagName === 'SELECT') {
+                return parent;
+            }
+        }
+    },
+    _updateoptions: function() {
+        var parent = this._selectparent();
+        if (parent) {
+            // has side effects and updates owner select's options
+            parent.options;
+        }
+    },
+    get form() {
+        var parent = this._selectparent();
+        return parent ? parent.form : null;
+    },
+    get index() {
+        var options, i;
+
+        if (! this.parentNode) {
+            return -1;
+        }
+        options = this.parentNode.options;
+        for (i=0; i < options.length; ++i) {
+            if (this === options[i]) {
+                return i;
+            }
+        }
+        return 0;
+    },
+    get label() {
+        return this.getAttribute('label');
+    },
+    set label(value) {
+        this.setAttribute('label', value);
+    },
+
+    /*
+     * This is not in the spec, but safari and firefox both
+     * use this
+     */
+    get name() {
+        return this.getAttribute('name');
+    },
+    set name(value) {
+        this.setAttribute('name', value);
+    },
+
+    /**
+     *
+     */
+    get selected() {
+        // if disabled, return false, no matter what
+        if (this.disabled) {
+            return false;
+        }
+        if (this._selected === null) {
+            return this.defaultSelected;
+        }
+
+        return this._selected;
+    },
+    set selected(value) {
+        this._selected = (value) ? true : false;
+    },
+
+    get text() {
+        var val = this.nodeValue;
+        return (val === null || this.value === undefined) ?
+            this.innerHTML :
+            val;
+    },
+    get value() {
+        var val = this.getAttribute('value');
+        return (val === null || val === undefined) ?
+            this.textContent :
+            val;
+    },
+    set value(value) {
+        this.setAttribute('value', value);
+    },
+    toString: function() {
+        return '[object HTMLOptionElement]';
+    }
+});
+
+Option = function(text, value, defaultSelected, selected) {
+
+    // Not sure if this is correct:
+    //
+    // The element's document must be the active document of the
+    // browsing context of the Window object on which the interface
+    // object of the invoked constructor is found.
+    HTMLOptionElement.apply(this, [document]);
+    this.nodeName = 'OPTION';
+
+    if (arguments.length >= 1) {
+        this.appendChild(document.createTextNode('' + text));
+    }
+    if (arguments.length >= 2) {
+        this.value = value;
+    }
+    if (arguments.length >= 3) {
+        if (defaultSelected) {
+            this.defaultSelected = '';
+        }
+    }
+    if (arguments.length >= 4) {
+        this.selected = (selected) ? true : false;
+    }
+};
+
+Option.prototype = new HTMLOptionElement();
+
+// Named Element Support
+
+function updater(node, value) {
+    node._updateoptions();
+}
+HTMLElement.registerSetAttribute('OPTION', 'name', updater);
+HTMLElement.registerSetAttribute('OPTION', 'id', updater);
+
+/*
+* HTMLParagraphElement - DOM Level 2
+*/
+HTMLParagraphElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLParagraphElement.prototype = new HTMLElement();
+__extend__(HTMLParagraphElement.prototype, {
+    toString: function(){
+        return '[object HTMLParagraphElement]';
+    }
+});
+
+
+/**
+ * HTMLParamElement
+ *
+ * HTML5: 4.8.6 The param element
+ * http://dev.w3.org/html5/spec/Overview.html#the-param-element
+ */
+HTMLParamElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLParamElement.prototype = new HTMLElement();
+__extend__(HTMLParamElement.prototype, {
+    get name() {
+        return this.getAttribute('name') || '';
+    },
+    set name(value) {
+        this.setAttribute('name', value);
+    },
+    get type(){
+        return this.getAttribute('type');
+    },
+    set type(value){
+        this.setAttribute('type',value);
+    },
+    get value(){
+        return this.getAttribute('value');
+    },
+    set value(value){
+        this.setAttribute('value',value);
+    },
+    get valueType(){
+        return this.getAttribute('valuetype');
+    },
+    set valueType(value){
+        this.setAttribute('valuetype',value);
+    },
+    toString: function() {
+        return '[object HTMLParamElement]';
+    }
+});
+
+
+/*
+ * HTMLPreElement
+ * HTML5: 4.5.4 The pre Element
+ * http://dev.w3.org/html5/spec/Overview.html#the-pre-element
+ */
+HTMLPreElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+
+HTMLPreElement.prototype = new HTMLElement();
+__extend__(HTMLPreElement.prototype, {
+
+    // no additional properties or elements
+
+    toString: function() {
+        return '[object HTMLPreElement]';
+    }
+});
+
+
+/**
+ * HTMLScriptElement - DOM Level 2
+ *
+ * HTML5: 4.3.1 The script element
+ * http://dev.w3.org/html5/spec/Overview.html#script
+ */
+HTMLScriptElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLScriptElement.prototype = new HTMLElement();
+__extend__(HTMLScriptElement.prototype, {
+
+    /**
+     * HTML5 spec @ http://dev.w3.org/html5/spec/Overview.html#script
+     *
+     * "The IDL attribute text must return a concatenation of the
+     * contents of all the text nodes that are direct children of the
+     * script element (ignoring any other nodes such as comments or
+     * elements), in tree order. On setting, it must act the same way
+     * as the textContent IDL attribute."
+     *
+     * AND... "The term text node refers to any Text node,
+     * including CDATASection nodes; specifically, any Node with node
+     * type TEXT_NODE (3) or CDATA_SECTION_NODE (4)"
+     */
+    get text() {
+        var kids = this.childNodes;
+        var kid;
+        var s = '';
+        var imax = kids.length;
+        for (var i = 0; i < imax; ++i) {
+            kid = kids[i];
+            if (kid.nodeType === Node.TEXT_NODE ||
+                kid.nodeType === Node.CDATA_SECTION_NODE) {
+                s += kid.nodeValue;
+            }
+        }
+        return s;
+    },
+
+    /**
+     * HTML5 spec "Can be set, to replace the element's children with
+     * the given value."
+     */
+    set text(value) {
+        // this deletes all children, and make a new single text node
+        // with value
+        this.textContent = value;
+
+        /* Currently we always execute, but this isn't quite right if
+         * the node has *not* been inserted into the document, then it
+         * should *not* fire.  The more detailed answer from the spec:
+         *
+         * When a script element that is neither marked as having
+         * "already started" nor marked as being "parser-inserted"
+         * experiences one of the events listed in the following list,
+         * the user agent must synchronously run the script element:
+         *
+         *   * The script element gets inserted into a document.
+         *   * The script element is in a Document and its child nodes
+         *     are changed.
+         *   * The script element is in a Document and has a src
+         *     attribute set where previously the element had no such
+         *     attribute.
+         *
+         * And no doubt there are other cases as well.
+         */
+        Envjs.loadInlineScript(this);
+    },
+
+    get htmlFor(){
+        return this.getAttribute('for');
+    },
+    set htmlFor(value){
+        this.setAttribute('for',value);
+    },
+    get event(){
+        return this.getAttribute('event');
+    },
+    set event(value){
+        this.setAttribute('event',value);
+    },
+    get charset(){
+        return this.getAttribute('charset');
+    },
+    set charset(value){
+        this.setAttribute('charset',value);
+    },
+    get defer(){
+        return this.getAttribute('defer');
+    },
+    set defer(value){
+        this.setAttribute('defer',value);
+    },
+    get src(){
+        return this.getAttribute('src')||'';
+    },
+    set src(value){
+        this.setAttribute('src',value);
+    },
+    get type(){
+        return this.getAttribute('type')||'';
+    },
+    set type(value){
+        this.setAttribute('type',value);
+    },
+    onload: HTMLEvents.prototype.onload,
+    onerror: HTMLEvents.prototype.onerror,
+    toString: function() {
+        return '[object HTMLScriptElement]';
+    }
+});
+
+
+/**
+ * HTMLSelectElement
+ * HTML5: http://dev.w3.org/html5/spec/Overview.html#the-select-element
+ */
+HTMLSelectElement = function(ownerDocument) {
+    HTMLTypeValueInputs.apply(this, arguments);
+    this._oldIndex = -1;
+};
+
+HTMLSelectElement.prototype = new HTMLTypeValueInputs();
+__extend__(HTMLSelectElement.prototype, inputElements_dataProperties);
+__extend__(HTMLButtonElement.prototype, inputElements_size);
+__extend__(HTMLSelectElement.prototype, inputElements_onchange);
+__extend__(HTMLSelectElement.prototype, inputElements_focusEvents);
+__extend__(HTMLSelectElement.prototype, {
+
+    get value() {
+        var index = this.selectedIndex;
+        return (index === -1) ? '' : this.options[index].value;
+    },
+    set value(newValue) {
+        var options = this.options;
+        var imax = options.length;
+        for (var i=0; i< imax; ++i) {
+            if (options[i].value == newValue) {
+                this.setAttribute('value', newValue);
+                this.selectedIndex = i;
+                return;
+            }
+        }
+    },
+    get multiple() {
+        return this.hasAttribute('multiple');
+    },
+    set multiple(value) {
+        if (value) {
+            this.setAttribute('multiple', '');
+        } else {
+            if (this.hasAttribute('multiple')) {
+                this.removeAttribute('multiple');
+            }
+        }
+    },
+    // Returns HTMLOptionsCollection
+    get options() {
+        var nodes = this.getElementsByTagName('option');
+        var alist = [];
+        var i, tmp;
+        for (i = 0; i < nodes.length; ++i) {
+            alist.push(nodes[i]);
+            this[i] = nodes[i];
+            tmp = nodes[i].name;
+            if (tmp) {
+                this[tmp] = nodes[i];
+            }
+            tmp = nodes[i].id;
+            if (tmp) {
+                this[tmp] = nodes[i];
+            }
+        }
+        return new HTMLCollection(alist);
+    },
+    get length() {
+        return this.options.length;
+    },
+    item: function(idx) {
+        return this.options[idx];
+    },
+    namedItem: function(aname) {
+        return this.options[aname];
+    },
+
+    get selectedIndex() {
+        var options = this.options;
+        var imax = options.length;
+        for (var i=0; i < imax; ++i) {
+            if (options[i].selected) {
+                //console.log('select get selectedIndex %s', i);
+                return i;
+            }
+        }
+        //console.log('select get selectedIndex %s', -1);
+        return -1;
+    },
+
+    set selectedIndex(value) {
+        var options = this.options;
+        var num = Number(value);
+        var imax = options.length;
+        for (var i = 0; i < imax; ++i) {
+            options[i].selected = (i === num);
+        }
+    },
+    get type() {
+        return this.multiple ? 'select-multiple' : 'select-one';
+    },
+
+    add: function(element, before) {
+        this.appendChild(element);
+        //__add__(this);
+    },
+    remove: function() {
+        __remove__(this);
+    },
+    toString: function() {
+        return '[object HTMLSelectElement]';
+    }
+});
+
+// Named Element Support
+HTMLElement.registerSetAttribute('SELECT', 'name',
+                                 __updateFormForNamedElement__);
+/**
+ * HTML 5: 4.6.22 The span element
+ * http://dev.w3.org/html5/spec/Overview.html#the-span-element
+ * 
+ */
+HTMLSpanElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLSpanElement.prototype = new HTMLElement();
+__extend__(HTMLSpanElement.prototype, {
+    toString: function(){
+        return '[object HTMLSpanElement]';
+    }
+});
+
+
+/**
+ * HTMLStyleElement - DOM Level 2
+ * HTML5 4.2.6 The style element
+ * http://dev.w3.org/html5/spec/Overview.html#the-style-element
+ */
+HTMLStyleElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLStyleElement.prototype = new HTMLElement();
+__extend__(HTMLStyleElement.prototype, {
+    get disabled(){
+        return this.getAttribute('disabled');
+    },
+    set disabled(value){
+        this.setAttribute('disabled',value);
+    },
+    get media(){
+        return this.getAttribute('media');
+    },
+    set media(value){
+        this.setAttribute('media',value);
+    },
+    get type(){
+        return this.getAttribute('type');
+    },
+    set type(value){
+        this.setAttribute('type',value);
+    },
+    toString: function() {
+        return '[object HTMLStyleElement]';
+    }
+});
+
+/**
+ * HTMLTableElement - DOM Level 2
+ * Implementation Provided by Steven Wood
+ *
+ * HTML5: 4.9.1 The table element
+ * http://dev.w3.org/html5/spec/Overview.html#the-table-element
+ */
+HTMLTableElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLTableElement.prototype = new HTMLElement();
+__extend__(HTMLTableElement.prototype, {
+
+    get tFoot() {
+        //tFoot returns the table footer.
+        return this.getElementsByTagName("tfoot")[0];
+    },
+
+    createTFoot : function () {
+        var tFoot = this.tFoot;
+
+        if (!tFoot) {
+            tFoot = document.createElement("tfoot");
+            this.appendChild(tFoot);
+        }
+
+        return tFoot;
+    },
+
+    deleteTFoot : function () {
+        var foot = this.tFoot;
+        if (foot) {
+            foot.parentNode.removeChild(foot);
+        }
+    },
+
+    get tHead() {
+        //tHead returns the table head.
+        return this.getElementsByTagName("thead")[0];
+    },
+
+    createTHead : function () {
+        var tHead = this.tHead;
+
+        if (!tHead) {
+            tHead = document.createElement("thead");
+            this.insertBefore(tHead, this.firstChild);
+        }
+
+        return tHead;
+    },
+
+    deleteTHead : function () {
+        var head = this.tHead;
+        if (head) {
+            head.parentNode.removeChild(head);
+        }
+    },
+
+    /*appendChild : function (child) {
+
+      var tagName;
+      if(child&&child.nodeType==Node.ELEMENT_NODE){
+      tagName = child.tagName.toLowerCase();
+      if (tagName === "tr") {
+      // need an implcit <tbody> to contain this...
+      if (!this.currentBody) {
+      this.currentBody = document.createElement("tbody");
+
+      Node.prototype.appendChild.apply(this, [this.currentBody]);
+      }
+
+      return this.currentBody.appendChild(child);
+
+      } else if (tagName === "tbody" || tagName === "tfoot" && this.currentBody) {
+      this.currentBody = child;
+      return Node.prototype.appendChild.apply(this, arguments);
+
+      } else {
+      return Node.prototype.appendChild.apply(this, arguments);
+      }
+      }else{
+      //tables can still have text node from white space
+      return Node.prototype.appendChild.apply(this, arguments);
+      }
+      },*/
+
+    get tBodies() {
+        return new HTMLCollection(this.getElementsByTagName("tbody"));
+
+    },
+
+    get rows() {
+        return new HTMLCollection(this.getElementsByTagName("tr"));
+    },
+
+    insertRow : function (idx) {
+        if (idx === undefined) {
+            throw new Error("Index omitted in call to HTMLTableElement.insertRow ");
+        }
+
+        var rows = this.rows,
+            numRows = rows.length,
+            node,
+            inserted,
+            lastRow;
+
+        if (idx > numRows) {
+            throw new Error("Index > rows.length in call to HTMLTableElement.insertRow");
+        }
+
+        inserted = document.createElement("tr");
+        // If index is -1 or equal to the number of rows,
+        // the row is appended as the last row. If index is omitted
+        // or greater than the number of rows, an error will result
+        if (idx === -1 || idx === numRows) {
+            this.appendChild(inserted);
+        } else {
+            rows[idx].parentNode.insertBefore(inserted, rows[idx]);
+        }
+
+        return inserted;
+    },
+
+    deleteRow : function (idx) {
+        var elem = this.rows[idx];
+        elem.parentNode.removeChild(elem);
+    },
+
+    get summary() {
+        return this.getAttribute("summary");
+    },
+
+    set summary(summary) {
+        this.setAttribute("summary", summary);
+    },
+
+    get align() {
+        return this.getAttribute("align");
+    },
+
+    set align(align) {
+        this.setAttribute("align", align);
+    },
+
+    get bgColor() {
+        return this.getAttribute("bgColor");
+    },
+
+    set bgColor(bgColor) {
+        return this.setAttribute("bgColor", bgColor);
+    },
+
+    get cellPadding() {
+        return this.getAttribute("cellPadding");
+    },
+
+    set cellPadding(cellPadding) {
+        return this.setAttribute("cellPadding", cellPadding);
+    },
+
+    get cellSpacing() {
+        return this.getAttribute("cellSpacing");
+    },
+
+    set cellSpacing(cellSpacing) {
+        this.setAttribute("cellSpacing", cellSpacing);
+    },
+
+    get frame() {
+        return this.getAttribute("frame");
+    },
+
+    set frame(frame) {
+        this.setAttribute("frame", frame);
+    },
+
+    get rules() {
+        return this.getAttribute("rules");
+    },
+
+    set rules(rules) {
+        this.setAttribute("rules", rules);
+    },
+
+    get width() {
+        return this.getAttribute("width");
+    },
+
+    set width(width) {
+        this.setAttribute("width", width);
+    },
+    toString: function() {
+        return '[object HTMLTableElement]';
+    }
+});
+
+/*
+ * HTMLxElement - DOM Level 2
+ * - Contributed by Steven Wood
+ *
+ * HTML5: 4.9.5 The tbody element
+ * http://dev.w3.org/html5/spec/Overview.html#the-tbody-element
+ * http://dev.w3.org/html5/spec/Overview.html#htmltablesectionelement
+ */
+HTMLTableSectionElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLTableSectionElement.prototype = new HTMLElement();
+__extend__(HTMLTableSectionElement.prototype, {
+
+    /*appendChild : function (child) {
+
+    // disallow nesting of these elements.
+    if (child.tagName.match(/TBODY|TFOOT|THEAD/)) {
+    return this.parentNode.appendChild(child);
+    } else {
+    return Node.prototype.appendChild.apply(this, arguments);
+    }
+
+    },*/
+
+    get align() {
+        return this.getAttribute("align");
+    },
+
+    get ch() {
+        return this.getAttribute("ch");
+    },
+
+    set ch(ch) {
+        this.setAttribute("ch", ch);
+    },
+
+    // ch gets or sets the alignment character for cells in a column.
+    set chOff(chOff) {
+        this.setAttribute("chOff", chOff);
+    },
+
+    get chOff() {
+        return this.getAttribute("chOff");
+    },
+
+    get vAlign () {
+        return this.getAttribute("vAlign");
+    },
+
+    get rows() {
+        return new HTMLCollection(this.getElementsByTagName("tr"));
+    },
+
+    insertRow : function (idx) {
+        if (idx === undefined) {
+            throw new Error("Index omitted in call to HTMLTableSectionElement.insertRow ");
+        }
+
+        var numRows = this.rows.length,
+        node = null;
+
+        if (idx > numRows) {
+            throw new Error("Index > rows.length in call to HTMLTableSectionElement.insertRow");
+        }
+
+        var row = document.createElement("tr");
+        // If index is -1 or equal to the number of rows,
+        // the row is appended as the last row. If index is omitted
+        // or greater than the number of rows, an error will result
+        if (idx === -1 || idx === numRows) {
+            this.appendChild(row);
+        } else {
+            node = this.firstChild;
+
+            for (var i=0; i<idx; i++) {
+                node = node.nextSibling;
+            }
+        }
+
+        this.insertBefore(row, node);
+
+        return row;
+    },
+
+    deleteRow : function (idx) {
+        var elem = this.rows[idx];
+        this.removeChild(elem);
+    },
+
+    toString: function() {
+        return '[object HTMLTableSectionElement]';
+    }
+});
+
+/**
+ * HTMLTableCellElement
+ * base interface for TD and TH
+ *
+ * HTML5: 4.9.11 Attributes common to td and th elements
+ * http://dev.w3.org/html5/spec/Overview.html#htmltablecellelement
+ */
+HTMLTableCellElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLTableCellElement.prototype = new HTMLElement();
+__extend__(HTMLTableCellElement.prototype, {
+
+
+    // TOOD: attribute unsigned long  colSpan;
+    // TODO: attribute unsigned long  rowSpan;
+    // TODO: attribute DOMString      headers;
+    // TODO: readonly attribute long  cellIndex;
+
+    // Not really necessary but might be helpful in debugging
+    toString: function() {
+        return '[object HTMLTableCellElement]';
+    }
+
+});
+
+/**
+ * HTMLTableDataCellElement
+ * HTML5: 4.9.9 The td Element
+ * http://dev.w3.org/html5/spec/Overview.html#the-td-element
+ */
+HTMLTableDataCellElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLTableDataCellElement.prototype = new HTMLTableCellElement();
+__extend__(HTMLTableDataCellElement.prototype, {
+
+    // adds no new properties or methods
+
+    toString: function() {
+        return '[object HTMLTableDataCellElement]';
+    }
+});
+
+/**
+ * HTMLTableHeaderCellElement
+ * HTML5: 4.9.10 The th Element
+ * http://dev.w3.org/html5/spec/Overview.html#the-th-element
+ */
+HTMLTableHeaderCellElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLTableHeaderCellElement.prototype = new HTMLTableCellElement();
+__extend__(HTMLTableHeaderCellElement.prototype, {
+
+    // TODO:  attribute DOMString scope
+
+    toString: function() {
+        return '[object HTMLTableHeaderCellElement]';
+    }
+});
+
+
+/**
+ * HTMLTextAreaElement - DOM Level 2
+ * HTML5: 4.10.11 The textarea element
+ * http://dev.w3.org/html5/spec/Overview.html#the-textarea-element
+ */
+HTMLTextAreaElement = function(ownerDocument) {
+    HTMLInputAreaCommon.apply(this, arguments);
+    this._rawvalue = null;
+};
+HTMLTextAreaElement.prototype = new HTMLInputAreaCommon();
+__extend__(HTMLTextAreaElement.prototype, {
+    get cols(){
+        return Number(this.getAttribute('cols')||'-1');
+    },
+    set cols(value){
+        this.setAttribute('cols', value);
+    },
+    get rows(){
+        return Number(this.getAttribute('rows')||'-1');
+    },
+    set rows(value){
+        this.setAttribute('rows', value);
+    },
+
+    /*
+     * read-only
+     */
+    get type() {
+        return this.getAttribute('type') || 'textarea';
+    },
+
+    /**
+     * This modifies the text node under the widget
+     */
+    get defaultValue() {
+        return this.textContent;
+    },
+    set defaultValue(value) {
+        this.textContent = value;
+    },
+
+    /**
+     * http://dev.w3.org/html5/spec/Overview.html#concept-textarea-raw-value
+     */
+    get value() {
+        return (this._rawvalue === null) ? this.defaultValue : this._rawvalue;
+    },
+    set value(value) {
+        this._rawvalue = value;
+    },
+    toString: function() {
+        return '[object HTMLTextAreaElement]';
+    }
+});
+
+// Named Element Support
+HTMLElement.registerSetAttribute('TEXTAREA', 'name',
+                                 __updateFormForNamedElement__);
+
+/**
+ * HTMLTitleElement - DOM Level 2
+ *
+ * HTML5: 4.2.2 The title element
+ * http://dev.w3.org/html5/spec/Overview.html#the-title-element-0
+ */
+HTMLTitleElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLTitleElement.prototype = new HTMLElement();
+__extend__(HTMLTitleElement.prototype, {
+    get text() {
+        return this.innerText;
+    },
+
+    set text(titleStr) {
+        this.textContent = titleStr;
+    },
+    toString: function() {
+        return '[object HTMLTitleElement]';
+    }
+});
+
+
+
+/**
+ * HTMLRowElement - DOM Level 2
+ * Implementation Provided by Steven Wood
+ *
+ * HTML5: 4.9.8 The tr element
+ * http://dev.w3.org/html5/spec/Overview.html#the-tr-element
+ */
+HTMLTableRowElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLTableRowElement.prototype = new HTMLElement();
+__extend__(HTMLTableRowElement.prototype, {
+
+    /*appendChild : function (child) {
+
+      var retVal = Node.prototype.appendChild.apply(this, arguments);
+      retVal.cellIndex = this.cells.length -1;
+
+      return retVal;
+      },*/
+    // align gets or sets the horizontal alignment of data within cells of the row.
+    get align() {
+        return this.getAttribute("align");
+    },
+
+    get bgColor() {
+        return this.getAttribute("bgcolor");
+    },
+
+    get cells() {
+        var nl = this.getElementsByTagName("td");
+        return new HTMLCollection(nl);
+    },
+
+    get ch() {
+        return this.getAttribute("ch");
+    },
+
+    set ch(ch) {
+        this.setAttribute("ch", ch);
+    },
+
+    // ch gets or sets the alignment character for cells in a column.
+    set chOff(chOff) {
+        this.setAttribute("chOff", chOff);
+    },
+
+    get chOff() {
+        return this.getAttribute("chOff");
+    },
+
+    /**
+     * http://dev.w3.org/html5/spec/Overview.html#dom-tr-rowindex
+     */
+    get rowIndex() {
+        var nl = this.parentNode.childNodes;
+        for (var i=0; i<nl.length; i++) {
+            if (nl[i] === this) {
+                return i;
+            }
+        }
+        return -1;
+    },
+
+    /**
+     * http://dev.w3.org/html5/spec/Overview.html#dom-tr-sectionrowindex
+     */
+    get sectionRowIndex() {
+        var nl = this.parentNode.getElementsByTagName(this.tagName);
+        for (var i=0; i<nl.length; i++) {
+            if (nl[i] === this) {
+                return i;
+            }
+        }
+        return -1;
+    },
+
+    get vAlign () {
+        return this.getAttribute("vAlign");
+    },
+
+    insertCell : function (idx) {
+        if (idx === undefined) {
+            throw new Error("Index omitted in call to HTMLTableRow.insertCell");
+        }
+
+        var numCells = this.cells.length,
+        node = null;
+
+        if (idx > numCells) {
+            throw new Error("Index > rows.length in call to HTMLTableRow.insertCell");
+        }
+
+        var cell = document.createElement("td");
+
+        if (idx === -1 || idx === numCells) {
+            this.appendChild(cell);
+        } else {
+
+
+            node = this.firstChild;
+
+            for (var i=0; i<idx; i++) {
+                node = node.nextSibling;
+            }
+        }
+
+        this.insertBefore(cell, node);
+        cell.cellIndex = idx;
+
+        return cell;
+    },
+    deleteCell : function (idx) {
+        var elem = this.cells[idx];
+        this.removeChild(elem);
+    },
+    toString: function() {
+        return '[object HTMLTableRowElement]';
+    }
+
+});
+
+/*
+ * HTMLUListElement
+ * HTML5: 4.5.7 The ul Element
+ * http://dev.w3.org/html5/spec/Overview.html#htmlhtmlelement
+ */
+HTMLUListElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+
+HTMLUListElement.prototype = new HTMLElement();
+__extend__(HTMLUListElement.prototype, {
+
+    // no additional properties or elements
+
+    toString: function() {
+        return '[object HTMLUListElement]';
+    }
+});
+
+
+/**
+ * HTMLUnknownElement DOM Level 2
+ */
+HTMLUnknownElement = function(ownerDocument) {
+    HTMLElement.apply(this, arguments);
+};
+HTMLUnknownElement.prototype = new HTMLElement();
+__extend__(HTMLUnknownElement.prototype,{
+    toString: function(){
+        return '[object HTMLUnknownElement]';
+    }
+});
+
+/**
+ * @author john resig & the envjs team
+ * @uri http://www.envjs.com/
+ * @copyright 2008-2010
+ * @license MIT
+ */
+//CLOSURE_END
+}());
+
+/**
+ * DOM Style Level 2
+ */
+/*var CSS2Properties,
+    CSSRule,
+    CSSStyleRule,
+    CSSImportRule,
+    CSSMediaRule,
+    CSSFontFaceRule,
+    CSSPageRule,
+    CSSRuleList,
+    CSSStyleSheet,
+    StyleSheet,
+    StyleSheetList;
+;*/
+
+/*
+ * Envjs css.1.2.35 
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ */
+
+//CLOSURE_START
+(function(){
+
+
+
+
+
+/**
+ * @author john resig
+ */
+// Helper method for extending one object with another.
+function __extend__(a,b) {
+    for ( var i in b ) {
+        var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
+        if ( g || s ) {
+            if ( g ) { a.__defineGetter__(i, g); }
+            if ( s ) { a.__defineSetter__(i, s); }
+        } else {
+            a[i] = b[i];
+        }
+    } return a;
+}
+
+/**
+ * @author john resig
+ */
+//from jQuery
+function __setArray__( target, array ) {
+    // Resetting the length to 0, then using the native Array push
+    // is a super-fast way to populate an object with array-like properties
+    target.length = 0;
+    Array.prototype.push.apply( target, array );
+}
+
+/**
+ * @author ariel flesler
+ *    http://flesler.blogspot.com/2008/11/fast-trim-function-for-javascript.html
+ * @param {Object} str
+ */
+function __trim__( str ){
+    return (str || "").replace( /^\s+|\s+$/g, "" );
+}
+
+/*
+ * Interface DocumentStyle (introduced in DOM Level 2)
+ * http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113/stylesheets.html#StyleSheets-StyleSheet-DocumentStyle
+ *
+ * interface DocumentStyle {
+ *   readonly attribute StyleSheetList   styleSheets;
+ * };
+ *
+ */
+__extend__(Document.prototype, {
+    get styleSheets() {
+        if (! this._styleSheets) {
+            this._styleSheets = new StyleSheetList();
+        }
+        return this._styleSheets;
+    }
+});
+/*
+ * CSS2Properties - DOM Level 2 CSS
+ * Renamed to CSSStyleDeclaration??
+ */
+
+var __toCamelCase__ = function(name) {
+    if (name) {
+        return name.replace(/\-(\w)/g, function(all, letter) {
+            return letter.toUpperCase();
+        });
+    }
+    return name;
+};
+
+var __toDashed__ = function(camelCaseName) {
+    if (camelCaseName) {
+        return camelCaseName.replace(/[A-Z]/g, function(all) {
+            return '-' + all.toLowerCase();
+        });
+    }
+    return camelCaseName;
+};
+
+CSS2Properties = function(element){
+    //console.log('css2properties %s', __cssproperties__++);
+    this.styleIndex = __supportedStyles__;//non-standard
+    this.type = element.tagName;//non-standard
+    __setArray__(this, []);
+    __cssTextToStyles__(this, element.cssText || '');
+};
+__extend__(CSS2Properties.prototype, {
+    get cssText() {
+        var i, css = [];
+        for (i = 0; i < this.length; ++i) {
+            css.push(this[i] + ': ' + this.getPropertyValue(this[i]) + ';');
+        }
+        return css.join(' ');
+    },
+    set cssText(cssText) {
+        __cssTextToStyles__(this, cssText);
+    },
+    getPropertyCSSValue: function(name) {
+        //?
+    },
+    getPropertyPriority: function() {
+
+    },
+    getPropertyValue: function(name) {
+        var index, cname = __toCamelCase__(name);
+        if (cname in this.styleIndex) {
+            return this[cname];
+        } else {
+            index = Array.prototype.indexOf.apply(this, [name]);
+            if (index > -1) {
+                return this[index];
+            }
+        }
+        return null;
+    },
+    item: function(index) {
+        return this[index];
+    },
+    removeProperty: function(name) {
+        this.styleIndex[name] = null;
+        name = __toDashed__(name);
+        var index = Array.prototype.indexOf.apply(this, [name]);
+        if (index > -1) {
+            Array.prototype.splice.apply(this, [1,index]);
+        }
+    },
+    setProperty: function(name, value, priority) {
+        var nval;
+        name = __toCamelCase__(name);
+        if (value !== undefined && name in this.styleIndex) {
+            // NOTE:  parseFloat('300px') ==> 300  no
+            // NOTE:  Number('300px') ==> Nan      yes
+            nval = Number(value);
+            this.styleIndex[name] = isNaN(nval) ? value : nval;
+            name = __toDashed__(name);
+            if (Array.prototype.indexOf.apply(this, [name]) === -1 ){
+                Array.prototype.push.apply(this,[name]);
+            }
+        }
+    },
+    toString: function() {
+        return '[object CSS2Properties]';
+    }
+});
+
+
+
+var __cssTextToStyles__ = function(css2props, cssText) {
+    //console.log('__cssTextToStyles__ %s %s', css2props, cssText);
+    //var styleArray=[];
+    var i, style, styles = cssText.split(';');
+    for (i = 0; i < styles.length; ++i) {
+        style = styles[i].split(':');
+        if (style.length === 2) {
+            css2props.setProperty(style[0].replace(' ', '', 'g'),
+                                  style[1].replace(' ', '', 'g'));
+        }
+    }
+};
+
+//Obviously these arent all supported but by commenting out various
+//sections this provides a single location to configure what is
+//exposed as supported.
+var __supportedStyles__ = {
+    azimuth:                null,
+    background:             null,
+    backgroundAttachment:   null,
+    backgroundColor:        'rgb(0,0,0)',
+    backgroundImage:        null,
+    backgroundPosition:     null,
+    backgroundRepeat:       null,
+    border:                 null,
+    borderBottom:           null,
+    borderBottomColor:      null,
+    borderBottomStyle:      null,
+    borderBottomWidth:      null,
+    borderCollapse:         null,
+    borderColor:            null,
+    borderLeft:             null,
+    borderLeftColor:        null,
+    borderLeftStyle:        null,
+    borderLeftWidth:        null,
+    borderRight:            null,
+    borderRightColor:       null,
+    borderRightStyle:       null,
+    borderRightWidth:       null,
+    borderSpacing:          null,
+    borderStyle:            null,
+    borderTop:              null,
+    borderTopColor:         null,
+    borderTopStyle:         null,
+    borderTopWidth:         null,
+    borderWidth:            null,
+    bottom:                 null,
+    captionSide:            null,
+    clear:                  null,
+    clip:                   null,
+    color:                  null,
+    content:                null,
+    counterIncrement:       null,
+    counterReset:           null,
+    cssFloat:               null,
+    cue:                    null,
+    cueAfter:               null,
+    cueBefore:              null,
+    cursor:                 null,
+    direction:              'ltr',
+    display:                null,
+    elevation:              null,
+    emptyCells:             null,
+    font:                   null,
+    fontFamily:             null,
+    fontSize:               '1em',
+    fontSizeAdjust:         null,
+    fontStretch:            null,
+    fontStyle:              null,
+    fontVariant:            null,
+    fontWeight:             null,
+    height:                 '',
+    left:                   null,
+    letterSpacing:          null,
+    lineHeight:             null,
+    listStyle:              null,
+    listStyleImage:         null,
+    listStylePosition:      null,
+    listStyleType:          null,
+    margin:                 null,
+    marginBottom:           '0px',
+    marginLeft:             '0px',
+    marginRight:            '0px',
+    marginTop:              '0px',
+    markerOffset:           null,
+    marks:                  null,
+    maxHeight:              null,
+    maxWidth:               null,
+    minHeight:              null,
+    minWidth:               null,
+    opacity:                1,
+    orphans:                null,
+    outline:                null,
+    outlineColor:           null,
+    outlineOffset:          null,
+    outlineStyle:           null,
+    outlineWidth:           null,
+    overflow:               null,
+    overflowX:              null,
+    overflowY:              null,
+    padding:                null,
+    paddingBottom:          '0px',
+    paddingLeft:            '0px',
+    paddingRight:           '0px',
+    paddingTop:             '0px',
+    page:                   null,
+    pageBreakAfter:         null,
+    pageBreakBefore:        null,
+    pageBreakInside:        null,
+    pause:                  null,
+    pauseAfter:             null,
+    pauseBefore:            null,
+    pitch:                  null,
+    pitchRange:             null,
+    position:               null,
+    quotes:                 null,
+    richness:               null,
+    right:                  null,
+    size:                   null,
+    speak:                  null,
+    speakHeader:            null,
+    speakNumeral:           null,
+    speakPunctuation:       null,
+    speechRate:             null,
+    stress:                 null,
+    tableLayout:            null,
+    textAlign:              null,
+    textDecoration:         null,
+    textIndent:             null,
+    textShadow:             null,
+    textTransform:          null,
+    top:                    null,
+    unicodeBidi:            null,
+    verticalAlign:          null,
+    visibility:             '',
+    voiceFamily:            null,
+    volume:                 null,
+    whiteSpace:             null,
+    widows:                 null,
+    width:                  '1px',
+    wordSpacing:            null,
+    zIndex:                 1
+};
+
+var __displayMap__ = {
+    DIV      : 'block',
+    P        : 'block',
+    A        : 'inline',
+    CODE     : 'inline',
+    PRE      : 'block',
+    SPAN     : 'inline',
+    TABLE    : 'table',
+    THEAD    : 'table-header-group',
+    TBODY    : 'table-row-group',
+    TR       : 'table-row',
+    TH       : 'table-cell',
+    TD       : 'table-cell',
+    UL       : 'block',
+    LI       : 'list-item'
+};
+
+for (var style in __supportedStyles__) {
+    if (__supportedStyles__.hasOwnProperty(style)) {
+        (function(name) {
+            if (name === 'width' || name === 'height') {
+                CSS2Properties.prototype.__defineGetter__(name, function() {
+                    if (this.display === 'none'){
+                        return '0px';
+                    }
+                    return this.styleIndex[name];
+                });
+            } else if (name === 'display') {
+                //display will be set to a tagName specific value if ''
+                CSS2Properties.prototype.__defineGetter__(name, function() {
+                    var val = this.styleIndex[name];
+                    val = val ? val :__displayMap__[this.type];
+                    return val;
+                });
+            } else {
+                CSS2Properties.prototype.__defineGetter__(name, function() {
+                    return this.styleIndex[name];
+                });
+            }
+            CSS2Properties.prototype.__defineSetter__(name, function(value) {
+                this.setProperty(name, value);
+            });
+        }(style));
+    }
+}
+
+/*
+ * CSSRule - DOM Level 2
+ */
+CSSRule = function(options) {
+
+
+
+    var $style,
+    $selectorText = options.selectorText ? options.selectorText : '';
+    $style = new CSS2Properties({
+        cssText: options.cssText ? options.cssText : null
+    });
+
+    return __extend__(this, {
+        get style(){
+            return $style;
+        },
+        get selectorText(){
+            return $selectorText;
+        },
+        set selectorText(selectorText){
+            $selectorText = selectorText;
+        },
+        toString : function(){
+            return "[object CSSRule]";
+        }
+    });
+};
+CSSRule.STYLE_RULE     =  1;
+CSSRule.IMPORT_RULE    =  3;
+CSSRule.MEDIA_RULE     =  4;
+CSSRule.FONT_FACE_RULE =  5;
+CSSRule.PAGE_RULE      =  6;
+//CSSRule.NAMESPACE_RULE = 10;
+
+
+CSSStyleRule = function() {
+
+};
+
+CSSImportRule = function() {
+
+};
+
+CSSMediaRule = function() {
+
+};
+
+CSSFontFaceRule = function() {
+
+};
+
+CSSPageRule = function() {
+
+};
+
+
+CSSRuleList = function(data) {
+    this.length = 0;
+    __setArray__(this, data);
+};
+
+__extend__(CSSRuleList.prototype, {
+    item : function(index) {
+        if ((index >= 0) && (index < this.length)) {
+            // bounds check
+            return this[index];
+        }
+        return null;
+    },
+    toString: function() {
+        return '[object CSSRuleList]';
+    }
+});
+
+/**
+ * StyleSheet
+ * http://dev.w3.org/csswg/cssom/#stylesheet
+ *
+ * interface StyleSheet {
+ *   readonly attribute DOMString type;
+ *   readonly attribute DOMString href;
+ *   readonly attribute Node ownerNode;
+ *   readonly attribute StyleSheet parentStyleSheet;
+ *   readonly attribute DOMString title;
+ *   [PutForwards=mediaText] readonly attribute MediaList media;
+ *          attribute boolean disabled;
+ * };
+ */
+StyleSheet = function() {
+}
+
+/*
+ * CSSStyleSheet
+ * http://dev.w3.org/csswg/cssom/#cssstylesheet
+ *
+ * interface CSSStyleSheet : StyleSheet {
+ *   readonly attribute CSSRule ownerRule;
+ *   readonly attribute CSSRuleList cssRules;
+ *   unsigned long insertRule(DOMString rule, unsigned long index);
+ *   void deleteRule(unsigned long index);
+ * };
+ */
+CSSStyleSheet = function(options){
+    var $cssRules,
+        $disabled = options.disabled ? options.disabled : false,
+        $href = options.href ? options.href : null,
+        $parentStyleSheet = options.parentStyleSheet ? options.parentStyleSheet : null,
+        $title = options.title ? options.title : "",
+        $type = "text/css";
+
+    function parseStyleSheet(text){
+        //$debug("parsing css");
+        //this is pretty ugly, but text is the entire text of a stylesheet
+        var cssRules = [];
+        if (!text) {
+            text = '';
+        }
+        text = __trim__(text.replace(/\/\*(\r|\n|.)*\*\//g,""));
+        // TODO: @import
+        var blocks = text.split("}");
+        blocks.pop();
+        var i, j, len = blocks.length;
+        var definition_block, properties, selectors;
+        for (i=0; i<len; i++) {
+            definition_block = blocks[i].split("{");
+            if (definition_block.length === 2) {
+                selectors = definition_block[0].split(",");
+                for (j=0; j<selectors.length; j++) {
+                    cssRules.push(new CSSRule({
+                        selectorText : __trim__(selectors[j]),
+                        cssText      : definition_block[1]
+                    }));
+                }
+            }
+        }
+        return cssRules;
+    }
+
+    $cssRules = new CSSRuleList(parseStyleSheet(options.textContent));
+
+    return __extend__(this, {
+        get cssRules(){
+            return $cssRules;
+        },
+        get rule(){
+            return $cssRules;
+        },//IE - may be deprecated
+        get href(){
+            return $href;
+        },
+        get parentStyleSheet(){
+            return $parentStyleSheet;
+        },
+        get title(){
+            return $title;
+        },
+        get type(){
+            return $type;
+        },
+        addRule: function(selector, style, index){/*TODO*/},
+        deleteRule: function(index){/*TODO*/},
+        insertRule: function(rule, index){/*TODO*/},
+        //IE - may be deprecated
+        removeRule: function(index){
+            this.deleteRule(index);
+        }
+    });
+};
+
+StyleSheetList = function() {
+}
+StyleSheetList.prototype = new Array();
+__extend__(StyleSheetList.prototype, {
+    item : function(index) {
+        if ((index >= 0) && (index < this.length)) {
+            // bounds check
+            return this[index];
+        }
+        return null;
+    },
+    toString: function() {
+        return '[object StyleSheetList]';
+    }
+});
+/**
+ * This extends HTMLElement to handle CSS-specific interfaces.
+ *
+ * More work / research would be needed to extend just (DOM) Element
+ * for xml use and additional changes for just HTMLElement.
+ */
+
+
+/**
+ * Replace or add  the getter for 'style'
+ *
+ * This could be wrapped in a closure
+ */
+var $css2properties = [{}];
+
+__extend__(HTMLElement.prototype, {
+    get style(){
+        if ( !this.css2uuid ) {
+            this.css2uuid = $css2properties.length;
+            $css2properties[this.css2uuid] = new CSS2Properties(this);
+        }
+        return $css2properties[this.css2uuid];
+    }
+});
+
+/**
+ * Change for how 'setAttribute("style", ...)' works
+ *
+ * We are truly adding functionality to HtmlElement.setAttribute, not
+ * replacing it.  So we need to save the old one first, call it, then
+ * do our stuff.  If we need to do more hacks like this, HTMLElement
+ * (or regular Element) needs to have a hooks array or dispatch table
+ * for global changes.
+ *
+ * This could be wrapped in a closure if desired.
+ */
+var updateCss2Props = function(elem, values) {
+    //console.log('__updateCss2Props__ %s %s', elem, values);
+    if ( !elem.css2uuid ) {
+        elem.css2uuid = $css2properties.length;
+        $css2properties[elem.css2uuid] = new CSS2Properties(elem);
+    }
+    __cssTextToStyles__($css2properties[elem.css2uuid], values);
+};
+
+var origSetAttribute =  HTMLElement.prototype.setAttribute;
+
+HTMLElement.prototype.setAttribute = function(name, value) {
+    //console.log("CSS set attribute: " + name + ", " + value);
+    origSetAttribute.apply(this, arguments);
+    if (name === "style") {
+        updateCss2Props(this, value);
+    }
+};
+
+var origGetAttribute =  HTMLElement.prototype.getAttribute;
+
+HTMLElement.prototype.getAttribute = function(name) {
+    //console.log("CSS set attribute: " + name + ", " + value);
+	var style;
+    if (name === "style") {
+        style = this.style.cssText;
+		return style===""?null:style;
+    }else{
+	    return origGetAttribute.apply(this, arguments);
+	}
+};
+
+/**
+ * @author john resig & the envjs team
+ * @uri http://www.envjs.com/
+ * @copyright 2008-2010
+ * @license MIT
+ */
+//CLOSURE_END
+}());
+
+//these are both non-standard globals that
+//provide static namespaces and functions
+//to support the html 5 parser from nu.
+XMLParser = {};
+HTMLParser = {};
+    
+/*
+ * Envjs parser.1.2.35 
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ */
+
+//CLOSURE_START
+(function(){
+
+
+
+
+
+/**
+ * @author john resig
+ */
+// Helper method for extending one object with another.
+function __extend__(a,b) {
+    for ( var i in b ) {
+        var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
+        if ( g || s ) {
+            if ( g ) { a.__defineGetter__(i, g); }
+            if ( s ) { a.__defineSetter__(i, s); }
+        } else {
+            a[i] = b[i];
+        }
+    } return a;
+}
+
+/**
+ * @author john resig
+ */
+//from jQuery
+function __setArray__( target, array ) {
+    // Resetting the length to 0, then using the native Array push
+    // is a super-fast way to populate an object with array-like properties
+    target.length = 0;
+    Array.prototype.push.apply( target, array );
+}
+var $_window = this;var __defineParser__ = function(){};(function () {var $gwt_version = "2.0.3";var $wnd = $_window;var $doc = $wnd.document;var $moduleName, $moduleBase;var $stats = $wnd.__gwtStatsEvent ? function(a) {$wnd.__gwtStatsEvent(a)} : null;var $strongName = '30CDE3211C153B9ED1F6B0000BE9890D';var _, N8000000000000000_longLit = [0, -9223372036854775808], P1000000_longLit = [16777216, 0], P7fffffffffffffff_longLit = [4294967295, 9223372032559808512];
+function nullMethod(){
+}
+
+function equals(other){
+  return this === (other == null?null:other);
+}
+
+function getClass_0(){
+  return Ljava_lang_Object_2_classLit;
+}
+
+function hashCode_0(){
+  return this.$H || (this.$H = ++sNextHashId);
+}
+
+function toString_0(){
+  return (this.typeMarker$ == nullMethod || this.typeId$ == 2?this.getClass$():Lcom_google_gwt_core_client_JavaScriptObject_2_classLit).typeName + '@' + toPowerOfTwoString(this.typeMarker$ == nullMethod || this.typeId$ == 2?this.hashCode$():this.$H || (this.$H = ++sNextHashId), 4);
+}
+
+function Object_0(){
+}
+
+_ = Object_0.prototype = {};
+_.equals$ = equals;
+_.getClass$ = getClass_0;
+_.hashCode$ = hashCode_0;
+_.toString$ = toString_0;
+_.toString = function(){
+  return this.toString$();
+}
+;
+_.typeMarker$ = nullMethod;
+_.typeId$ = 1;
+function $setStackTrace(stackTrace){
+  var c, copy, i;
+  copy = initDim(_3Ljava_lang_StackTraceElement_2_classLit, 55, 9, stackTrace.length, 0);
+  for (i = 0 , c = stackTrace.length; i < c; ++i) {
+    if (!stackTrace[i]) {
+      throw $NullPointerException(new NullPointerException);
+    }
+    copy[i] = stackTrace[i];
+  }
+}
+
+function $toString(this$static){
+  var className, msg;
+  className = this$static.getClass$().typeName;
+  msg = this$static.getMessage();
+  if (msg != null) {
+    return className + ': ' + msg;
+  }
+   else {
+    return className;
+  }
+}
+
+function getClass_1(){
+  return Ljava_lang_Throwable_2_classLit;
+}
+
+function getMessage(){
+  return this.detailMessage;
+}
+
+function toString_1(){
+  return $toString(this);
+}
+
+function Throwable(){
+}
+
+_ = Throwable.prototype = new Object_0;
+_.getClass$ = getClass_1;
+_.getMessage = getMessage;
+_.toString$ = toString_1;
+_.typeId$ = 3;
+_.detailMessage = null;
+function getClass_2(){
+  return Ljava_lang_Exception_2_classLit;
+}
+
+function Exception(){
+}
+
+_ = Exception.prototype = new Throwable;
+_.getClass$ = getClass_2;
+_.typeId$ = 4;
+function $RuntimeException(this$static, message){
+  $fillInStackTrace();
+  this$static.detailMessage = message;
+  return this$static;
+}
+
+function getClass_3(){
+  return Ljava_lang_RuntimeException_2_classLit;
+}
+
+function RuntimeException(){
+}
+
+_ = RuntimeException.prototype = new Exception;
+_.getClass$ = getClass_3;
+_.typeId$ = 5;
+function $JavaScriptException(this$static, e){
+  $fillInStackTrace();
+  this$static.e = e;
+  $createStackTrace(this$static);
+  return this$static;
+}
+
+function $getMessage_0(this$static){
+  this$static.message_0 == null && (this$static.name_0 = getName(this$static.e) , this$static.description = getDescription(this$static.e) , this$static.message_0 = '(' + this$static.name_0 + '): ' + this$static.description + getProperties(this$static.e) , undefined);
+  return this$static.message_0;
+}
+
+function getClass_4(){
+  return Lcom_google_gwt_core_client_JavaScriptException_2_classLit;
+}
+
+function getDescription(e){
+  if (e != null && e.typeMarker$ != nullMethod && e.typeId$ != 2) {
+    return getDescription0(dynamicCastJso(e));
+  }
+   else {
+    return e + '';
+  }
+}
+
+function getDescription0(e){
+  return e == null?null:e.message;
+}
+
+function getMessage_0(){
+  return $getMessage_0(this);
+}
+
+function getName(e){
+  if (e == null) {
+    return 'null';
+  }
+   else if (e != null && e.typeMarker$ != nullMethod && e.typeId$ != 2) {
+    return getName0(dynamicCastJso(e));
+  }
+   else if (e != null && canCast(e.typeId$, 1)) {
+    return 'String';
+  }
+   else {
+    return (e.typeMarker$ == nullMethod || e.typeId$ == 2?e.getClass$():Lcom_google_gwt_core_client_JavaScriptObject_2_classLit).typeName;
+  }
+}
+
+function getName0(e){
+  return e == null?null:e.name;
+}
+
+function getProperties(e){
+  return e != null && e.typeMarker$ != nullMethod && e.typeId$ != 2?getProperties0(dynamicCastJso(e)):'';
+}
+
+function getProperties0(e){
+  var result = '';
+  try {
+    for (prop in e) {
+      if (prop != 'name' && prop != 'message' && prop != 'toString') {
+        try {
+          result += '\n ' + prop + ': ' + e[prop];
+        }
+         catch (ignored) {
+        }
+      }
+    }
+  }
+   catch (ignored) {
+  }
+  return result;
+}
+
+function JavaScriptException(){
+}
+
+_ = JavaScriptException.prototype = new RuntimeException;
+_.getClass$ = getClass_4;
+_.getMessage = getMessage_0;
+_.typeId$ = 6;
+_.description = null;
+_.e = null;
+_.message_0 = null;
+_.name_0 = null;
+function createFunction(){
+  return function(){
+  }
+  ;
+}
+
+function equals__devirtual$(this$static, other){
+  return this$static.typeMarker$ == nullMethod || this$static.typeId$ == 2?this$static.equals$(other):(this$static == null?null:this$static) === (other == null?null:other);
+}
+
+function hashCode__devirtual$(this$static){
+  return this$static.typeMarker$ == nullMethod || this$static.typeId$ == 2?this$static.hashCode$():this$static.$H || (this$static.$H = ++sNextHashId);
+}
+
+function getClass_6(){
+  return Lcom_google_gwt_core_client_Scheduler_2_classLit;
+}
+
+function Scheduler(){
+}
+
+_ = Scheduler.prototype = new Object_0;
+_.getClass$ = getClass_6;
+_.typeId$ = 0;
+function entry_0(jsFunction){
+  return function(){
+    return entry0(jsFunction, this, arguments);
+  }
+  ;
+}
+
+function entry0(jsFunction, thisObj, arguments_0){
+  var initialEntry;
+  initialEntry = entryDepth++ == 0;
+  try {
+    return jsFunction.apply(thisObj, arguments_0);
+  }
+   finally {
+    initialEntry && $flushFinallyCommands(($clinit_12() , INSTANCE));
+    --entryDepth;
+  }
+}
+
+var entryDepth = 0, sNextHashId = 0;
+function $clinit_12(){
+  $clinit_12 = nullMethod;
+  INSTANCE = $SchedulerImpl(new SchedulerImpl);
+}
+
+function $SchedulerImpl(this$static){
+  $clinit_12();
+  this$static.flusher = $SchedulerImpl$1(new SchedulerImpl$1, this$static);
+  $SchedulerImpl$2(new SchedulerImpl$2, this$static);
+  this$static.deferredCommands = [];
+  this$static.incrementalCommands = [];
+  this$static.finallyCommands = [];
+  return this$static;
+}
+
+function $flushFinallyCommands(this$static){
+  var oldFinally;
+  oldFinally = this$static.finallyCommands;
+  this$static.finallyCommands = [];
+  runScheduledTasks(oldFinally, this$static.finallyCommands);
+}
+
+function $flushPostEventPumpCommands(this$static){
+  var oldDeferred;
+  oldDeferred = this$static.deferredCommands;
+  this$static.deferredCommands = [];
+  runScheduledTasks(oldDeferred, this$static.incrementalCommands);
+  this$static.incrementalCommands = runRepeatingTasks(this$static.incrementalCommands);
+}
+
+function $isWorkQueued(this$static){
+  return this$static.deferredCommands.length > 0 || this$static.incrementalCommands.length > 0;
+}
+
+function execute(cmd){
+  return cmd.execute();
+}
+
+function getClass_7(){
+  return Lcom_google_gwt_core_client_impl_SchedulerImpl_2_classLit;
+}
+
+function runRepeatingTasks(tasks){
+  var canceledSomeTasks, i, length_0, newTasks, start, t;
+  canceledSomeTasks = false;
+  length_0 = tasks.length;
+  start = (new Date).getTime();
+  while ((new Date).getTime() - start < 100) {
+    for (i = 0; i < length_0; ++i) {
+      t = tasks[i];
+      if (!t) {
+        continue;
+      }
+      if (!t[0].execute()) {
+        tasks[i] = null;
+        canceledSomeTasks = true;
+      }
+    }
+  }
+  if (canceledSomeTasks) {
+    newTasks = [];
+    for (i = 0; i < length_0; ++i) {
+      if (!tasks[i]) {
+        continue;
+      }
+      newTasks[newTasks.length] = tasks[i];
+    }
+    return newTasks;
+  }
+   else {
+    return tasks;
+  }
+}
+
+function runScheduledTasks(tasks, rescheduled){
+  var $e0, i, j, t;
+  for (i = 0 , j = tasks.length; i < j; ++i) {
+    t = tasks[i];
+    try {
+      t[1]?t[0].execute() && (rescheduled[rescheduled.length] = t , undefined):t[0].nullMethod();
+    }
+     catch ($e0) {
+      $e0 = caught($e0);
+      if (!instanceOf($e0, 2))
+        throw $e0;
+    }
+  }
+}
+
+function scheduleFixedDelayImpl(cmd, delayMs){
+  $clinit_12();
+  $wnd.setTimeout(function(){
+    var ret = $entry(execute)(cmd);
+    ret && $wnd.setTimeout(arguments.callee, delayMs);
+  }
+  , delayMs);
+}
+
+function SchedulerImpl(){
+}
+
+_ = SchedulerImpl.prototype = new Scheduler;
+_.getClass$ = getClass_7;
+_.typeId$ = 0;
+_.flushRunning = false;
+_.shouldBeRunning = false;
+var INSTANCE;
+function $SchedulerImpl$1(this$static, this$0){
+  this$static.this$0 = this$0;
+  return this$static;
+}
+
+function execute_0(){
+  this.this$0.flushRunning = true;
+  $flushPostEventPumpCommands(this.this$0);
+  this.this$0.flushRunning = false;
+  return this.this$0.shouldBeRunning = $isWorkQueued(this.this$0);
+}
+
+function getClass_8(){
+  return Lcom_google_gwt_core_client_impl_SchedulerImpl$1_2_classLit;
+}
+
+function SchedulerImpl$1(){
+}
+
+_ = SchedulerImpl$1.prototype = new Object_0;
+_.execute = execute_0;
+_.getClass$ = getClass_8;
+_.typeId$ = 0;
+_.this$0 = null;
+function $SchedulerImpl$2(this$static, this$0){
+  this$static.this$0 = this$0;
+  return this$static;
+}
+
+function execute_1(){
+  this.this$0.flushRunning && scheduleFixedDelayImpl(this.this$0.flusher, 1);
+  return this.this$0.shouldBeRunning;
+}
+
+function getClass_9(){
+  return Lcom_google_gwt_core_client_impl_SchedulerImpl$2_2_classLit;
+}
+
+function SchedulerImpl$2(){
+}
+
+_ = SchedulerImpl$2.prototype = new Object_0;
+_.execute = execute_1;
+_.getClass$ = getClass_9;
+_.typeId$ = 0;
+_.this$0 = null;
+function extractNameFromToString(fnToString){
+  var index, start, toReturn;
+  toReturn = '';
+  fnToString = $trim(fnToString);
+  index = fnToString.indexOf('(');
+  if (index != -1) {
+    start = fnToString.indexOf('function') == 0?8:0;
+    toReturn = $trim(fnToString.substr(start, index - start));
+  }
+  return toReturn.length > 0?toReturn:'anonymous';
+}
+
+function splice(arr, length_0){
+  arr.length >= length_0 && arr.splice(0, length_0);
+  return arr;
+}
+
+function $createStackTrace(e){
+  var i, j, stack, stackTrace;
+  stack = $inferFrom(instanceOfJso(e.e)?dynamicCastJso(e.e):null);
+  stackTrace = initDim(_3Ljava_lang_StackTraceElement_2_classLit, 55, 9, stack.length, 0);
+  for (i = 0 , j = stackTrace.length; i < j; ++i) {
+    stackTrace[i] = $StackTraceElement(new StackTraceElement, 'Unknown', stack[i], 'Unknown source', 0);
+  }
+  $setStackTrace(stackTrace);
+}
+
+function $fillInStackTrace(){
+  var i, j, stack, stackTrace;
+  stack = splice($inferFrom($makeException()), 2);
+  stackTrace = initDim(_3Ljava_lang_StackTraceElement_2_classLit, 55, 9, stack.length, 0);
+  for (i = 0 , j = stackTrace.length; i < j; ++i) {
+    stackTrace[i] = $StackTraceElement(new StackTraceElement, 'Unknown', stack[i], 'Unknown source', 0);
+  }
+  $setStackTrace(stackTrace);
+}
+
+function $makeException(){
+  try {
+    null.a();
+  }
+   catch (e) {
+    return e;
+  }
+}
+
+function $inferFrom(e){
+  var i, j, stack;
+  stack = e && e.stack?e.stack.split('\n'):[];
+  for (i = 0 , j = stack.length; i < j; ++i) {
+    stack[i] = extractNameFromToString(stack[i]);
+  }
+  return stack;
+}
+
+function getClass_10(){
+  return Lcom_google_gwt_core_client_impl_StringBufferImpl_2_classLit;
+}
+
+function StringBufferImpl(){
+}
+
+_ = StringBufferImpl.prototype = new Object_0;
+_.getClass$ = getClass_10;
+_.typeId$ = 0;
+function $replace(this$static, start, end, toInsert){
+  this$static.string = this$static.string.substr(0, start - 0) + toInsert + $substring(this$static.string, end);
+}
+
+function getClass_11(){
+  return Lcom_google_gwt_core_client_impl_StringBufferImplAppend_2_classLit;
+}
+
+function StringBufferImplAppend(){
+}
+
+_ = StringBufferImplAppend.prototype = new StringBufferImpl;
+_.getClass$ = getClass_11;
+_.typeId$ = 0;
+_.string = '';
+function getClass_12(){
+  return Lcom_google_gwt_event_shared_GwtEvent_2_classLit;
+}
+
+function toString_3(){
+  return 'An event type';
+}
+
+function GwtEvent(){
+}
+
+_ = GwtEvent.prototype = new Object_0;
+_.getClass$ = getClass_12;
+_.toString$ = toString_3;
+_.typeId$ = 0;
+_.dead = false;
+_.source = null;
+function dispatch(p0){
+  $onClose();
+}
+
+function fire(source){
+  var event_0;
+  if (TYPE) {
+    event_0 = new CloseEvent;
+    $fireEvent(source, event_0);
+  }
+}
+
+function getAssociatedType(){
+  return TYPE;
+}
+
+function getClass_13(){
+  return Lcom_google_gwt_event_logical_shared_CloseEvent_2_classLit;
+}
+
+function CloseEvent(){
+}
+
+_ = CloseEvent.prototype = new GwtEvent;
+_.dispatch = dispatch;
+_.getAssociatedType = getAssociatedType;
+_.getClass$ = getClass_13;
+_.typeId$ = 0;
+var TYPE = null;
+function getClass_14(){
+  return Lcom_google_gwt_event_shared_DefaultHandlerRegistration_2_classLit;
+}
+
+function DefaultHandlerRegistration(){
+}
+
+_ = DefaultHandlerRegistration.prototype = new Object_0;
+_.getClass$ = getClass_14;
+_.typeId$ = 0;
+function $GwtEvent$Type(this$static){
+  this$static.index = ++nextHashCode;
+  return this$static;
+}
+
+function getClass_15(){
+  return Lcom_google_gwt_event_shared_GwtEvent$Type_2_classLit;
+}
+
+function hashCode_2(){
+  return this.index;
+}
+
+function toString_4(){
+  return 'Event type';
+}
+
+function GwtEvent$Type(){
+}
+
+_ = GwtEvent$Type.prototype = new Object_0;
+_.getClass$ = getClass_15;
+_.hashCode$ = hashCode_2;
+_.toString$ = toString_4;
+_.typeId$ = 0;
+_.index = 0;
+var nextHashCode = 0;
+function $addHandler(this$static, type, handler){
+  this$static.firingDepth > 0?$defer(this$static, $HandlerManager$1(new HandlerManager$1, this$static, type, handler)):$addHandler_0(this$static.registry, type, handler);
+  return new DefaultHandlerRegistration;
+}
+
+function $defer(this$static, command){
+  !this$static.deferredDeltas && (this$static.deferredDeltas = $ArrayList(new ArrayList));
+  $add(this$static.deferredDeltas, command);
+}
+
+function $fireEvent(this$static, event_0){
+  var oldSource;
+  if (event_0.dead) {
+    event_0.dead = false;
+    event_0.source = null;
+  }
+  oldSource = event_0.source;
+  event_0.source = this$static.source;
+  try {
+    ++this$static.firingDepth;
+    $fireEvent_0(this$static.registry, event_0, this$static.isReverseOrder);
+  }
+   finally {
+    --this$static.firingDepth;
+    this$static.firingDepth == 0 && $handleQueuedAddsAndRemoves(this$static);
+  }
+  if (oldSource == null) {
+    event_0.dead = true;
+    event_0.source = null;
+  }
+   else {
+    event_0.source = oldSource;
+  }
+}
+
+function $handleQueuedAddsAndRemoves(this$static){
+  var c, c$iterator;
+  if (this$static.deferredDeltas) {
+    try {
+      for (c$iterator = $AbstractList$IteratorImpl(new AbstractList$IteratorImpl, this$static.deferredDeltas); c$iterator.i < c$iterator.this$0.size_0();) {
+        c = dynamicCast($next_0(c$iterator), 3);
+        $addHandler_0(c.this$0.registry, c.val$type, c.val$handler);
+      }
+    }
+     finally {
+      this$static.deferredDeltas = null;
+    }
+  }
+}
+
+function getClass_16(){
+  return Lcom_google_gwt_event_shared_HandlerManager_2_classLit;
+}
+
+function HandlerManager(){
+}
+
+_ = HandlerManager.prototype = new Object_0;
+_.getClass$ = getClass_16;
+_.typeId$ = 0;
+_.deferredDeltas = null;
+_.firingDepth = 0;
+_.isReverseOrder = false;
+_.registry = null;
+_.source = null;
+function $HandlerManager$1(this$static, this$0, val$type, val$handler){
+  this$static.this$0 = this$0;
+  this$static.val$type = val$type;
+  this$static.val$handler = val$handler;
+  return this$static;
+}
+
+function getClass_17(){
+  return Lcom_google_gwt_event_shared_HandlerManager$1_2_classLit;
+}
+
+function HandlerManager$1(){
+}
+
+_ = HandlerManager$1.prototype = new Object_0;
+_.getClass$ = getClass_17;
+_.typeId$ = 7;
+_.this$0 = null;
+_.val$handler = null;
+_.val$type = null;
+function $HandlerManager$HandlerRegistry(this$static){
+  this$static.map = $HashMap(new HashMap);
+  return this$static;
+}
+
+function $addHandler_0(this$static, type, handler){
+  var l;
+  l = dynamicCast($get_1(this$static.map, type), 4);
+  if (!l) {
+    l = $ArrayList(new ArrayList);
+    $put(this$static.map, type, l);
+  }
+  setCheck(l.array, l.size++, handler);
+}
+
+function $fireEvent_0(this$static, event_0, isReverseOrder){
+  var count, handler, i, type, l, l_0, l_1;
+  type = event_0.getAssociatedType();
+  count = (l = dynamicCast($get_1(this$static.map, type), 4) , !l?0:l.size);
+  if (isReverseOrder) {
+    for (i = count - 1; i >= 0; --i) {
+      handler = (l_0 = dynamicCast($get_1(this$static.map, type), 4) , dynamicCast((checkIndex(i, l_0.size) , l_0.array[i]), 20));
+      event_0.dispatch(handler);
+    }
+  }
+   else {
+    for (i = 0; i < count; ++i) {
+      handler = (l_1 = dynamicCast($get_1(this$static.map, type), 4) , dynamicCast((checkIndex(i, l_1.size) , l_1.array[i]), 20));
+      event_0.dispatch(handler);
+    }
+  }
+}
+
+function getClass_18(){
+  return Lcom_google_gwt_event_shared_HandlerManager$HandlerRegistry_2_classLit;
+}
+
+function HandlerManager$HandlerRegistry(){
+}
+
+_ = HandlerManager$HandlerRegistry.prototype = new Object_0;
+_.getClass$ = getClass_18;
+_.typeId$ = 0;
+function createFromSeed(seedType, length_0){
+  var array = new Array(length_0);
+  if (seedType > 0) {
+    var value = [null, 0, false, [0, 0]][seedType];
+    for (var i = 0; i < length_0; ++i) {
+      array[i] = value;
+    }
+  }
+  return array;
+}
+
+function getClass_19(){
+  return this.arrayClass$;
+}
+
+function initDim(arrayClass, typeId, queryId, length_0, seedType){
+  var result;
+  result = createFromSeed(seedType, length_0);
+  $clinit_37();
+  wrapArray(result, expandoNames_0, expandoValues_0);
+  result.arrayClass$ = arrayClass;
+  result.typeId$ = typeId;
+  result.queryId$ = queryId;
+  return result;
+}
+
+function initValues(arrayClass, typeId, queryId, array){
+  $clinit_37();
+  wrapArray(array, expandoNames_0, expandoValues_0);
+  array.arrayClass$ = arrayClass;
+  array.typeId$ = typeId;
+  array.queryId$ = queryId;
+  return array;
+}
+
+function setCheck(array, index, value){
+  if (value != null) {
+    if (array.queryId$ > 0 && !canCastUnsafe(value.typeId$, array.queryId$)) {
+      throw $ArrayStoreException(new ArrayStoreException);
+    }
+    if (array.queryId$ < 0 && (value.typeMarker$ == nullMethod || value.typeId$ == 2)) {
+      throw $ArrayStoreException(new ArrayStoreException);
+    }
+  }
+  return array[index] = value;
+}
+
+function Array_0(){
+}
+
+_ = Array_0.prototype = new Object_0;
+_.getClass$ = getClass_19;
+_.typeId$ = 0;
+_.arrayClass$ = null;
+_.length = 0;
+_.queryId$ = 0;
+function $clinit_37(){
+  $clinit_37 = nullMethod;
+  expandoNames_0 = [];
+  expandoValues_0 = [];
+  initExpandos(new Array_0, expandoNames_0, expandoValues_0);
+}
+
+function initExpandos(protoType, expandoNames, expandoValues){
+  var i = 0, value;
+  for (var name_0 in protoType) {
+    if (value = protoType[name_0]) {
+      expandoNames[i] = name_0;
+      expandoValues[i] = value;
+      ++i;
+    }
+  }
+}
+
+function wrapArray(array, expandoNames, expandoValues){
+  $clinit_37();
+  for (var i = 0, c = expandoNames.length; i < c; ++i) {
+    array[expandoNames[i]] = expandoValues[i];
+  }
+}
+
+var expandoNames_0, expandoValues_0;
+function canCast(srcId, dstId){
+  return srcId && !!typeIdArray[srcId][dstId];
+}
+
+function canCastUnsafe(srcId, dstId){
+  return srcId && typeIdArray[srcId][dstId];
+}
+
+function dynamicCast(src, dstId){
+  if (src != null && !canCastUnsafe(src.typeId$, dstId)) {
+    throw $ClassCastException(new ClassCastException);
+  }
+  return src;
+}
+
+function dynamicCastJso(src){
+  if (src != null && (src.typeMarker$ == nullMethod || src.typeId$ == 2)) {
+    throw $ClassCastException(new ClassCastException);
+  }
+  return src;
+}
+
+function instanceOf(src, dstId){
+  return src != null && canCast(src.typeId$, dstId);
+}
+
+function instanceOfJso(src){
+  return src != null && src.typeMarker$ != nullMethod && src.typeId$ != 2;
+}
+
+function throwClassCastExceptionUnlessNull(o){
+  if (o != null) {
+    throw $ClassCastException(new ClassCastException);
+  }
+  return o;
+}
+
+var typeIdArray = [{}, {}, {1:1, 5:1, 6:1, 7:1}, {5:1, 21:1}, {5:1, 21:1}, {2:1, 5:1, 21:1}, {2:1, 5:1, 21:1, 29:1}, {3:1}, {20:1}, {2:1, 5:1, 21:1}, {2:1, 5:1, 21:1}, {5:1, 21:1}, {5:1, 21:1}, {2:1, 5:1, 21:1}, {5:1, 7:1, 8:1}, {2:1, 5:1, 21:1}, {2:1, 5:1, 21:1}, {2:1, 5:1, 21:1}, {5:1, 9:1}, {6:1}, {6:1}, {2:1, 5:1, 21:1}, {2:1, 5:1, 21:1}, {28:1}, {24:1}, {24:1}, {24:1}, {25:1}, {25:1}, {4:1, 5:1, 25:1}, {5:1, 26:1}, {5:1, 25:1}, {24:1}, {2:1, 5:1, 21:1, 27:1}, {5:1, 7:1, 8:1, 10:1}, {5:1, 7:1, 8:1, 11:1}, {5:1, 7:1, 8:1, 12:1}, {30:1}, {22:1}, {13:1}, {14:1}, {15:1}, {32:1}, {5:1, 21:1, 31:1}, {5:1, 21:1, 31:1}, {5:1}, {5:1, 16:1}, {5:1, 17:1}, {5:1, 18:1}, {5:1, 19:1}, {5:1, 23:1}, {5:1, 23:1}, {5:1, 23:1}, {5:1, 23:1}, {5:1, 23:1}, {5:1, 23:1}, {5:1, 23:1}, {5:1, 23:1}, {5:1, 23:1}, {5:1, 23:1}, {5:1, 23:1}, {5:1, 23:1}, {5:1, 23:1}, {5:1, 23:1}, {5:1, 23:1}, {5:1, 23:1}, {5:1, 23:1}];
+function init(){
+  !!$stats && $stats({moduleName:$moduleName, sessionId:$sessionId, subSystem:'startup', evtGroup:'moduleStartup', millis:(new Date).getTime(), type:'onModuleLoadStart', className:'nu.validator.htmlparser.gwt.HtmlParserModule'});
+  Envjs.parseHtmlDocument = parseHtmlDocument;
+}
+
+function caught(e){
+  if (e != null && canCast(e.typeId$, 21)) {
+    return e;
+  }
+  return $JavaScriptException(new JavaScriptException, e);
+}
+
+function create(valueLow, valueHigh){
+  var diffHigh, diffLow;
+  valueHigh %= 1.8446744073709552E19;
+  valueLow %= 1.8446744073709552E19;
+  diffHigh = valueHigh % 4294967296;
+  diffLow = Math.floor(valueLow / 4294967296) * 4294967296;
+  valueHigh = valueHigh - diffHigh + diffLow;
+  valueLow = valueLow - diffLow + diffHigh;
+  while (valueLow < 0) {
+    valueLow += 4294967296;
+    valueHigh -= 4294967296;
+  }
+  while (valueLow > 4294967295) {
+    valueLow -= 4294967296;
+    valueHigh += 4294967296;
+  }
+  valueHigh = valueHigh % 1.8446744073709552E19;
+  while (valueHigh > 9223372032559808512) {
+    valueHigh -= 1.8446744073709552E19;
+  }
+  while (valueHigh < -9223372036854775808) {
+    valueHigh += 1.8446744073709552E19;
+  }
+  return [valueLow, valueHigh];
+}
+
+function fromDouble(value){
+  if (isNaN(value)) {
+    return $clinit_44() , ZERO;
+  }
+  if (value < -9223372036854775808) {
+    return $clinit_44() , MIN_VALUE;
+  }
+  if (value >= 9223372036854775807) {
+    return $clinit_44() , MAX_VALUE;
+  }
+  if (value > 0) {
+    return create(Math.floor(value), 0);
+  }
+   else {
+    return create(Math.ceil(value), 0);
+  }
+}
+
+function fromInt(value){
+  var rebase, result;
+  if (value > -129 && value < 128) {
+    rebase = value + 128;
+    result = ($clinit_43() , boxedValues)[rebase];
+    result == null && (result = boxedValues[rebase] = internalFromInt(value));
+    return result;
+  }
+  return internalFromInt(value);
+}
+
+function internalFromInt(value){
+  if (value >= 0) {
+    return [value, 0];
+  }
+   else {
+    return [value + 4294967296, -4294967296];
+  }
+}
+
+function $clinit_43(){
+  $clinit_43 = nullMethod;
+  boxedValues = initDim(_3_3D_classLit, 65, 18, 256, 0);
+}
+
+var boxedValues;
+function $clinit_44(){
+  $clinit_44 = nullMethod;
+  Math.log(2);
+  MAX_VALUE = P7fffffffffffffff_longLit;
+  MIN_VALUE = N8000000000000000_longLit;
+  fromInt(-1);
+  fromInt(1);
+  fromInt(2);
+  ZERO = fromInt(0);
+}
+
+var MAX_VALUE, MIN_VALUE, ZERO;
+function $clinit_47(){
+  $clinit_47 = nullMethod;
+  timers = $ArrayList(new ArrayList);
+  addCloseHandler(new Timer$1);
+}
+
+function $cancel(this$static){
+  this$static.isRepeating?($wnd.clearInterval(this$static.timerId) , undefined):($wnd.clearTimeout(this$static.timerId) , undefined);
+  $remove_0(timers, this$static);
+}
+
+function $schedule(this$static, delayMillis){
+  if (delayMillis <= 0) {
+    throw $IllegalArgumentException(new IllegalArgumentException, 'must be positive');
+  }
+  $cancel(this$static);
+  this$static.isRepeating = false;
+  this$static.timerId = createTimeout(this$static, delayMillis);
+  $add(timers, this$static);
+}
+
+function createTimeout(timer, delay){
+  return $wnd.setTimeout($entry(function(){
+    timer.fire();
+  }
+  ), delay);
+}
+
+function fire_0(){
+  !this.isRepeating && $remove_0(timers, this);
+  $run(this);
+}
+
+function getClass_20(){
+  return Lcom_google_gwt_user_client_Timer_2_classLit;
+}
+
+function Timer(){
+}
+
+_ = Timer.prototype = new Object_0;
+_.fire = fire_0;
+_.getClass$ = getClass_20;
+_.typeId$ = 0;
+_.isRepeating = false;
+_.timerId = 0;
+var timers;
+function $onClose(){
+  while (($clinit_47() , timers).size > 0) {
+    $cancel(dynamicCast($get_2(timers, 0), 22));
+  }
+}
+
+function getClass_21(){
+  return Lcom_google_gwt_user_client_Timer$1_2_classLit;
+}
+
+function Timer$1(){
+}
+
+_ = Timer$1.prototype = new Object_0;
+_.getClass$ = getClass_21;
+_.typeId$ = 8;
+function addCloseHandler(handler){
+  maybeInitializeCloseHandlers();
+  return addHandler(TYPE?TYPE:(TYPE = $GwtEvent$Type(new GwtEvent$Type)), handler);
+}
+
+function addHandler(type, handler){
+  return $addHandler(getHandlers(), type, handler);
+}
+
+function getHandlers(){
+  !handlers && (handlers = $Window$WindowHandlers(new Window$WindowHandlers));
+  return handlers;
+}
+
+function maybeInitializeCloseHandlers(){
+  if (!closeHandlersInitialized) {
+    $initWindowCloseHandler();
+    closeHandlersInitialized = true;
+  }
+}
+
+function onClosing(){
+  var event_0;
+  if (closeHandlersInitialized) {
+    event_0 = ($clinit_50() , new Window$ClosingEvent);
+    !!handlers && $fireEvent(handlers, event_0);
+    return null;
+  }
+  return null;
+}
+
+var closeHandlersInitialized = false, handlers = null;
+function $clinit_50(){
+  $clinit_50 = nullMethod;
+  TYPE_0 = $GwtEvent$Type(new GwtEvent$Type);
+}
+
+function dispatch_0(p0){
+  throwClassCastExceptionUnlessNull(p0);
+  null.nullMethod();
+}
+
+function getAssociatedType_0(){
+  return TYPE_0;
+}
+
+function getClass_22(){
+  return Lcom_google_gwt_user_client_Window$ClosingEvent_2_classLit;
+}
+
+function Window$ClosingEvent(){
+}
+
+_ = Window$ClosingEvent.prototype = new GwtEvent;
+_.dispatch = dispatch_0;
+_.getAssociatedType = getAssociatedType_0;
+_.getClass$ = getClass_22;
+_.typeId$ = 0;
+var TYPE_0;
+function $Window$WindowHandlers(this$static){
+  this$static.registry = $HandlerManager$HandlerRegistry(new HandlerManager$HandlerRegistry);
+  this$static.source = null;
+  this$static.isReverseOrder = false;
+  return this$static;
+}
+
+function getClass_23(){
+  return Lcom_google_gwt_user_client_Window$WindowHandlers_2_classLit;
+}
+
+function Window$WindowHandlers(){
+}
+
+_ = Window$WindowHandlers.prototype = new HandlerManager;
+_.getClass$ = getClass_23;
+_.typeId$ = 0;
+function $initWindowCloseHandler(){
+  var oldOnBeforeUnload = $wnd.onbeforeunload;
+  var oldOnUnload = $wnd.onunload;
+  $wnd.onbeforeunload = function(evt){
+    var ret, oldRet;
+    try {
+      ret = $entry(onClosing)();
+    }
+     finally {
+      oldRet = oldOnBeforeUnload && oldOnBeforeUnload(evt);
+    }
+    if (ret != null) {
+      return ret;
+    }
+    if (oldRet != null) {
+      return oldRet;
+    }
+  }
+  ;
+  $wnd.onunload = $entry(function(evt){
+    try {
+      closeHandlersInitialized && fire(getHandlers());
+    }
+     finally {
+      oldOnUnload && oldOnUnload(evt);
+      $wnd.onresize = null;
+      $wnd.onscroll = null;
+      $wnd.onbeforeunload = null;
+      $wnd.onunload = null;
+    }
+  }
+  );
+}
+
+function $ArrayStoreException(this$static){
+  $fillInStackTrace();
+  return this$static;
+}
+
+function $ArrayStoreException_0(this$static, message){
+  $fillInStackTrace();
+  this$static.detailMessage = message;
+  return this$static;
+}
+
+function getClass_24(){
+  return Ljava_lang_ArrayStoreException_2_classLit;
+}
+
+function ArrayStoreException(){
+}
+
+_ = ArrayStoreException.prototype = new RuntimeException;
+_.getClass$ = getClass_24;
+_.typeId$ = 10;
+function createForArray(packageName, className, componentType){
+  var clazz;
+  clazz = new Class;
+  clazz.typeName = packageName + className;
+  clazz.modifiers = 4;
+  clazz.componentType = componentType;
+  return clazz;
+}
+
+function createForClass(packageName, className){
+  var clazz;
+  clazz = new Class;
+  clazz.typeName = packageName + className;
+  return clazz;
+}
+
+function createForEnum(packageName, className, enumConstantsFunc){
+  var clazz;
+  clazz = new Class;
+  clazz.typeName = packageName + className;
+  clazz.modifiers = enumConstantsFunc?8:0;
+  return clazz;
+}
+
+function createForPrimitive(packageName, className){
+  var clazz;
+  clazz = new Class;
+  clazz.typeName = packageName + className;
+  clazz.modifiers = 1;
+  return clazz;
+}
+
+function getClass_25(){
+  return Ljava_lang_Class_2_classLit;
+}
+
+function toString_5(){
+  return ((this.modifiers & 2) != 0?'interface ':(this.modifiers & 1) != 0?'':'class ') + this.typeName;
+}
+
+function Class(){
+}
+
+_ = Class.prototype = new Object_0;
+_.getClass$ = getClass_25;
+_.toString$ = toString_5;
+_.typeId$ = 0;
+_.componentType = null;
+_.modifiers = 0;
+_.typeName = null;
+function $ClassCastException(this$static){
+  $fillInStackTrace();
+  return this$static;
+}
+
+function getClass_26(){
+  return Ljava_lang_ClassCastException_2_classLit;
+}
+
+function ClassCastException(){
+}
+
+_ = ClassCastException.prototype = new RuntimeException;
+_.getClass$ = getClass_26;
+_.typeId$ = 13;
+function equals_1(other){
+  return this === (other == null?null:other);
+}
+
+function getClass_27(){
+  return Ljava_lang_Enum_2_classLit;
+}
+
+function hashCode_3(){
+  return this.$H || (this.$H = ++sNextHashId);
+}
+
+function toString_6(){
+  return this.name_0;
+}
+
+function Enum(){
+}
+
+_ = Enum.prototype = new Object_0;
+_.equals$ = equals_1;
+_.getClass$ = getClass_27;
+_.hashCode$ = hashCode_3;
+_.toString$ = toString_6;
+_.typeId$ = 14;
+_.name_0 = null;
+_.ordinal = 0;
+function $IllegalArgumentException(this$static, message){
+  $fillInStackTrace();
+  this$static.detailMessage = message;
+  return this$static;
+}
+
+function getClass_28(){
+  return Ljava_lang_IllegalArgumentException_2_classLit;
+}
+
+function IllegalArgumentException(){
+}
+
+_ = IllegalArgumentException.prototype = new RuntimeException;
+_.getClass$ = getClass_28;
+_.typeId$ = 15;
+function $IndexOutOfBoundsException(this$static){
+  $fillInStackTrace();
+  return this$static;
+}
+
+function $IndexOutOfBoundsException_0(this$static, message){
+  $fillInStackTrace();
+  this$static.detailMessage = message;
+  return this$static;
+}
+
+function getClass_29(){
+  return Ljava_lang_IndexOutOfBoundsException_2_classLit;
+}
+
+function IndexOutOfBoundsException(){
+}
+
+_ = IndexOutOfBoundsException.prototype = new RuntimeException;
+_.getClass$ = getClass_29;
+_.typeId$ = 16;
+function toPowerOfTwoString(value, shift){
+  var bitMask, buf, bufSize, digits, pos;
+  bufSize = ~~(32 / shift);
+  bitMask = (1 << shift) - 1;
+  buf = initDim(_3C_classLit, 47, -1, bufSize, 1);
+  digits = ($clinit_70() , digits_0);
+  pos = bufSize - 1;
+  if (value >= 0) {
+    while (value > bitMask) {
+      buf[pos--] = digits[value & bitMask];
+      value >>= shift;
+    }
+  }
+   else {
+    while (pos > 0) {
+      buf[pos--] = digits[value & bitMask];
+      value >>= shift;
+    }
+  }
+  buf[pos] = digits[value & bitMask];
+  return __valueOf(buf, pos, bufSize);
+}
+
+function $NullPointerException(this$static){
+  $fillInStackTrace();
+  return this$static;
+}
+
+function getClass_30(){
+  return Ljava_lang_NullPointerException_2_classLit;
+}
+
+function NullPointerException(){
+}
+
+_ = NullPointerException.prototype = new RuntimeException;
+_.getClass$ = getClass_30;
+_.typeId$ = 17;
+function $clinit_70(){
+  $clinit_70 = nullMethod;
+  digits_0 = initValues(_3C_classLit, 47, -1, [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122]);
+}
+
+var digits_0;
+function $StackTraceElement(this$static, className, methodName, fileName, lineNumber){
+  this$static.className = className;
+  this$static.methodName = methodName;
+  this$static.fileName = fileName;
+  this$static.lineNumber = lineNumber;
+  return this$static;
+}
+
+function getClass_31(){
+  return Ljava_lang_StackTraceElement_2_classLit;
+}
+
+function toString_7(){
+  return this.className + '.' + this.methodName + '(' + this.fileName + ':' + this.lineNumber + ')';
+}
+
+function StackTraceElement(){
+}
+
+_ = StackTraceElement.prototype = new Object_0;
+_.getClass$ = getClass_31;
+_.toString$ = toString_7;
+_.typeId$ = 18;
+_.className = null;
+_.fileName = null;
+_.lineNumber = 0;
+_.methodName = null;
+function $equals_1(this$static, other){
+  if (!(other != null && canCast(other.typeId$, 1))) {
+    return false;
+  }
+  return String(this$static) == other;
+}
+
+function $getChars(this$static, srcBegin, srcEnd, dst, dstBegin){
+  var srcIdx;
+  for (srcIdx = srcBegin; srcIdx < srcEnd; ++srcIdx) {
+    dst[dstBegin++] = this$static.charCodeAt(srcIdx);
+  }
+}
+
+function $substring(this$static, beginIndex){
+  return this$static.substr(beginIndex, this$static.length - beginIndex);
+}
+
+function $toCharArray(this$static){
+  var charArr, n;
+  n = this$static.length;
+  charArr = initDim(_3C_classLit, 47, -1, n, 1);
+  $getChars(this$static, 0, n, charArr, 0);
+  return charArr;
+}
+
+function $trim(this$static){
+  if (this$static.length == 0 || this$static[0] > ' ' && this$static[this$static.length - 1] > ' ') {
+    return this$static;
+  }
+  var r1 = this$static.replace(/^(\s*)/, '');
+  var r2 = r1.replace(/\s*$/, '');
+  return r2;
+}
+
+function __checkBounds(legalCount, start, end){
+  if (start < 0) {
+    throw $StringIndexOutOfBoundsException(new StringIndexOutOfBoundsException, start);
+  }
+  if (end < start) {
+    throw $StringIndexOutOfBoundsException(new StringIndexOutOfBoundsException, end - start);
+  }
+  if (end > legalCount) {
+    throw $StringIndexOutOfBoundsException(new StringIndexOutOfBoundsException, end);
+  }
+}
+
+function __valueOf(x, start, end){
+  x = x.slice(start, end);
+  return String.fromCharCode.apply(null, x);
+}
+
+function compareTo(thisStr, otherStr){
+  thisStr = String(thisStr);
+  if (thisStr == otherStr) {
+    return 0;
+  }
+  return thisStr < otherStr?-1:1;
+}
+
+function equals_2(other){
+  return $equals_1(this, other);
+}
+
+function getClass_32(){
+  return Ljava_lang_String_2_classLit;
+}
+
+function hashCode_4(){
+  return getHashCode_0(this);
+}
+
+function toString_8(){
+  return this;
+}
+
+function valueOf_0(x, offset, count){
+  var end;
+  end = offset + count;
+  __checkBounds(x.length, offset, end);
+  return __valueOf(x, offset, end);
+}
+
+_ = String.prototype;
+_.equals$ = equals_2;
+_.getClass$ = getClass_32;
+_.hashCode$ = hashCode_4;
+_.toString$ = toString_8;
+_.typeId$ = 2;
+function $clinit_73(){
+  $clinit_73 = nullMethod;
+  back = {};
+  front = {};
+}
+
+function compute(str){
+  var hashCode, i, n, nBatch;
+  hashCode = 0;
+  n = str.length;
+  nBatch = n - 4;
+  i = 0;
+  while (i < nBatch) {
+    hashCode = str.charCodeAt(i + 3) + 31 * (str.charCodeAt(i + 2) + 31 * (str.charCodeAt(i + 1) + 31 * (str.charCodeAt(i) + 31 * hashCode))) | 0;
+    i += 4;
+  }
+  while (i < n) {
+    hashCode = hashCode * 31 + str.charCodeAt(i++);
+  }
+  return hashCode | 0;
+}
+
+function getHashCode_0(str){
+  $clinit_73();
+  var key = ':' + str;
+  var result = front[key];
+  if (result != null) {
+    return result;
+  }
+  result = back[key];
+  result == null && (result = compute(str));
+  increment();
+  return front[key] = result;
+}
+
+function increment(){
+  if (count_0 == 256) {
+    back = front;
+    front = {};
+    count_0 = 0;
+  }
+  ++count_0;
+}
+
+var back, count_0 = 0, front;
+function $StringBuffer(this$static){
+  this$static.impl = new StringBufferImplAppend;
+  return this$static;
+}
+
+function $append_0(this$static, x){
+  this$static.impl.string += x;
+  return this$static;
+}
+
+function getClass_33(){
+  return Ljava_lang_StringBuffer_2_classLit;
+}
+
+function toString_9(){
+  return this.impl.string;
+}
+
+function StringBuffer(){
+}
+
+_ = StringBuffer.prototype = new Object_0;
+_.getClass$ = getClass_33;
+_.toString$ = toString_9;
+_.typeId$ = 19;
+function $StringBuilder(this$static){
+  this$static.impl = new StringBufferImplAppend;
+  return this$static;
+}
+
+function $append_1(this$static, x){
+  this$static.impl.string += String.fromCharCode(x);
+  return this$static;
+}
+
+function $append_2(this$static, x){
+  this$static.impl.string += String.fromCharCode.apply(null, x);
+  return this$static;
+}
+
+function $getChars_0(this$static, srcStart, srcEnd, dst, dstStart){
+  var s;
+  __checkBounds(this$static.impl.string.length, srcStart, srcEnd);
+  __checkBounds(dst.length, dstStart, dstStart + (srcEnd - srcStart));
+  s = this$static.impl.string;
+  while (srcStart < srcEnd) {
+    dst[dstStart++] = s.charCodeAt(srcStart++);
+  }
+}
+
+function $setLength(this$static, newLength){
+  var oldLength;
+  oldLength = this$static.impl.string.length;
+  newLength < oldLength?$replace(this$static.impl, newLength, oldLength, ''):newLength > oldLength && $append_2(this$static, initDim(_3C_classLit, 47, -1, newLength - oldLength, 1));
+}
+
+function getClass_34(){
+  return Ljava_lang_StringBuilder_2_classLit;
+}
+
+function toString_10(){
+  return this.impl.string;
+}
+
+function StringBuilder(){
+}
+
+_ = StringBuilder.prototype = new Object_0;
+_.getClass$ = getClass_34;
+_.toString$ = toString_10;
+_.typeId$ = 20;
+function $StringIndexOutOfBoundsException(this$static, index){
+  $fillInStackTrace();
+  this$static.detailMessage = 'String index out of range: ' + index;
+  return this$static;
+}
+
+function getClass_35(){
+  return Ljava_lang_StringIndexOutOfBoundsException_2_classLit;
+}
+
+function StringIndexOutOfBoundsException(){
+}
+
+_ = StringIndexOutOfBoundsException.prototype = new IndexOutOfBoundsException;
+_.getClass$ = getClass_35;
+_.typeId$ = 21;
+function arrayTypeMatch(srcComp, destComp){
+  if ((srcComp.modifiers & 1) != 0) {
+    return srcComp == destComp;
+  }
+   else {
+    return (destComp.modifiers & 1) == 0;
+  }
+}
+
+function arraycopy(src, srcOfs, dest, destOfs, len){
+  var destArray, destComp, destEnd, destType, destlen, srcArray, srcComp, srcType, srclen;
+  if (src == null || dest == null) {
+    throw $NullPointerException(new NullPointerException);
+  }
+  srcType = src.typeMarker$ == nullMethod || src.typeId$ == 2?src.getClass$():Lcom_google_gwt_core_client_JavaScriptObject_2_classLit;
+  destType = dest.typeMarker$ == nullMethod || dest.typeId$ == 2?dest.getClass$():Lcom_google_gwt_core_client_JavaScriptObject_2_classLit;
+  if ((srcType.modifiers & 4) == 0 || (destType.modifiers & 4) == 0) {
+    throw $ArrayStoreException_0(new ArrayStoreException, 'Must be array types');
+  }
+  srcComp = srcType.componentType;
+  destComp = destType.componentType;
+  if (!arrayTypeMatch(srcComp, destComp)) {
+    throw $ArrayStoreException_0(new ArrayStoreException, 'Array types must match');
+  }
+  srclen = src.length;
+  destlen = dest.length;
+  if (srcOfs < 0 || destOfs < 0 || len < 0 || srcOfs + len > srclen || destOfs + len > destlen) {
+    throw $IndexOutOfBoundsException(new IndexOutOfBoundsException);
+  }
+  if (((srcComp.modifiers & 1) == 0 || (srcComp.modifiers & 4) != 0) && srcType != destType) {
+    srcArray = dynamicCast(src, 23);
+    destArray = dynamicCast(dest, 23);
+    if ((src == null?null:src) === (dest == null?null:dest) && srcOfs < destOfs) {
+      srcOfs += len;
+      for (destEnd = destOfs + len; destEnd-- > destOfs;) {
+        setCheck(destArray, destEnd, srcArray[--srcOfs]);
+      }
+    }
+     else {
+      for (destEnd = destOfs + len; destOfs < destEnd;) {
+        setCheck(destArray, destOfs++, srcArray[srcOfs++]);
+      }
+    }
+  }
+   else {
+    Array.prototype.splice.apply(dest, [destOfs, len].concat(src.slice(srcOfs, srcOfs + len)));
+  }
+}
+
+function $UnsupportedOperationException(this$static, message){
+  $fillInStackTrace();
+  this$static.detailMessage = message;
+  return this$static;
+}
+
+function getClass_36(){
+  return Ljava_lang_UnsupportedOperationException_2_classLit;
+}
+
+function UnsupportedOperationException(){
+}
+
+_ = UnsupportedOperationException.prototype = new RuntimeException;
+_.getClass$ = getClass_36;
+_.typeId$ = 22;
+function $advanceToFind(iter, o){
+  var t;
+  while (iter.hasNext()) {
+    t = iter.next_0();
+    if (o == null?t == null:equals__devirtual$(o, t)) {
+      return iter;
+    }
+  }
+  return null;
+}
+
+function add(o){
+  throw $UnsupportedOperationException(new UnsupportedOperationException, 'Add not supported on this collection');
+}
+
+function contains(o){
+  var iter;
+  iter = $advanceToFind(this.iterator(), o);
+  return !!iter;
+}
+
+function getClass_37(){
+  return Ljava_util_AbstractCollection_2_classLit;
+}
+
+function toString_11(){
+  var comma, iter, sb;
+  sb = $StringBuffer(new StringBuffer);
+  comma = null;
+  sb.impl.string += '[';
+  iter = this.iterator();
+  while (iter.hasNext()) {
+    comma != null?(sb.impl.string += comma , undefined):(comma = ', ');
+    $append_0(sb, '' + iter.next_0());
+  }
+  sb.impl.string += ']';
+  return sb.impl.string;
+}
+
+function AbstractCollection(){
+}
+
+_ = AbstractCollection.prototype = new Object_0;
+_.add_0 = add;
+_.contains = contains;
+_.getClass$ = getClass_37;
+_.toString$ = toString_11;
+_.typeId$ = 0;
+function equals_3(obj){
+  var entry, entry$iterator, otherKey, otherMap, otherValue;
+  if ((obj == null?null:obj) === this) {
+    return true;
+  }
+  if (!(obj != null && canCast(obj.typeId$, 26))) {
+    return false;
+  }
+  otherMap = dynamicCast(obj, 26);
+  if (dynamicCast(this, 26).size != otherMap.size) {
+    return false;
+  }
+  for (entry$iterator = $AbstractHashMap$EntrySetIterator(new AbstractHashMap$EntrySetIterator, $AbstractHashMap$EntrySet(new AbstractHashMap$EntrySet, otherMap).this$0); $hasNext_0(entry$iterator.iter);) {
+    entry = dynamicCast($next_0(entry$iterator.iter), 24);
+    otherKey = entry.getKey();
+    otherValue = entry.getValue();
+    if (!(otherKey == null?dynamicCast(this, 26).nullSlotLive:otherKey != null && canCast(otherKey.typeId$, 1)?$hasStringValue(dynamicCast(this, 26), dynamicCast(otherKey, 1)):$hasHashValue(dynamicCast(this, 26), otherKey, ~~hashCode__devirtual$(otherKey)))) {
+      return false;
+    }
+    if (!equalsWithNullCheck(otherValue, otherKey == null?dynamicCast(this, 26).nullSlot:otherKey != null && canCast(otherKey.typeId$, 1)?dynamicCast(this, 26).stringMap[':' + dynamicCast(otherKey, 1)]:$getHashValue(dynamicCast(this, 26), otherKey, ~~hashCode__devirtual$(otherKey)))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+function getClass_38(){
+  return Ljava_util_AbstractMap_2_classLit;
+}
+
+function hashCode_5(){
+  var entry, entry$iterator, hashCode;
+  hashCode = 0;
+  for (entry$iterator = $AbstractHashMap$EntrySetIterator(new AbstractHashMap$EntrySetIterator, $AbstractHashMap$EntrySet(new AbstractHashMap$EntrySet, dynamicCast(this, 26)).this$0); $hasNext_0(entry$iterator.iter);) {
+    entry = dynamicCast($next_0(entry$iterator.iter), 24);
+    hashCode += entry.hashCode$();
+    hashCode = ~~hashCode;
+  }
+  return hashCode;
+}
+
+function toString_12(){
+  var comma, entry, iter, s;
+  s = '{';
+  comma = false;
+  for (iter = $AbstractHashMap$EntrySetIterator(new AbstractHashMap$EntrySetIterator, $AbstractHashMap$EntrySet(new AbstractHashMap$EntrySet, dynamicCast(this, 26)).this$0); $hasNext_0(iter.iter);) {
+    entry = dynamicCast($next_0(iter.iter), 24);
+    comma?(s += ', '):(comma = true);
+    s += '' + entry.getKey();
+    s += '=';
+    s += '' + entry.getValue();
+  }
+  return s + '}';
+}
+
+function AbstractMap(){
+}
+
+_ = AbstractMap.prototype = new Object_0;
+_.equals$ = equals_3;
+_.getClass$ = getClass_38;
+_.hashCode$ = hashCode_5;
+_.toString$ = toString_12;
+_.typeId$ = 0;
+function $addAllHashEntries(this$static, dest){
+  var hashCodeMap = this$static.hashCodeMap;
+  for (var hashCode in hashCodeMap) {
+    if (hashCode == parseInt(hashCode)) {
+      var array = hashCodeMap[hashCode];
+      for (var i = 0, c = array.length; i < c; ++i) {
+        dest.add_0(array[i]);
+      }
+    }
+  }
+}
+
+function $addAllStringEntries(this$static, dest){
+  var stringMap = this$static.stringMap;
+  for (var key in stringMap) {
+    if (key.charCodeAt(0) == 58) {
+      var entry = new_$(this$static, key.substring(1));
+      dest.add_0(entry);
+    }
+  }
+}
+
+function $clearImpl(this$static){
+  this$static.hashCodeMap = [];
+  this$static.stringMap = {};
+  this$static.nullSlotLive = false;
+  this$static.nullSlot = null;
+  this$static.size = 0;
+}
+
+function $containsKey(this$static, key){
+  return key == null?this$static.nullSlotLive:key != null && canCast(key.typeId$, 1)?$hasStringValue(this$static, dynamicCast(key, 1)):$hasHashValue(this$static, key, ~~hashCode__devirtual$(key));
+}
+
+function $get_1(this$static, key){
+  return key == null?this$static.nullSlot:key != null && canCast(key.typeId$, 1)?this$static.stringMap[':' + dynamicCast(key, 1)]:$getHashValue(this$static, key, ~~hashCode__devirtual$(key));
+}
+
+function $getHashValue(this$static, key, hashCode){
+  var array = this$static.hashCodeMap[hashCode];
+  if (array) {
+    for (var i = 0, c = array.length; i < c; ++i) {
+      var entry = array[i];
+      var entryKey = entry.getKey();
+      if (this$static.equalsBridge(key, entryKey)) {
+        return entry.getValue();
+      }
+    }
+  }
+  return null;
+}
+
+function $hasHashValue(this$static, key, hashCode){
+  var array = this$static.hashCodeMap[hashCode];
+  if (array) {
+    for (var i = 0, c = array.length; i < c; ++i) {
+      var entry = array[i];
+      var entryKey = entry.getKey();
+      if (this$static.equalsBridge(key, entryKey)) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+function $hasStringValue(this$static, key){
+  return ':' + key in this$static.stringMap;
+}
+
+function $put(this$static, key, value){
+  return !key?$putNullSlot(this$static, value):$putHashValue(this$static, key, value, ~~key.index);
+}
+
+function $putHashValue(this$static, key, value, hashCode){
+  var array = this$static.hashCodeMap[hashCode];
+  if (array) {
+    for (var i = 0, c = array.length; i < c; ++i) {
+      var entry = array[i];
+      var entryKey = entry.getKey();
+      if (this$static.equalsBridge(key, entryKey)) {
+        var previous = entry.getValue();
+        entry.setValue(value);
+        return previous;
+      }
+    }
+  }
+   else {
+    array = this$static.hashCodeMap[hashCode] = [];
+  }
+  var entry = $MapEntryImpl(new MapEntryImpl, key, value);
+  array.push(entry);
+  ++this$static.size;
+  return null;
+}
+
+function $putNullSlot(this$static, value){
+  var result;
+  result = this$static.nullSlot;
+  this$static.nullSlot = value;
+  if (!this$static.nullSlotLive) {
+    this$static.nullSlotLive = true;
+    ++this$static.size;
+  }
+  return result;
+}
+
+function $putStringValue(this$static, key, value){
+  var result, stringMap = this$static.stringMap;
+  key = ':' + key;
+  key in stringMap?(result = stringMap[key]):++this$static.size;
+  stringMap[key] = value;
+  return result;
+}
+
+function equalsBridge(value1, value2){
+  return (value1 == null?null:value1) === (value2 == null?null:value2) || value1 != null && equals__devirtual$(value1, value2);
+}
+
+function getClass_39(){
+  return Ljava_util_AbstractHashMap_2_classLit;
+}
+
+function AbstractHashMap(){
+}
+
+_ = AbstractHashMap.prototype = new AbstractMap;
+_.equalsBridge = equalsBridge;
+_.getClass$ = getClass_39;
+_.typeId$ = 0;
+_.hashCodeMap = null;
+_.nullSlot = null;
+_.nullSlotLive = false;
+_.size = 0;
+_.stringMap = null;
+function equals_4(o){
+  var iter, other, otherItem;
+  if ((o == null?null:o) === this) {
+    return true;
+  }
+  if (!(o != null && canCast(o.typeId$, 28))) {
+    return false;
+  }
+  other = dynamicCast(o, 28);
+  if (other.this$0.size != this.size_0()) {
+    return false;
+  }
+  for (iter = $AbstractHashMap$EntrySetIterator(new AbstractHashMap$EntrySetIterator, other.this$0); $hasNext_0(iter.iter);) {
+    otherItem = dynamicCast($next_0(iter.iter), 24);
+    if (!this.contains(otherItem)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+function getClass_40(){
+  return Ljava_util_AbstractSet_2_classLit;
+}
+
+function hashCode_6(){
+  var hashCode, iter, next;
+  hashCode = 0;
+  for (iter = this.iterator(); iter.hasNext();) {
+    next = iter.next_0();
+    if (next != null) {
+      hashCode += hashCode__devirtual$(next);
+      hashCode = ~~hashCode;
+    }
+  }
+  return hashCode;
+}
+
+function AbstractSet(){
+}
+
+_ = AbstractSet.prototype = new AbstractCollection;
+_.equals$ = equals_4;
+_.getClass$ = getClass_40;
+_.hashCode$ = hashCode_6;
+_.typeId$ = 0;
+function $AbstractHashMap$EntrySet(this$static, this$0){
+  this$static.this$0 = this$0;
+  return this$static;
+}
+
+function contains_0(o){
+  var entry, key, value;
+  if (o != null && canCast(o.typeId$, 24)) {
+    entry = dynamicCast(o, 24);
+    key = entry.getKey();
+    if ($containsKey(this.this$0, key)) {
+      value = $get_1(this.this$0, key);
+      return $equals_2(entry.getValue(), value);
+    }
+  }
+  return false;
+}
+
+function getClass_41(){
+  return Ljava_util_AbstractHashMap$EntrySet_2_classLit;
+}
+
+function iterator(){
+  return $AbstractHashMap$EntrySetIterator(new AbstractHashMap$EntrySetIterator, this.this$0);
+}
+
+function size_0(){
+  return this.this$0.size;
+}
+
+function AbstractHashMap$EntrySet(){
+}
+
+_ = AbstractHashMap$EntrySet.prototype = new AbstractSet;
+_.contains = contains_0;
+_.getClass$ = getClass_41;
+_.iterator = iterator;
+_.size_0 = size_0;
+_.typeId$ = 23;
+_.this$0 = null;
+function $AbstractHashMap$EntrySetIterator(this$static, this$0){
+  var list;
+  this$static.this$0 = this$0;
+  list = $ArrayList(new ArrayList);
+  this$static.this$0.nullSlotLive && $add(list, $AbstractHashMap$MapEntryNull(new AbstractHashMap$MapEntryNull, this$static.this$0));
+  $addAllStringEntries(this$static.this$0, list);
+  $addAllHashEntries(this$static.this$0, list);
+  this$static.iter = $AbstractList$IteratorImpl(new AbstractList$IteratorImpl, list);
+  return this$static;
+}
+
+function getClass_42(){
+  return Ljava_util_AbstractHashMap$EntrySetIterator_2_classLit;
+}
+
+function hasNext(){
+  return $hasNext_0(this.iter);
+}
+
+function next_0(){
+  return dynamicCast($next_0(this.iter), 24);
+}
+
+function AbstractHashMap$EntrySetIterator(){
+}
+
+_ = AbstractHashMap$EntrySetIterator.prototype = new Object_0;
+_.getClass$ = getClass_42;
+_.hasNext = hasNext;
+_.next_0 = next_0;
+_.typeId$ = 0;
+_.iter = null;
+_.this$0 = null;
+function equals_5(other){
+  var entry;
+  if (other != null && canCast(other.typeId$, 24)) {
+    entry = dynamicCast(other, 24);
+    if (equalsWithNullCheck(this.getKey(), entry.getKey()) && equalsWithNullCheck(this.getValue(), entry.getValue())) {
+      return true;
+    }
+  }
+  return false;
+}
+
+function getClass_43(){
+  return Ljava_util_AbstractMapEntry_2_classLit;
+}
+
+function hashCode_7(){
+  var keyHash, valueHash;
+  keyHash = 0;
+  valueHash = 0;
+  this.getKey() != null && (keyHash = hashCode__devirtual$(this.getKey()));
+  this.getValue() != null && (valueHash = hashCode__devirtual$(this.getValue()));
+  return keyHash ^ valueHash;
+}
+
+function toString_13(){
+  return this.getKey() + '=' + this.getValue();
+}
+
+function AbstractMapEntry(){
+}
+
+_ = AbstractMapEntry.prototype = new Object_0;
+_.equals$ = equals_5;
+_.getClass$ = getClass_43;
+_.hashCode$ = hashCode_7;
+_.toString$ = toString_13;
+_.typeId$ = 24;
+function $AbstractHashMap$MapEntryNull(this$static, this$0){
+  this$static.this$0 = this$0;
+  return this$static;
+}
+
+function getClass_44(){
+  return Ljava_util_AbstractHashMap$MapEntryNull_2_classLit;
+}
+
+function getKey(){
+  return null;
+}
+
+function getValue(){
+  return this.this$0.nullSlot;
+}
+
+function setValue(object){
+  return $putNullSlot(this.this$0, object);
+}
+
+function AbstractHashMap$MapEntryNull(){
+}
+
+_ = AbstractHashMap$MapEntryNull.prototype = new AbstractMapEntry;
+_.getClass$ = getClass_44;
+_.getKey = getKey;
+_.getValue = getValue;
+_.setValue = setValue;
+_.typeId$ = 25;
+_.this$0 = null;
+function $AbstractHashMap$MapEntryString(this$static, key, this$0){
+  this$static.this$0 = this$0;
+  this$static.key = key;
+  return this$static;
+}
+
+function getClass_45(){
+  return Ljava_util_AbstractHashMap$MapEntryString_2_classLit;
+}
+
+function getKey_0(){
+  return this.key;
+}
+
+function getValue_0(){
+  return this.this$0.stringMap[':' + this.key];
+}
+
+function new_$(this$outer, key){
+  return $AbstractHashMap$MapEntryString(new AbstractHashMap$MapEntryString, key, this$outer);
+}
+
+function setValue_0(object){
+  return $putStringValue(this.this$0, this.key, object);
+}
+
+function AbstractHashMap$MapEntryString(){
+}
+
+_ = AbstractHashMap$MapEntryString.prototype = new AbstractMapEntry;
+_.getClass$ = getClass_45;
+_.getKey = getKey_0;
+_.getValue = getValue_0;
+_.setValue = setValue_0;
+_.typeId$ = 26;
+_.key = null;
+_.this$0 = null;
+function add_0(obj){
+  this.add_1(this.size_0(), obj);
+  return true;
+}
+
+function add_1(index, element){
+  throw $UnsupportedOperationException(new UnsupportedOperationException, 'Add not supported on this list');
+}
+
+function checkIndex(index, size){
+  (index < 0 || index >= size) && indexOutOfBounds(index, size);
+}
+
+function equals_6(o){
+  var elem, elemOther, iter, iterOther, other;
+  if ((o == null?null:o) === this) {
+    return true;
+  }
+  if (!(o != null && canCast(o.typeId$, 25))) {
+    return false;
+  }
+  other = dynamicCast(o, 25);
+  if (this.size_0() != other.size_0()) {
+    return false;
+  }
+  iter = this.iterator();
+  iterOther = other.iterator();
+  while (iter.hasNext()) {
+    elem = iter.next_0();
+    elemOther = iterOther.next_0();
+    if (!(elem == null?elemOther == null:equals__devirtual$(elem, elemOther))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+function getClass_46(){
+  return Ljava_util_AbstractList_2_classLit;
+}
+
+function hashCode_8(){
+  var iter, k, obj;
+  k = 1;
+  iter = this.iterator();
+  while (iter.hasNext()) {
+    obj = iter.next_0();
+    k = 31 * k + (obj == null?0:hashCode__devirtual$(obj));
+    k = ~~k;
+  }
+  return k;
+}
+
+function indexOutOfBounds(index, size){
+  throw $IndexOutOfBoundsException_0(new IndexOutOfBoundsException, 'Index: ' + index + ', Size: ' + size);
+}
+
+function iterator_0(){
+  return $AbstractList$IteratorImpl(new AbstractList$IteratorImpl, this);
+}
+
+function AbstractList(){
+}
+
+_ = AbstractList.prototype = new AbstractCollection;
+_.add_0 = add_0;
+_.add_1 = add_1;
+_.equals$ = equals_6;
+_.getClass$ = getClass_46;
+_.hashCode$ = hashCode_8;
+_.iterator = iterator_0;
+_.typeId$ = 27;
+function $AbstractList$IteratorImpl(this$static, this$0){
+  this$static.this$0 = this$0;
+  return this$static;
+}
+
+function $hasNext_0(this$static){
+  return this$static.i < this$static.this$0.size_0();
+}
+
+function $next_0(this$static){
+  if (this$static.i >= this$static.this$0.size_0()) {
+    throw $NoSuchElementException(new NoSuchElementException);
+  }
+  return this$static.this$0.get(this$static.i++);
+}
+
+function getClass_47(){
+  return Ljava_util_AbstractList$IteratorImpl_2_classLit;
+}
+
+function hasNext_0(){
+  return this.i < this.this$0.size_0();
+}
+
+function next_1(){
+  return $next_0(this);
+}
+
+function AbstractList$IteratorImpl(){
+}
+
+_ = AbstractList$IteratorImpl.prototype = new Object_0;
+_.getClass$ = getClass_47;
+_.hasNext = hasNext_0;
+_.next_0 = next_1;
+_.typeId$ = 0;
+_.i = 0;
+_.this$0 = null;
+function add_2(index, element){
+  var iter;
+  iter = $listIterator(this, index);
+  $addBefore(iter.this$0, element, iter.currentNode);
+  ++iter.currentIndex;
+  iter.lastNode = null;
+}
+
+function get(index){
+  var $e0, iter;
+  iter = $listIterator(this, index);
+  try {
+    return $next_1(iter);
+  }
+   catch ($e0) {
+    $e0 = caught($e0);
+    if (instanceOf($e0, 27)) {
+      throw $IndexOutOfBoundsException_0(new IndexOutOfBoundsException, "Can't get element " + index);
+    }
+     else 
+      throw $e0;
+  }
+}
+
+function getClass_48(){
+  return Ljava_util_AbstractSequentialList_2_classLit;
+}
+
+function iterator_1(){
+  return $listIterator(this, 0);
+}
+
+function AbstractSequentialList(){
+}
+
+_ = AbstractSequentialList.prototype = new AbstractList;
+_.add_1 = add_2;
+_.get = get;
+_.getClass$ = getClass_48;
+_.iterator = iterator_1;
+_.typeId$ = 28;
+function $ArrayList(this$static){
+  this$static.array = initDim(_3Ljava_lang_Object_2_classLit, 54, 0, 0, 0);
+  return this$static;
+}
+
+function $add(this$static, o){
+  setCheck(this$static.array, this$static.size++, o);
+  return true;
+}
+
+function $get_2(this$static, index){
+  checkIndex(index, this$static.size);
+  return this$static.array[index];
+}
+
+function $indexOf_0(this$static, o, index){
+  for (; index < this$static.size; ++index) {
+    if (equalsWithNullCheck(o, this$static.array[index])) {
+      return index;
+    }
+  }
+  return -1;
+}
+
+function $remove_0(this$static, o){
+  var i, previous;
+  i = $indexOf_0(this$static, o, 0);
+  if (i == -1) {
+    return false;
+  }
+  previous = (checkIndex(i, this$static.size) , this$static.array[i]);
+  this$static.array.splice(i, 1);
+  --this$static.size;
+  return true;
+}
+
+function add_3(o){
+  return setCheck(this.array, this.size++, o) , true;
+}
+
+function add_4(index, o){
+  (index < 0 || index > this.size) && indexOutOfBounds(index, this.size);
+  this.array.splice(index, 0, o);
+  ++this.size;
+}
+
+function contains_1(o){
+  return $indexOf_0(this, o, 0) != -1;
+}
+
+function get_0(index){
+  return checkIndex(index, this.size) , this.array[index];
+}
+
+function getClass_49(){
+  return Ljava_util_ArrayList_2_classLit;
+}
+
+function size_1(){
+  return this.size;
+}
+
+function ArrayList(){
+}
+
+_ = ArrayList.prototype = new AbstractList;
+_.add_0 = add_3;
+_.add_1 = add_4;
+_.contains = contains_1;
+_.get = get_0;
+_.getClass$ = getClass_49;
+_.size_0 = size_1;
+_.typeId$ = 29;
+_.size = 0;
+function binarySearch(sortedArray, key){
+  var high, low, mid, midVal;
+  low = 0;
+  high = sortedArray.length - 1;
+  while (low <= high) {
+    mid = low + (high - low >> 1);
+    midVal = sortedArray[mid];
+    if (midVal < key) {
+      low = mid + 1;
+    }
+     else if (midVal > key) {
+      high = mid - 1;
+    }
+     else {
+      return mid;
+    }
+  }
+  return -low - 1;
+}
+
+function binarySearch_0(sortedArray, key, comparator){
+  var compareResult, high, low, mid, midVal;
+  !comparator && (comparator = ($clinit_95() , $clinit_95() , NATURAL));
+  low = 0;
+  high = sortedArray.length - 1;
+  while (low <= high) {
+    mid = low + (high - low >> 1);
+    midVal = sortedArray[mid];
+    compareResult = compareTo(midVal, key);
+    if (compareResult < 0) {
+      low = mid + 1;
+    }
+     else if (compareResult > 0) {
+      high = mid - 1;
+    }
+     else {
+      return mid;
+    }
+  }
+  return -low - 1;
+}
+
+function $clinit_95(){
+  $clinit_95 = nullMethod;
+  NATURAL = new Comparators$1;
+}
+
+var NATURAL;
+function getClass_50(){
+  return Ljava_util_Comparators$1_2_classLit;
+}
+
+function Comparators$1(){
+}
+
+_ = Comparators$1.prototype = new Object_0;
+_.getClass$ = getClass_50;
+_.typeId$ = 0;
+function $HashMap(this$static){
+  $clearImpl(this$static);
+  return this$static;
+}
+
+function $equals_2(value1, value2){
+  return (value1 == null?null:value1) === (value2 == null?null:value2) || value1 != null && equals__devirtual$(value1, value2);
+}
+
+function getClass_51(){
+  return Ljava_util_HashMap_2_classLit;
+}
+
+function HashMap(){
+}
+
+_ = HashMap.prototype = new AbstractHashMap;
+_.getClass$ = getClass_51;
+_.typeId$ = 30;
+function $LinkedList(this$static){
+  this$static.header = $LinkedList$Node(new LinkedList$Node);
+  this$static.size = 0;
+  return this$static;
+}
+
+function $addBefore(this$static, o, target){
+  $LinkedList$Node_0(new LinkedList$Node, o, target);
+  ++this$static.size;
+}
+
+function $addLast(this$static, o){
+  $LinkedList$Node_0(new LinkedList$Node, o, this$static.header);
+  ++this$static.size;
+}
+
+function $clear(this$static){
+  this$static.header = $LinkedList$Node(new LinkedList$Node);
+  this$static.size = 0;
+}
+
+function $getLast(this$static){
+  $throwEmptyException(this$static);
+  return this$static.header.prev.value;
+}
+
+function $listIterator(this$static, index){
+  var i, node;
+  (index < 0 || index > this$static.size) && indexOutOfBounds(index, this$static.size);
+  if (index >= this$static.size >> 1) {
+    node = this$static.header;
+    for (i = this$static.size; i > index; --i) {
+      node = node.prev;
+    }
+  }
+   else {
+    node = this$static.header.next;
+    for (i = 0; i < index; ++i) {
+      node = node.next;
+    }
+  }
+  return $LinkedList$ListIteratorImpl(new LinkedList$ListIteratorImpl, index, node, this$static);
+}
+
+function $removeLast(this$static){
+  var node;
+  $throwEmptyException(this$static);
+  --this$static.size;
+  node = this$static.header.prev;
+  node.next.prev = node.prev;
+  node.prev.next = node.next;
+  node.next = node.prev = node;
+  return node.value;
+}
+
+function $throwEmptyException(this$static){
+  if (this$static.size == 0) {
+    throw $NoSuchElementException(new NoSuchElementException);
+  }
+}
+
+function add_5(o){
+  $LinkedList$Node_0(new LinkedList$Node, o, this.header);
+  ++this.size;
+  return true;
+}
+
+function getClass_52(){
+  return Ljava_util_LinkedList_2_classLit;
+}
+
+function size_2(){
+  return this.size;
+}
+
+function LinkedList(){
+}
+
+_ = LinkedList.prototype = new AbstractSequentialList;
+_.add_0 = add_5;
+_.getClass$ = getClass_52;
+_.size_0 = size_2;
+_.typeId$ = 31;
+_.header = null;
+_.size = 0;
+function $LinkedList$ListIteratorImpl(this$static, index, startNode, this$0){
+  this$static.this$0 = this$0;
+  this$static.currentNode = startNode;
+  this$static.currentIndex = index;
+  return this$static;
+}
+
+function $next_1(this$static){
+  if (this$static.currentNode == this$static.this$0.header) {
+    throw $NoSuchElementException(new NoSuchElementException);
+  }
+  this$static.lastNode = this$static.currentNode;
+  this$static.currentNode = this$static.currentNode.next;
+  ++this$static.currentIndex;
+  return this$static.lastNode.value;
+}
+
+function getClass_53(){
+  return Ljava_util_LinkedList$ListIteratorImpl_2_classLit;
+}
+
+function hasNext_1(){
+  return this.currentNode != this.this$0.header;
+}
+
+function next_2(){
+  return $next_1(this);
+}
+
+function LinkedList$ListIteratorImpl(){
+}
+
+_ = LinkedList$ListIteratorImpl.prototype = new Object_0;
+_.getClass$ = getClass_53;
+_.hasNext = hasNext_1;
+_.next_0 = next_2;
+_.typeId$ = 0;
+_.currentIndex = 0;
+_.currentNode = null;
+_.lastNode = null;
+_.this$0 = null;
+function $LinkedList$Node(this$static){
+  this$static.next = this$static.prev = this$static;
+  return this$static;
+}
+
+function $LinkedList$Node_0(this$static, value, nextNode){
+  this$static.value = value;
+  this$static.next = nextNode;
+  this$static.prev = nextNode.prev;
+  nextNode.prev.next = this$static;
+  nextNode.prev = this$static;
+  return this$static;
+}
+
+function getClass_54(){
+  return Ljava_util_LinkedList$Node_2_classLit;
+}
+
+function LinkedList$Node(){
+}
+
+_ = LinkedList$Node.prototype = new Object_0;
+_.getClass$ = getClass_54;
+_.typeId$ = 0;
+_.next = null;
+_.prev = null;
+_.value = null;
+function $MapEntryImpl(this$static, key, value){
+  this$static.key = key;
+  this$static.value = value;
+  return this$static;
+}
+
+function getClass_55(){
+  return Ljava_util_MapEntryImpl_2_classLit;
+}
+
+function getKey_1(){
+  return this.key;
+}
+
+function getValue_1(){
+  return this.value;
+}
+
+function setValue_1(value){
+  var old;
+  old = this.value;
+  this.value = value;
+  return old;
+}
+
+function MapEntryImpl(){
+}
+
+_ = MapEntryImpl.prototype = new AbstractMapEntry;
+_.getClass$ = getClass_55;
+_.getKey = getKey_1;
+_.getValue = getValue_1;
+_.setValue = setValue_1;
+_.typeId$ = 32;
+_.key = null;
+_.value = null;
+function $NoSuchElementException(this$static){
+  $fillInStackTrace();
+  return this$static;
+}
+
+function getClass_56(){
+  return Ljava_util_NoSuchElementException_2_classLit;
+}
+
+function NoSuchElementException(){
+}
+
+_ = NoSuchElementException.prototype = new RuntimeException;
+_.getClass$ = getClass_56;
+_.typeId$ = 33;
+function equalsWithNullCheck(a, b){
+  return (a == null?null:a) === (b == null?null:b) || a != null && equals__devirtual$(a, b);
+}
+
+function $clinit_112(){
+  $clinit_112 = nullMethod;
+  HTML = $DoctypeExpectation(new DoctypeExpectation, 'HTML', 0);
+  HTML401_TRANSITIONAL = $DoctypeExpectation(new DoctypeExpectation, 'HTML401_TRANSITIONAL', 1);
+  HTML401_STRICT = $DoctypeExpectation(new DoctypeExpectation, 'HTML401_STRICT', 2);
+  AUTO = $DoctypeExpectation(new DoctypeExpectation, 'AUTO', 3);
+  NO_DOCTYPE_ERRORS = $DoctypeExpectation(new DoctypeExpectation, 'NO_DOCTYPE_ERRORS', 4);
+}
+
+function $DoctypeExpectation(this$static, enum$name, enum$ordinal){
+  $clinit_112();
+  this$static.name_0 = enum$name;
+  this$static.ordinal = enum$ordinal;
+  return this$static;
+}
+
+function getClass_57(){
+  return Lnu_validator_htmlparser_common_DoctypeExpectation_2_classLit;
+}
+
+function values_0(){
+  $clinit_112();
+  return initValues(_3Lnu_validator_htmlparser_common_DoctypeExpectation_2_classLit, 57, 10, [HTML, HTML401_TRANSITIONAL, HTML401_STRICT, AUTO, NO_DOCTYPE_ERRORS]);
+}
+
+function DoctypeExpectation(){
+}
+
+_ = DoctypeExpectation.prototype = new Enum;
+_.getClass$ = getClass_57;
+_.typeId$ = 34;
+var AUTO, HTML, HTML401_STRICT, HTML401_TRANSITIONAL, NO_DOCTYPE_ERRORS;
+function $clinit_113(){
+  $clinit_113 = nullMethod;
+  STANDARDS_MODE = $DocumentMode(new DocumentMode, 'STANDARDS_MODE', 0);
+  ALMOST_STANDARDS_MODE = $DocumentMode(new DocumentMode, 'ALMOST_STANDARDS_MODE', 1);
+  QUIRKS_MODE = $DocumentMode(new DocumentMode, 'QUIRKS_MODE', 2);
+}
+
+function $DocumentMode(this$static, enum$name, enum$ordinal){
+  $clinit_113();
+  this$static.name_0 = enum$name;
+  this$static.ordinal = enum$ordinal;
+  return this$static;
+}
+
+function getClass_58(){
+  return Lnu_validator_htmlparser_common_DocumentMode_2_classLit;
+}
+
+function values_1(){
+  $clinit_113();
+  return initValues(_3Lnu_validator_htmlparser_common_DocumentMode_2_classLit, 58, 11, [STANDARDS_MODE, ALMOST_STANDARDS_MODE, QUIRKS_MODE]);
+}
+
+function DocumentMode(){
+}
+
+_ = DocumentMode.prototype = new Enum;
+_.getClass$ = getClass_58;
+_.typeId$ = 35;
+var ALMOST_STANDARDS_MODE, QUIRKS_MODE, STANDARDS_MODE;
+function $clinit_115(){
+  $clinit_115 = nullMethod;
+  ALLOW = $XmlViolationPolicy(new XmlViolationPolicy, 'ALLOW', 0);
+  FATAL = $XmlViolationPolicy(new XmlViolationPolicy, 'FATAL', 1);
+  ALTER_INFOSET = $XmlViolationPolicy(new XmlViolationPolicy, 'ALTER_INFOSET', 2);
+}
+
+function $XmlViolationPolicy(this$static, enum$name, enum$ordinal){
+  $clinit_115();
+  this$static.name_0 = enum$name;
+  this$static.ordinal = enum$ordinal;
+  return this$static;
+}
+
+function getClass_59(){
+  return Lnu_validator_htmlparser_common_XmlViolationPolicy_2_classLit;
+}
+
+function values_2(){
+  $clinit_115();
+  return initValues(_3Lnu_validator_htmlparser_common_XmlViolationPolicy_2_classLit, 59, 12, [ALLOW, FATAL, ALTER_INFOSET]);
+}
+
+function XmlViolationPolicy(){
+}
+
+_ = XmlViolationPolicy.prototype = new Enum;
+_.getClass$ = getClass_59;
+_.typeId$ = 36;
+var ALLOW, ALTER_INFOSET, FATAL;
+function $clinit_116(){
+  $clinit_116 = nullMethod;
+  REPLACEMENT_CHARACTER = initValues(_3C_classLit, 47, -1, [65533]);
+  HTML4_PUBLIC_IDS = initValues(_3Ljava_lang_String_2_classLit, 56, 1, ['-//W3C//DTD HTML 4.0 Frameset//EN', '-//W3C//DTD HTML 4.0 Transitional//EN', '-//W3C//DTD HTML 4.0//EN', '-//W3C//DTD HTML 4.01 Frameset//EN', '-//W3C//DTD HTML 4.01 Transitional//EN', '-//W3C//DTD HTML 4.01//EN']);
+  QUIRKY_PUBLIC_IDS = initValues(_3Ljava_lang_String_2_classLit, 56, 1, ['+//silmaril//dtd html pro v0r11 19970101//', '-//advasoft ltd//dtd html 3.0 aswedit + extensions//', '-//as//dtd html 3.0 aswedit + extensions//', '-//ietf//dtd html 2.0 level 1//', '-//ietf//dtd html 2.0 level 2//', '-//ietf//dtd html 2.0 strict level 1//', '-//ietf//dtd html 2.0 strict level 2//', '-//ietf//dtd html 2.0 strict//', '-//ietf//dtd html 2.0//', '-//ietf//dtd html 2.1e//', '-//ietf//dtd html 3.0//', '-//ietf//dtd html 3.2 final//', '-//ietf//dtd html 3.2//', '-//ietf//dtd html 3//', '-//ietf//dtd html level 0//', '-//ietf//dtd html level 1//', '-//ietf//dtd html level 2//', '-//ietf//dtd html level 3//', '-//ietf//dtd html strict level 0//', '-//ietf//dtd html strict level 1//', '-//ietf//dtd html strict level 2//', '-//ietf//dtd html strict level 3//', '-//ietf//dtd html strict//', '-//ietf//dtd html//', '-//metrius//dtd metrius presentational//', '-//microsoft//dtd internet explorer 2.0 html strict//', '-//microsoft//dtd internet explorer 2.0 html//', '-//microsoft//dtd internet explorer 2.0 tables//', '-//microsoft//dtd internet explorer 3.0 html strict//', '-//microsoft//dtd internet explorer 3.0 html//', '-//microsoft//dtd internet explorer 3.0 tables//', '-//netscape comm. corp.//dtd html//', '-//netscape comm. corp.//dtd strict html//', "-//o'reilly and associates//dtd html 2.0//", "-//o'reilly and associates//dtd html extended 1.0//", "-//o'reilly and associates//dtd html extended relaxed 1.0//", '-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//', '-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//', '-//spyglass//dtd html 2.0 extended//', '-//sq//dtd html 2.0 hotmetal + extensions//', '-//sun microsystems corp.//dtd hotjava html//', '-//sun microsystems corp.//dtd hotjava strict html//', '-//w3c//dtd html 3 1995-03-24//', '-//w3c//dtd html 3.2 draft//', '-//w3c//dtd html 3.2 final//', '-//w3c//dtd html 3.2//', '-//w3c//dtd html 3.2s draft//', '-//w3c//dtd html 4.0 frameset//', '-//w3c//dtd html 4.0 transitional//', '-//w3c//dtd html experimental 19960712//', '-//w3c//dtd html experimental 970421//', '-//w3c//dtd w3 html//', '-//w3o//dtd w3 html 3.0//', '-//webtechs//dtd mozilla html 2.0//', '-//webtechs//dtd mozilla html//']);
+}
+
+function $accumulateCharacter(this$static, c){
+  var newBuf, newLen;
+  newLen = this$static.charBufferLen + 1;
+  if (newLen > this$static.charBuffer.length) {
+    newBuf = initDim(_3C_classLit, 47, -1, newLen, 1);
+    arraycopy(this$static.charBuffer, 0, newBuf, 0, this$static.charBufferLen);
+    this$static.charBuffer = newBuf;
+  }
+  this$static.charBuffer[this$static.charBufferLen] = c;
+  this$static.charBufferLen = newLen;
+}
+
+function $addAttributesToBody(this$static, attributes){
+  var body;
+  $processNonNcNames(attributes, this$static, this$static.namePolicy);
+  if (this$static.currentPtr >= 1) {
+    body = this$static.stack_0[1];
+    if (body.group == 3) {
+      $addAttributesToElement(this$static, body.node, attributes);
+      return true;
+    }
+  }
+  return false;
+}
+
+function $adoptionAgencyEndTag(this$static, name_0){
+  var bookmark, clone, commonAncestor, formattingClone, formattingElt, formattingEltListPos, formattingEltStackPos, furthestBlock, furthestBlockPos, inScope, lastNode, listNode, newNode, node, nodeListPos, nodePos;
+  $flushCharacters(this$static);
+  for (;;) {
+    formattingEltListPos = this$static.listPtr;
+    while (formattingEltListPos > -1) {
+      listNode = this$static.listOfActiveFormattingElements[formattingEltListPos];
+      if (!listNode) {
+        formattingEltListPos = -1;
+        break;
+      }
+       else if (listNode.name_0 == name_0) {
+        break;
+      }
+      --formattingEltListPos;
+    }
+    if (formattingEltListPos == -1) {
+      return;
+    }
+    formattingElt = this$static.listOfActiveFormattingElements[formattingEltListPos];
+    formattingEltStackPos = this$static.currentPtr;
+    inScope = true;
+    while (formattingEltStackPos > -1) {
+      node = this$static.stack_0[formattingEltStackPos];
+      if (node == formattingElt) {
+        break;
+      }
+       else 
+        node.scoping && (inScope = false);
+      --formattingEltStackPos;
+    }
+    if (formattingEltStackPos == -1) {
+      $removeFromListOfActiveFormattingElements(this$static, formattingEltListPos);
+      return;
+    }
+    if (!inScope) {
+      return;
+    }
+    furthestBlockPos = formattingEltStackPos + 1;
+    while (furthestBlockPos <= this$static.currentPtr) {
+      node = this$static.stack_0[furthestBlockPos];
+      if (node.scoping || node.special) {
+        break;
+      }
+      ++furthestBlockPos;
+    }
+    if (furthestBlockPos > this$static.currentPtr) {
+      while (this$static.currentPtr >= formattingEltStackPos) {
+        $pop(this$static);
+      }
+      $removeFromListOfActiveFormattingElements(this$static, formattingEltListPos);
+      return;
+    }
+    commonAncestor = this$static.stack_0[formattingEltStackPos - 1];
+    furthestBlock = this$static.stack_0[furthestBlockPos];
+    bookmark = formattingEltListPos;
+    nodePos = furthestBlockPos;
+    lastNode = furthestBlock;
+    for (;;) {
+      --nodePos;
+      node = this$static.stack_0[nodePos];
+      nodeListPos = $findInListOfActiveFormattingElements(this$static, node);
+      if (nodeListPos == -1) {
+        $removeFromStack(this$static, nodePos);
+        --furthestBlockPos;
+        continue;
+      }
+      if (nodePos == formattingEltStackPos) {
+        break;
+      }
+      nodePos == furthestBlockPos && (bookmark = nodeListPos + 1);
+      clone = $createElement(this$static, 'http://www.w3.org/1999/xhtml', node.name_0, $cloneAttributes(node.attributes));
+      newNode = $StackNode(new StackNode, node.group, node.ns, node.name_0, clone, node.scoping, node.special, node.fosterParenting, node.popName, node.attributes);
+      node.attributes = null;
+      this$static.stack_0[nodePos] = newNode;
+      ++newNode.refcount;
+      this$static.listOfActiveFormattingElements[nodeListPos] = newNode;
+      --node.refcount;
+      --node.refcount;
+      node = newNode;
+      $detachFromParent(this$static, lastNode.node);
+      $appendElement(this$static, lastNode.node, node.node);
+      lastNode = node;
+    }
+    if (commonAncestor.fosterParenting) {
+      $detachFromParent(this$static, lastNode.node);
+      $insertIntoFosterParent(this$static, lastNode.node);
+    }
+     else {
+      $detachFromParent(this$static, lastNode.node);
+      $appendElement(this$static, lastNode.node, commonAncestor.node);
+    }
+    clone = $createElement(this$static, 'http://www.w3.org/1999/xhtml', formattingElt.name_0, $cloneAttributes(formattingElt.attributes));
+    formattingClone = $StackNode(new StackNode, formattingElt.group, formattingElt.ns, formattingElt.name_0, clone, formattingElt.scoping, formattingElt.special, formattingElt.fosterParenting, formattingElt.popName, formattingElt.attributes);
+    formattingElt.attributes = null;
+    $appendChildrenToNewParent(this$static, furthestBlock.node, clone);
+    $appendElement(this$static, clone, furthestBlock.node);
+    $removeFromListOfActiveFormattingElements(this$static, formattingEltListPos);
+    ++formattingClone.refcount;
+    bookmark <= this$static.listPtr && arraycopy(this$static.listOfActiveFormattingElements, bookmark, this$static.listOfActiveFormattingElements, bookmark + 1, this$static.listPtr - bookmark + 1);
+    ++this$static.listPtr;
+    this$static.listOfActiveFormattingElements[bookmark] = formattingClone;
+    $removeFromStack(this$static, formattingEltStackPos);
+    $insertIntoStack(this$static, formattingClone, furthestBlockPos);
+  }
+}
+
+function $append_3(this$static, node){
+  var newList;
+  ++this$static.listPtr;
+  if (this$static.listPtr == this$static.listOfActiveFormattingElements.length) {
+    newList = initDim(_3Lnu_validator_htmlparser_impl_StackNode_2_classLit, 62, 15, this$static.listOfActiveFormattingElements.length + 64, 0);
+    arraycopy(this$static.listOfActiveFormattingElements, 0, newList, 0, this$static.listOfActiveFormattingElements.length);
+    this$static.listOfActiveFormattingElements = newList;
+  }
+  this$static.listOfActiveFormattingElements[this$static.listPtr] = node;
+}
+
+function $appendHtmlElementToDocumentAndPush(this$static, attributes){
+  var elt, node;
+  $processNonNcNames(attributes, this$static, this$static.namePolicy);
+  elt = $createHtmlElementSetAsRoot(this$static, attributes);
+  node = $StackNode_0(new StackNode, 'http://www.w3.org/1999/xhtml', ($clinit_125() , HTML_0), elt);
+  $push_0(this$static, node);
+}
+
+function $appendToCurrentNodeAndPushElement(this$static, ns, elementName, attributes){
+  var elt, node;
+  $flushCharacters(this$static);
+  $processNonNcNames(attributes, this$static, this$static.namePolicy);
+  elt = $createElement(this$static, ns, elementName.name_0, attributes);
+  $appendElement(this$static, elt, this$static.stack_0[this$static.currentPtr].node);
+  node = $StackNode_0(new StackNode, ns, elementName, elt);
+  $push_0(this$static, node);
+}
+
+function $appendToCurrentNodeAndPushElementMayFoster(this$static, ns, elementName, attributes){
+  var current, elt, node, popName;
+  $flushCharacters(this$static);
+  popName = elementName.name_0;
+  $processNonNcNames(attributes, this$static, this$static.namePolicy);
+  elementName.custom && (popName = $checkPopName(this$static, popName));
+  elt = $createElement(this$static, ns, popName, attributes);
+  current = this$static.stack_0[this$static.currentPtr];
+  current.fosterParenting?$insertIntoFosterParent(this$static, elt):$appendElement(this$static, elt, current.node);
+  node = $StackNode_2(new StackNode, ns, elementName, elt, popName);
+  $push_0(this$static, node);
+}
+
+function $appendToCurrentNodeAndPushElementMayFoster_0(this$static, ns, elementName, attributes){
+  var current, elt, node;
+  $flushCharacters(this$static);
+  $processNonNcNames(attributes, this$static, this$static.namePolicy);
+  elt = $createElement_0(this$static, ns, elementName.name_0, attributes);
+  current = this$static.stack_0[this$static.currentPtr];
+  if (current) {
+  current.fosterParenting?$insertIntoFosterParent(this$static, elt):$appendElement(this$static, elt, current.node);
+  }
+  node = $StackNode_0(new StackNode, ns, elementName, elt);
+  $push_0(this$static, node);
+}
+
+function $appendToCurrentNodeAndPushFormElementMayFoster(this$static, attributes){
+  var current, elt, node;
+  $flushCharacters(this$static);
+  $processNonNcNames(attributes, this$static, this$static.namePolicy);
+  elt = $createElement(this$static, 'http://www.w3.org/1999/xhtml', 'form', attributes);
+  this$static.formPointer = elt;
+  current = this$static.stack_0[this$static.currentPtr];
+  current.fosterParenting?$insertIntoFosterParent(this$static, elt):$appendElement(this$static, elt, current.node);
+  node = $StackNode_0(new StackNode, 'http://www.w3.org/1999/xhtml', ($clinit_125() , FORM_0), elt);
+  $push_0(this$static, node);
+}
+
+function $appendToCurrentNodeAndPushFormattingElementMayFoster(this$static, ns, elementName, attributes){
+  var current, elt, node;
+  $flushCharacters(this$static);
+  $processNonNcNames(attributes, this$static, this$static.namePolicy);
+  elt = $createElement(this$static, ns, elementName.name_0, attributes);
+  current = this$static.stack_0[this$static.currentPtr];
+  current.fosterParenting?$insertIntoFosterParent(this$static, elt):$appendElement(this$static, elt, current.node);
+  node = $StackNode_1(new StackNode, ns, elementName, elt, $cloneAttributes(attributes));
+  $push_0(this$static, node);
+  $append_3(this$static, node);
+  ++node.refcount;
+}
+
+function $appendToCurrentNodeAndPushHeadElement(this$static, attributes){
+  var elt, node;
+  $flushCharacters(this$static);
+  $processNonNcNames(attributes, this$static, this$static.namePolicy);
+  elt = $createElement(this$static, 'http://www.w3.org/1999/xhtml', 'head', attributes);
+  $appendElement(this$static, elt, this$static.stack_0[this$static.currentPtr].node);
+  this$static.headPointer = elt;
+  node = $StackNode_0(new StackNode, 'http://www.w3.org/1999/xhtml', ($clinit_125() , HEAD), elt);
+  $push_0(this$static, node);
+}
+
+function $appendVoidElementToCurrentMayFoster(this$static, ns, name_0, attributes){
+  var current, elt;
+  $flushCharacters(this$static);
+  $processNonNcNames(attributes, this$static, this$static.namePolicy);
+  elt = $createElement_0(this$static, ns, name_0, attributes);
+  current = this$static.stack_0[this$static.currentPtr];
+  current.fosterParenting?$insertIntoFosterParent(this$static, elt):$appendElement(this$static, elt, current.node);
+  $elementPopped(this$static, ns, name_0, elt);
+}
+
+function $appendVoidElementToCurrentMayFoster_0(this$static, ns, elementName, attributes){
+  var current, elt, popName;
+  $flushCharacters(this$static);
+  popName = elementName.name_0;
+  $processNonNcNames(attributes, this$static, this$static.namePolicy);
+  elementName.custom && (popName = $checkPopName(this$static, popName));
+  elt = $createElement(this$static, ns, popName, attributes);
+  current = this$static.stack_0[this$static.currentPtr];
+  current.fosterParenting?$insertIntoFosterParent(this$static, elt):$appendElement(this$static, elt, current.node);
+  $elementPopped(this$static, ns, popName, elt);
+}
+
+function $appendVoidElementToCurrentMayFosterCamelCase(this$static, ns, elementName, attributes){
+  var current, elt, popName;
+  $flushCharacters(this$static);
+  popName = elementName.camelCaseName;
+  $processNonNcNames(attributes, this$static, this$static.namePolicy);
+  elementName.custom && (popName = $checkPopName(this$static, popName));
+  elt = $createElement(this$static, ns, popName, attributes);
+  current = this$static.stack_0[this$static.currentPtr];
+  current.fosterParenting?$insertIntoFosterParent(this$static, elt):$appendElement(this$static, elt, current.node);
+  $elementPopped(this$static, ns, popName, elt);
+}
+
+function $charBufferContainsNonWhitespace(this$static){
+  var i;
+  for (i = 0; i < this$static.charBufferLen; ++i) {
+    switch (this$static.charBuffer[i]) {
+      case 32:
+      case 9:
+      case 10:
+      case 13:
+      case 12:
+        continue;
+      default:return true;
+    }
+  }
+  return false;
+}
+
+function $characters(this$static, buf, start, length_0){
+  var end, i;
+  if (this$static.needToDropLF) {
+    if (buf[start] == 10) {
+      ++start;
+      --length_0;
+      if (length_0 == 0) {
+        return;
+      }
+    }
+    this$static.needToDropLF = false;
+  }
+  if (this$static.inForeign) {
+    $accumulateCharacters(this$static, buf, start, length_0);
+    return;
+  }
+  switch (this$static.mode) {
+    case 6:
+    case 12:
+    case 8:
+      $reconstructTheActiveFormattingElements(this$static);
+    case 20:
+      $accumulateCharacters(this$static, buf, start, length_0);
+      return;
+    default:end = start + length_0;
+      charactersloop: for (i = start; i < end; ++i) {
+        switch (buf[i]) {
+          case 32:
+          case 9:
+          case 10:
+          case 13:
+          case 12:
+            switch (this$static.mode) {
+              case 0:
+              case 1:
+              case 2:
+                start = i + 1;
+                continue;
+              case 21:
+              case 3:
+              case 4:
+              case 5:
+              case 9:
+              case 16:
+              case 17:
+                continue;
+              case 6:
+              case 12:
+              case 8:
+                if (start < i) {
+                  $accumulateCharacters(this$static, buf, start, i - start);
+                  start = i;
+                }
+
+                $reconstructTheActiveFormattingElements(this$static);
+                break charactersloop;
+              case 13:
+              case 14:
+                break charactersloop;
+              case 7:
+              case 10:
+              case 11:
+                $reconstructTheActiveFormattingElements(this$static);
+                $accumulateCharacter(this$static, buf[i]);
+                start = i + 1;
+                continue;
+              case 15:
+                if (start < i) {
+                  $accumulateCharacters(this$static, buf, start, i - start);
+                  start = i;
+                }
+
+                $reconstructTheActiveFormattingElements(this$static);
+                continue;
+              case 18:
+              case 19:
+                if (start < i) {
+                  $accumulateCharacters(this$static, buf, start, i - start);
+                  start = i;
+                }
+
+                $reconstructTheActiveFormattingElements(this$static);
+                continue;
+            }
+
+          default:switch (this$static.mode) {
+              case 0:
+                $documentModeInternal(this$static, ($clinit_113() , QUIRKS_MODE));
+                this$static.mode = 1;
+                --i;
+                continue;
+              case 1:
+                $appendHtmlElementToDocumentAndPush(this$static, $emptyAttributes(this$static.tokenizer));
+                this$static.mode = 2;
+                --i;
+                continue;
+              case 2:
+                if (start < i) {
+                  $accumulateCharacters(this$static, buf, start, i - start);
+                  start = i;
+                }
+
+                $appendToCurrentNodeAndPushHeadElement(this$static, ($clinit_128() , EMPTY_ATTRIBUTES));
+                this$static.mode = 3;
+                --i;
+                continue;
+              case 3:
+                if (start < i) {
+                  $accumulateCharacters(this$static, buf, start, i - start);
+                  start = i;
+                }
+
+                $pop(this$static);
+                this$static.mode = 5;
+                --i;
+                continue;
+              case 4:
+                if (start < i) {
+                  $accumulateCharacters(this$static, buf, start, i - start);
+                  start = i;
+                }
+
+                $pop(this$static);
+                this$static.mode = 3;
+                --i;
+                continue;
+              case 5:
+                if (start < i) {
+                  $accumulateCharacters(this$static, buf, start, i - start);
+                  start = i;
+                }
+
+                $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', ($clinit_125() , BODY), $emptyAttributes(this$static.tokenizer));
+                this$static.mode = 21;
+                --i;
+                continue;
+              case 21:
+                this$static.framesetOk = false;
+                this$static.mode = 6;
+                --i;
+                continue;
+              case 6:
+              case 12:
+              case 8:
+                if (start < i) {
+                  $accumulateCharacters(this$static, buf, start, i - start);
+                  start = i;
+                }
+
+                $reconstructTheActiveFormattingElements(this$static);
+                break charactersloop;
+              case 7:
+              case 10:
+              case 11:
+                $reconstructTheActiveFormattingElements(this$static);
+                $accumulateCharacter(this$static, buf[i]);
+                start = i + 1;
+                continue;
+              case 9:
+                if (start < i) {
+                  $accumulateCharacters(this$static, buf, start, i - start);
+                  start = i;
+                }
+
+                if (this$static.currentPtr == 0) {
+                  start = i + 1;
+                  continue;
+                }
+
+                $pop(this$static);
+                this$static.mode = 7;
+                --i;
+                continue;
+              case 13:
+              case 14:
+                break charactersloop;
+              case 15:
+                this$static.mode = this$static.framesetOk?21:6;
+                --i;
+                continue;
+              case 16:
+                if (start < i) {
+                  $accumulateCharacters(this$static, buf, start, i - start);
+                  start = i;
+                }
+
+                start = i + 1;
+                continue;
+              case 17:
+                if (start < i) {
+                  $accumulateCharacters(this$static, buf, start, i - start);
+                  start = i;
+                }
+
+                start = i + 1;
+                continue;
+              case 18:
+                this$static.mode = this$static.framesetOk?21:6;
+                --i;
+                continue;
+              case 19:
+                this$static.mode = 16;
+                --i;
+                continue;
+            }
+
+        }
+      }
+
+      start < end && $accumulateCharacters(this$static, buf, start, end - start);
+  }
+}
+
+function $checkMetaCharset(this$static, attributes){
+  var content, internalCharsetHtml5, internalCharsetLegacy;
+  content = $getValue_1(attributes, ($clinit_124() , CONTENT));
+  internalCharsetLegacy = null;
+  content != null && (internalCharsetLegacy = extractCharsetFromContent(content));
+  if (internalCharsetLegacy == null) {
+    internalCharsetHtml5 = $getValue_1(attributes, CHARSET);
+    internalCharsetHtml5 != null && (this$static.tokenizer.shouldSuspend = true);
+  }
+   else {
+    this$static.tokenizer.shouldSuspend = true;
+  }
+}
+
+function $checkPopName(this$static, name_0){
+  if (isNCName(name_0)) {
+    return name_0;
+  }
+   else {
+    switch (this$static.namePolicy.ordinal) {
+      case 0:
+        return name_0;
+      case 2:
+        return escapeName(name_0);
+      case 1:
+        $fatal_0(this$static, 'Element name \u201C' + name_0 + '\u201D cannot be represented as XML 1.0.');
+    }
+  }
+  return null;
+}
+
+function $clearStackBackTo(this$static, eltPos){
+  while (this$static.currentPtr > eltPos) {
+    $pop(this$static);
+  }
+}
+
+function $clearTheListOfActiveFormattingElementsUpToTheLastMarker(this$static){
+  while (this$static.listPtr > -1) {
+    if (!this$static.listOfActiveFormattingElements[this$static.listPtr]) {
+      --this$static.listPtr;
+      return;
+    }
+    --this$static.listOfActiveFormattingElements[this$static.listPtr].refcount;
+    --this$static.listPtr;
+  }
+}
+
+function $closeTheCell(this$static, eltPos){
+  $generateImpliedEndTags(this$static);
+  while (this$static.currentPtr >= eltPos) {
+    $pop(this$static);
+  }
+  $clearTheListOfActiveFormattingElementsUpToTheLastMarker(this$static);
+  this$static.mode = 11;
+  return;
+}
+
+function $comment(this$static, buf, start, length_0){
+  var end, end_0, end_1;
+  this$static.needToDropLF = false;
+  if (!this$static.wantingComments) {
+    return;
+  }
+  if (!this$static.inForeign) {
+    switch (this$static.mode) {
+      case 0:
+      case 1:
+      case 18:
+      case 19:
+        $appendCommentToDocument(this$static, (end = start + length_0 , __checkBounds(buf.length, start, end) , __valueOf(buf, start, end)));
+        return;
+      case 15:
+        $flushCharacters(this$static);
+        $appendComment(this$static, this$static.stack_0[0].node, (end_0 = start + length_0 , __checkBounds(buf.length, start, end_0) , __valueOf(buf, start, end_0)));
+        return;
+    }
+  }
+  $flushCharacters(this$static);
+  $appendComment(this$static, this$static.stack_0[this$static.currentPtr].node, (end_1 = start + length_0 , __checkBounds(buf.length, start, end_1) , __valueOf(buf, start, end_1)));
+  return;
+}
+
+function $doctype(this$static, name_0, publicIdentifier, systemIdentifier, forceQuirks){
+  this$static.needToDropLF = false;
+  if (!this$static.inForeign) {
+    switch (this$static.mode) {
+      case 0:
+        switch (this$static.doctypeExpectation.ordinal) {
+          case 0:
+            if ($isQuirky(name_0, publicIdentifier, systemIdentifier, forceQuirks)) {
+              $documentModeInternal(this$static, ($clinit_113() , QUIRKS_MODE));
+            }
+             else if ($isAlmostStandards(publicIdentifier, systemIdentifier)) {
+              $documentModeInternal(this$static, ($clinit_113() , ALMOST_STANDARDS_MODE));
+            }
+             else {
+              $equals_1('-//W3C//DTD HTML 4.0//EN', publicIdentifier) && (systemIdentifier == null || $equals_1('http://www.w3.org/TR/REC-html40/strict.dtd', systemIdentifier)) || $equals_1('-//W3C//DTD HTML 4.01//EN', publicIdentifier) && (systemIdentifier == null || $equals_1('http://www.w3.org/TR/html4/strict.dtd', systemIdentifier)) || $equals_1('-//W3C//DTD XHTML 1.0 Strict//EN', publicIdentifier) && $equals_1('http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd', systemIdentifier) || $equals_1('-//W3C//DTD XHTML 1.1//EN', publicIdentifier) && $equals_1('http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd', systemIdentifier) || !((systemIdentifier == null || $equals_1('about:legacy-compat', systemIdentifier)) && publicIdentifier == null);
+              $documentModeInternal(this$static, ($clinit_113() , STANDARDS_MODE));
+            }
+
+            break;
+          case 2:
+            this$static.html4 = true;
+            this$static.tokenizer.html4 = true;
+            if ($isQuirky(name_0, publicIdentifier, systemIdentifier, forceQuirks)) {
+              $documentModeInternal(this$static, ($clinit_113() , QUIRKS_MODE));
+            }
+             else if ($isAlmostStandards(publicIdentifier, systemIdentifier)) {
+              $documentModeInternal(this$static, ($clinit_113() , ALMOST_STANDARDS_MODE));
+            }
+             else {
+              $equals_1('-//W3C//DTD HTML 4.01//EN', publicIdentifier) && !$equals_1('http://www.w3.org/TR/html4/strict.dtd', systemIdentifier);
+              $documentModeInternal(this$static, ($clinit_113() , STANDARDS_MODE));
+            }
+
+            break;
+          case 1:
+            this$static.html4 = true;
+            this$static.tokenizer.html4 = true;
+            if ($isQuirky(name_0, publicIdentifier, systemIdentifier, forceQuirks)) {
+              $documentModeInternal(this$static, ($clinit_113() , QUIRKS_MODE));
+            }
+             else if ($isAlmostStandards(publicIdentifier, systemIdentifier)) {
+              $equals_1('-//W3C//DTD HTML 4.01 Transitional//EN', publicIdentifier) && systemIdentifier != null && !$equals_1('http://www.w3.org/TR/html4/loose.dtd', systemIdentifier);
+              $documentModeInternal(this$static, ($clinit_113() , ALMOST_STANDARDS_MODE));
+            }
+             else {
+              $documentModeInternal(this$static, ($clinit_113() , STANDARDS_MODE));
+            }
+
+            break;
+          case 3:
+            this$static.html4 = $isHtml4Doctype(publicIdentifier);
+            this$static.html4 && (this$static.tokenizer.html4 = true);
+            if ($isQuirky(name_0, publicIdentifier, systemIdentifier, forceQuirks)) {
+              $documentModeInternal(this$static, ($clinit_113() , QUIRKS_MODE));
+            }
+             else if ($isAlmostStandards(publicIdentifier, systemIdentifier)) {
+              $equals_1('-//W3C//DTD HTML 4.01 Transitional//EN', publicIdentifier) && !$equals_1('http://www.w3.org/TR/html4/loose.dtd', systemIdentifier);
+              $documentModeInternal(this$static, ($clinit_113() , ALMOST_STANDARDS_MODE));
+            }
+             else {
+              $equals_1('-//W3C//DTD HTML 4.01//EN', publicIdentifier) && !$equals_1('http://www.w3.org/TR/html4/strict.dtd', systemIdentifier);
+              $documentModeInternal(this$static, ($clinit_113() , STANDARDS_MODE));
+            }
+
+            break;
+          case 4:
+            $isQuirky(name_0, publicIdentifier, systemIdentifier, forceQuirks)?$documentModeInternal(this$static, ($clinit_113() , QUIRKS_MODE)):$isAlmostStandards(publicIdentifier, systemIdentifier)?$documentModeInternal(this$static, ($clinit_113() , ALMOST_STANDARDS_MODE)):$documentModeInternal(this$static, ($clinit_113() , STANDARDS_MODE));
+        }
+
+        this$static.mode = 1;
+        return;
+    }
+  }
+  return;
+}
+
+function $documentModeInternal(this$static, m){
+  this$static.quirks = m == ($clinit_113() , QUIRKS_MODE);
+}
+
+function $endTag(this$static, elementName){
+  var eltPos, group, name_0, node, node_33;
+  this$static.needToDropLF = false;
+  group = elementName.group;
+  name_0 = elementName.name_0;
+  endtagloop: for (;;) {
+    if (this$static.inForeign && this$static.stack_0[this$static.currentPtr].ns != 'http://www.w3.org/1999/xhtml') {
+      eltPos = this$static.currentPtr;
+      for (;;) {
+        if (this$static.stack_0[eltPos].name_0 == name_0) {
+          while (this$static.currentPtr >= eltPos) {
+            $pop(this$static);
+          }
+          return;
+        }
+        if (this$static.stack_0[--eltPos].ns == 'http://www.w3.org/1999/xhtml') {
+          break;
+        }
+      }
+    }
+    switch (this$static.mode) {
+      case 11:
+        switch (group) {
+          case 37:
+            eltPos = $findLastOrRoot_0(this$static, 37);
+            if (eltPos == 0) {
+              break endtagloop;
+            }
+
+            $clearStackBackTo(this$static, eltPos);
+            $pop(this$static);
+            this$static.mode = 10;
+            break endtagloop;
+          case 34:
+            eltPos = $findLastOrRoot_0(this$static, 37);
+            if (eltPos == 0) {
+              break endtagloop;
+            }
+
+            $clearStackBackTo(this$static, eltPos);
+            $pop(this$static);
+            this$static.mode = 10;
+            continue;
+          case 39:
+            if ($findLastInTableScope(this$static, name_0) == 2147483647) {
+              break endtagloop;
+            }
+
+            eltPos = $findLastOrRoot_0(this$static, 37);
+            if (eltPos == 0) {
+              break endtagloop;
+            }
+
+            $clearStackBackTo(this$static, eltPos);
+            $pop(this$static);
+            this$static.mode = 10;
+            continue;
+          case 3:
+          case 6:
+          case 7:
+          case 8:
+          case 23:
+          case 40:
+            break endtagloop;
+        }
+
+      case 10:
+        switch (group) {
+          case 39:
+            eltPos = $findLastOrRoot(this$static, name_0);
+            if (eltPos == 0) {
+              break endtagloop;
+            }
+
+            $clearStackBackTo(this$static, eltPos);
+            $pop(this$static);
+            this$static.mode = 7;
+            break endtagloop;
+          case 34:
+            eltPos = $findLastInTableScopeOrRootTbodyTheadTfoot(this$static);
+            if (eltPos == 0) {
+              break endtagloop;
+            }
+
+            $clearStackBackTo(this$static, eltPos);
+            $pop(this$static);
+            this$static.mode = 7;
+            continue;
+          case 3:
+          case 6:
+          case 7:
+          case 8:
+          case 23:
+          case 40:
+          case 37:
+            break endtagloop;
+        }
+
+      case 7:
+        switch (group) {
+          case 34:
+            eltPos = $findLast(this$static, 'table');
+            if (eltPos == 2147483647) {
+              break endtagloop;
+            }
+
+            while (this$static.currentPtr >= eltPos) {
+              $pop(this$static);
+            }
+
+            $resetTheInsertionMode(this$static);
+            break endtagloop;
+          case 3:
+          case 6:
+          case 7:
+          case 8:
+          case 23:
+          case 39:
+          case 40:
+          case 37:
+            break endtagloop;
+        }
+
+      case 8:
+        switch (group) {
+          case 6:
+            eltPos = $findLastInTableScope(this$static, 'caption');
+            if (eltPos == 2147483647) {
+              break endtagloop;
+            }
+
+            $generateImpliedEndTags(this$static);
+            while (this$static.currentPtr >= eltPos) {
+              $pop(this$static);
+            }
+
+            $clearTheListOfActiveFormattingElementsUpToTheLastMarker(this$static);
+            this$static.mode = 7;
+            break endtagloop;
+          case 34:
+            eltPos = $findLastInTableScope(this$static, 'caption');
+            if (eltPos == 2147483647) {
+              break endtagloop;
+            }
+
+            $generateImpliedEndTags(this$static);
+            while (this$static.currentPtr >= eltPos) {
+              $pop(this$static);
+            }
+
+            $clearTheListOfActiveFormattingElementsUpToTheLastMarker(this$static);
+            this$static.mode = 7;
+            continue;
+          case 3:
+          case 7:
+          case 8:
+          case 23:
+          case 39:
+          case 40:
+          case 37:
+            break endtagloop;
+        }
+
+      case 12:
+        switch (group) {
+          case 40:
+            eltPos = $findLastInTableScope(this$static, name_0);
+            if (eltPos == 2147483647) {
+              break endtagloop;
+            }
+
+            $generateImpliedEndTags(this$static);
+            while (this$static.currentPtr >= eltPos) {
+              $pop(this$static);
+            }
+
+            $clearTheListOfActiveFormattingElementsUpToTheLastMarker(this$static);
+            this$static.mode = 11;
+            break endtagloop;
+          case 34:
+          case 39:
+          case 37:
+            if ($findLastInTableScope(this$static, name_0) == 2147483647) {
+              break endtagloop;
+            }
+
+            $closeTheCell(this$static, $findLastInTableScopeTdTh(this$static));
+            continue;
+          case 3:
+          case 6:
+          case 7:
+          case 8:
+          case 23:
+            break endtagloop;
+        }
+
+      case 21:
+      case 6:
+        switch (group) {
+          case 3:
+            if (!(this$static.currentPtr >= 1 && this$static.stack_0[1].group == 3)) {
+              break endtagloop;
+            }
+
+            this$static.mode = 15;
+            break endtagloop;
+          case 23:
+            if (!(this$static.currentPtr >= 1 && this$static.stack_0[1].group == 3)) {
+              break endtagloop;
+            }
+
+            this$static.mode = 15;
+            continue;
+          case 50:
+          case 46:
+          case 44:
+          case 61:
+          case 5:
+          case 51:
+            eltPos = $findLastInScope(this$static, name_0);
+            if (!(eltPos == 2147483647)) {
+              $generateImpliedEndTags(this$static);
+              while (this$static.currentPtr >= eltPos) {
+                $pop(this$static);
+              }
+            }
+
+            break endtagloop;
+          case 9:
+            if (!this$static.formPointer) {
+              break endtagloop;
+            }
+
+            this$static.formPointer = null;
+            eltPos = $findLastInScope(this$static, name_0);
+            if (eltPos == 2147483647) {
+              break endtagloop;
+            }
+
+            $generateImpliedEndTags(this$static);
+            $removeFromStack(this$static, eltPos);
+            break endtagloop;
+          case 29:
+            eltPos = $findLastInScope(this$static, 'p');
+            if (eltPos == 2147483647) {
+              if (this$static.inForeign) {
+                while (this$static.stack_0[this$static.currentPtr].ns != 'http://www.w3.org/1999/xhtml') {
+                  $pop(this$static);
+                }
+                this$static.inForeign = false;
+              }
+              $appendVoidElementToCurrentMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, ($clinit_128() , EMPTY_ATTRIBUTES));
+              break endtagloop;
+            }
+
+            $generateImpliedEndTagsExceptFor(this$static, 'p');
+            while (this$static.currentPtr >= eltPos) {
+              $pop(this$static);
+            }
+
+            break endtagloop;
+          case 15:
+            eltPos = $findLastInListScope(this$static, name_0);
+            if (!(eltPos == 2147483647)) {
+              $generateImpliedEndTagsExceptFor(this$static, name_0);
+              while (this$static.currentPtr >= eltPos) {
+                $pop(this$static);
+              }
+            }
+
+            break endtagloop;
+          case 41:
+            eltPos = $findLastInScope(this$static, name_0);
+            if (!(eltPos == 2147483647)) {
+              $generateImpliedEndTagsExceptFor(this$static, name_0);
+              while (this$static.currentPtr >= eltPos) {
+                $pop(this$static);
+              }
+            }
+
+            break endtagloop;
+          case 42:
+            eltPos = $findLastInScopeHn(this$static);
+            if (!(eltPos == 2147483647)) {
+              $generateImpliedEndTags(this$static);
+              while (this$static.currentPtr >= eltPos) {
+                $pop(this$static);
+              }
+            }
+
+            break endtagloop;
+          case 1:
+          case 45:
+          case 64:
+          case 24:
+            $adoptionAgencyEndTag(this$static, name_0);
+            break endtagloop;
+          case 63:
+          case 43:
+            eltPos = $findLastInScope(this$static, name_0);
+            if (!(eltPos == 2147483647)) {
+              $generateImpliedEndTags(this$static);
+              while (this$static.currentPtr >= eltPos) {
+                $pop(this$static);
+              }
+              $clearTheListOfActiveFormattingElementsUpToTheLastMarker(this$static);
+            }
+
+            break endtagloop;
+          case 4:
+            if (this$static.inForeign) {
+              while (this$static.stack_0[this$static.currentPtr].ns != 'http://www.w3.org/1999/xhtml') {
+                $pop(this$static);
+              }
+              this$static.inForeign = false;
+            }
+
+            $reconstructTheActiveFormattingElements(this$static);
+            $appendVoidElementToCurrentMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, ($clinit_128() , EMPTY_ATTRIBUTES));
+            break endtagloop;
+          case 49:
+          case 55:
+          case 48:
+          case 12:
+          case 13:
+          case 65:
+          case 22:
+          case 14:
+          case 47:
+          case 60:
+          case 25:
+          case 32:
+          case 34:
+          case 35:
+            break endtagloop;
+          case 26:
+          default:if (name_0 == this$static.stack_0[this$static.currentPtr].name_0) {
+              $pop(this$static);
+              break endtagloop;
+            }
+
+            eltPos = this$static.currentPtr;
+            for (;;) {
+              node = this$static.stack_0[eltPos];
+              if (node.name_0 == name_0) {
+                $generateImpliedEndTags(this$static);
+                while (this$static.currentPtr >= eltPos) {
+                  $pop(this$static);
+                }
+                break endtagloop;
+              }
+               else if (node.scoping || node.special) {
+                break endtagloop;
+              }
+              --eltPos;
+            }
+
+        }
+
+      case 9:
+        switch (group) {
+          case 8:
+            if (this$static.currentPtr == 0) {
+              break endtagloop;
+            }
+
+            $pop(this$static);
+            this$static.mode = 7;
+            break endtagloop;
+          case 7:
+            break endtagloop;
+          default:if (this$static.currentPtr == 0) {
+              break endtagloop;
+            }
+
+            $pop(this$static);
+            this$static.mode = 7;
+            continue;
+        }
+
+      case 14:
+        switch (group) {
+          case 6:
+          case 34:
+          case 39:
+          case 37:
+          case 40:
+            if ($findLastInTableScope(this$static, name_0) != 2147483647) {
+              eltPos = $findLastInTableScope(this$static, 'select');
+              if (eltPos == 2147483647) {
+                break endtagloop;
+              }
+              while (this$static.currentPtr >= eltPos) {
+                $pop(this$static);
+              }
+              $resetTheInsertionMode(this$static);
+              continue;
+            }
+             else {
+              break endtagloop;
+            }
+
+        }
+
+      case 13:
+        switch (group) {
+          case 28:
+            if ('option' == this$static.stack_0[this$static.currentPtr].name_0) {
+              $pop(this$static);
+              break endtagloop;
+            }
+             else {
+              break endtagloop;
+            }
+
+          case 27:
+            'option' == this$static.stack_0[this$static.currentPtr].name_0 && 'optgroup' == this$static.stack_0[this$static.currentPtr - 1].name_0 && $pop(this$static);
+            'optgroup' == this$static.stack_0[this$static.currentPtr].name_0 && $pop(this$static);
+            break endtagloop;
+          case 32:
+            eltPos = $findLastInTableScope(this$static, 'select');
+            if (eltPos == 2147483647) {
+              break endtagloop;
+            }
+
+            while (this$static.currentPtr >= eltPos) {
+              $pop(this$static);
+            }
+
+            $resetTheInsertionMode(this$static);
+            break endtagloop;
+          default:break endtagloop;
+        }
+
+      case 15:
+        switch (group) {
+          case 23:
+            if (this$static.fragment) {
+              break endtagloop;
+            }
+             else {
+              this$static.mode = 18;
+              break endtagloop;
+            }
+
+          default:this$static.mode = this$static.framesetOk?21:6;
+            continue;
+        }
+
+      case 16:
+        switch (group) {
+          case 11:
+            if (this$static.currentPtr == 0) {
+              break endtagloop;
+            }
+
+            $pop(this$static);
+            !this$static.fragment && 'frameset' != this$static.stack_0[this$static.currentPtr].name_0 && (this$static.mode = 17);
+            break endtagloop;
+          default:break endtagloop;
+        }
+
+      case 17:
+        switch (group) {
+          case 23:
+            this$static.mode = 19;
+            break endtagloop;
+          default:break endtagloop;
+        }
+
+      case 0:
+        $documentModeInternal(this$static, ($clinit_113() , QUIRKS_MODE));
+        this$static.mode = 1;
+        continue;
+      case 1:
+        switch (group) {
+          case 20:
+          case 4:
+          case 23:
+          case 3:
+            $appendHtmlElementToDocumentAndPush(this$static, $emptyAttributes(this$static.tokenizer));
+            this$static.mode = 2;
+            continue;
+          default:break endtagloop;
+        }
+
+      case 2:
+        switch (group) {
+          case 20:
+          case 4:
+          case 23:
+          case 3:
+            $appendToCurrentNodeAndPushHeadElement(this$static, ($clinit_128() , EMPTY_ATTRIBUTES));
+            this$static.mode = 3;
+            continue;
+          default:break endtagloop;
+        }
+
+      case 3:
+        switch (group) {
+          case 20:
+            $pop(this$static);
+            this$static.mode = 5;
+            break endtagloop;
+          case 4:
+          case 23:
+          case 3:
+            $pop(this$static);
+            this$static.mode = 5;
+            continue;
+          default:break endtagloop;
+        }
+
+      case 4:
+        switch (group) {
+          case 26:
+            $pop(this$static);
+            this$static.mode = 3;
+            break endtagloop;
+          case 4:
+            $pop(this$static);
+            this$static.mode = 3;
+            continue;
+          default:break endtagloop;
+        }
+
+      case 5:
+        switch (group) {
+          case 23:
+          case 3:
+          case 4:
+            $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', ($clinit_125() , BODY), $emptyAttributes(this$static.tokenizer));
+            this$static.mode = 21;
+            continue;
+          default:break endtagloop;
+        }
+
+      case 18:
+        this$static.mode = this$static.framesetOk?21:6;
+        continue;
+      case 19:
+        this$static.mode = 16;
+        continue;
+      case 20:
+        $pop(this$static);
+        this$static.originalMode == 5 && ($flushCharacters(this$static) , node_33 = this$static.stack_0[this$static.currentPtr] , --this$static.currentPtr , --node_33.refcount , undefined);
+        this$static.mode = this$static.originalMode;
+        break endtagloop;
+    }
+  }
+  this$static.inForeign && !$hasForeignInScope(this$static) && (this$static.inForeign = false);
+}
+
+function $endTokenization(this$static){
+  this$static.formPointer = null;
+  this$static.headPointer = null;
+  if (this$static.stack_0 != null) {
+    while (this$static.currentPtr > -1) {
+      --this$static.stack_0[this$static.currentPtr].refcount;
+      --this$static.currentPtr;
+    }
+    this$static.stack_0 = null;
+  }
+  if (this$static.listOfActiveFormattingElements != null) {
+    while (this$static.listPtr > -1) {
+      !!this$static.listOfActiveFormattingElements[this$static.listPtr] && --this$static.listOfActiveFormattingElements[this$static.listPtr].refcount;
+      --this$static.listPtr;
+    }
+    this$static.listOfActiveFormattingElements = null;
+  }
+  $clearImpl(this$static.idLocations);
+  this$static.charBuffer != null && (this$static.charBuffer = null);
+}
+
+function $eof(this$static){
+  var group, i;
+  $flushCharacters(this$static);
+  if (this$static.inForeign) {
+    while (this$static.stack_0[this$static.currentPtr].ns != 'http://www.w3.org/1999/xhtml') {
+      $popOnEof(this$static);
+    }
+    this$static.inForeign = false;
+  }
+  eofloop: for (;;) {
+    switch (this$static.mode) {
+      case 0:
+        $documentModeInternal(this$static, ($clinit_113() , QUIRKS_MODE));
+        this$static.mode = 1;
+        continue;
+      case 1:
+        $appendHtmlElementToDocumentAndPush(this$static, $emptyAttributes(this$static.tokenizer));
+        this$static.mode = 2;
+        continue;
+      case 2:
+        $appendToCurrentNodeAndPushHeadElement(this$static, ($clinit_128() , EMPTY_ATTRIBUTES));
+        this$static.mode = 3;
+        continue;
+      case 3:
+        while (this$static.currentPtr > 0) {
+          $popOnEof(this$static);
+        }
+
+        this$static.mode = 5;
+        continue;
+      case 4:
+        while (this$static.currentPtr > 1) {
+          $popOnEof(this$static);
+        }
+
+        this$static.mode = 3;
+        continue;
+      case 5:
+        $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', ($clinit_125() , BODY), $emptyAttributes(this$static.tokenizer));
+        this$static.mode = 6;
+        continue;
+      case 9:
+        if (this$static.currentPtr == 0) {
+          break eofloop;
+        }
+         else {
+          $popOnEof(this$static);
+          this$static.mode = 7;
+          continue;
+        }
+
+      case 21:
+      case 8:
+      case 12:
+      case 6:
+        openelementloop: for (i = this$static.currentPtr; i >= 0; --i) {
+          group = this$static.stack_0[i].group;
+          switch (group) {
+            case 41:
+            case 15:
+            case 29:
+            case 39:
+            case 40:
+            case 3:
+            case 23:
+              break;
+            default:break openelementloop;
+          }
+        }
+
+        break eofloop;
+      case 20:
+        this$static.originalMode == 5 && $popOnEof(this$static);
+        $popOnEof(this$static);
+        this$static.mode = this$static.originalMode;
+        continue;
+      case 10:
+      case 11:
+      case 7:
+      case 13:
+      case 14:
+      case 16:
+        break eofloop;
+      case 15:
+      case 17:
+      case 18:
+      case 19:
+      default:this$static.currentPtr == 0 && fromDouble((new Date).getTime());
+        break eofloop;
+    }
+  }
+  while (this$static.currentPtr > 0) {
+    $popOnEof(this$static);
+  }
+  !this$static.fragment && $popOnEof(this$static);
+}
+
+function $fatal(this$static, e){
+  var spe;
+  spe = $SAXParseException_0(new SAXParseException, e.getMessage(), this$static.tokenizer, e);
+  throw spe;
+}
+
+function $fatal_0(this$static, s){
+  var spe;
+  spe = $SAXParseException(new SAXParseException, s, this$static.tokenizer);
+  throw spe;
+}
+
+function $findInListOfActiveFormattingElements(this$static, node){
+  var i;
+  for (i = this$static.listPtr; i >= 0; --i) {
+    if (node == this$static.listOfActiveFormattingElements[i]) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+function $findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker(this$static, name_0){
+  var i, node;
+  for (i = this$static.listPtr; i >= 0; --i) {
+    node = this$static.listOfActiveFormattingElements[i];
+    if (!node) {
+      return -1;
+    }
+     else if (node.name_0 == name_0) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+function $findLast(this$static, name_0){
+  var i;
+  for (i = this$static.currentPtr; i > 0; --i) {
+    if (this$static.stack_0[i].name_0 == name_0) {
+      return i;
+    }
+  }
+  return 2147483647;
+}
+
+function $findLastInListScope(this$static, name_0){
+  var i;
+  for (i = this$static.currentPtr; i > 0; --i) {
+    if (this$static.stack_0[i].name_0 == name_0) {
+      return i;
+    }
+     else if (this$static.stack_0[i].scoping || this$static.stack_0[i].name_0 == 'ul' || this$static.stack_0[i].name_0 == 'ol') {
+      return 2147483647;
+    }
+  }
+  return 2147483647;
+}
+
+function $findLastInScope(this$static, name_0){
+  var i;
+  for (i = this$static.currentPtr; i > 0; --i) {
+    if (this$static.stack_0[i].name_0 == name_0) {
+      return i;
+    }
+     else if (this$static.stack_0[i].scoping) {
+      return 2147483647;
+    }
+  }
+  return 2147483647;
+}
+
+function $findLastInScopeHn(this$static){
+  var i;
+  for (i = this$static.currentPtr; i > 0; --i) {
+    if (this$static.stack_0[i].group == 42) {
+      return i;
+    }
+     else if (this$static.stack_0[i].scoping) {
+      return 2147483647;
+    }
+  }
+  return 2147483647;
+}
+
+function $findLastInTableScope(this$static, name_0){
+  var i;
+  for (i = this$static.currentPtr; i > 0; --i) {
+    if (this$static.stack_0[i].name_0 == name_0) {
+      return i;
+    }
+     else if (this$static.stack_0[i].name_0 == 'table') {
+      return 2147483647;
+    }
+  }
+  return 2147483647;
+}
+
+function $findLastInTableScopeOrRootTbodyTheadTfoot(this$static){
+  var i;
+  for (i = this$static.currentPtr; i > 0; --i) {
+    if (this$static.stack_0[i].group == 39) {
+      return i;
+    }
+  }
+  return 0;
+}
+
+function $findLastInTableScopeTdTh(this$static){
+  var i, name_0;
+  for (i = this$static.currentPtr; i > 0; --i) {
+    name_0 = this$static.stack_0[i].name_0;
+    if ('td' == name_0 || 'th' == name_0) {
+      return i;
+    }
+     else if (name_0 == 'table') {
+      return 2147483647;
+    }
+  }
+  return 2147483647;
+}
+
+function $findLastOrRoot(this$static, name_0){
+  var i;
+  for (i = this$static.currentPtr; i > 0; --i) {
+    if (this$static.stack_0[i].name_0 == name_0) {
+      return i;
+    }
+  }
+  return 0;
+}
+
+function $findLastOrRoot_0(this$static, group){
+  var i;
+  for (i = this$static.currentPtr; i > 0; --i) {
+    if (this$static.stack_0[i].group == group) {
+      return i;
+    }
+  }
+  return 0;
+}
+
+function $flushCharacters(this$static){
+  var current, elt, eltPos, node;
+  if (this$static.charBufferLen > 0) {
+    current = this$static.stack_0[this$static.currentPtr];
+    if (current.fosterParenting && $charBufferContainsNonWhitespace(this$static)) {
+      eltPos = $findLastOrRoot_0(this$static, 34);
+      node = this$static.stack_0[eltPos];
+      elt = node.node;
+      if (eltPos == 0) {
+        $appendCharacters(this$static, elt, valueOf_0(this$static.charBuffer, 0, this$static.charBufferLen));
+        this$static.charBufferLen = 0;
+        return;
+      }
+      $insertFosterParentedCharacters(this$static, this$static.charBuffer, 0, this$static.charBufferLen, elt, this$static.stack_0[eltPos - 1].node);
+      this$static.charBufferLen = 0;
+      return;
+    }
+    $appendCharacters(this$static, this$static.stack_0[this$static.currentPtr].node, valueOf_0(this$static.charBuffer, 0, this$static.charBufferLen));
+    this$static.charBufferLen = 0;
+  }
+}
+
+function $generateImpliedEndTags(this$static){
+  for (;;) {
+    switch (this$static.stack_0[this$static.currentPtr].group) {
+      case 29:
+      case 15:
+      case 41:
+      case 28:
+      case 27:
+      case 53:
+        $pop(this$static);
+        continue;
+      default:return;
+    }
+  }
+}
+
+function $generateImpliedEndTagsExceptFor(this$static, name_0){
+  var node;
+  for (;;) {
+    node = this$static.stack_0[this$static.currentPtr];
+    switch (node.group) {
+      case 29:
+      case 15:
+      case 41:
+      case 28:
+      case 27:
+      case 53:
+        if (node.name_0 == name_0) {
+          return;
+        }
+
+        $pop(this$static);
+        continue;
+      default:return;
+    }
+  }
+}
+
+function $hasForeignInScope(this$static){
+  var i;
+  for (i = this$static.currentPtr; i > 0; --i) {
+    if (this$static.stack_0[i].ns != 'http://www.w3.org/1999/xhtml') {
+      return true;
+    }
+     else if (this$static.stack_0[i].scoping) {
+      return false;
+    }
+  }
+  return false;
+}
+
+function $implicitlyCloseP(this$static){
+  var eltPos;
+  eltPos = $findLastInScope(this$static, 'p');
+  if (eltPos == 2147483647) {
+    return;
+  }
+  $generateImpliedEndTagsExceptFor(this$static, 'p');
+  while (this$static.currentPtr >= eltPos) {
+    $pop(this$static);
+  }
+}
+
+function $insertIntoFosterParent(this$static, child){
+  var elt, eltPos, node;
+  eltPos = $findLastOrRoot_0(this$static, 34);
+  node = this$static.stack_0[eltPos];
+  elt = node.node;
+  if (eltPos == 0) {
+    $appendElement(this$static, child, elt);
+    return;
+  }
+  $insertFosterParentedChild(this$static, child, elt, this$static.stack_0[eltPos - 1].node);
+}
+
+function $insertIntoStack(this$static, node, position){
+  if (position == this$static.currentPtr + 1) {
+    $flushCharacters(this$static);
+    $push_0(this$static, node);
+  }
+   else {
+    arraycopy(this$static.stack_0, position, this$static.stack_0, position + 1, this$static.currentPtr - position + 1);
+    ++this$static.currentPtr;
+    this$static.stack_0[position] = node;
+  }
+}
+
+function $isAlmostStandards(publicIdentifier, systemIdentifier){
+  if (lowerCaseLiteralEqualsIgnoreAsciiCaseString('-//w3c//dtd xhtml 1.0 transitional//en', publicIdentifier)) {
+    return true;
+  }
+  if (lowerCaseLiteralEqualsIgnoreAsciiCaseString('-//w3c//dtd xhtml 1.0 frameset//en', publicIdentifier)) {
+    return true;
+  }
+  if (systemIdentifier != null) {
+    if (lowerCaseLiteralEqualsIgnoreAsciiCaseString('-//w3c//dtd html 4.01 transitional//en', publicIdentifier)) {
+      return true;
+    }
+    if (lowerCaseLiteralEqualsIgnoreAsciiCaseString('-//w3c//dtd html 4.01 frameset//en', publicIdentifier)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+function $isHtml4Doctype(publicIdentifier){
+  if (publicIdentifier != null && binarySearch_0(HTML4_PUBLIC_IDS, publicIdentifier, ($clinit_95() , $clinit_95() , NATURAL)) > -1) {
+    return true;
+  }
+  return false;
+}
+
+function $isInStack(this$static, node){
+  var i;
+  for (i = this$static.currentPtr; i >= 0; --i) {
+    if (this$static.stack_0[i] == node) {
+      return true;
+    }
+  }
+  return false;
+}
+
+function $isQuirky(name_0, publicIdentifier, systemIdentifier, forceQuirks){
+  var i;
+  if (forceQuirks) {
+    return true;
+  }
+  if (name_0 != 'html') {
+    return true;
+  }
+  if (publicIdentifier != null) {
+    for (i = 0; i < QUIRKY_PUBLIC_IDS.length; ++i) {
+      if (lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(QUIRKY_PUBLIC_IDS[i], publicIdentifier)) {
+        return true;
+      }
+    }
+    if (lowerCaseLiteralEqualsIgnoreAsciiCaseString('-//w3o//dtd w3 html strict 3.0//en//', publicIdentifier) || lowerCaseLiteralEqualsIgnoreAsciiCaseString('-/w3c/dtd html 4.0 transitional/en', publicIdentifier) || lowerCaseLiteralEqualsIgnoreAsciiCaseString('html', publicIdentifier)) {
+      return true;
+    }
+  }
+  if (systemIdentifier == null) {
+    if (lowerCaseLiteralEqualsIgnoreAsciiCaseString('-//w3c//dtd html 4.01 transitional//en', publicIdentifier)) {
+      return true;
+    }
+     else if (lowerCaseLiteralEqualsIgnoreAsciiCaseString('-//w3c//dtd html 4.01 frameset//en', publicIdentifier)) {
+      return true;
+    }
+  }
+   else if (lowerCaseLiteralEqualsIgnoreAsciiCaseString('http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd', systemIdentifier)) {
+    return true;
+  }
+  return false;
+}
+
+function $pop(this$static){
+  var node;
+  $flushCharacters(this$static);
+  node = this$static.stack_0[this$static.currentPtr];
+  --this$static.currentPtr;
+  $elementPopped(this$static, node.ns, node.popName, node.node);
+  --node.refcount;
+}
+
+function $popOnEof(this$static){
+  var node;
+  $flushCharacters(this$static);
+  node = this$static.stack_0[this$static.currentPtr];
+  --this$static.currentPtr;
+  $elementPopped(this$static, node.ns, node.popName, node.node);
+  --node.refcount;
+}
+
+function $push_0(this$static, node){
+  var newStack;
+  ++this$static.currentPtr;
+  if (this$static.currentPtr == this$static.stack_0.length) {
+    newStack = initDim(_3Lnu_validator_htmlparser_impl_StackNode_2_classLit, 62, 15, this$static.stack_0.length + 64, 0);
+    arraycopy(this$static.stack_0, 0, newStack, 0, this$static.stack_0.length);
+    this$static.stack_0 = newStack;
+  }
+  this$static.stack_0[this$static.currentPtr] = node;
+}
+
+function $reconstructTheActiveFormattingElements(this$static){
+  var clone, currentNode, entry, entryClone, entryPos, mostRecent;
+  if (this$static.listPtr == -1) {
+    return;
+  }
+  mostRecent = this$static.listOfActiveFormattingElements[this$static.listPtr];
+  if (!mostRecent || $isInStack(this$static, mostRecent)) {
+    return;
+  }
+  entryPos = this$static.listPtr;
+  for (;;) {
+    --entryPos;
+    if (entryPos == -1) {
+      break;
+    }
+    if (!this$static.listOfActiveFormattingElements[entryPos]) {
+      break;
+    }
+    if ($isInStack(this$static, this$static.listOfActiveFormattingElements[entryPos])) {
+      break;
+    }
+  }
+  entryPos < this$static.listPtr && $flushCharacters(this$static);
+  while (entryPos < this$static.listPtr) {
+    ++entryPos;
+    entry = this$static.listOfActiveFormattingElements[entryPos];
+    clone = $createElement(this$static, 'http://www.w3.org/1999/xhtml', entry.name_0, $cloneAttributes(entry.attributes));
+    entryClone = $StackNode(new StackNode, entry.group, entry.ns, entry.name_0, clone, entry.scoping, entry.special, entry.fosterParenting, entry.popName, entry.attributes);
+    entry.attributes = null;
+    currentNode = this$static.stack_0[this$static.currentPtr];
+    currentNode.fosterParenting?$insertIntoFosterParent(this$static, clone):$appendElement(this$static, clone, currentNode.node);
+    $push_0(this$static, entryClone);
+    this$static.listOfActiveFormattingElements[entryPos] = entryClone;
+    --entry.refcount;
+    ++entryClone.refcount;
+  }
+}
+
+function $removeFromListOfActiveFormattingElements(this$static, pos){
+  --this$static.listOfActiveFormattingElements[pos].refcount;
+  if (pos == this$static.listPtr) {
+    --this$static.listPtr;
+    return;
+  }
+  arraycopy(this$static.listOfActiveFormattingElements, pos + 1, this$static.listOfActiveFormattingElements, pos, this$static.listPtr - pos);
+  --this$static.listPtr;
+}
+
+function $removeFromStack(this$static, pos){
+  if (this$static.currentPtr == pos) {
+    $pop(this$static);
+  }
+   else {
+    --this$static.stack_0[pos].refcount;
+    arraycopy(this$static.stack_0, pos + 1, this$static.stack_0, pos, this$static.currentPtr - pos);
+    --this$static.currentPtr;
+  }
+}
+
+function $removeFromStack_0(this$static, node){
+  var pos;
+  if (this$static.stack_0[this$static.currentPtr] == node) {
+    $pop(this$static);
+  }
+   else {
+    pos = this$static.currentPtr - 1;
+    while (pos >= 0 && this$static.stack_0[pos] != node) {
+      --pos;
+    }
+    if (pos == -1) {
+      return;
+    }
+    --node.refcount;
+    arraycopy(this$static.stack_0, pos + 1, this$static.stack_0, pos, this$static.currentPtr - pos);
+    --this$static.currentPtr;
+  }
+}
+
+function $resetTheInsertionMode(this$static){
+  var i, name_0, node, ns;
+  this$static.inForeign = false;
+  for (i = this$static.currentPtr; i >= 0; --i) {
+    node = this$static.stack_0[i];
+    name_0 = node.name_0;
+    ns = node.ns;
+    if (i == 0) {
+      if (this$static.contextNamespace == 'http://www.w3.org/1999/xhtml' && (this$static.contextName == 'td' || this$static.contextName == 'th')) {
+        this$static.mode = this$static.framesetOk?21:6;
+        return;
+      }
+       else {
+        name_0 = this$static.contextName;
+        ns = this$static.contextNamespace;
+      }
+    }
+    if ('select' == name_0) {
+      this$static.mode = 13;
+      return;
+    }
+     else if ('td' == name_0 || 'th' == name_0) {
+      this$static.mode = 12;
+      return;
+    }
+     else if ('tr' == name_0) {
+      this$static.mode = 11;
+      return;
+    }
+     else if ('tbody' == name_0 || 'thead' == name_0 || 'tfoot' == name_0) {
+      this$static.mode = 10;
+      return;
+    }
+     else if ('caption' == name_0) {
+      this$static.mode = 8;
+      return;
+    }
+     else if ('colgroup' == name_0) {
+      this$static.mode = 9;
+      return;
+    }
+     else if ('table' == name_0) {
+      this$static.mode = 7;
+      return;
+    }
+     else if ('http://www.w3.org/1999/xhtml' != ns) {
+      this$static.inForeign = true;
+      this$static.mode = this$static.framesetOk?21:6;
+      return;
+    }
+     else if ('head' == name_0) {
+      this$static.mode = this$static.framesetOk?21:6;
+      return;
+    }
+     else if ('body' == name_0) {
+      this$static.mode = this$static.framesetOk?21:6;
+      return;
+    }
+     else if ('frameset' == name_0) {
+      this$static.mode = 16;
+      return;
+    }
+     else if ('html' == name_0) {
+      !this$static.headPointer?(this$static.mode = 2):(this$static.mode = 5);
+      return;
+    }
+     else if (i == 0) {
+      this$static.mode = this$static.framesetOk?21:6;
+      return;
+    }
+  }
+}
+
+function $setFragmentContext(this$static, context){
+  this$static.contextName = context;
+  this$static.contextNamespace = 'http://www.w3.org/1999/xhtml';
+  this$static.fragment = false;
+  this$static.quirks = false;
+}
+
+function $silentPush(this$static, node){
+  var newStack;
+  ++this$static.currentPtr;
+  if (this$static.currentPtr == this$static.stack_0.length) {
+    newStack = initDim(_3Lnu_validator_htmlparser_impl_StackNode_2_classLit, 62, 15, this$static.stack_0.length + 64, 0);
+    arraycopy(this$static.stack_0, 0, newStack, 0, this$static.stack_0.length);
+    this$static.stack_0 = newStack;
+  }
+  this$static.stack_0[this$static.currentPtr] = node;
+}
+
+function $startTag(this$static, elementName, attributes, selfClosing){
+  var actionIndex, activeA, activeAPos, attributeQName, currGroup, currNs, currentNode, eltPos, formAttrs, group, i, inputAttributes, name_0, needsPostProcessing, node, prompt_0, promptIndex, current_0, elt_0, node_2, popName_0, current_2, elt_2, node_3, popName_2, current_3, elt_10, current_4, elt_11;
+  this$static.needToDropLF = false;
+  needsPostProcessing = false;
+  starttagloop: for (;;) {
+    group = elementName.group;
+    name_0 = elementName.name_0;
+    if (this$static.inForeign) {
+      currentNode = this$static.stack_0[this$static.currentPtr];
+      currNs = currentNode.ns;
+      currGroup = currentNode.group;
+      if ('http://www.w3.org/1999/xhtml' == currNs || 'http://www.w3.org/1998/Math/MathML' == currNs && (56 != group && 57 == currGroup || 19 == group && 58 == currGroup) || 'http://www.w3.org/2000/svg' == currNs && (36 == currGroup || 59 == currGroup)) {
+        needsPostProcessing = true;
+      }
+       else {
+        switch (group) {
+          case 45:
+          case 50:
+          case 3:
+          case 4:
+          case 52:
+          case 41:
+          case 46:
+          case 48:
+          case 42:
+          case 20:
+          case 22:
+          case 15:
+          case 18:
+          case 24:
+          case 29:
+          case 44:
+          case 34:
+            while (this$static.stack_0[this$static.currentPtr].ns != 'http://www.w3.org/1999/xhtml') {
+              $pop(this$static);
+            }
+
+            this$static.inForeign = false;
+            continue starttagloop;
+          case 64:
+            if ($contains(attributes, ($clinit_124() , COLOR)) || $contains(attributes, FACE) || $contains(attributes, SIZE)) {
+              while (this$static.stack_0[this$static.currentPtr].ns != 'http://www.w3.org/1999/xhtml') {
+                $pop(this$static);
+              }
+              this$static.inForeign = false;
+              continue starttagloop;
+            }
+
+          default:if ('http://www.w3.org/2000/svg' == currNs) {
+              attributes.mode = 2;
+              if (selfClosing) {
+                $appendVoidElementToCurrentMayFosterCamelCase(this$static, currNs, elementName, attributes);
+                selfClosing = false;
+              }
+               else {
+                $flushCharacters(this$static);
+                popName_0 = elementName.camelCaseName;
+                $processNonNcNames(attributes, this$static, this$static.namePolicy);
+                elementName.custom && (popName_0 = $checkPopName(this$static, popName_0));
+                elt_0 = $createElement(this$static, currNs, popName_0, attributes);
+                current_0 = this$static.stack_0[this$static.currentPtr];
+                current_0.fosterParenting?$insertIntoFosterParent(this$static, elt_0):$appendElement(this$static, elt_0, current_0.node);
+                node_2 = $StackNode_3(new StackNode, currNs, elementName, elt_0, popName_0, ($clinit_125() , FOREIGNOBJECT) == elementName);
+                $push_0(this$static, node_2);
+              }
+              attributes = null;
+              break starttagloop;
+            }
+             else {
+              attributes.mode = 1;
+              if (selfClosing) {
+                $appendVoidElementToCurrentMayFoster_0(this$static, currNs, elementName, attributes);
+                selfClosing = false;
+              }
+               else {
+                $flushCharacters(this$static);
+                popName_2 = elementName.name_0;
+                $processNonNcNames(attributes, this$static, this$static.namePolicy);
+                elementName.custom && (popName_2 = $checkPopName(this$static, popName_2));
+                elt_2 = $createElement(this$static, currNs, popName_2, attributes);
+                current_2 = this$static.stack_0[this$static.currentPtr];
+                current_2.fosterParenting?$insertIntoFosterParent(this$static, elt_2):$appendElement(this$static, elt_2, current_2.node);
+                node_3 = $StackNode_3(new StackNode, currNs, elementName, elt_2, popName_2, false);
+                $push_0(this$static, node_3);
+              }
+              attributes = null;
+              break starttagloop;
+            }
+
+        }
+      }
+    }
+    switch (this$static.mode) {
+      case 10:
+        switch (group) {
+          case 37:
+            $clearStackBackTo(this$static, $findLastInTableScopeOrRootTbodyTheadTfoot(this$static));
+            $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            this$static.mode = 11;
+            attributes = null;
+            break starttagloop;
+          case 40:
+            $clearStackBackTo(this$static, $findLastInTableScopeOrRootTbodyTheadTfoot(this$static));
+            $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', ($clinit_125() , TR), ($clinit_128() , EMPTY_ATTRIBUTES));
+            this$static.mode = 11;
+            continue;
+          case 6:
+          case 7:
+          case 8:
+          case 39:
+            eltPos = $findLastInTableScopeOrRootTbodyTheadTfoot(this$static);
+            if (eltPos == 0) {
+              break starttagloop;
+            }
+             else {
+              $clearStackBackTo(this$static, eltPos);
+              $pop(this$static);
+              this$static.mode = 7;
+              continue;
+            }
+
+        }
+
+      case 11:
+        switch (group) {
+          case 40:
+            $clearStackBackTo(this$static, $findLastOrRoot_0(this$static, 37));
+            $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            this$static.mode = 12;
+            $append_3(this$static, null);
+            attributes = null;
+            break starttagloop;
+          case 6:
+          case 7:
+          case 8:
+          case 39:
+          case 37:
+            eltPos = $findLastOrRoot_0(this$static, 37);
+            if (eltPos == 0) {
+              break starttagloop;
+            }
+
+            $clearStackBackTo(this$static, eltPos);
+            $pop(this$static);
+            this$static.mode = 10;
+            continue;
+        }
+
+      case 7:
+        intableloop: for (;;) {
+          switch (group) {
+            case 6:
+              $clearStackBackTo(this$static, $findLastOrRoot_0(this$static, 34));
+              $append_3(this$static, null);
+              $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              this$static.mode = 8;
+              attributes = null;
+              break starttagloop;
+            case 8:
+              $clearStackBackTo(this$static, $findLastOrRoot_0(this$static, 34));
+              $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              this$static.mode = 9;
+              attributes = null;
+              break starttagloop;
+            case 7:
+              $clearStackBackTo(this$static, $findLastOrRoot_0(this$static, 34));
+              $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', ($clinit_125() , COLGROUP), ($clinit_128() , EMPTY_ATTRIBUTES));
+              this$static.mode = 9;
+              continue starttagloop;
+            case 39:
+              $clearStackBackTo(this$static, $findLastOrRoot_0(this$static, 34));
+              $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              this$static.mode = 10;
+              attributes = null;
+              break starttagloop;
+            case 37:
+            case 40:
+              $clearStackBackTo(this$static, $findLastOrRoot_0(this$static, 34));
+              $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', ($clinit_125() , TBODY), ($clinit_128() , EMPTY_ATTRIBUTES));
+              this$static.mode = 10;
+              continue starttagloop;
+            case 34:
+              eltPos = $findLastInTableScope(this$static, name_0);
+              if (eltPos == 2147483647) {
+                break starttagloop;
+              }
+
+              $generateImpliedEndTags(this$static);
+              while (this$static.currentPtr >= eltPos) {
+                $pop(this$static);
+              }
+
+              $resetTheInsertionMode(this$static);
+              continue starttagloop;
+            case 31:
+              $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              this$static.originalMode = this$static.mode;
+              this$static.mode = 20;
+              $setStateAndEndTagExpectation_0(this$static.tokenizer, 2, elementName);
+              attributes = null;
+              break starttagloop;
+            case 33:
+              $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              this$static.originalMode = this$static.mode;
+              this$static.mode = 20;
+              $setStateAndEndTagExpectation_0(this$static.tokenizer, 60, elementName);
+              attributes = null;
+              break starttagloop;
+            case 13:
+              if (!lowerCaseLiteralEqualsIgnoreAsciiCaseString('hidden', $getValue_1(attributes, ($clinit_124() , TYPE_1)))) {
+                break intableloop;
+              }
+
+              $flushCharacters(this$static);
+              $processNonNcNames(attributes, this$static, this$static.namePolicy);
+              elt_10 = $createElement_0(this$static, 'http://www.w3.org/1999/xhtml', name_0, attributes);
+              current_3 = this$static.stack_0[this$static.currentPtr];
+              $appendElement(this$static, elt_10, current_3.node);
+              $elementPopped(this$static, 'http://www.w3.org/1999/xhtml', name_0, elt_10);
+              selfClosing = false;
+              attributes = null;
+              break starttagloop;
+            case 9:
+              if (this$static.formPointer) {
+                break starttagloop;
+              }
+               else {
+                $flushCharacters(this$static);
+                $processNonNcNames(attributes, this$static, this$static.namePolicy);
+                elt_11 = $createElement(this$static, 'http://www.w3.org/1999/xhtml', 'form', attributes);
+                this$static.formPointer = elt_11;
+                current_4 = this$static.stack_0[this$static.currentPtr];
+                $appendElement(this$static, elt_11, current_4.node);
+                $elementPopped(this$static, 'http://www.w3.org/1999/xhtml', 'form', elt_11);
+                attributes = null;
+                break starttagloop;
+              }
+
+            default:break intableloop;
+          }
+        }
+
+      case 8:
+        switch (group) {
+          case 6:
+          case 7:
+          case 8:
+          case 39:
+          case 37:
+          case 40:
+            eltPos = $findLastInTableScope(this$static, 'caption');
+            if (eltPos == 2147483647) {
+              break starttagloop;
+            }
+
+            $generateImpliedEndTags(this$static);
+            while (this$static.currentPtr >= eltPos) {
+              $pop(this$static);
+            }
+
+            $clearTheListOfActiveFormattingElementsUpToTheLastMarker(this$static);
+            this$static.mode = 7;
+            continue;
+        }
+
+      case 12:
+        switch (group) {
+          case 6:
+          case 7:
+          case 8:
+          case 39:
+          case 37:
+          case 40:
+            eltPos = $findLastInTableScopeTdTh(this$static);
+            if (eltPos == 2147483647) {
+              break starttagloop;
+            }
+             else {
+              $closeTheCell(this$static, eltPos);
+              continue;
+            }
+
+        }
+
+      case 21:
+        switch (group) {
+          case 11:
+            if (this$static.mode == 21) {
+              if (this$static.currentPtr == 0 || this$static.stack_0[1].group != 3) {
+                break starttagloop;
+              }
+               else {
+                $detachFromParent(this$static, this$static.stack_0[1].node);
+                while (this$static.currentPtr > 0) {
+                  $pop(this$static);
+                }
+                $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+                this$static.mode = 16;
+                attributes = null;
+                break starttagloop;
+              }
+            }
+             else {
+              break starttagloop;
+            }
+
+          case 44:
+          case 15:
+          case 41:
+          case 5:
+          case 43:
+          case 63:
+          case 34:
+          case 49:
+          case 4:
+          case 48:
+          case 13:
+          case 65:
+          case 22:
+          case 35:
+          case 38:
+          case 47:
+          case 32:
+            if (this$static.mode == 21) {
+              this$static.framesetOk = false;
+              this$static.mode = 6;
+            }
+
+        }
+
+      case 6:
+        inbodyloop: for (;;) {
+          switch (group) {
+            case 23:
+              if (!this$static.fragment) {
+                $processNonNcNames(attributes, this$static, this$static.namePolicy);
+                $addAttributesToElement(this$static, this$static.stack_0[0].node, attributes);
+                attributes = null;
+              }
+
+              break starttagloop;
+            case 2:
+            case 16:
+            case 18:
+            case 33:
+            case 31:
+            case 36:
+            case 54:
+              break inbodyloop;
+            case 3:
+              $addAttributesToBody(this$static, attributes) && (attributes = null);
+              break starttagloop;
+            case 29:
+            case 50:
+            case 46:
+            case 51:
+              $implicitlyCloseP(this$static);
+              $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              attributes = null;
+              break starttagloop;
+            case 42:
+              $implicitlyCloseP(this$static);
+              this$static.stack_0[this$static.currentPtr].group == 42 && $pop(this$static);
+              $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              attributes = null;
+              break starttagloop;
+            case 61:
+              $implicitlyCloseP(this$static);
+              $appendToCurrentNodeAndPushElementMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              attributes = null;
+              break starttagloop;
+            case 44:
+              $implicitlyCloseP(this$static);
+              $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              this$static.needToDropLF = true;
+              attributes = null;
+              break starttagloop;
+            case 9:
+              if (this$static.formPointer) {
+                break starttagloop;
+              }
+               else {
+                $implicitlyCloseP(this$static);
+                $appendToCurrentNodeAndPushFormElementMayFoster(this$static, attributes);
+                attributes = null;
+                break starttagloop;
+              }
+
+            case 15:
+            case 41:
+              eltPos = this$static.currentPtr;
+              for (;;) {
+                node = this$static.stack_0[eltPos];
+                if (node.group == group) {
+                  $generateImpliedEndTagsExceptFor(this$static, node.name_0);
+                  while (this$static.currentPtr >= eltPos) {
+                    $pop(this$static);
+                  }
+                  break;
+                }
+                 else if (node.scoping || node.special && node.name_0 != 'p' && node.name_0 != 'address' && node.name_0 != 'div') {
+                  break;
+                }
+                --eltPos;
+              }
+
+              $implicitlyCloseP(this$static);
+              $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              attributes = null;
+              break starttagloop;
+            case 30:
+              $implicitlyCloseP(this$static);
+              $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              $setStateAndEndTagExpectation_0(this$static.tokenizer, 3, elementName);
+              attributes = null;
+              break starttagloop;
+            case 1:
+              activeAPos = $findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker(this$static, 'a');
+              if (activeAPos != -1) {
+                activeA = this$static.listOfActiveFormattingElements[activeAPos];
+                ++activeA.refcount;
+                $adoptionAgencyEndTag(this$static, 'a');
+                $removeFromStack_0(this$static, activeA);
+                activeAPos = $findInListOfActiveFormattingElements(this$static, activeA);
+                activeAPos != -1 && $removeFromListOfActiveFormattingElements(this$static, activeAPos);
+                --activeA.refcount;
+              }
+
+              $reconstructTheActiveFormattingElements(this$static);
+              $appendToCurrentNodeAndPushFormattingElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              attributes = null;
+              break starttagloop;
+            case 45:
+            case 64:
+              $reconstructTheActiveFormattingElements(this$static);
+              $appendToCurrentNodeAndPushFormattingElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              attributes = null;
+              break starttagloop;
+            case 24:
+              $reconstructTheActiveFormattingElements(this$static);
+              2147483647 != $findLastInScope(this$static, 'nobr') && $adoptionAgencyEndTag(this$static, 'nobr');
+              $appendToCurrentNodeAndPushFormattingElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              attributes = null;
+              break starttagloop;
+            case 5:
+              eltPos = $findLastInScope(this$static, name_0);
+              if (eltPos != 2147483647) {
+                $generateImpliedEndTags(this$static);
+                while (this$static.currentPtr >= eltPos) {
+                  $pop(this$static);
+                }
+                continue starttagloop;
+              }
+               else {
+                $reconstructTheActiveFormattingElements(this$static);
+                $appendToCurrentNodeAndPushElementMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+                attributes = null;
+                break starttagloop;
+              }
+
+            case 63:
+              $reconstructTheActiveFormattingElements(this$static);
+              $appendToCurrentNodeAndPushElementMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              $append_3(this$static, null);
+              attributes = null;
+              break starttagloop;
+            case 43:
+              $reconstructTheActiveFormattingElements(this$static);
+              $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              $append_3(this$static, null);
+              attributes = null;
+              break starttagloop;
+            case 34:
+              !this$static.quirks && $implicitlyCloseP(this$static);
+              $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              this$static.mode = 7;
+              attributes = null;
+              break starttagloop;
+            case 4:
+            case 48:
+            case 49:
+              $reconstructTheActiveFormattingElements(this$static);
+            case 55:
+              $appendVoidElementToCurrentMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              selfClosing = false;
+              attributes = null;
+              break starttagloop;
+            case 22:
+              $implicitlyCloseP(this$static);
+              $appendVoidElementToCurrentMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              selfClosing = false;
+              attributes = null;
+              break starttagloop;
+            case 12:
+              elementName = ($clinit_125() , IMG);
+              continue starttagloop;
+            case 65:
+            case 13:
+              $reconstructTheActiveFormattingElements(this$static);
+              $appendVoidElementToCurrentMayFoster(this$static, 'http://www.w3.org/1999/xhtml', name_0, attributes);
+              selfClosing = false;
+              attributes = null;
+              break starttagloop;
+            case 14:
+              if (this$static.formPointer) {
+                break starttagloop;
+              }
+
+              $implicitlyCloseP(this$static);
+              formAttrs = $HtmlAttributes(new HtmlAttributes, 0);
+              actionIndex = $getIndex(attributes, ($clinit_124() , ACTION));
+              actionIndex > -1 && $addAttribute(formAttrs, ACTION, $getValue_0(attributes, actionIndex), ($clinit_115() , ALLOW));
+              $appendToCurrentNodeAndPushFormElementMayFoster(this$static, formAttrs);
+              $appendVoidElementToCurrentMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', ($clinit_125() , HR), ($clinit_128() , EMPTY_ATTRIBUTES));
+              $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', LABEL_0, EMPTY_ATTRIBUTES);
+              promptIndex = $getIndex(attributes, PROMPT);
+              if (promptIndex > -1) {
+                prompt_0 = $toCharArray($getValue_0(attributes, promptIndex));
+                $appendCharacters(this$static, this$static.stack_0[this$static.currentPtr].node, valueOf_0(prompt_0, 0, prompt_0.length));
+              }
+               else {
+                $appendCharacters(this$static, this$static.stack_0[this$static.currentPtr].node, 'This is a searchable index. Enter search keywords: ');
+              }
+
+              inputAttributes = $HtmlAttributes(new HtmlAttributes, 0);
+              $addAttribute(inputAttributes, NAME, 'isindex', ($clinit_115() , ALLOW));
+              for (i = 0; i < attributes.length_0; ++i) {
+                attributeQName = $getAttributeName(attributes, i);
+                NAME == attributeQName || PROMPT == attributeQName || ACTION != attributeQName && $addAttribute(inputAttributes, attributeQName, $getValue_0(attributes, i), ALLOW);
+              }
+
+              $clearWithoutReleasingContents(attributes);
+              $appendVoidElementToCurrentMayFoster(this$static, 'http://www.w3.org/1999/xhtml', 'input', inputAttributes);
+              $pop(this$static);
+              $appendVoidElementToCurrentMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', HR, EMPTY_ATTRIBUTES);
+              $pop(this$static);
+              selfClosing = false;
+              break starttagloop;
+            case 35:
+              $appendToCurrentNodeAndPushElementMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              $setStateAndEndTagExpectation_0(this$static.tokenizer, 1, elementName);
+              this$static.originalMode = this$static.mode;
+              this$static.mode = 20;
+              this$static.needToDropLF = true;
+              attributes = null;
+              break starttagloop;
+            case 38:
+              $implicitlyCloseP(this$static);
+              $reconstructTheActiveFormattingElements(this$static);
+              $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              this$static.originalMode = this$static.mode;
+              this$static.mode = 20;
+              $setStateAndEndTagExpectation_0(this$static.tokenizer, 60, elementName);
+              attributes = null;
+              break starttagloop;
+            case 26:
+              {
+                $reconstructTheActiveFormattingElements(this$static);
+                $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+                attributes = null;
+                break starttagloop;
+              }
+
+            case 25:
+            case 47:
+            case 60:
+              $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              this$static.originalMode = this$static.mode;
+              this$static.mode = 20;
+              $setStateAndEndTagExpectation_0(this$static.tokenizer, 60, elementName);
+              attributes = null;
+              break starttagloop;
+            case 32:
+              $reconstructTheActiveFormattingElements(this$static);
+              $appendToCurrentNodeAndPushElementMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              switch (this$static.mode) {
+                case 7:
+                case 8:
+                case 9:
+                case 10:
+                case 11:
+                case 12:
+                  this$static.mode = 14;
+                  break;
+                default:this$static.mode = 13;
+              }
+
+              attributes = null;
+              break starttagloop;
+            case 27:
+            case 28:
+              if ($findLastInScope(this$static, 'option') != 2147483647) {
+                optionendtagloop: for (;;) {
+                  if ('option' == this$static.stack_0[this$static.currentPtr].name_0) {
+                    $pop(this$static);
+                    break optionendtagloop;
+                  }
+                  eltPos = this$static.currentPtr;
+                  for (;;) {
+                    if (this$static.stack_0[eltPos].name_0 == 'option') {
+                      $generateImpliedEndTags(this$static);
+                      while (this$static.currentPtr >= eltPos) {
+                        $pop(this$static);
+                      }
+                      break optionendtagloop;
+                    }
+                    --eltPos;
+                  }
+                }
+              }
+
+              $reconstructTheActiveFormattingElements(this$static);
+              $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              attributes = null;
+              break starttagloop;
+            case 53:
+              eltPos = $findLastInScope(this$static, 'ruby');
+              eltPos != 2147483647 && $generateImpliedEndTags(this$static);
+              if (eltPos != this$static.currentPtr) {
+                while (this$static.currentPtr > eltPos) {
+                  $pop(this$static);
+                }
+              }
+
+              $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              attributes = null;
+              break starttagloop;
+            case 17:
+              $reconstructTheActiveFormattingElements(this$static);
+              attributes.mode = 1;
+              if (selfClosing) {
+                $appendVoidElementToCurrentMayFoster_0(this$static, 'http://www.w3.org/1998/Math/MathML', elementName, attributes);
+                selfClosing = false;
+              }
+               else {
+                $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1998/Math/MathML', elementName, attributes);
+                this$static.inForeign = true;
+              }
+
+              attributes = null;
+              break starttagloop;
+            case 19:
+              $reconstructTheActiveFormattingElements(this$static);
+              attributes.mode = 2;
+              if (selfClosing) {
+                $appendVoidElementToCurrentMayFosterCamelCase(this$static, 'http://www.w3.org/2000/svg', elementName, attributes);
+                selfClosing = false;
+              }
+               else {
+                $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/2000/svg', elementName, attributes);
+                this$static.inForeign = true;
+              }
+
+              attributes = null;
+              break starttagloop;
+            case 6:
+            case 7:
+            case 8:
+            case 39:
+            case 37:
+            case 40:
+            case 10:
+            case 11:
+            case 20:
+              break starttagloop;
+            case 62:
+              $reconstructTheActiveFormattingElements(this$static);
+              $appendToCurrentNodeAndPushElementMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              attributes = null;
+              break starttagloop;
+            default:$reconstructTheActiveFormattingElements(this$static);
+              $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              attributes = null;
+              break starttagloop;
+          }
+        }
+
+      case 3:
+        inheadloop: for (;;) {
+          switch (group) {
+            case 23:
+              if (!this$static.fragment) {
+                $processNonNcNames(attributes, this$static, this$static.namePolicy);
+                $addAttributesToElement(this$static, this$static.stack_0[0].node, attributes);
+                attributes = null;
+              }
+
+              break starttagloop;
+            case 2:
+            case 54:
+              $appendVoidElementToCurrentMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              selfClosing = false;
+              attributes = null;
+              break starttagloop;
+            case 18:
+            case 16:
+              break inheadloop;
+            case 36:
+              $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              this$static.originalMode = this$static.mode;
+              this$static.mode = 20;
+              $setStateAndEndTagExpectation_0(this$static.tokenizer, 1, elementName);
+              attributes = null;
+              break starttagloop;
+            case 26:
+              {
+                $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+                this$static.mode = 4;
+              }
+
+              attributes = null;
+              break starttagloop;
+            case 31:
+              $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              this$static.originalMode = this$static.mode;
+              this$static.mode = 20;
+              $setStateAndEndTagExpectation_0(this$static.tokenizer, 2, elementName);
+              attributes = null;
+              break starttagloop;
+            case 33:
+            case 25:
+              $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+              this$static.originalMode = this$static.mode;
+              this$static.mode = 20;
+              $setStateAndEndTagExpectation_0(this$static.tokenizer, 60, elementName);
+              attributes = null;
+              break starttagloop;
+            case 20:
+              break starttagloop;
+            default:$pop(this$static);
+              this$static.mode = 5;
+              continue starttagloop;
+          }
+        }
+
+      case 4:
+        switch (group) {
+          case 23:
+            if (!this$static.fragment) {
+              $processNonNcNames(attributes, this$static, this$static.namePolicy);
+              $addAttributesToElement(this$static, this$static.stack_0[0].node, attributes);
+              attributes = null;
+            }
+
+            break starttagloop;
+          case 16:
+            $appendVoidElementToCurrentMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            selfClosing = false;
+            attributes = null;
+            break starttagloop;
+          case 18:
+            $checkMetaCharset(this$static, attributes);
+            $appendVoidElementToCurrentMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            selfClosing = false;
+            attributes = null;
+            break starttagloop;
+          case 33:
+          case 25:
+            $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            this$static.originalMode = this$static.mode;
+            this$static.mode = 20;
+            $setStateAndEndTagExpectation_0(this$static.tokenizer, 60, elementName);
+            attributes = null;
+            break starttagloop;
+          case 20:
+            break starttagloop;
+          case 26:
+            break starttagloop;
+          default:$pop(this$static);
+            this$static.mode = 3;
+            continue;
+        }
+
+      case 9:
+        switch (group) {
+          case 23:
+            if (!this$static.fragment) {
+              $processNonNcNames(attributes, this$static, this$static.namePolicy);
+              $addAttributesToElement(this$static, this$static.stack_0[0].node, attributes);
+              attributes = null;
+            }
+
+            break starttagloop;
+          case 7:
+            $appendVoidElementToCurrentMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            selfClosing = false;
+            attributes = null;
+            break starttagloop;
+          default:if (this$static.currentPtr == 0) {
+              break starttagloop;
+            }
+
+            $pop(this$static);
+            this$static.mode = 7;
+            continue;
+        }
+
+      case 14:
+        switch (group) {
+          case 6:
+          case 39:
+          case 37:
+          case 40:
+          case 34:
+            eltPos = $findLastInTableScope(this$static, 'select');
+            if (eltPos == 2147483647) {
+              break starttagloop;
+            }
+
+            while (this$static.currentPtr >= eltPos) {
+              $pop(this$static);
+            }
+
+            $resetTheInsertionMode(this$static);
+            continue;
+        }
+
+      case 13:
+        switch (group) {
+          case 23:
+            if (!this$static.fragment) {
+              $processNonNcNames(attributes, this$static, this$static.namePolicy);
+              $addAttributesToElement(this$static, this$static.stack_0[0].node, attributes);
+              attributes = null;
+            }
+
+            break starttagloop;
+          case 28:
+            'option' == this$static.stack_0[this$static.currentPtr].name_0 && $pop(this$static);
+            $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            attributes = null;
+            break starttagloop;
+          case 27:
+            'option' == this$static.stack_0[this$static.currentPtr].name_0 && $pop(this$static);
+            'optgroup' == this$static.stack_0[this$static.currentPtr].name_0 && $pop(this$static);
+            $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            attributes = null;
+            break starttagloop;
+          case 32:
+            eltPos = $findLastInTableScope(this$static, name_0);
+            if (eltPos == 2147483647) {
+              break starttagloop;
+            }
+             else {
+              while (this$static.currentPtr >= eltPos) {
+                $pop(this$static);
+              }
+              $resetTheInsertionMode(this$static);
+              break starttagloop;
+            }
+
+          case 13:
+          case 35:
+          case 65:
+            eltPos = $findLastInTableScope(this$static, 'select');
+            if (eltPos == 2147483647) {
+              break starttagloop;
+            }
+
+            while (this$static.currentPtr >= eltPos) {
+              $pop(this$static);
+            }
+
+            $resetTheInsertionMode(this$static);
+            continue;
+          case 31:
+            $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            this$static.originalMode = this$static.mode;
+            this$static.mode = 20;
+            $setStateAndEndTagExpectation_0(this$static.tokenizer, 2, elementName);
+            attributes = null;
+            break starttagloop;
+          default:break starttagloop;
+        }
+
+      case 15:
+        switch (group) {
+          case 23:
+            if (!this$static.fragment) {
+              $processNonNcNames(attributes, this$static, this$static.namePolicy);
+              $addAttributesToElement(this$static, this$static.stack_0[0].node, attributes);
+              attributes = null;
+            }
+
+            break starttagloop;
+          default:this$static.mode = this$static.framesetOk?21:6;
+            continue;
+        }
+
+      case 16:
+        switch (group) {
+          case 11:
+            $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            attributes = null;
+            break starttagloop;
+          case 10:
+            $appendVoidElementToCurrentMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            selfClosing = false;
+            attributes = null;
+            break starttagloop;
+        }
+
+      case 17:
+        switch (group) {
+          case 23:
+            if (!this$static.fragment) {
+              $processNonNcNames(attributes, this$static, this$static.namePolicy);
+              $addAttributesToElement(this$static, this$static.stack_0[0].node, attributes);
+              attributes = null;
+            }
+
+            break starttagloop;
+          case 25:
+            $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            this$static.originalMode = this$static.mode;
+            this$static.mode = 20;
+            $setStateAndEndTagExpectation_0(this$static.tokenizer, 60, elementName);
+            attributes = null;
+            break starttagloop;
+          default:break starttagloop;
+        }
+
+      case 0:
+        $documentModeInternal(this$static, ($clinit_113() , QUIRKS_MODE));
+        this$static.mode = 1;
+        continue;
+      case 1:
+        switch (group) {
+          case 23:
+            attributes == ($clinit_128() , EMPTY_ATTRIBUTES)?$appendHtmlElementToDocumentAndPush(this$static, $emptyAttributes(this$static.tokenizer)):$appendHtmlElementToDocumentAndPush(this$static, attributes);
+            this$static.mode = 2;
+            attributes = null;
+            break starttagloop;
+          default:$appendHtmlElementToDocumentAndPush(this$static, $emptyAttributes(this$static.tokenizer));
+            this$static.mode = 2;
+            continue;
+        }
+
+      case 2:
+        switch (group) {
+          case 23:
+            if (!this$static.fragment) {
+              $processNonNcNames(attributes, this$static, this$static.namePolicy);
+              $addAttributesToElement(this$static, this$static.stack_0[0].node, attributes);
+              attributes = null;
+            }
+
+            break starttagloop;
+          case 20:
+            $appendToCurrentNodeAndPushHeadElement(this$static, attributes);
+            this$static.mode = 3;
+            attributes = null;
+            break starttagloop;
+          default:$appendToCurrentNodeAndPushHeadElement(this$static, ($clinit_128() , EMPTY_ATTRIBUTES));
+            this$static.mode = 3;
+            continue;
+        }
+
+      case 5:
+        switch (group) {
+          case 23:
+            if (!this$static.fragment) {
+              $processNonNcNames(attributes, this$static, this$static.namePolicy);
+              $addAttributesToElement(this$static, this$static.stack_0[0].node, attributes);
+              attributes = null;
+            }
+
+            break starttagloop;
+          case 3:
+            attributes.length_0 == 0?($appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', ($clinit_125() , BODY), $emptyAttributes(this$static.tokenizer)) , undefined):$appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', ($clinit_125() , BODY), attributes);
+            this$static.framesetOk = false;
+            this$static.mode = 6;
+            attributes = null;
+            break starttagloop;
+          case 11:
+            $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            this$static.mode = 16;
+            attributes = null;
+            break starttagloop;
+          case 2:
+            $flushCharacters(this$static);
+            $silentPush(this$static, $StackNode_0(new StackNode, 'http://www.w3.org/1999/xhtml', ($clinit_125() , HEAD), this$static.headPointer));
+            $appendVoidElementToCurrentMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            selfClosing = false;
+            $pop(this$static);
+            attributes = null;
+            break starttagloop;
+          case 16:
+            $flushCharacters(this$static);
+            $silentPush(this$static, $StackNode_0(new StackNode, 'http://www.w3.org/1999/xhtml', ($clinit_125() , HEAD), this$static.headPointer));
+            $appendVoidElementToCurrentMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            selfClosing = false;
+            $pop(this$static);
+            attributes = null;
+            break starttagloop;
+          case 18:
+            $checkMetaCharset(this$static, attributes);
+            $flushCharacters(this$static);
+            $silentPush(this$static, $StackNode_0(new StackNode, 'http://www.w3.org/1999/xhtml', ($clinit_125() , HEAD), this$static.headPointer));
+            $appendVoidElementToCurrentMayFoster_0(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            selfClosing = false;
+            $pop(this$static);
+            attributes = null;
+            break starttagloop;
+          case 31:
+            $flushCharacters(this$static);
+            $silentPush(this$static, $StackNode_0(new StackNode, 'http://www.w3.org/1999/xhtml', ($clinit_125() , HEAD), this$static.headPointer));
+            $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            this$static.originalMode = this$static.mode;
+            this$static.mode = 20;
+            $setStateAndEndTagExpectation_0(this$static.tokenizer, 2, elementName);
+            attributes = null;
+            break starttagloop;
+          case 33:
+          case 25:
+            $flushCharacters(this$static);
+            $silentPush(this$static, $StackNode_0(new StackNode, 'http://www.w3.org/1999/xhtml', ($clinit_125() , HEAD), this$static.headPointer));
+            $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            this$static.originalMode = this$static.mode;
+            this$static.mode = 20;
+            $setStateAndEndTagExpectation_0(this$static.tokenizer, 60, elementName);
+            attributes = null;
+            break starttagloop;
+          case 36:
+            $flushCharacters(this$static);
+            $silentPush(this$static, $StackNode_0(new StackNode, 'http://www.w3.org/1999/xhtml', ($clinit_125() , HEAD), this$static.headPointer));
+            $appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            this$static.originalMode = this$static.mode;
+            this$static.mode = 20;
+            $setStateAndEndTagExpectation_0(this$static.tokenizer, 1, elementName);
+            attributes = null;
+            break starttagloop;
+          case 20:
+            break starttagloop;
+          default:$appendToCurrentNodeAndPushElement(this$static, 'http://www.w3.org/1999/xhtml', ($clinit_125() , BODY), $emptyAttributes(this$static.tokenizer));
+            this$static.mode = 21;
+            continue;
+        }
+
+      case 18:
+        switch (group) {
+          case 23:
+            if (!this$static.fragment) {
+              $processNonNcNames(attributes, this$static, this$static.namePolicy);
+              $addAttributesToElement(this$static, this$static.stack_0[0].node, attributes);
+              attributes = null;
+            }
+
+            break starttagloop;
+          default:this$static.mode = this$static.framesetOk?21:6;
+            continue;
+        }
+
+      case 19:
+        switch (group) {
+          case 25:
+            $appendToCurrentNodeAndPushElementMayFoster(this$static, 'http://www.w3.org/1999/xhtml', elementName, attributes);
+            this$static.originalMode = this$static.mode;
+            this$static.mode = 20;
+            $setStateAndEndTagExpectation_0(this$static.tokenizer, 2, elementName);
+            attributes = null;
+            break starttagloop;
+          default:break starttagloop;
+        }
+
+      case 20:
+        break starttagloop;
+    }
+  }
+  needsPostProcessing && this$static.inForeign && !$hasForeignInScope(this$static) && (this$static.inForeign = false);
+  attributes != ($clinit_128() , EMPTY_ATTRIBUTES);
+}
+
+function $startTokenization(this$static, self_0){
+  var elt, node;
+  this$static.tokenizer = self_0;
+  this$static.stack_0 = initDim(_3Lnu_validator_htmlparser_impl_StackNode_2_classLit, 62, 15, 64, 0);
+  this$static.listOfActiveFormattingElements = initDim(_3Lnu_validator_htmlparser_impl_StackNode_2_classLit, 62, 15, 64, 0);
+  this$static.needToDropLF = false;
+  this$static.originalMode = 0;
+  this$static.currentPtr = -1;
+  this$static.listPtr = -1;
+  this$static.formPointer = null;
+  this$static.headPointer = null;
+  this$static.html4 = false;
+  $clearImpl(this$static.idLocations);
+  this$static.wantingComments = this$static.wantingComments;
+  this$static.script = null;
+  this$static.placeholder = null;
+  this$static.readyToRun = false;
+  this$static.charBufferLen = 0;
+  this$static.charBuffer = initDim(_3C_classLit, 47, -1, 1024, 1);
+  this$static.framesetOk = true;
+  if (this$static.fragment) {
+    elt = $createHtmlElementSetAsRoot(this$static, $emptyAttributes(this$static.tokenizer));
+    node = $StackNode_0(new StackNode, 'http://www.w3.org/1999/xhtml', ($clinit_125() , HTML_0), elt);
+    ++this$static.currentPtr;
+    this$static.stack_0[this$static.currentPtr] = node;
+    $resetTheInsertionMode(this$static);
+    'title' == this$static.contextName || 'textarea' == this$static.contextName?$setStateAndEndTagExpectation(this$static.tokenizer, 1):'style' == this$static.contextName || 'xmp' == this$static.contextName || 'iframe' == this$static.contextName || 'noembed' == this$static.contextName || 'noframes' == this$static.contextName?$setStateAndEndTagExpectation(this$static.tokenizer, 60):'plaintext' == this$static.contextName?$setStateAndEndTagExpectation(this$static.tokenizer, 3):'script' == this$static.contextName?$setStateAndEndTagExpectation(this$static.tokenizer, 2):$setStateAndEndTagExpectation(this$static.tokenizer, 0);
+    this$static.contextName = null;
+  }
+   else {
+    this$static.mode = 0;
+    this$static.inForeign = false;
+  }
+}
+
+function $zeroOriginatingReplacementCharacter(this$static){
+  (this$static.inForeign || this$static.mode == 20) && $characters(this$static, REPLACEMENT_CHARACTER, 0, 1);
+}
+
+function extractCharsetFromContent(attributeValue){
+  var buffer, c, charset, charsetState, end, i, start;
+  charsetState = 0;
+  start = -1;
+  end = -1;
+  buffer = $toCharArray(attributeValue);
+  charsetloop: for (i = 0; i < buffer.length; ++i) {
+    c = buffer[i];
+    switch (charsetState) {
+      case 0:
+        switch (c) {
+          case 99:
+          case 67:
+            charsetState = 1;
+            continue;
+          default:continue;
+        }
+
+      case 1:
+        switch (c) {
+          case 104:
+          case 72:
+            charsetState = 2;
+            continue;
+          default:charsetState = 0;
+            continue;
+        }
+
+      case 2:
+        switch (c) {
+          case 97:
+          case 65:
+            charsetState = 3;
+            continue;
+          default:charsetState = 0;
+            continue;
+        }
+
+      case 3:
+        switch (c) {
+          case 114:
+          case 82:
+            charsetState = 4;
+            continue;
+          default:charsetState = 0;
+            continue;
+        }
+
+      case 4:
+        switch (c) {
+          case 115:
+          case 83:
+            charsetState = 5;
+            continue;
+          default:charsetState = 0;
+            continue;
+        }
+
+      case 5:
+        switch (c) {
+          case 101:
+          case 69:
+            charsetState = 6;
+            continue;
+          default:charsetState = 0;
+            continue;
+        }
+
+      case 6:
+        switch (c) {
+          case 116:
+          case 84:
+            charsetState = 7;
+            continue;
+          default:charsetState = 0;
+            continue;
+        }
+
+      case 7:
+        switch (c) {
+          case 9:
+          case 10:
+          case 12:
+          case 13:
+          case 32:
+            continue;
+          case 61:
+            charsetState = 8;
+            continue;
+          default:return null;
+        }
+
+      case 8:
+        switch (c) {
+          case 9:
+          case 10:
+          case 12:
+          case 13:
+          case 32:
+            continue;
+          case 39:
+            start = i + 1;
+            charsetState = 9;
+            continue;
+          case 34:
+            start = i + 1;
+            charsetState = 10;
+            continue;
+          default:start = i;
+            charsetState = 11;
+            continue;
+        }
+
+      case 9:
+        switch (c) {
+          case 39:
+            end = i;
+            break charsetloop;
+          default:continue;
+        }
+
+      case 10:
+        switch (c) {
+          case 34:
+            end = i;
+            break charsetloop;
+          default:continue;
+        }
+
+      case 11:
+        switch (c) {
+          case 9:
+          case 10:
+          case 12:
+          case 13:
+          case 32:
+          case 59:
+            end = i;
+            break charsetloop;
+          default:continue;
+        }
+
+    }
+  }
+  charset = null;
+  if (start != -1) {
+    end == -1 && (end = buffer.length);
+    charset = valueOf_0(buffer, start, end - start);
+  }
+  return charset;
+}
+
+function getClass_60(){
+  return Lnu_validator_htmlparser_impl_TreeBuilder_2_classLit;
+}
+
+function TreeBuilder(){
+}
+
+_ = TreeBuilder.prototype = new Object_0;
+_.getClass$ = getClass_60;
+_.typeId$ = 0;
+_.charBuffer = null;
+_.charBufferLen = 0;
+_.contextName = null;
+_.contextNamespace = null;
+_.currentPtr = -1;
+_.formPointer = null;
+_.fragment = false;
+_.framesetOk = true;
+_.headPointer = null;
+_.html4 = false;
+_.inForeign = false;
+_.listOfActiveFormattingElements = null;
+_.listPtr = -1;
+_.mode = 0;
+_.needToDropLF = false;
+_.originalMode = 0;
+_.quirks = false;
+_.stack_0 = null;
+_.tokenizer = null;
+_.wantingComments = false;
+var HTML4_PUBLIC_IDS, QUIRKY_PUBLIC_IDS, REPLACEMENT_CHARACTER;
+function $clinit_117(){
+  $clinit_117 = nullMethod;
+  $clinit_116();
+}
+
+function $accumulateCharacters(this$static, buf, start, length_0){
+  var newBuf, newLen;
+  newLen = this$static.charBufferLen + length_0;
+  if (newLen > this$static.charBuffer.length) {
+    newBuf = initDim(_3C_classLit, 47, -1, newLen, 1);
+    arraycopy(this$static.charBuffer, 0, newBuf, 0, this$static.charBufferLen);
+    this$static.charBuffer = newBuf;
+  }
+  arraycopy(buf, start, this$static.charBuffer, this$static.charBufferLen, length_0);
+  this$static.charBufferLen = newLen;
+}
+
+function $insertFosterParentedCharacters(this$static, buf, start, length_0, table, stackParent){
+  var end;
+  $insertFosterParentedCharacters_0(this$static, (end = start + length_0 , __checkBounds(buf.length, start, end) , __valueOf(buf, start, end)), table, stackParent);
+}
+
+function getClass_61(){
+  return Lnu_validator_htmlparser_impl_CoalescingTreeBuilder_2_classLit;
+}
+
+function CoalescingTreeBuilder(){
+}
+
+_ = CoalescingTreeBuilder.prototype = new TreeBuilder;
+_.getClass$ = getClass_61;
+_.typeId$ = 0;
+function $clinit_118(){
+  $clinit_118 = nullMethod;
+  $clinit_117();
+}
+
+function $BrowserTreeBuilder(this$static, document_0){
+  $clinit_118();
+  this$static.doctypeExpectation = ($clinit_112() , HTML);
+  this$static.namePolicy = ($clinit_115() , ALTER_INFOSET);
+  this$static.idLocations = $HashMap(new HashMap);
+  this$static.fragment = false;
+  this$static.scriptStack = $LinkedList(new LinkedList);
+  this$static.document_0 = document_0;
+  installExplorerCreateElementNS(document_0);
+  return this$static;
+}
+
+function $addAttributesToElement(this$static, element, attributes){
+  var $e0, e, i, localName, uri;
+  try {
+    for (i = 0; i < attributes.length_0; ++i) {
+      localName = $getLocalName(attributes, i);
+      uri = $getURI(attributes, i);
+      !element.hasAttributeNS(uri, localName) && (element.setAttributeNS(uri, localName, $getValue_0(attributes, i)) , undefined);
+    }
+  }
+   catch ($e0) {
+    $e0 = caught($e0);
+    if (instanceOf($e0, 29)) {
+      e = $e0;
+      $fatal(this$static, e);
+    }
+     else 
+      throw $e0;
+  }
+}
+
+function $appendCharacters(this$static, parent_0, text){
+  var $e0, e;
+  try {
+    parent_0 == this$static.placeholder && (this$static.script.appendChild(this$static.document_0.createTextNode(text)) , undefined);
+    parent_0.appendChild(this$static.document_0.createTextNode(text));
+  }
+   catch ($e0) {
+    $e0 = caught($e0);
+    if (instanceOf($e0, 29)) {
+      e = $e0;
+      $fatal(this$static, e);
+    }
+     else 
+      throw $e0;
+  }
+}
+
+function $appendChildrenToNewParent(this$static, oldParent, newParent){
+  var $e0, e;
+  try {
+    while (oldParent.hasChildNodes()) {
+      newParent.appendChild(oldParent.firstChild);
+    }
+  }
+   catch ($e0) {
+    $e0 = caught($e0);
+    if (instanceOf($e0, 29)) {
+      e = $e0;
+      $fatal(this$static, e);
+    }
+     else 
+      throw $e0;
+  }
+}
+
+function $appendComment(this$static, parent_0, comment){
+  var $e0, e;
+  try {
+    parent_0 == this$static.placeholder && (this$static.script.appendChild(this$static.document_0.createComment(comment)) , undefined);
+    parent_0.appendChild(this$static.document_0.createComment(comment));
+  }
+   catch ($e0) {
+    $e0 = caught($e0);
+    if (instanceOf($e0, 29)) {
+      e = $e0;
+      $fatal(this$static, e);
+    }
+     else 
+      throw $e0;
+  }
+}
+
+function $appendCommentToDocument(this$static, comment){
+  var $e0, e;
+  try {
+    this$static.document_0.appendChild(this$static.document_0.createComment(comment));
+  }
+   catch ($e0) {
+    $e0 = caught($e0);
+    if (instanceOf($e0, 29)) {
+      e = $e0;
+      $fatal(this$static, e);
+    }
+     else 
+      throw $e0;
+  }
+}
+
+function $appendElement(this$static, child, newParent){
+  var $e0, e;
+  try {
+    newParent == this$static.placeholder && (this$static.script.appendChild(child.cloneNode(true)) , undefined);
+    newParent.appendChild(child);
+  }
+   catch ($e0) {
+    $e0 = caught($e0);
+    if (instanceOf($e0, 29)) {
+      e = $e0;
+      $fatal(this$static, e);
+    }
+     else 
+      throw $e0;
+  }
+}
+
+function $createElement(this$static, ns, name_0, attributes){
+  var $e0, e, i, rv;
+  try {
+    rv = this$static.document_0.createElementNS(ns, name_0);
+    for (i = 0; i < attributes.length_0; ++i) {
+      rv.setAttributeNS($getURI(attributes, i), $getLocalName(attributes, i), $getValue_0(attributes, i));
+    }
+    if ('script' == name_0) {
+      !!this$static.placeholder && $addLast(this$static.scriptStack, $BrowserTreeBuilder$ScriptHolder(new BrowserTreeBuilder$ScriptHolder, this$static.script, this$static.placeholder));
+      this$static.script = rv;
+      this$static.placeholder = this$static.document_0.createElementNS('http://n.validator.nu/placeholder/', 'script');
+      rv = this$static.placeholder;
+      for (i = 0; i < attributes.length_0; ++i) {
+        rv.setAttributeNS($getURI(attributes, i), $getLocalName(attributes, i), $getValue_0(attributes, i));
+      }
+    }
+    return rv;
+  }
+   catch ($e0) {
+    $e0 = caught($e0);
+    if (instanceOf($e0, 29)) {
+      e = $e0;
+      $fatal(this$static, e);
+      throw $RuntimeException(new RuntimeException, 'Unreachable');
+    }
+     else 
+      throw $e0;
+  }
+}
+
+function $createElement_0(this$static, ns, name_0, attributes){
+  var $e0, e, rv;
+  try {
+    rv = $createElement(this$static, ns, name_0, attributes);
+    return rv;
+  }
+   catch ($e0) {
+    $e0 = caught($e0);
+    if (instanceOf($e0, 29)) {
+      e = $e0;
+      $fatal(this$static, e);
+      return null;
+    }
+     else 
+      throw $e0;
+  }
+}
+
+function $createHtmlElementSetAsRoot(this$static, attributes){
+  var $e0, e, i, rv;
+  try {
+    rv = this$static.document_0.createElementNS('http://www.w3.org/1999/xhtml', 'html');
+    for (i = 0; i < attributes.length_0; ++i) {
+      rv.setAttributeNS($getURI(attributes, i), $getLocalName(attributes, i), $getValue_0(attributes, i));
+    }
+    this$static.document_0.appendChild(rv);
+    return rv;
+  }
+   catch ($e0) {
+    $e0 = caught($e0);
+    if (instanceOf($e0, 29)) {
+      e = $e0;
+      $fatal(this$static, e);
+      throw $RuntimeException(new RuntimeException, 'Unreachable');
+    }
+     else 
+      throw $e0;
+  }
+}
+
+function $detachFromParent(this$static, element){
+  var $e0, e, parent_0;
+  try {
+    parent_0 = element.parentNode;
+    !!parent_0 && (parent_0.removeChild(element) , undefined);
+  }
+   catch ($e0) {
+    $e0 = caught($e0);
+    if (instanceOf($e0, 29)) {
+      e = $e0;
+      $fatal(this$static, e);
+    }
+     else 
+      throw $e0;
+  }
+}
+
+function $elementPopped(this$static, ns, name_0, node){
+  if (node == this$static.placeholder) {
+    this$static.readyToRun = true;
+    this$static.tokenizer.shouldSuspend = true;
+  }
+  __elementPopped__(ns, name_0, node);
+}
+
+function $getDocument(this$static){
+  var rv;
+  rv = this$static.document_0;
+  this$static.document_0 = null;
+  return rv;
+}
+
+function $insertFosterParentedCharacters_0(this$static, text, table, stackParent){
+  var $e0, child, e, parent_0;
+  try {
+    child = this$static.document_0.createTextNode(text);
+    parent_0 = table.parentNode;
+    !!parent_0 && parent_0.nodeType == 1?(parent_0.insertBefore(child, table) , undefined):(stackParent.appendChild(child) , undefined);
+  }
+   catch ($e0) {
+    $e0 = caught($e0);
+    if (instanceOf($e0, 29)) {
+      e = $e0;
+      $fatal(this$static, e);
+    }
+     else 
+      throw $e0;
+  }
+}
+
+function $insertFosterParentedChild(this$static, child, table, stackParent){
+  var $e0, e, parent_0;
+  parent_0 = table.parentNode;
+  try {
+    !!parent_0 && parent_0.nodeType == 1?(parent_0.insertBefore(child, table) , undefined):(stackParent.appendChild(child) , undefined);
+  }
+   catch ($e0) {
+    $e0 = caught($e0);
+    if (instanceOf($e0, 29)) {
+      e = $e0;
+      $fatal(this$static, e);
+    }
+     else 
+      throw $e0;
+  }
+}
+
+function $maybeRunScript(this$static){
+  var scriptHolder;
+  if (this$static.readyToRun) {
+    this$static.readyToRun = false;
+    replace_0(this$static.placeholder, this$static.script);
+    if (this$static.scriptStack.size == 0) {
+      this$static.script = null;
+      this$static.placeholder = null;
+    }
+     else {
+      scriptHolder = dynamicCast($removeLast(this$static.scriptStack), 30);
+      this$static.script = scriptHolder.script;
+      this$static.placeholder = scriptHolder.placeholder;
+    }
+  }
+}
+
+function getClass_62(){
+  return Lnu_validator_htmlparser_gwt_BrowserTreeBuilder_2_classLit;
+}
+
+function installExplorerCreateElementNS(doc){
+  !doc.createElementNS && (doc.createElementNS = function(uri, local){
+    if ('http://www.w3.org/1999/xhtml' == uri) {
+      return doc.createElement(local);
+    }
+     else if ('http://www.w3.org/1998/Math/MathML' == uri) {
+      if (!doc.mathplayerinitialized) {
+        var obj = document.createElement('object');
+        obj.setAttribute('id', 'mathplayer');
+        obj.setAttribute('classid', 'clsid:32F66A20-7614-11D4-BD11-00104BD3F987');
+        document.getElementsByTagName('head')[0].appendChild(obj);
+        document.namespaces.add('m', 'http://www.w3.org/1998/Math/MathML', '#mathplayer');
+        doc.mathplayerinitialized = true;
+      }
+      return doc.createElement('m:' + local);
+    }
+     else if ('http://www.w3.org/2000/svg' == uri) {
+      if (!doc.renesisinitialized) {
+        var obj = document.createElement('object');
+        obj.setAttribute('id', 'renesis');
+        obj.setAttribute('classid', 'clsid:AC159093-1683-4BA2-9DCF-0C350141D7F2');
+        document.getElementsByTagName('head')[0].appendChild(obj);
+        document.namespaces.add('s', 'http://www.w3.org/2000/svg', '#renesis');
+        doc.renesisinitialized = true;
+      }
+      return doc.createElement('s:' + local);
+    }
+  }
+  );
+}
+
+function replace_0(oldNode, newNode){
+  oldNode.parentNode.replaceChild(newNode, oldNode);
+  __elementPopped__('', newNode.nodeName, newNode);
+}
+
+function BrowserTreeBuilder(){
+}
+
+_ = BrowserTreeBuilder.prototype = new CoalescingTreeBuilder;
+_.getClass$ = getClass_62;
+_.typeId$ = 0;
+_.document_0 = null;
+_.placeholder = null;
+_.readyToRun = false;
+_.script = null;
+function $BrowserTreeBuilder$ScriptHolder(this$static, script, placeholder){
+  this$static.script = script;
+  this$static.placeholder = placeholder;
+  return this$static;
+}
+
+function getClass_63(){
+  return Lnu_validator_htmlparser_gwt_BrowserTreeBuilder$ScriptHolder_2_classLit;
+}
+
+function BrowserTreeBuilder$ScriptHolder(){
+}
+
+_ = BrowserTreeBuilder$ScriptHolder.prototype = new Object_0;
+_.getClass$ = getClass_63;
+_.typeId$ = 37;
+_.placeholder = null;
+_.script = null;
+function $HtmlParser(this$static, document_0){
+  this$static.documentWriteBuffer = $StringBuilder(new StringBuilder);
+  this$static.bufferStack = $LinkedList(new LinkedList);
+  this$static.domTreeBuilder = $BrowserTreeBuilder(new BrowserTreeBuilder, document_0);
+  this$static.tokenizer = $ErrorReportingTokenizer(new ErrorReportingTokenizer, this$static.domTreeBuilder);
+  this$static.domTreeBuilder.namePolicy = ($clinit_115() , ALTER_INFOSET);
+  this$static.tokenizer.commentPolicy = ALTER_INFOSET;
+  this$static.tokenizer.contentNonXmlCharPolicy = ALTER_INFOSET;
+  this$static.tokenizer.contentSpacePolicy = ALTER_INFOSET;
+  this$static.tokenizer.namePolicy = ALTER_INFOSET;
+  $setXmlnsPolicy(this$static.tokenizer, ALTER_INFOSET);
+  return this$static;
+}
+
+function $parse(this$static, source, useSetTimeouts, callback){
+  this$static.parseEndListener = callback;
+  $setFragmentContext(this$static.domTreeBuilder, null);
+  this$static.lastWasCR = false;
+  this$static.ending = false;
+  $setLength(this$static.documentWriteBuffer, 0);
+  this$static.streamLength = source.length;
+  this$static.stream = $UTF16Buffer(new UTF16Buffer, $toCharArray(source), 0, this$static.streamLength < 512?this$static.streamLength:512);
+  $clear(this$static.bufferStack);
+  $addLast(this$static.bufferStack, this$static.stream);
+  $setFragmentContext(this$static.domTreeBuilder, null);
+  $start_0(this$static.tokenizer);
+  $pump(this$static, useSetTimeouts);
+}
+
+function $pump(this$static, useSetTimeouts){
+  var $e0, timer;
+  if ($pumpcore(this$static)) {
+    return;
+  }
+  if (useSetTimeouts) {
+    timer = $HtmlParser$1(new HtmlParser$1, this$static);
+    $schedule(timer, 1);
+  }
+   else {
+    try {
+      while (!$pumpcore(this$static)) {
+      }
+    }
+     catch ($e0) {
+      $e0 = caught($e0);
+      if (instanceOf($e0, 31)) {
+        this$static.ending = true;
+      }
+       else 
+        throw $e0;
+    }
+  }
+}
+
+function $pumpcore(this$static){
+  var buffer, docWriteLen, newBuf, newEnd;
+  if (this$static.ending) {
+    $end(this$static.tokenizer);
+    $getDocument(this$static.domTreeBuilder);
+    this$static.parseEndListener.callback();
+    return true;
+  }
+  docWriteLen = this$static.documentWriteBuffer.impl.string.length;
+  if (docWriteLen > 0) {
+    newBuf = initDim(_3C_classLit, 47, -1, docWriteLen, 1);
+    $getChars_0(this$static.documentWriteBuffer, 0, docWriteLen, newBuf, 0);
+    $addLast(this$static.bufferStack, $UTF16Buffer(new UTF16Buffer, newBuf, 0, docWriteLen));
+    $setLength(this$static.documentWriteBuffer, 0);
+  }
+  for (;;) {
+    buffer = dynamicCast($getLast(this$static.bufferStack), 32);
+    if (buffer.start >= buffer.end) {
+      if (buffer == this$static.stream) {
+        if (buffer.end == this$static.streamLength) {
+          $eof_0(this$static.tokenizer);
+          this$static.ending = true;
+          break;
+        }
+         else {
+          newEnd = buffer.start + 512;
+          buffer.end = newEnd < this$static.streamLength?newEnd:this$static.streamLength;
+          continue;
+        }
+      }
+       else {
+        $removeLast(this$static.bufferStack);
+        continue;
+      }
+    }
+    $adjust(buffer, this$static.lastWasCR);
+    this$static.lastWasCR = false;
+    if (buffer.start < buffer.end) {
+      this$static.lastWasCR = $tokenizeBuffer(this$static.tokenizer, buffer);
+      $maybeRunScript(this$static.domTreeBuilder);
+      break;
+    }
+     else {
+      continue;
+    }
+  }
+  return false;
+}
+
+function documentWrite(text){
+  var buffer;
+  buffer = $UTF16Buffer(new UTF16Buffer, $toCharArray(text), 0, text.length);
+  while (buffer.start < buffer.end) {
+    $adjust(buffer, this.lastWasCR);
+    this.lastWasCR = false;
+    if (buffer.start < buffer.end) {
+      this.lastWasCR = $tokenizeBuffer(this.tokenizer, buffer);
+      $maybeRunScript(this.domTreeBuilder);
+    }
+  }
+}
+
+function getClass_64(){
+  return Lnu_validator_htmlparser_gwt_HtmlParser_2_classLit;
+}
+
+function HtmlParser(){
+}
+
+_ = HtmlParser.prototype = new Object_0;
+_.documentWrite = documentWrite;
+_.getClass$ = getClass_64;
+_.typeId$ = 0;
+_.domTreeBuilder = null;
+_.ending = false;
+_.lastWasCR = false;
+_.parseEndListener = null;
+_.stream = null;
+_.streamLength = 0;
+_.tokenizer = null;
+function $clinit_121(){
+  $clinit_121 = nullMethod;
+  $clinit_47();
+}
+
+function $HtmlParser$1(this$static, this$0){
+  $clinit_121();
+  this$static.this$0 = this$0;
+  return this$static;
+}
+
+function $run(this$static){
+  var $e0;
+  try {
+    $pump(this$static.this$0, true);
+  }
+   catch ($e0) {
+    $e0 = caught($e0);
+    if (instanceOf($e0, 31)) {
+      this$static.this$0.ending = true;
+    }
+     else 
+      throw $e0;
+  }
+}
+
+function getClass_65(){
+  return Lnu_validator_htmlparser_gwt_HtmlParser$1_2_classLit;
+}
+
+function HtmlParser$1(){
+}
+
+_ = HtmlParser$1.prototype = new Timer;
+_.getClass$ = getClass_65;
+_.typeId$ = 38;
+_.this$0 = null;
+function installDocWrite(doc, parser){
+  doc.write = function(){
+    if (arguments.length == 0) {
+      return;
+    }
+    var text = arguments[0];
+    for (var i = 1; i < arguments.length; i++) {
+      text += arguments[i];
+    }
+    parser.documentWrite(text);
+  }
+  ;
+  doc.writeln = function(){
+    if (arguments.length == 0) {
+      parser.documentWrite('\n');
+      return;
+    }
+    var text = arguments[0];
+    for (var i = 1; i < arguments.length; i++) {
+      text += arguments[i];
+    }
+    text += '\n';
+    parser.documentWrite(text);
+  }
+  ;
+}
+
+function parseHtmlDocument(source, document_0, useSetTimeouts, readyCallback, errorHandler){
+  var parser;
+  !readyCallback && (readyCallback = createFunction());
+  zapChildren(document_0);
+  parser = $HtmlParser(new HtmlParser, document_0);
+  installDocWrite(document_0, parser);
+  $parse(parser, source, useSetTimeouts, $ParseEndListener(new ParseEndListener, readyCallback));
+}
+
+function zapChildren(node){
+  while (node.hasChildNodes()) {
+    node.removeChild(node.lastChild);
+  }
+}
+
+function $ParseEndListener(this$static, callback){
+  this$static.callback = callback;
+  return this$static;
+}
+
+function getClass_66(){
+  return Lnu_validator_htmlparser_gwt_ParseEndListener_2_classLit;
+}
+
+function ParseEndListener(){
+}
+
+_ = ParseEndListener.prototype = new Object_0;
+_.getClass$ = getClass_66;
+_.typeId$ = 0;
+_.callback = null;
+function $clinit_124(){
+  var arr_471;
+  $clinit_124 = nullMethod;
+  ALL_NO_NS = initValues(_3Ljava_lang_String_2_classLit, 56, 1, ['', '', '', '']);
+  XMLNS_NS = initValues(_3Ljava_lang_String_2_classLit, 56, 1, ['', 'http://www.w3.org/2000/xmlns/', 'http://www.w3.org/2000/xmlns/', '']);
+  XML_NS = initValues(_3Ljava_lang_String_2_classLit, 56, 1, ['', 'http://www.w3.org/XML/1998/namespace', 'http://www.w3.org/XML/1998/namespace', '']);
+  XLINK_NS = initValues(_3Ljava_lang_String_2_classLit, 56, 1, ['', 'http://www.w3.org/1999/xlink', 'http://www.w3.org/1999/xlink', '']);
+  LANG_NS = initValues(_3Ljava_lang_String_2_classLit, 56, 1, ['', '', '', 'http://www.w3.org/XML/1998/namespace']);
+  ALL_NO_PREFIX = initValues(_3Ljava_lang_String_2_classLit, 56, 1, [null, null, null, null]);
+  XMLNS_PREFIX = initValues(_3Ljava_lang_String_2_classLit, 56, 1, [null, 'xmlns', 'xmlns', null]);
+  XLINK_PREFIX = initValues(_3Ljava_lang_String_2_classLit, 56, 1, [null, 'xlink', 'xlink', null]);
+  XML_PREFIX = initValues(_3Ljava_lang_String_2_classLit, 56, 1, [null, 'xml', 'xml', null]);
+  LANG_PREFIX = initValues(_3Ljava_lang_String_2_classLit, 56, 1, [null, null, null, 'xml']);
+  ALL_NCNAME = initValues(_3Z_classLit, 45, -1, [true, true, true, true]);
+  ALL_NO_NCNAME = initValues(_3Z_classLit, 45, -1, [false, false, false, false]);
+  D = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('d'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  K = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('k'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  R = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('r'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  X = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('x'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  Y = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('y'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  Z = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('z'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  BY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('by'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CX = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('cx'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('cy'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DX = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('dx'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('dy'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  G2 = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('g2'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  G1 = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('g1'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FX = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('fx'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('fy'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  K4 = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('k4'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  K2 = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('k2'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  K3 = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('k3'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  K1 = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('k1'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ID = $AttributeName(new AttributeName, ALL_NO_NS, SAME_LOCAL('id'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  IN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('in'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  U2 = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('u2'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  U1 = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('u1'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  RT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('rt'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  RX = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('rx'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  RY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ry'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  TO = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('to'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  Y2 = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('y2'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  Y1 = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('y1'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  X1 = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('x1'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  X2 = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('x2'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ALT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('alt'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DIR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('dir'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DUR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('dur'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  END = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('end'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FOR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('for'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  IN2 = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('in2'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MAX = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('max'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MIN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('min'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LOW = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('low'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  REL = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('rel'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  REV = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('rev'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SRC = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('src'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  AXIS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('axis'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ABBR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('abbr'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  BBOX = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('bbox'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CITE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('cite'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CODE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('code'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  BIAS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('bias'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  COLS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('cols'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CLIP = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('clip'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CHAR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('char'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  BASE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('base'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  EDGE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('edge'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DATA = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('data'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FILL = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('fill'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FROM = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('from'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FORM = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('form'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FACE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('face'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  HIGH = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('high'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  HREF = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('href'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  OPEN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('open'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ICON = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('icon'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  NAME = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('name'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MODE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('mode'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MASK = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('mask'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LINK = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('link'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LANG = $AttributeName_0(new AttributeName, LANG_NS, SAME_LOCAL('lang'), LANG_PREFIX, ALL_NCNAME, false);
+  LIST = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('list'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  TYPE_1 = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('type'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  WHEN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('when'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  WRAP = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('wrap'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  TEXT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('text'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  PATH = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('path'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  PING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ping'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  REFX = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('refx', 'refX'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  REFY = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('refy', 'refY'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SIZE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('size'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SEED = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('seed'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ROWS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('rows'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SPAN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('span'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STEP = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('step'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ROLE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('role'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  XREF = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('xref'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ASYNC = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('async'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ALINK = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('alink'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ALIGN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('align'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CLOSE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('close'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  COLOR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('color'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CLASS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('class'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CLEAR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('clear'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  BEGIN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('begin'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DEPTH = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('depth'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DEFER = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('defer'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FENCE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('fence'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FRAME = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('frame'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ISMAP = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ismap'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONEND = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onend'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  INDEX = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('index'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ORDER = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('order'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  OTHER = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('other'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONCUT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('oncut'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  NARGS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('nargs'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MEDIA = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('media'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LABEL = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('label'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LOCAL = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('local'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  WIDTH = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('width'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  TITLE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('title'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  VLINK = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('vlink'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  VALUE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('value'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SLOPE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('slope'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SHAPE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('shape'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SCOPE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('scope'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SCALE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('scale'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SPEED = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('speed'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STYLE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('style'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  RULES = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('rules'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STEMH = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('stemh'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STEMV = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('stemv'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  START = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('start'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  XMLNS = $AttributeName_0(new AttributeName, XMLNS_NS, SAME_LOCAL('xmlns'), ALL_NO_PREFIX, initValues(_3Z_classLit, 45, -1, [false, false, false, false]), true);
+  ACCEPT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('accept'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ACCENT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('accent'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ASCENT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ascent'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ACTIVE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('active'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ALTIMG = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('altimg'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ACTION = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('action'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  BORDER = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('border'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CURSOR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('cursor'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  COORDS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('coords'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FILTER = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('filter'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FORMAT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('format'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  HIDDEN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('hidden'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  HSPACE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('hspace'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  HEIGHT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('height'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONMOVE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onmove'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONLOAD = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onload'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONDRAG = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ondrag'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ORIGIN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('origin'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONZOOM = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onzoom'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONHELP = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onhelp'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONSTOP = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onstop'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONDROP = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ondrop'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONBLUR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onblur'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  OBJECT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('object'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  OFFSET = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('offset'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ORIENT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('orient'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONCOPY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('oncopy'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  NOWRAP = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('nowrap'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  NOHREF = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('nohref'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MACROS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('macros'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  METHOD = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('method'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LOWSRC = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('lowsrc'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LSPACE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('lspace'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LQUOTE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('lquote'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  USEMAP = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('usemap'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  WIDTHS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('widths'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  TARGET = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('target'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  VALUES = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('values'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  VALIGN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('valign'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  VSPACE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('vspace'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  POSTER = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('poster'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  POINTS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('points'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  PROMPT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('prompt'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SCOPED = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('scoped'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STRING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('string'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SCHEME = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('scheme'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STROKE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('stroke'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  RADIUS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('radius'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  RESULT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('result'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  REPEAT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('repeat'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  RSPACE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('rspace'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ROTATE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('rotate'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  RQUOTE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('rquote'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ALTTEXT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('alttext'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARCHIVE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('archive'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  AZIMUTH = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('azimuth'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CLOSURE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('closure'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CHECKED = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('checked'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CLASSID = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('classid'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CHAROFF = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('charoff'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  BGCOLOR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('bgcolor'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  COLSPAN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('colspan'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CHARSET = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('charset'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  COMPACT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('compact'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CONTENT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('content'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ENCTYPE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('enctype'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DATASRC = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('datasrc'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DATAFLD = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('datafld'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DECLARE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('declare'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DISPLAY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('display'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DIVISOR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('divisor'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DEFAULT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('default'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DESCENT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('descent'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  KERNING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('kerning'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  HANGING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('hanging'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  HEADERS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('headers'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONPASTE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onpaste'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONCLICK = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onclick'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  OPTIMUM = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('optimum'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONBEGIN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onbegin'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONKEYUP = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onkeyup'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONFOCUS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onfocus'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONERROR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onerror'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONINPUT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('oninput'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONABORT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onabort'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONSTART = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onstart'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONRESET = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onreset'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  OPACITY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('opacity'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  NOSHADE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('noshade'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MINSIZE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('minsize'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MAXSIZE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('maxsize'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LOOPEND = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('loopend'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LARGEOP = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('largeop'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  UNICODE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('unicode'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  TARGETX = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('targetx', 'targetX'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  TARGETY = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('targety', 'targetY'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  VIEWBOX = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('viewbox', 'viewBox'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  VERSION = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('version'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  PATTERN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('pattern'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  PROFILE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('profile'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SPACING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('spacing'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  RESTART = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('restart'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ROWSPAN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('rowspan'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SANDBOX = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('sandbox'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SUMMARY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('summary'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STANDBY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('standby'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  REPLACE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('replace'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  AUTOPLAY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('autoplay'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ADDITIVE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('additive'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CALCMODE = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('calcmode', 'calcMode'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CODETYPE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('codetype'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CODEBASE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('codebase'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CONTROLS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('controls'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  BEVELLED = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('bevelled'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  BASELINE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('baseline'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  EXPONENT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('exponent'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  EDGEMODE = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('edgemode', 'edgeMode'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ENCODING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('encoding'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  GLYPHREF = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('glyphref', 'glyphRef'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DATETIME = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('datetime'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DISABLED = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('disabled'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FONTSIZE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('fontsize'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  KEYTIMES = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('keytimes', 'keyTimes'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  PANOSE_1 = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('panose-1'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  HREFLANG = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('hreflang'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONRESIZE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onresize'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONCHANGE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onchange'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONBOUNCE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onbounce'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONUNLOAD = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onunload'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONFINISH = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onfinish'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONSCROLL = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onscroll'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  OPERATOR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('operator'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  OVERFLOW = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('overflow'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONSUBMIT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onsubmit'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONREPEAT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onrepeat'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONSELECT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onselect'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  NOTATION = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('notation'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  NORESIZE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('noresize'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MANIFEST = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('manifest'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MATHSIZE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('mathsize'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MULTIPLE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('multiple'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LONGDESC = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('longdesc'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LANGUAGE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('language'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  TEMPLATE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('template'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  TABINDEX = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('tabindex'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  READONLY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('readonly'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SELECTED = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('selected'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ROWLINES = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('rowlines'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SEAMLESS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('seamless'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ROWALIGN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('rowalign'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STRETCHY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('stretchy'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  REQUIRED = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('required'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  XML_BASE = $AttributeName_0(new AttributeName, XML_NS, COLONIFIED_LOCAL('xml:base', 'base'), XML_PREFIX, initValues(_3Z_classLit, 45, -1, [false, true, true, false]), false);
+  XML_LANG = $AttributeName_0(new AttributeName, XML_NS, COLONIFIED_LOCAL('xml:lang', 'lang'), XML_PREFIX, initValues(_3Z_classLit, 45, -1, [false, true, true, false]), false);
+  X_HEIGHT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('x-height'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_OWNS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-owns'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  AUTOFOCUS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('autofocus'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_SORT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-sort'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ACCESSKEY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('accesskey'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_BUSY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-busy'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_GRAB = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-grab'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  AMPLITUDE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('amplitude'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_LIVE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-live'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CLIP_RULE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('clip-rule'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CLIP_PATH = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('clip-path'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  EQUALROWS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('equalrows'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ELEVATION = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('elevation'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DIRECTION = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('direction'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DRAGGABLE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('draggable'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FILTERRES = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('filterres', 'filterRes'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FILL_RULE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('fill-rule'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FONTSTYLE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('fontstyle'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FONT_SIZE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('font-size'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  KEYPOINTS = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('keypoints', 'keyPoints'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  HIDEFOCUS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('hidefocus'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONMESSAGE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onmessage'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  INTERCEPT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('intercept'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONDRAGEND = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ondragend'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONMOVEEND = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onmoveend'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONINVALID = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('oninvalid'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONKEYDOWN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onkeydown'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONFOCUSIN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onfocusin'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONMOUSEUP = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onmouseup'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  INPUTMODE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('inputmode'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONROWEXIT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onrowexit'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MATHCOLOR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('mathcolor'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MASKUNITS = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('maskunits', 'maskUnits'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MAXLENGTH = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('maxlength'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LINEBREAK = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('linebreak'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LOOPSTART = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('loopstart'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  TRANSFORM = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('transform'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  V_HANGING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('v-hanging'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  VALUETYPE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('valuetype'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  POINTSATZ = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('pointsatz', 'pointsAtZ'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  POINTSATX = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('pointsatx', 'pointsAtX'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  POINTSATY = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('pointsaty', 'pointsAtY'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  PLAYCOUNT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('playcount'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SYMMETRIC = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('symmetric'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SCROLLING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('scrolling'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  REPEATDUR = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('repeatdur', 'repeatDur'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SELECTION = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('selection'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SEPARATOR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('separator'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  XML_SPACE = $AttributeName_0(new AttributeName, XML_NS, COLONIFIED_LOCAL('xml:space', 'space'), XML_PREFIX, initValues(_3Z_classLit, 45, -1, [false, true, true, false]), false);
+  AUTOSUBMIT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('autosubmit'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ALPHABETIC = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('alphabetic'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ACTIONTYPE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('actiontype'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ACCUMULATE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('accumulate'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_LEVEL = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-level'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  COLUMNSPAN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('columnspan'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CAP_HEIGHT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('cap-height'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  BACKGROUND = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('background'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  GLYPH_NAME = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('glyph-name'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  GROUPALIGN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('groupalign'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FONTFAMILY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('fontfamily'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FONTWEIGHT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('fontweight'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FONT_STYLE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('font-style'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  KEYSPLINES = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('keysplines', 'keySplines'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  HTTP_EQUIV = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('http-equiv'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONACTIVATE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onactivate'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  OCCURRENCE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('occurrence'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  IRRELEVANT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('irrelevant'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONDBLCLICK = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ondblclick'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONDRAGDROP = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ondragdrop'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONKEYPRESS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onkeypress'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONROWENTER = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onrowenter'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONDRAGOVER = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ondragover'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONFOCUSOUT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onfocusout'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONMOUSEOUT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onmouseout'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  NUMOCTAVES = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('numoctaves', 'numOctaves'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MARKER_MID = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('marker-mid'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MARKER_END = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('marker-end'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  TEXTLENGTH = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('textlength', 'textLength'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  VISIBILITY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('visibility'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  VIEWTARGET = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('viewtarget', 'viewTarget'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  VERT_ADV_Y = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('vert-adv-y'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  PATHLENGTH = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('pathlength', 'pathLength'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  REPEAT_MAX = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('repeat-max'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  RADIOGROUP = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('radiogroup'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STOP_COLOR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('stop-color'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SEPARATORS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('separators'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  REPEAT_MIN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('repeat-min'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ROWSPACING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('rowspacing'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ZOOMANDPAN = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('zoomandpan', 'zoomAndPan'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  XLINK_TYPE = $AttributeName_0(new AttributeName, XLINK_NS, COLONIFIED_LOCAL('xlink:type', 'type'), XLINK_PREFIX, initValues(_3Z_classLit, 45, -1, [false, true, true, false]), false);
+  XLINK_ROLE = $AttributeName_0(new AttributeName, XLINK_NS, COLONIFIED_LOCAL('xlink:role', 'role'), XLINK_PREFIX, initValues(_3Z_classLit, 45, -1, [false, true, true, false]), false);
+  XLINK_HREF = $AttributeName_0(new AttributeName, XLINK_NS, COLONIFIED_LOCAL('xlink:href', 'href'), XLINK_PREFIX, initValues(_3Z_classLit, 45, -1, [false, true, true, false]), false);
+  XLINK_SHOW = $AttributeName_0(new AttributeName, XLINK_NS, COLONIFIED_LOCAL('xlink:show', 'show'), XLINK_PREFIX, initValues(_3Z_classLit, 45, -1, [false, true, true, false]), false);
+  ACCENTUNDER = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('accentunder'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_SECRET = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-secret'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_ATOMIC = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-atomic'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_HIDDEN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-hidden'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_FLOWTO = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-flowto'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARABIC_FORM = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('arabic-form'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CELLPADDING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('cellpadding'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CELLSPACING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('cellspacing'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  COLUMNWIDTH = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('columnwidth'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  COLUMNALIGN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('columnalign'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  COLUMNLINES = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('columnlines'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CONTEXTMENU = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('contextmenu'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  BASEPROFILE = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('baseprofile', 'baseProfile'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FONT_FAMILY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('font-family'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FRAMEBORDER = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('frameborder'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FILTERUNITS = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('filterunits', 'filterUnits'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FLOOD_COLOR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('flood-color'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FONT_WEIGHT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('font-weight'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  HORIZ_ADV_X = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('horiz-adv-x'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONDRAGLEAVE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ondragleave'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONMOUSEMOVE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onmousemove'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ORIENTATION = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('orientation'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONMOUSEDOWN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onmousedown'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONMOUSEOVER = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onmouseover'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONDRAGENTER = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ondragenter'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  IDEOGRAPHIC = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ideographic'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONBEFORECUT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onbeforecut'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONFORMINPUT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onforminput'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONDRAGSTART = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ondragstart'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONMOVESTART = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onmovestart'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MARKERUNITS = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('markerunits', 'markerUnits'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MATHVARIANT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('mathvariant'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MARGINWIDTH = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('marginwidth'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MARKERWIDTH = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('markerwidth', 'markerWidth'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  TEXT_ANCHOR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('text-anchor'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  TABLEVALUES = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('tablevalues', 'tableValues'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SCRIPTLEVEL = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('scriptlevel'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  REPEATCOUNT = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('repeatcount', 'repeatCount'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STITCHTILES = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('stitchtiles', 'stitchTiles'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STARTOFFSET = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('startoffset', 'startOffset'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SCROLLDELAY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('scrolldelay'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  XMLNS_XLINK = $AttributeName_0(new AttributeName, XMLNS_NS, COLONIFIED_LOCAL('xmlns:xlink', 'xlink'), XMLNS_PREFIX, initValues(_3Z_classLit, 45, -1, [false, false, false, false]), true);
+  XLINK_TITLE = $AttributeName_0(new AttributeName, XLINK_NS, COLONIFIED_LOCAL('xlink:title', 'title'), XLINK_PREFIX, initValues(_3Z_classLit, 45, -1, [false, true, true, false]), false);
+  ARIA_INVALID = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-invalid'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_PRESSED = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-pressed'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_CHECKED = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-checked'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  AUTOCOMPLETE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('autocomplete'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_SETSIZE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-setsize'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_CHANNEL = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-channel'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  EQUALCOLUMNS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('equalcolumns'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DISPLAYSTYLE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('displaystyle'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DATAFORMATAS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('dataformatas'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FILL_OPACITY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('fill-opacity'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FONT_VARIANT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('font-variant'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FONT_STRETCH = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('font-stretch'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FRAMESPACING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('framespacing'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  KERNELMATRIX = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('kernelmatrix', 'kernelMatrix'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONDEACTIVATE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ondeactivate'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONROWSDELETE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onrowsdelete'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONMOUSELEAVE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onmouseleave'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONFORMCHANGE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onformchange'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONCELLCHANGE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('oncellchange'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONMOUSEWHEEL = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onmousewheel'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONMOUSEENTER = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onmouseenter'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONAFTERPRINT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onafterprint'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONBEFORECOPY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onbeforecopy'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MARGINHEIGHT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('marginheight'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MARKERHEIGHT = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('markerheight', 'markerHeight'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MARKER_START = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('marker-start'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MATHEMATICAL = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('mathematical'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LENGTHADJUST = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('lengthadjust', 'lengthAdjust'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  UNSELECTABLE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('unselectable'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  UNICODE_BIDI = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('unicode-bidi'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  UNITS_PER_EM = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('units-per-em'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  WORD_SPACING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('word-spacing'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  WRITING_MODE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('writing-mode'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  V_ALPHABETIC = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('v-alphabetic'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  PATTERNUNITS = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('patternunits', 'patternUnits'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SPREADMETHOD = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('spreadmethod', 'spreadMethod'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SURFACESCALE = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('surfacescale', 'surfaceScale'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STROKE_WIDTH = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('stroke-width'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  REPEAT_START = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('repeat-start'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STDDEVIATION = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('stddeviation', 'stdDeviation'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STOP_OPACITY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('stop-opacity'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_CONTROLS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-controls'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_HASPOPUP = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-haspopup'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ACCENT_HEIGHT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('accent-height'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_VALUENOW = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-valuenow'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_RELEVANT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-relevant'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_POSINSET = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-posinset'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_VALUEMAX = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-valuemax'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_READONLY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-readonly'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_SELECTED = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-selected'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_REQUIRED = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-required'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_EXPANDED = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-expanded'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_DISABLED = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-disabled'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ATTRIBUTETYPE = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('attributetype', 'attributeType'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ATTRIBUTENAME = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('attributename', 'attributeName'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_DATATYPE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-datatype'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_VALUEMIN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-valuemin'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  BASEFREQUENCY = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('basefrequency', 'baseFrequency'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  COLUMNSPACING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('columnspacing'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  COLOR_PROFILE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('color-profile'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CLIPPATHUNITS = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('clippathunits', 'clipPathUnits'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DEFINITIONURL = $AttributeName_0(new AttributeName, ALL_NO_NS, (arr_471 = initDim(_3Ljava_lang_String_2_classLit, 56, 1, 4, 0) , arr_471[0] = 'definitionurl' , arr_471[1] = 'definitionURL' , arr_471[2] = 'definitionurl' , arr_471[3] = 'definitionurl' , arr_471), ALL_NO_PREFIX, ALL_NCNAME, false);
+  GRADIENTUNITS = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('gradientunits', 'gradientUnits'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FLOOD_OPACITY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('flood-opacity'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONAFTERUPDATE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onafterupdate'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONERRORUPDATE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onerrorupdate'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONBEFOREPASTE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onbeforepaste'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONLOSECAPTURE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onlosecapture'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONCONTEXTMENU = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('oncontextmenu'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONSELECTSTART = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onselectstart'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONBEFOREPRINT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onbeforeprint'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MOVABLELIMITS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('movablelimits'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LINETHICKNESS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('linethickness'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  UNICODE_RANGE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('unicode-range'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  THINMATHSPACE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('thinmathspace'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  VERT_ORIGIN_X = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('vert-origin-x'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  VERT_ORIGIN_Y = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('vert-origin-y'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  V_IDEOGRAPHIC = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('v-ideographic'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  PRESERVEALPHA = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('preservealpha', 'preserveAlpha'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SCRIPTMINSIZE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('scriptminsize'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SPECIFICATION = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('specification'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  XLINK_ACTUATE = $AttributeName_0(new AttributeName, XLINK_NS, COLONIFIED_LOCAL('xlink:actuate', 'actuate'), XLINK_PREFIX, initValues(_3Z_classLit, 45, -1, [false, true, true, false]), false);
+  XLINK_ARCROLE = $AttributeName_0(new AttributeName, XLINK_NS, COLONIFIED_LOCAL('xlink:arcrole', 'arcrole'), XLINK_PREFIX, initValues(_3Z_classLit, 45, -1, [false, true, true, false]), false);
+  ACCEPT_CHARSET = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('accept-charset'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ALIGNMENTSCOPE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('alignmentscope'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_MULTILINE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-multiline'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  BASELINE_SHIFT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('baseline-shift'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  HORIZ_ORIGIN_X = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('horiz-origin-x'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  HORIZ_ORIGIN_Y = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('horiz-origin-y'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONBEFOREUPDATE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onbeforeupdate'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONFILTERCHANGE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onfilterchange'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONROWSINSERTED = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onrowsinserted'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONBEFOREUNLOAD = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onbeforeunload'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MATHBACKGROUND = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('mathbackground'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LETTER_SPACING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('letter-spacing'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LIGHTING_COLOR = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('lighting-color'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  THICKMATHSPACE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('thickmathspace'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  TEXT_RENDERING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('text-rendering'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  V_MATHEMATICAL = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('v-mathematical'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  POINTER_EVENTS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('pointer-events'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  PRIMITIVEUNITS = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('primitiveunits', 'primitiveUnits'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SYSTEMLANGUAGE = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('systemlanguage', 'systemLanguage'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STROKE_LINECAP = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('stroke-linecap'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SUBSCRIPTSHIFT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('subscriptshift'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STROKE_OPACITY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('stroke-opacity'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_DROPEFFECT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-dropeffect'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_LABELLEDBY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-labelledby'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_TEMPLATEID = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-templateid'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  COLOR_RENDERING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('color-rendering'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CONTENTEDITABLE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('contenteditable'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DIFFUSECONSTANT = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('diffuseconstant', 'diffuseConstant'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONDATAAVAILABLE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ondataavailable'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONCONTROLSELECT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('oncontrolselect'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  IMAGE_RENDERING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('image-rendering'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MEDIUMMATHSPACE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('mediummathspace'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  TEXT_DECORATION = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('text-decoration'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SHAPE_RENDERING = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('shape-rendering'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STROKE_LINEJOIN = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('stroke-linejoin'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  REPEAT_TEMPLATE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('repeat-template'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_DESCRIBEDBY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-describedby'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CONTENTSTYLETYPE = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('contentstyletype', 'contentStyleType'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  FONT_SIZE_ADJUST = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('font-size-adjust'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  KERNELUNITLENGTH = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('kernelunitlength', 'kernelUnitLength'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONBEFOREACTIVATE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onbeforeactivate'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONPROPERTYCHANGE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onpropertychange'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONDATASETCHANGED = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ondatasetchanged'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  MASKCONTENTUNITS = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('maskcontentunits', 'maskContentUnits'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  PATTERNTRANSFORM = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('patterntransform', 'patternTransform'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  REQUIREDFEATURES = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('requiredfeatures', 'requiredFeatures'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  RENDERING_INTENT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('rendering-intent'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SPECULAREXPONENT = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('specularexponent', 'specularExponent'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SPECULARCONSTANT = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('specularconstant', 'specularConstant'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SUPERSCRIPTSHIFT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('superscriptshift'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STROKE_DASHARRAY = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('stroke-dasharray'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  XCHANNELSELECTOR = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('xchannelselector', 'xChannelSelector'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  YCHANNELSELECTOR = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('ychannelselector', 'yChannelSelector'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_AUTOCOMPLETE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-autocomplete'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  CONTENTSCRIPTTYPE = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('contentscripttype', 'contentScriptType'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ENABLE_BACKGROUND = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('enable-background'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  DOMINANT_BASELINE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('dominant-baseline'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  GRADIENTTRANSFORM = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('gradienttransform', 'gradientTransform'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONBEFORDEACTIVATE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onbefordeactivate'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONDATASETCOMPLETE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('ondatasetcomplete'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  OVERLINE_POSITION = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('overline-position'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONBEFOREEDITFOCUS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onbeforeeditfocus'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  LIMITINGCONEANGLE = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('limitingconeangle', 'limitingConeAngle'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  VERYTHINMATHSPACE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('verythinmathspace'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STROKE_DASHOFFSET = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('stroke-dashoffset'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STROKE_MITERLIMIT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('stroke-miterlimit'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ALIGNMENT_BASELINE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('alignment-baseline'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ONREADYSTATECHANGE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('onreadystatechange'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  OVERLINE_THICKNESS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('overline-thickness'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  UNDERLINE_POSITION = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('underline-position'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  VERYTHICKMATHSPACE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('verythickmathspace'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  REQUIREDEXTENSIONS = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('requiredextensions', 'requiredExtensions'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  COLOR_INTERPOLATION = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('color-interpolation'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  UNDERLINE_THICKNESS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('underline-thickness'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  PRESERVEASPECTRATIO = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('preserveaspectratio', 'preserveAspectRatio'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  PATTERNCONTENTUNITS = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('patterncontentunits', 'patternContentUnits'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_MULTISELECTABLE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-multiselectable'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  SCRIPTSIZEMULTIPLIER = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('scriptsizemultiplier'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ARIA_ACTIVEDESCENDANT = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('aria-activedescendant'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  VERYVERYTHINMATHSPACE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('veryverythinmathspace'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  VERYVERYTHICKMATHSPACE = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('veryverythickmathspace'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STRIKETHROUGH_POSITION = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('strikethrough-position'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  STRIKETHROUGH_THICKNESS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('strikethrough-thickness'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  EXTERNALRESOURCESREQUIRED = $AttributeName_0(new AttributeName, ALL_NO_NS, SVG_DIFFERENT('externalresourcesrequired', 'externalResourcesRequired'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  GLYPH_ORIENTATION_VERTICAL = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('glyph-orientation-vertical'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  COLOR_INTERPOLATION_FILTERS = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('color-interpolation-filters'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  GLYPH_ORIENTATION_HORIZONTAL = $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL('glyph-orientation-horizontal'), ALL_NO_PREFIX, ALL_NCNAME, false);
+  ATTRIBUTE_NAMES = initValues(_3Lnu_validator_htmlparser_impl_AttributeName_2_classLit, 60, 13, [D, K, R, X, Y, Z, BY, CX, CY, DX, DY, G2, G1, FX, FY, K4, K2, K3, K1, ID, IN, U2, U1, RT, RX, RY, TO, Y2, Y1, X1, X2, ALT, DIR, DUR, END, FOR, IN2, MAX, MIN, LOW, REL, REV, SRC, AXIS, ABBR, BBOX, CITE, CODE, BIAS, COLS, CLIP, CHAR, BASE, EDGE, DATA, FILL, FROM, FORM, FACE, HIGH, HREF, OPEN, ICON, NAME, MODE, MASK, LINK, LANG, LIST, TYPE_1, WHEN, WRAP, TEXT, PATH, PING, REFX, REFY, SIZE, SEED, ROWS, SPAN, STEP, ROLE, XREF, ASYNC, ALINK, ALIGN, CLOSE, COLOR, CLASS, CLEAR, BEGIN, DEPTH, DEFER, FENCE, FRAME, ISMAP, ONEND, INDEX, ORDER, OTHER, ONCUT, NARGS, MEDIA, LABEL, LOCAL, WIDTH, TITLE, VLINK, VALUE, SLOPE, SHAPE, SCOPE, SCALE, SPEED, STYLE, RULES, STEMH, STEMV, START, XMLNS, ACCEPT, ACCENT, ASCENT, ACTIVE, ALTIMG, ACTION, BORDER, CURSOR, COORDS, FILTER, FORMAT, HIDDEN, HSPACE, HEIGHT, ONMOVE, ONLOAD, ONDRAG, ORIGIN, ONZOOM, ONHELP, ONSTOP, ONDROP, ONBLUR, OBJECT, OFFSET, ORIENT, ONCOPY, NOWRAP, NOHREF, MACROS, METHOD, LOWSRC, LSPACE, LQUOTE, USEMAP, WIDTHS, TARGET, VALUES, VALIGN, VSPACE, POSTER, POINTS, PROMPT, SCOPED, STRING, SCHEME, STROKE, RADIUS, RESULT, REPEAT, RSPACE, ROTATE, RQUOTE, ALTTEXT, ARCHIVE, AZIMUTH, CLOSURE, CHECKED, CLASSID, CHAROFF, BGCOLOR, COLSPAN, CHARSET, COMPACT, CONTENT, ENCTYPE, DATASRC, DATAFLD, DECLARE, DISPLAY, DIVISOR, DEFAULT, DESCENT, KERNING, HANGING, HEADERS, ONPASTE, ONCLICK, OPTIMUM, ONBEGIN, ONKEYUP, ONFOCUS, ONERROR, ONINPUT, ONABORT, ONSTART, ONRESET, OPACITY, NOSHADE, MINSIZE, MAXSIZE, LOOPEND, LARGEOP, UNICODE, TARGETX, TARGETY, VIEWBOX, VERSION, PATTERN, PROFILE, SPACING, RESTART, ROWSPAN, SANDBOX, SUMMARY, STANDBY, REPLACE, AUTOPLAY, ADDITIVE, CALCMODE, CODETYPE, CODEBASE, CONTROLS, BEVELLED, BASELINE, EXPONENT, EDGEMODE, ENCODING, GLYPHREF, DATETIME, DISABLED, FONTSIZE, KEYTIMES, PANOSE_1, HREFLANG, ONRESIZE, ONCHANGE, ONBOUNCE, ONUNLOAD, ONFINISH, ONSCROLL, OPERATOR, OVERFLOW, ONSUBMIT, ONREPEAT, ONSELECT, NOTATION, NORESIZE, MANIFEST, MATHSIZE, MULTIPLE, LONGDESC, LANGUAGE, TEMPLATE, TABINDEX, READONLY, SELECTED, ROWLINES, SEAMLESS, ROWALIGN, STRETCHY, REQUIRED, XML_BASE, XML_LANG, X_HEIGHT, ARIA_OWNS, AUTOFOCUS, ARIA_SORT, ACCESSKEY, ARIA_BUSY, ARIA_GRAB, AMPLITUDE, ARIA_LIVE, CLIP_RULE, CLIP_PATH, EQUALROWS, ELEVATION, DIRECTION, DRAGGABLE, FILTERRES, FILL_RULE, FONTSTYLE, FONT_SIZE, KEYPOINTS, HIDEFOCUS, ONMESSAGE, INTERCEPT, ONDRAGEND, ONMOVEEND, ONINVALID, ONKEYDOWN, ONFOCUSIN, ONMOUSEUP, INPUTMODE, ONROWEXIT, MATHCOLOR, MASKUNITS, MAXLENGTH, LINEBREAK, LOOPSTART, TRANSFORM, V_HANGING, VALUETYPE, POINTSATZ, POINTSATX, POINTSATY, PLAYCOUNT, SYMMETRIC, SCROLLING, REPEATDUR, SELECTION, SEPARATOR, XML_SPACE, AUTOSUBMIT, ALPHABETIC, ACTIONTYPE, ACCUMULATE, ARIA_LEVEL, COLUMNSPAN, CAP_HEIGHT, BACKGROUND, GLYPH_NAME, GROUPALIGN, FONTFAMILY, FONTWEIGHT, FONT_STYLE, KEYSPLINES, HTTP_EQUIV, ONACTIVATE, OCCURRENCE, IRRELEVANT, ONDBLCLICK, ONDRAGDROP, ONKEYPRESS, ONROWENTER, ONDRAGOVER, ONFOCUSOUT, ONMOUSEOUT, NUMOCTAVES, MARKER_MID, MARKER_END, TEXTLENGTH, VISIBILITY, VIEWTARGET, VERT_ADV_Y, PATHLENGTH, REPEAT_MAX, RADIOGROUP, STOP_COLOR, SEPARATORS, REPEAT_MIN, ROWSPACING, ZOOMANDPAN, XLINK_TYPE, XLINK_ROLE, XLINK_HREF, XLINK_SHOW, ACCENTUNDER, ARIA_SECRET, ARIA_ATOMIC, ARIA_HIDDEN, ARIA_FLOWTO, ARABIC_FORM, CELLPADDING, CELLSPACING, COLUMNWIDTH, COLUMNALIGN, COLUMNLINES, CONTEXTMENU, BASEPROFILE, FONT_FAMILY, FRAMEBORDER, FILTERUNITS, FLOOD_COLOR, FONT_WEIGHT, HORIZ_ADV_X, ONDRAGLEAVE, ONMOUSEMOVE, ORIENTATION, ONMOUSEDOWN, ONMOUSEOVER, ONDRAGENTER, IDEOGRAPHIC, ONBEFORECUT, ONFORMINPUT, ONDRAGSTART, ONMOVESTART, MARKERUNITS, MATHVARIANT, MARGINWIDTH, MARKERWIDTH, TEXT_ANCHOR, TABLEVALUES, SCRIPTLEVEL, REPEATCOUNT, STITCHTILES, STARTOFFSET, SCROLLDELAY, XMLNS_XLINK, XLINK_TITLE, ARIA_INVALID, ARIA_PRESSED, ARIA_CHECKED, AUTOCOMPLETE, ARIA_SETSIZE, ARIA_CHANNEL, EQUALCOLUMNS, DISPLAYSTYLE, DATAFORMATAS, FILL_OPACITY, FONT_VARIANT, FONT_STRETCH, FRAMESPACING, KERNELMATRIX, ONDEACTIVATE, ONROWSDELETE, ONMOUSELEAVE, ONFORMCHANGE, ONCELLCHANGE, ONMOUSEWHEEL, ONMOUSEENTER, ONAFTERPRINT, ONBEFORECOPY, MARGINHEIGHT, MARKERHEIGHT, MARKER_START, MATHEMATICAL, LENGTHADJUST, UNSELECTABLE, UNICODE_BIDI, UNITS_PER_EM, WORD_SPACING, WRITING_MODE, V_ALPHABETIC, PATTERNUNITS, SPREADMETHOD, SURFACESCALE, STROKE_WIDTH, REPEAT_START, STDDEVIATION, STOP_OPACITY, ARIA_CONTROLS, ARIA_HASPOPUP, ACCENT_HEIGHT, ARIA_VALUENOW, ARIA_RELEVANT, ARIA_POSINSET, ARIA_VALUEMAX, ARIA_READONLY, ARIA_SELECTED, ARIA_REQUIRED, ARIA_EXPANDED, ARIA_DISABLED, ATTRIBUTETYPE, ATTRIBUTENAME, ARIA_DATATYPE, ARIA_VALUEMIN, BASEFREQUENCY, COLUMNSPACING, COLOR_PROFILE, CLIPPATHUNITS, DEFINITIONURL, GRADIENTUNITS, FLOOD_OPACITY, ONAFTERUPDATE, ONERRORUPDATE, ONBEFOREPASTE, ONLOSECAPTURE, ONCONTEXTMENU, ONSELECTSTART, ONBEFOREPRINT, MOVABLELIMITS, LINETHICKNESS, UNICODE_RANGE, THINMATHSPACE, VERT_ORIGIN_X, VERT_ORIGIN_Y, V_IDEOGRAPHIC, PRESERVEALPHA, SCRIPTMINSIZE, SPECIFICATION, XLINK_ACTUATE, XLINK_ARCROLE, ACCEPT_CHARSET, ALIGNMENTSCOPE, ARIA_MULTILINE, BASELINE_SHIFT, HORIZ_ORIGIN_X, HORIZ_ORIGIN_Y, ONBEFOREUPDATE, ONFILTERCHANGE, ONROWSINSERTED, ONBEFOREUNLOAD, MATHBACKGROUND, LETTER_SPACING, LIGHTING_COLOR, THICKMATHSPACE, TEXT_RENDERING, V_MATHEMATICAL, POINTER_EVENTS, PRIMITIVEUNITS, SYSTEMLANGUAGE, STROKE_LINECAP, SUBSCRIPTSHIFT, STROKE_OPACITY, ARIA_DROPEFFECT, ARIA_LABELLEDBY, ARIA_TEMPLATEID, COLOR_RENDERING, CONTENTEDITABLE, DIFFUSECONSTANT, ONDATAAVAILABLE, ONCONTROLSELECT, IMAGE_RENDERING, MEDIUMMATHSPACE, TEXT_DECORATION, SHAPE_RENDERING, STROKE_LINEJOIN, REPEAT_TEMPLATE, ARIA_DESCRIBEDBY, CONTENTSTYLETYPE, FONT_SIZE_ADJUST, KERNELUNITLENGTH, ONBEFOREACTIVATE, ONPROPERTYCHANGE, ONDATASETCHANGED, MASKCONTENTUNITS, PATTERNTRANSFORM, REQUIREDFEATURES, RENDERING_INTENT, SPECULAREXPONENT, SPECULARCONSTANT, SUPERSCRIPTSHIFT, STROKE_DASHARRAY, XCHANNELSELECTOR, YCHANNELSELECTOR, ARIA_AUTOCOMPLETE, CONTENTSCRIPTTYPE, ENABLE_BACKGROUND, DOMINANT_BASELINE, GRADIENTTRANSFORM, ONBEFORDEACTIVATE, ONDATASETCOMPLETE, OVERLINE_POSITION, ONBEFOREEDITFOCUS, LIMITINGCONEANGLE, VERYTHINMATHSPACE, STROKE_DASHOFFSET, STROKE_MITERLIMIT, ALIGNMENT_BASELINE, ONREADYSTATECHANGE, OVERLINE_THICKNESS, UNDERLINE_POSITION, VERYTHICKMATHSPACE, REQUIREDEXTENSIONS, COLOR_INTERPOLATION, UNDERLINE_THICKNESS, PRESERVEASPECTRATIO, PATTERNCONTENTUNITS, ARIA_MULTISELECTABLE, SCRIPTSIZEMULTIPLIER, ARIA_ACTIVEDESCENDANT, VERYVERYTHINMATHSPACE, VERYVERYTHICKMATHSPACE, STRIKETHROUGH_POSITION, STRIKETHROUGH_THICKNESS, EXTERNALRESOURCESREQUIRED, GLYPH_ORIENTATION_VERTICAL, COLOR_INTERPOLATION_FILTERS, GLYPH_ORIENTATION_HORIZONTAL]);
+  ATTRIBUTE_HASHES = initValues(_3I_classLit, 49, -1, [1153, 1383, 1601, 1793, 1827, 1857, 68600, 69146, 69177, 70237, 70270, 71572, 71669, 72415, 72444, 74846, 74904, 74943, 75001, 75276, 75590, 84742, 84839, 85575, 85963, 85992, 87204, 88074, 88171, 89130, 89163, 3207892, 3283895, 3284791, 3338752, 3358197, 3369562, 3539124, 3562402, 3574260, 3670335, 3696933, 3721879, 135280021, 135346322, 136317019, 136475749, 136548517, 136652214, 136884919, 136902418, 136942992, 137292068, 139120259, 139785574, 142250603, 142314056, 142331176, 142519584, 144752417, 145106895, 146147200, 146765926, 148805544, 149655723, 149809441, 150018784, 150445028, 150923321, 152528754, 152536216, 152647366, 152962785, 155219321, 155654904, 157317483, 157350248, 157437941, 157447478, 157604838, 157685404, 157894402, 158315188, 166078431, 169409980, 169700259, 169856932, 170007032, 170409695, 170466488, 170513710, 170608367, 173028944, 173896963, 176090625, 176129212, 179390001, 179489057, 179627464, 179840468, 179849042, 180004216, 181779081, 183027151, 183645319, 183698797, 185922012, 185997252, 188312483, 188675799, 190977533, 190992569, 191006194, 191033518, 191038774, 191096249, 191166163, 191194426, 191522106, 191568039, 200104642, 202506661, 202537381, 202602917, 203070590, 203120766, 203389054, 203690071, 203971238, 203986524, 209040857, 209125756, 212055489, 212322418, 212746849, 213002877, 213055164, 213088023, 213259873, 213273386, 213435118, 213437318, 213438231, 213493071, 213532268, 213542834, 213584431, 213659891, 215285828, 215880731, 216112976, 216684637, 217369699, 217565298, 217576549, 218186795, 219743185, 220082234, 221623802, 221986406, 222283890, 223089542, 223138630, 223311265, 224547358, 224587256, 224589550, 224655650, 224785518, 224810917, 224813302, 225429618, 225432950, 225440869, 236107233, 236709921, 236838947, 237117095, 237143271, 237172455, 237209953, 237354143, 237372743, 237668065, 237703073, 237714273, 239743521, 240512803, 240522627, 240560417, 240656513, 241015715, 241062755, 241065383, 243523041, 245865199, 246261793, 246556195, 246774817, 246923491, 246928419, 246981667, 247014847, 247058369, 247112833, 247118177, 247119137, 247128739, 247316903, 249533729, 250235623, 250269543, 251083937, 251402351, 252339047, 253260911, 253293679, 254844367, 255547879, 256077281, 256345377, 258124199, 258354465, 258605063, 258744193, 258845603, 258856961, 258926689, 269869248, 270174334, 270709417, 270778994, 270781796, 271102503, 271478858, 271490090, 272870654, 273335275, 273369140, 273924313, 274108530, 274116736, 276818662, 277476156, 279156579, 279349675, 280108533, 280128712, 280132869, 280162403, 280280292, 280413430, 280506130, 280677397, 280678580, 280686710, 280689066, 282736758, 283110901, 283275116, 283823226, 283890012, 284479340, 284606461, 286700477, 286798916, 291557706, 291665349, 291804100, 292138018, 292166446, 292418738, 292451039, 300298041, 300374839, 300597935, 303073389, 303083839, 303266673, 303354997, 303430688, 303576261, 303724281, 303819694, 304242723, 304382625, 306247792, 307227811, 307468786, 307724489, 309671175, 310252031, 310358241, 310373094, 311015256, 313357609, 313683893, 313701861, 313706996, 313707317, 313710350, 314027746, 314038181, 314091299, 314205627, 314233813, 316741830, 316797986, 317486755, 317794164, 318721061, 320076137, 322657125, 322887778, 323506876, 323572412, 323605180, 323938869, 325060058, 325320188, 325398738, 325541490, 325671619, 333868843, 336806130, 337212108, 337282686, 337285434, 337585223, 338036037, 338298087, 338566051, 340943551, 341190970, 342995704, 343352124, 343912673, 344585053, 346977248, 347218098, 347262163, 347278576, 347438191, 347655959, 347684788, 347726430, 347727772, 347776035, 347776629, 349500753, 350880161, 350887073, 353384123, 355496998, 355906922, 355979793, 356545959, 358637867, 358905016, 359164318, 359247286, 359350571, 359579447, 365560330, 367399355, 367420285, 367510727, 368013212, 370234760, 370353345, 370710317, 371074566, 371122285, 371194213, 371448425, 371448430, 371545055, 371596922, 371758751, 371964792, 372151328, 376550136, 376710172, 376795771, 376826271, 376906556, 380514830, 380774774, 380775037, 381030322, 381136500, 381281631, 381282269, 381285504, 381330595, 381331422, 381335911, 381336484, 383907298, 383917408, 384595009, 384595013, 387799894, 387823201, 392581647, 392584937, 392742684, 392906485, 393003349, 400644707, 400973830, 404428547, 404432113, 404432865, 404469244, 404478897, 404694860, 406887479, 408294949, 408789955, 410022510, 410467324, 410586448, 410945965, 411845275, 414327152, 414327932, 414329781, 414346257, 414346439, 414639928, 414835998, 414894517, 414986533, 417465377, 417465381, 417492216, 418259232, 419310946, 420103495, 420242342, 420380455, 420658662, 420717432, 423183880, 424539259, 425929170, 425972964, 426050649, 426126450, 426142833, 426607922, 437289840, 437347469, 437412335, 437423943, 437455540, 437462252, 437597991, 437617485, 437986305, 437986507, 437986828, 437987072, 438015591, 438034813, 438038966, 438179623, 438347971, 438483573, 438547062, 438895551, 441592676, 442032555, 443548979, 447881379, 447881655, 447881895, 447887844, 448416189, 448445746, 448449012, 450942191, 452816744, 453668677, 454434495, 456610076, 456642844, 456738709, 457544600, 459451897, 459680944, 468058810, 468083581, 470964084, 471470955, 471567278, 472267822, 481177859, 481210627, 481435874, 481455115, 481485378, 481490218, 485105638, 486005878, 486383494, 487988916, 488103783, 490661867, 491574090, 491578272, 493041952, 493441205, 493582844, 493716979, 504577572, 504740359, 505091638, 505592418, 505656212, 509516275, 514998531, 515571132, 515594682, 518712698, 521362273, 526592419, 526807354, 527348842, 538294791, 539214049, 544689535, 545535009, 548544752, 548563346, 548595116, 551679010, 558034099, 560329411, 560356209, 560671018, 560671152, 560692590, 560845442, 569212097, 569474241, 572252718, 572768481, 575326764, 576174758, 576190819, 582099184, 582099438, 582372519, 582558889, 586552164, 591325418, 594231990, 594243961, 605711268, 615672071, 616086845, 621792370, 624879850, 627432831, 640040548, 654392808, 658675477, 659420283, 672891587, 694768102, 705890982, 725543146, 759097578, 761686526, 795383908, 843809551, 878105336, 908643300, 945213471]);
+}
+
+function $AttributeName(this$static, uri, local, prefix, ncname, xmlns){
+  $clinit_124();
+  this$static.uri = uri;
+  this$static.local = local;
+  COMPUTE_QNAME(local, prefix);
+  this$static.ncname = ncname;
+  this$static.xmlns = xmlns;
+  return this$static;
+}
+
+function $AttributeName_0(this$static, uri, local, prefix, ncname, xmlns){
+  $clinit_124();
+  this$static.uri = uri;
+  this$static.local = local;
+  COMPUTE_QNAME(local, prefix);
+  this$static.ncname = ncname;
+  this$static.xmlns = xmlns;
+  return this$static;
+}
+
+function $isBoolean(this$static){
+  return this$static == ACTIVE || this$static == ASYNC || this$static == AUTOFOCUS || this$static == AUTOSUBMIT || this$static == CHECKED || this$static == COMPACT || this$static == DECLARE || this$static == DEFAULT || this$static == DEFER || this$static == DISABLED || this$static == ISMAP || this$static == MULTIPLE || this$static == NOHREF || this$static == NORESIZE || this$static == NOSHADE || this$static == NOWRAP || this$static == READONLY || this$static == REQUIRED || this$static == SELECTED;
+}
+
+function $isCaseFolded(this$static){
+  return this$static == ACTIVE || this$static == ALIGN || this$static == ASYNC || this$static == AUTOCOMPLETE || this$static == AUTOFOCUS || this$static == AUTOSUBMIT || this$static == CHECKED || this$static == CLEAR || this$static == COMPACT || this$static == DATAFORMATAS || this$static == DECLARE || this$static == DEFAULT || this$static == DEFER || this$static == DIR || this$static == DISABLED || this$static == ENCTYPE || this$static == FRAME || this$static == ISMAP || this$static == METHOD || this$static == MULTIPLE || this$static == NOHREF || this$static == NORESIZE || this$static == NOSHADE || this$static == NOWRAP || this$static == READONLY || this$static == REPLACE || this$static == REQUIRED || this$static == RULES || this$static == SCOPE || this$static == SCROLLING || this$static == SELECTED || this$static == SHAPE || this$static == STEP || this$static == TYPE_1 || this$static == VALIGN || this$static == VALUETYPE;
+}
+
+function COLONIFIED_LOCAL(name_0, suffix){
+  var arr;
+  arr = initDim(_3Ljava_lang_String_2_classLit, 56, 1, 4, 0);
+  arr[0] = name_0;
+  arr[1] = suffix;
+  arr[2] = suffix;
+  arr[3] = name_0;
+  return arr;
+}
+
+function COMPUTE_QNAME(local, prefix){
+  var arr, i;
+  arr = initDim(_3Ljava_lang_String_2_classLit, 56, 1, 4, 0);
+  for (i = 0; i < arr.length; ++i) {
+    prefix[i] == null?(arr[i] = local[i]):(arr[i] = String(prefix[i] + ':' + local[i]));
+  }
+  return arr;
+}
+
+function SAME_LOCAL(name_0){
+  var arr;
+  arr = initDim(_3Ljava_lang_String_2_classLit, 56, 1, 4, 0);
+  arr[0] = name_0;
+  arr[1] = name_0;
+  arr[2] = name_0;
+  arr[3] = name_0;
+  return arr;
+}
+
+function SVG_DIFFERENT(name_0, camel){
+  var arr;
+  arr = initDim(_3Ljava_lang_String_2_classLit, 56, 1, 4, 0);
+  arr[0] = name_0;
+  arr[1] = name_0;
+  arr[2] = camel;
+  arr[3] = name_0;
+  return arr;
+}
+
+function bufToHash(buf, len){
+  var hash, hash2, i, j;
+  hash2 = 0;
+  hash = len;
+  hash <<= 5;
+  hash += buf[0] - 96;
+  j = len;
+  for (i = 0; i < 4 && j > 0; ++i) {
+    --j;
+    hash <<= 5;
+    hash += buf[j] - 96;
+    hash2 <<= 6;
+    hash2 += buf[i] - 95;
+  }
+  return hash ^ hash2;
+}
+
+function createAttributeName(name_0, checkNcName){
+  var ncName, xmlns;
+  ncName = true;
+  xmlns = name_0.indexOf('xmlns:') == 0;
+  checkNcName && (xmlns?(ncName = false):(ncName = isNCName(name_0)));
+  return $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL(name_0), ALL_NO_PREFIX, ncName?ALL_NCNAME:ALL_NO_NCNAME, xmlns);
+}
+
+function getClass_67(){
+  return Lnu_validator_htmlparser_impl_AttributeName_2_classLit;
+}
+
+function nameByBuffer(buf, offset, length_0, checkNcName){
+  var end, end_0;
+  $clinit_124();
+  var attributeName, hash, index, name_0;
+  hash = bufToHash(buf, length_0);
+  index = binarySearch(ATTRIBUTE_HASHES, hash);
+  if (index < 0) {
+    return createAttributeName(String((end = offset + length_0 , __checkBounds(buf.length, offset, end) , __valueOf(buf, offset, end))), checkNcName);
+  }
+   else {
+    attributeName = ATTRIBUTE_NAMES[index];
+    name_0 = attributeName.local[0];
+    if (!localEqualsBuffer(name_0, buf, offset, length_0)) {
+      return createAttributeName(String((end_0 = offset + length_0 , __checkBounds(buf.length, offset, end_0) , __valueOf(buf, offset, end_0))), checkNcName);
+    }
+    return attributeName;
+  }
+}
+
+function AttributeName(){
+}
+
+_ = AttributeName.prototype = new Object_0;
+_.getClass$ = getClass_67;
+_.typeId$ = 39;
+_.local = null;
+_.ncname = null;
+_.uri = null;
+_.xmlns = false;
+var ABBR, ACCENT, ACCENTUNDER, ACCENT_HEIGHT, ACCEPT, ACCEPT_CHARSET, ACCESSKEY, ACCUMULATE, ACTION, ACTIONTYPE, ACTIVE, ADDITIVE, ALIGN, ALIGNMENTSCOPE, ALIGNMENT_BASELINE, ALINK, ALL_NCNAME, ALL_NO_NCNAME, ALL_NO_NS, ALL_NO_PREFIX, ALPHABETIC, ALT, ALTIMG, ALTTEXT, AMPLITUDE, ARABIC_FORM, ARCHIVE, ARIA_ACTIVEDESCENDANT, ARIA_ATOMIC, ARIA_AUTOCOMPLETE, ARIA_BUSY, ARIA_CHANNEL, ARIA_CHECKED, ARIA_CONTROLS, ARIA_DATATYPE, ARIA_DESCRIBEDBY, ARIA_DISABLED, ARIA_DROPEFFECT, ARIA_EXPANDED, ARIA_FLOWTO, ARIA_GRAB, ARIA_HASPOPUP, ARIA_HIDDEN, ARIA_INVALID, ARIA_LABELLEDBY, ARIA_LEVEL, ARIA_LIVE, ARIA_MULTILINE, ARIA_MULTISELECTABLE, ARIA_OWNS, ARIA_POSINSET, ARIA_PRESSED, ARIA_READONLY, ARIA_RELEVANT, ARIA_REQUIRED, ARIA_SECRET, ARIA_SELECTED, ARIA_SETSIZE, ARIA_SORT, ARIA_TEMPLATEID, ARIA_VALUEMAX, ARIA_VALUEMIN, ARIA_VALUENOW, ASCENT, ASYNC, ATTRIBUTENAME, ATTRIBUTETYPE, ATTRIBUTE_HASHES, ATTRIBUTE_NAMES, AUTOCOMPLETE, AUTOFOCUS, AUTOPLAY, AUTOSUBMIT, AXIS, AZIMUTH, BACKGROUND, BASE, BASEFREQUENCY, BASELINE, BASELINE_SHIFT, BASEPROFILE, BBOX, BEGIN, BEVELLED, BGCOLOR, BIAS, BORDER, BY, CALCMODE, CAP_HEIGHT, CELLPADDING, CELLSPACING, CHAR, CHAROFF, CHARSET, CHECKED, CITE, CLASS, CLASSID, CLEAR, CLIP, CLIPPATHUNITS, CLIP_PATH, CLIP_RULE, CLOSE, CLOSURE, CODE, CODEBASE, CODETYPE, COLOR, COLOR_INTERPOLATION, COLOR_INTERPOLATION_FILTERS, COLOR_PROFILE, COLOR_RENDERING, COLS, COLSPAN, COLUMNALIGN, COLUMNLINES, COLUMNSPACING, COLUMNSPAN, COLUMNWIDTH, COMPACT, CONTENT, CONTENTEDITABLE, CONTENTSCRIPTTYPE, CONTENTSTYLETYPE, CONTEXTMENU, CONTROLS, COORDS, CURSOR, CX, CY, D, DATA, DATAFLD, DATAFORMATAS, DATASRC, DATETIME, DECLARE, DEFAULT, DEFER, DEFINITIONURL, DEPTH, DESCENT, DIFFUSECONSTANT, DIR, DIRECTION, DISABLED, DISPLAY, DISPLAYSTYLE, DIVISOR, DOMINANT_BASELINE, DRAGGABLE, DUR, DX, DY, EDGE, EDGEMODE, ELEVATION, ENABLE_BACKGROUND, ENCODING, ENCTYPE, END, EQUALCOLUMNS, EQUALROWS, EXPONENT, EXTERNALRESOURCESREQUIRED, FACE, FENCE, FILL, FILL_OPACITY, FILL_RULE, FILTER, FILTERRES, FILTERUNITS, FLOOD_COLOR, FLOOD_OPACITY, FONTFAMILY, FONTSIZE, FONTSTYLE, FONTWEIGHT, FONT_FAMILY, FONT_SIZE, FONT_SIZE_ADJUST, FONT_STRETCH, FONT_STYLE, FONT_VARIANT, FONT_WEIGHT, FOR, FORM, FORMAT, FRAME, FRAMEBORDER, FRAMESPACING, FROM, FX, FY, G1, G2, GLYPHREF, GLYPH_NAME, GLYPH_ORIENTATION_HORIZONTAL, GLYPH_ORIENTATION_VERTICAL, GRADIENTTRANSFORM, GRADIENTUNITS, GROUPALIGN, HANGING, HEADERS, HEIGHT, HIDDEN, HIDEFOCUS, HIGH, HORIZ_ADV_X, HORIZ_ORIGIN_X, HORIZ_ORIGIN_Y, HREF, HREFLANG, HSPACE, HTTP_EQUIV, ICON, ID, IDEOGRAPHIC, IMAGE_RENDERING, IN, IN2, INDEX, INPUTMODE, INTERCEPT, IRRELEVANT, ISMAP, K, K1, K2, K3, K4, KERNELMATRIX, KERNELUNITLENGTH, KERNING, KEYPOINTS, KEYSPLINES, KEYTIMES, LABEL, LANG, LANGUAGE, LANG_NS, LANG_PREFIX, LARGEOP, LENGTHADJUST, LETTER_SPACING, LIGHTING_COLOR, LIMITINGCONEANGLE, LINEBREAK, LINETHICKNESS, LINK, LIST, LOCAL, LONGDESC, LOOPEND, LOOPSTART, LOW, LOWSRC, LQUOTE, LSPACE, MACROS, MANIFEST, MARGINHEIGHT, MARGINWIDTH, MARKERHEIGHT, MARKERUNITS, MARKERWIDTH, MARKER_END, MARKER_MID, MARKER_START, MASK, MASKCONTENTUNITS, MASKUNITS, MATHBACKGROUND, MATHCOLOR, MATHEMATICAL, MATHSIZE, MATHVARIANT, MAX, MAXLENGTH, MAXSIZE, MEDIA, MEDIUMMATHSPACE, METHOD, MIN, MINSIZE, MODE, MOVABLELIMITS, MULTIPLE, NAME, NARGS, NOHREF, NORESIZE, NOSHADE, NOTATION, NOWRAP, NUMOCTAVES, OBJECT, OCCURRENCE, OFFSET, ONABORT, ONACTIVATE, ONAFTERPRINT, ONAFTERUPDATE, ONBEFORDEACTIVATE, ONBEFOREACTIVATE, ONBEFORECOPY, ONBEFORECUT, ONBEFOREEDITFOCUS, ONBEFOREPASTE, ONBEFOREPRINT, ONBEFOREUNLOAD, ONBEFOREUPDATE, ONBEGIN, ONBLUR, ONBOUNCE, ONCELLCHANGE, ONCHANGE, ONCLICK, ONCONTEXTMENU, ONCONTROLSELECT, ONCOPY, ONCUT, ONDATAAVAILABLE, ONDATASETCHANGED, ONDATASETCOMPLETE, ONDBLCLICK, ONDEACTIVATE, ONDRAG, ONDRAGDROP, ONDRAGEND, ONDRAGENTER, ONDRAGLEAVE, ONDRAGOVER, ONDRAGSTART, ONDROP, ONEND, ONERROR, ONERRORUPDATE, ONFILTERCHANGE, ONFINISH, ONFOCUS, ONFOCUSIN, ONFOCUSOUT, ONFORMCHANGE, ONFORMINPUT, ONHELP, ONINPUT, ONINVALID, ONKEYDOWN, ONKEYPRESS, ONKEYUP, ONLOAD, ONLOSECAPTURE, ONMESSAGE, ONMOUSEDOWN, ONMOUSEENTER, ONMOUSELEAVE, ONMOUSEMOVE, ONMOUSEOUT, ONMOUSEOVER, ONMOUSEUP, ONMOUSEWHEEL, ONMOVE, ONMOVEEND, ONMOVESTART, ONPASTE, ONPROPERTYCHANGE, ONREADYSTATECHANGE, ONREPEAT, ONRESET, ONRESIZE, ONROWENTER, ONROWEXIT, ONROWSDELETE, ONROWSINSERTED, ONSCROLL, ONSELECT, ONSELECTSTART, ONSTART, ONSTOP, ONSUBMIT, ONUNLOAD, ONZOOM, OPACITY, OPEN, OPERATOR, OPTIMUM, ORDER, ORIENT, ORIENTATION, ORIGIN, OTHER, OVERFLOW, OVERLINE_POSITION, OVERLINE_THICKNESS, PANOSE_1, PATH, PATHLENGTH, PATTERN, PATTERNCONTENTUNITS, PATTERNTRANSFORM, PATTERNUNITS, PING, PLAYCOUNT, POINTER_EVENTS, POINTS, POINTSATX, POINTSATY, POINTSATZ, POSTER, PRESERVEALPHA, PRESERVEASPECTRATIO, PRIMITIVEUNITS, PROFILE, PROMPT, R, RADIOGROUP, RADIUS, READONLY, REFX, REFY, REL, RENDERING_INTENT, REPEAT, REPEATCOUNT, REPEATDUR, REPEAT_MAX, REPEAT_MIN, REPEAT_START, REPEAT_TEMPLATE, REPLACE, REQUIRED, REQUIREDEXTENSIONS, REQUIREDFEATURES, RESTART, RESULT, REV, ROLE, ROTATE, ROWALIGN, ROWLINES, ROWS, ROWSPACING, ROWSPAN, RQUOTE, RSPACE, RT, RULES, RX, RY, SANDBOX, SCALE, SCHEME, SCOPE, SCOPED, SCRIPTLEVEL, SCRIPTMINSIZE, SCRIPTSIZEMULTIPLIER, SCROLLDELAY, SCROLLING, SEAMLESS, SEED, SELECTED, SELECTION, SEPARATOR, SEPARATORS, SHAPE, SHAPE_RENDERING, SIZE, SLOPE, SPACING, SPAN, SPECIFICATION, SPECULARCONSTANT, SPECULAREXPONENT, SPEED, SPREADMETHOD, SRC, STANDBY, START, STARTOFFSET, STDDEVIATION, STEMH, STEMV, STEP, STITCHTILES, STOP_COLOR, STOP_OPACITY, STRETCHY, STRIKETHROUGH_POSITION, STRIKETHROUGH_THICKNESS, STRING, STROKE, STROKE_DASHARRAY, STROKE_DASHOFFSET, STROKE_LINECAP, STROKE_LINEJOIN, STROKE_MITERLIMIT, STROKE_OPACITY, STROKE_WIDTH, STYLE, SUBSCRIPTSHIFT, SUMMARY, SUPERSCRIPTSHIFT, SURFACESCALE, SYMMETRIC, SYSTEMLANGUAGE, TABINDEX, TABLEVALUES, TARGET, TARGETX, TARGETY, TEMPLATE, TEXT, TEXTLENGTH, TEXT_ANCHOR, TEXT_DECORATION, TEXT_RENDERING, THICKMATHSPACE, THINMATHSPACE, TITLE, TO, TRANSFORM, TYPE_1, U1, U2, UNDERLINE_POSITION, UNDERLINE_THICKNESS, UNICODE, UNICODE_BIDI, UNICODE_RANGE, UNITS_PER_EM, UNSELECTABLE, USEMAP, VALIGN, VALUE, VALUES, VALUETYPE, VERSION, VERT_ADV_Y, VERT_ORIGIN_X, VERT_ORIGIN_Y, VERYTHICKMATHSPACE, VERYTHINMATHSPACE, VERYVERYTHICKMATHSPACE, VERYVERYTHINMATHSPACE, VIEWBOX, VIEWTARGET, VISIBILITY, VLINK, VSPACE, V_ALPHABETIC, V_HANGING, V_IDEOGRAPHIC, V_MATHEMATICAL, WHEN, WIDTH, WIDTHS, WORD_SPACING, WRAP, WRITING_MODE, X, X1, X2, XCHANNELSELECTOR, XLINK_ACTUATE, XLINK_ARCROLE, XLINK_HREF, XLINK_NS, XLINK_PREFIX, XLINK_ROLE, XLINK_SHOW, XLINK_TITLE, XLINK_TYPE, XMLNS, XMLNS_NS, XMLNS_PREFIX, XMLNS_XLINK, XML_BASE, XML_LANG, XML_NS, XML_PREFIX, XML_SPACE, XREF, X_HEIGHT, Y, Y1, Y2, YCHANNELSELECTOR, Z, ZOOMANDPAN;
+function $clinit_125(){
+  $clinit_125 = nullMethod;
+  $ElementName_0(new ElementName, null);
+  A = $ElementName(new ElementName, 'a', 'a', 1, false, false, false);
+  B = $ElementName(new ElementName, 'b', 'b', 45, false, false, false);
+  G = $ElementName(new ElementName, 'g', 'g', 0, false, false, false);
+  I = $ElementName(new ElementName, 'i', 'i', 45, false, false, false);
+  P = $ElementName(new ElementName, 'p', 'p', 29, true, false, false);
+  Q = $ElementName(new ElementName, 'q', 'q', 0, false, false, false);
+  S = $ElementName(new ElementName, 's', 's', 45, false, false, false);
+  U = $ElementName(new ElementName, 'u', 'u', 45, false, false, false);
+  BR = $ElementName(new ElementName, 'br', 'br', 4, true, false, false);
+  CI = $ElementName(new ElementName, 'ci', 'ci', 0, false, false, false);
+  CN = $ElementName(new ElementName, 'cn', 'cn', 0, false, false, false);
+  DD = $ElementName(new ElementName, 'dd', 'dd', 41, true, false, false);
+  DL = $ElementName(new ElementName, 'dl', 'dl', 46, true, false, false);
+  DT = $ElementName(new ElementName, 'dt', 'dt', 41, true, false, false);
+  EM = $ElementName(new ElementName, 'em', 'em', 45, false, false, false);
+  EQ = $ElementName(new ElementName, 'eq', 'eq', 0, false, false, false);
+  FN = $ElementName(new ElementName, 'fn', 'fn', 0, false, false, false);
+  H1 = $ElementName(new ElementName, 'h1', 'h1', 42, true, false, false);
+  H2 = $ElementName(new ElementName, 'h2', 'h2', 42, true, false, false);
+  H3 = $ElementName(new ElementName, 'h3', 'h3', 42, true, false, false);
+  H4 = $ElementName(new ElementName, 'h4', 'h4', 42, true, false, false);
+  H5 = $ElementName(new ElementName, 'h5', 'h5', 42, true, false, false);
+  H6 = $ElementName(new ElementName, 'h6', 'h6', 42, true, false, false);
+  GT = $ElementName(new ElementName, 'gt', 'gt', 0, false, false, false);
+  HR = $ElementName(new ElementName, 'hr', 'hr', 22, true, false, false);
+  IN_0 = $ElementName(new ElementName, 'in', 'in', 0, false, false, false);
+  LI = $ElementName(new ElementName, 'li', 'li', 15, true, false, false);
+  LN = $ElementName(new ElementName, 'ln', 'ln', 0, false, false, false);
+  LT = $ElementName(new ElementName, 'lt', 'lt', 0, false, false, false);
+  MI = $ElementName(new ElementName, 'mi', 'mi', 57, false, false, false);
+  MN = $ElementName(new ElementName, 'mn', 'mn', 57, false, false, false);
+  MO = $ElementName(new ElementName, 'mo', 'mo', 57, false, false, false);
+  MS = $ElementName(new ElementName, 'ms', 'ms', 57, false, false, false);
+  OL = $ElementName(new ElementName, 'ol', 'ol', 46, true, false, false);
+  OR = $ElementName(new ElementName, 'or', 'or', 0, false, false, false);
+  PI = $ElementName(new ElementName, 'pi', 'pi', 0, false, false, false);
+  RP = $ElementName(new ElementName, 'rp', 'rp', 53, false, false, false);
+  RT_0 = $ElementName(new ElementName, 'rt', 'rt', 53, false, false, false);
+  TD = $ElementName(new ElementName, 'td', 'td', 40, false, true, false);
+  TH = $ElementName(new ElementName, 'th', 'th', 40, false, true, false);
+  TR = $ElementName(new ElementName, 'tr', 'tr', 37, true, false, true);
+  TT = $ElementName(new ElementName, 'tt', 'tt', 45, false, false, false);
+  UL = $ElementName(new ElementName, 'ul', 'ul', 46, true, false, false);
+  AND = $ElementName(new ElementName, 'and', 'and', 0, false, false, false);
+  ARG = $ElementName(new ElementName, 'arg', 'arg', 0, false, false, false);
+  ABS = $ElementName(new ElementName, 'abs', 'abs', 0, false, false, false);
+  BIG = $ElementName(new ElementName, 'big', 'big', 45, false, false, false);
+  BDO = $ElementName(new ElementName, 'bdo', 'bdo', 0, false, false, false);
+  CSC = $ElementName(new ElementName, 'csc', 'csc', 0, false, false, false);
+  COL = $ElementName(new ElementName, 'col', 'col', 7, true, false, false);
+  COS = $ElementName(new ElementName, 'cos', 'cos', 0, false, false, false);
+  COT = $ElementName(new ElementName, 'cot', 'cot', 0, false, false, false);
+  DEL = $ElementName(new ElementName, 'del', 'del', 0, false, false, false);
+  DFN = $ElementName(new ElementName, 'dfn', 'dfn', 0, false, false, false);
+  DIR_0 = $ElementName(new ElementName, 'dir', 'dir', 51, true, false, false);
+  DIV = $ElementName(new ElementName, 'div', 'div', 50, true, false, false);
+  EXP = $ElementName(new ElementName, 'exp', 'exp', 0, false, false, false);
+  GCD = $ElementName(new ElementName, 'gcd', 'gcd', 0, false, false, false);
+  GEQ = $ElementName(new ElementName, 'geq', 'geq', 0, false, false, false);
+  IMG = $ElementName(new ElementName, 'img', 'img', 48, true, false, false);
+  INS = $ElementName(new ElementName, 'ins', 'ins', 0, false, false, false);
+  INT = $ElementName(new ElementName, 'int', 'int', 0, false, false, false);
+  KBD = $ElementName(new ElementName, 'kbd', 'kbd', 0, false, false, false);
+  LOG = $ElementName(new ElementName, 'log', 'log', 0, false, false, false);
+  LCM = $ElementName(new ElementName, 'lcm', 'lcm', 0, false, false, false);
+  LEQ = $ElementName(new ElementName, 'leq', 'leq', 0, false, false, false);
+  MTD = $ElementName(new ElementName, 'mtd', 'mtd', 0, false, false, false);
+  MIN_0 = $ElementName(new ElementName, 'min', 'min', 0, false, false, false);
+  MAP = $ElementName(new ElementName, 'map', 'map', 0, false, false, false);
+  MTR = $ElementName(new ElementName, 'mtr', 'mtr', 0, false, false, false);
+  MAX_0 = $ElementName(new ElementName, 'max', 'max', 0, false, false, false);
+  NEQ = $ElementName(new ElementName, 'neq', 'neq', 0, false, false, false);
+  NOT = $ElementName(new ElementName, 'not', 'not', 0, false, false, false);
+  NAV = $ElementName(new ElementName, 'nav', 'nav', 51, true, false, false);
+  PRE = $ElementName(new ElementName, 'pre', 'pre', 44, true, false, false);
+  REM = $ElementName(new ElementName, 'rem', 'rem', 0, false, false, false);
+  SUB = $ElementName(new ElementName, 'sub', 'sub', 52, false, false, false);
+  SEC = $ElementName(new ElementName, 'sec', 'sec', 0, false, false, false);
+  SVG = $ElementName(new ElementName, 'svg', 'svg', 19, false, false, false);
+  SUM = $ElementName(new ElementName, 'sum', 'sum', 0, false, false, false);
+  SIN = $ElementName(new ElementName, 'sin', 'sin', 0, false, false, false);
+  SEP = $ElementName(new ElementName, 'sep', 'sep', 0, false, false, false);
+  SUP = $ElementName(new ElementName, 'sup', 'sup', 52, false, false, false);
+  SET = $ElementName(new ElementName, 'set', 'set', 0, false, false, false);
+  TAN = $ElementName(new ElementName, 'tan', 'tan', 0, false, false, false);
+  USE = $ElementName(new ElementName, 'use', 'use', 0, false, false, false);
+  VAR = $ElementName(new ElementName, 'var', 'var', 52, false, false, false);
+  WBR = $ElementName(new ElementName, 'wbr', 'wbr', 49, true, false, false);
+  XMP = $ElementName(new ElementName, 'xmp', 'xmp', 38, false, false, false);
+  XOR = $ElementName(new ElementName, 'xor', 'xor', 0, false, false, false);
+  AREA = $ElementName(new ElementName, 'area', 'area', 49, true, false, false);
+  ABBR_0 = $ElementName(new ElementName, 'abbr', 'abbr', 0, false, false, false);
+  BASE_0 = $ElementName(new ElementName, 'base', 'base', 2, true, false, false);
+  BVAR = $ElementName(new ElementName, 'bvar', 'bvar', 0, false, false, false);
+  BODY = $ElementName(new ElementName, 'body', 'body', 3, true, false, false);
+  CARD = $ElementName(new ElementName, 'card', 'card', 0, false, false, false);
+  CODE_0 = $ElementName(new ElementName, 'code', 'code', 45, false, false, false);
+  CITE_0 = $ElementName(new ElementName, 'cite', 'cite', 0, false, false, false);
+  CSCH = $ElementName(new ElementName, 'csch', 'csch', 0, false, false, false);
+  COSH = $ElementName(new ElementName, 'cosh', 'cosh', 0, false, false, false);
+  COTH = $ElementName(new ElementName, 'coth', 'coth', 0, false, false, false);
+  CURL = $ElementName(new ElementName, 'curl', 'curl', 0, false, false, false);
+  DESC = $ElementName(new ElementName, 'desc', 'desc', 59, false, false, false);
+  DIFF = $ElementName(new ElementName, 'diff', 'diff', 0, false, false, false);
+  DEFS = $ElementName(new ElementName, 'defs', 'defs', 0, false, false, false);
+  FORM_0 = $ElementName(new ElementName, 'form', 'form', 9, true, false, false);
+  FONT = $ElementName(new ElementName, 'font', 'font', 64, false, false, false);
+  GRAD = $ElementName(new ElementName, 'grad', 'grad', 0, false, false, false);
+  HEAD = $ElementName(new ElementName, 'head', 'head', 20, true, false, false);
+  HTML_0 = $ElementName(new ElementName, 'html', 'html', 23, false, true, false);
+  LINE = $ElementName(new ElementName, 'line', 'line', 0, false, false, false);
+  LINK_0 = $ElementName(new ElementName, 'link', 'link', 16, true, false, false);
+  LIST_0 = $ElementName(new ElementName, 'list', 'list', 0, false, false, false);
+  META = $ElementName(new ElementName, 'meta', 'meta', 18, true, false, false);
+  MSUB = $ElementName(new ElementName, 'msub', 'msub', 0, false, false, false);
+  MODE_0 = $ElementName(new ElementName, 'mode', 'mode', 0, false, false, false);
+  MATH = $ElementName(new ElementName, 'math', 'math', 17, false, false, false);
+  MARK = $ElementName(new ElementName, 'mark', 'mark', 0, false, false, false);
+  MASK_0 = $ElementName(new ElementName, 'mask', 'mask', 0, false, false, false);
+  MEAN = $ElementName(new ElementName, 'mean', 'mean', 0, false, false, false);
+  MSUP = $ElementName(new ElementName, 'msup', 'msup', 0, false, false, false);
+  MENU = $ElementName(new ElementName, 'menu', 'menu', 50, true, false, false);
+  MROW = $ElementName(new ElementName, 'mrow', 'mrow', 0, false, false, false);
+  NONE = $ElementName(new ElementName, 'none', 'none', 0, false, false, false);
+  NOBR = $ElementName(new ElementName, 'nobr', 'nobr', 24, false, false, false);
+  NEST = $ElementName(new ElementName, 'nest', 'nest', 0, false, false, false);
+  PATH_0 = $ElementName(new ElementName, 'path', 'path', 0, false, false, false);
+  PLUS = $ElementName(new ElementName, 'plus', 'plus', 0, false, false, false);
+  RULE = $ElementName(new ElementName, 'rule', 'rule', 0, false, false, false);
+  REAL = $ElementName(new ElementName, 'real', 'real', 0, false, false, false);
+  RELN = $ElementName(new ElementName, 'reln', 'reln', 0, false, false, false);
+  RECT = $ElementName(new ElementName, 'rect', 'rect', 0, false, false, false);
+  ROOT = $ElementName(new ElementName, 'root', 'root', 0, false, false, false);
+  RUBY = $ElementName(new ElementName, 'ruby', 'ruby', 52, false, false, false);
+  SECH = $ElementName(new ElementName, 'sech', 'sech', 0, false, false, false);
+  SINH = $ElementName(new ElementName, 'sinh', 'sinh', 0, false, false, false);
+  SPAN_0 = $ElementName(new ElementName, 'span', 'span', 52, false, false, false);
+  SAMP = $ElementName(new ElementName, 'samp', 'samp', 0, false, false, false);
+  STOP = $ElementName(new ElementName, 'stop', 'stop', 0, false, false, false);
+  SDEV = $ElementName(new ElementName, 'sdev', 'sdev', 0, false, false, false);
+  TIME = $ElementName(new ElementName, 'time', 'time', 0, false, false, false);
+  TRUE = $ElementName(new ElementName, 'true', 'true', 0, false, false, false);
+  TREF = $ElementName(new ElementName, 'tref', 'tref', 0, false, false, false);
+  TANH = $ElementName(new ElementName, 'tanh', 'tanh', 0, false, false, false);
+  TEXT_0 = $ElementName(new ElementName, 'text', 'text', 0, false, false, false);
+  VIEW = $ElementName(new ElementName, 'view', 'view', 0, false, false, false);
+  ASIDE = $ElementName(new ElementName, 'aside', 'aside', 51, true, false, false);
+  AUDIO = $ElementName(new ElementName, 'audio', 'audio', 0, false, false, false);
+  APPLY = $ElementName(new ElementName, 'apply', 'apply', 0, false, false, false);
+  EMBED = $ElementName(new ElementName, 'embed', 'embed', 48, true, false, false);
+  FRAME_0 = $ElementName(new ElementName, 'frame', 'frame', 10, true, false, false);
+  FALSE = $ElementName(new ElementName, 'false', 'false', 0, false, false, false);
+  FLOOR = $ElementName(new ElementName, 'floor', 'floor', 0, false, false, false);
+  GLYPH = $ElementName(new ElementName, 'glyph', 'glyph', 0, false, false, false);
+  HKERN = $ElementName(new ElementName, 'hkern', 'hkern', 0, false, false, false);
+  IMAGE = $ElementName(new ElementName, 'image', 'image', 12, true, false, false);
+  IDENT = $ElementName(new ElementName, 'ident', 'ident', 0, false, false, false);
+  INPUT = $ElementName(new ElementName, 'input', 'input', 13, true, false, false);
+  LABEL_0 = $ElementName(new ElementName, 'label', 'label', 62, false, false, false);
+  LIMIT = $ElementName(new ElementName, 'limit', 'limit', 0, false, false, false);
+  MFRAC = $ElementName(new ElementName, 'mfrac', 'mfrac', 0, false, false, false);
+  MPATH = $ElementName(new ElementName, 'mpath', 'mpath', 0, false, false, false);
+  METER = $ElementName(new ElementName, 'meter', 'meter', 0, false, false, false);
+  MOVER = $ElementName(new ElementName, 'mover', 'mover', 0, false, false, false);
+  MINUS = $ElementName(new ElementName, 'minus', 'minus', 0, false, false, false);
+  MROOT = $ElementName(new ElementName, 'mroot', 'mroot', 0, false, false, false);
+  MSQRT = $ElementName(new ElementName, 'msqrt', 'msqrt', 0, false, false, false);
+  MTEXT = $ElementName(new ElementName, 'mtext', 'mtext', 57, false, false, false);
+  NOTIN = $ElementName(new ElementName, 'notin', 'notin', 0, false, false, false);
+  PIECE = $ElementName(new ElementName, 'piece', 'piece', 0, false, false, false);
+  PARAM = $ElementName(new ElementName, 'param', 'param', 55, true, false, false);
+  POWER = $ElementName(new ElementName, 'power', 'power', 0, false, false, false);
+  REALS = $ElementName(new ElementName, 'reals', 'reals', 0, false, false, false);
+  STYLE_0 = $ElementName(new ElementName, 'style', 'style', 33, true, false, false);
+  SMALL = $ElementName(new ElementName, 'small', 'small', 45, false, false, false);
+  THEAD = $ElementName(new ElementName, 'thead', 'thead', 39, true, false, true);
+  TABLE = $ElementName(new ElementName, 'table', 'table', 34, false, true, true);
+  TITLE_0 = $ElementName(new ElementName, 'title', 'title', 36, true, false, false);
+  TSPAN = $ElementName(new ElementName, 'tspan', 'tspan', 0, false, false, false);
+  TIMES = $ElementName(new ElementName, 'times', 'times', 0, false, false, false);
+  TFOOT = $ElementName(new ElementName, 'tfoot', 'tfoot', 39, true, false, true);
+  TBODY = $ElementName(new ElementName, 'tbody', 'tbody', 39, true, false, true);
+  UNION = $ElementName(new ElementName, 'union', 'union', 0, false, false, false);
+  VKERN = $ElementName(new ElementName, 'vkern', 'vkern', 0, false, false, false);
+  VIDEO = $ElementName(new ElementName, 'video', 'video', 0, false, false, false);
+  ARCSEC = $ElementName(new ElementName, 'arcsec', 'arcsec', 0, false, false, false);
+  ARCCSC = $ElementName(new ElementName, 'arccsc', 'arccsc', 0, false, false, false);
+  ARCTAN = $ElementName(new ElementName, 'arctan', 'arctan', 0, false, false, false);
+  ARCSIN = $ElementName(new ElementName, 'arcsin', 'arcsin', 0, false, false, false);
+  ARCCOS = $ElementName(new ElementName, 'arccos', 'arccos', 0, false, false, false);
+  APPLET = $ElementName(new ElementName, 'applet', 'applet', 43, false, true, false);
+  ARCCOT = $ElementName(new ElementName, 'arccot', 'arccot', 0, false, false, false);
+  APPROX = $ElementName(new ElementName, 'approx', 'approx', 0, false, false, false);
+  BUTTON = $ElementName(new ElementName, 'button', 'button', 5, false, false, false);
+  CIRCLE = $ElementName(new ElementName, 'circle', 'circle', 0, false, false, false);
+  CENTER = $ElementName(new ElementName, 'center', 'center', 50, true, false, false);
+  CURSOR_0 = $ElementName(new ElementName, 'cursor', 'cursor', 0, false, false, false);
+  CANVAS = $ElementName(new ElementName, 'canvas', 'canvas', 0, false, false, false);
+  DIVIDE = $ElementName(new ElementName, 'divide', 'divide', 0, false, false, false);
+  DEGREE = $ElementName(new ElementName, 'degree', 'degree', 0, false, false, false);
+  DOMAIN = $ElementName(new ElementName, 'domain', 'domain', 0, false, false, false);
+  EXISTS = $ElementName(new ElementName, 'exists', 'exists', 0, false, false, false);
+  FETILE = $ElementName(new ElementName, 'fetile', 'feTile', 0, false, false, false);
+  FIGURE = $ElementName(new ElementName, 'figure', 'figure', 51, true, false, false);
+  FORALL = $ElementName(new ElementName, 'forall', 'forall', 0, false, false, false);
+  FILTER_0 = $ElementName(new ElementName, 'filter', 'filter', 0, false, false, false);
+  FOOTER = $ElementName(new ElementName, 'footer', 'footer', 51, true, false, false);
+  HGROUP = $ElementName(new ElementName, 'hgroup', 'hgroup', 51, true, false, false);
+  HEADER = $ElementName(new ElementName, 'header', 'header', 51, true, false, false);
+  IFRAME = $ElementName(new ElementName, 'iframe', 'iframe', 47, true, false, false);
+  KEYGEN = $ElementName(new ElementName, 'keygen', 'keygen', 65, true, false, false);
+  LAMBDA = $ElementName(new ElementName, 'lambda', 'lambda', 0, false, false, false);
+  LEGEND = $ElementName(new ElementName, 'legend', 'legend', 0, false, false, false);
+  MSPACE = $ElementName(new ElementName, 'mspace', 'mspace', 0, false, false, false);
+  MTABLE = $ElementName(new ElementName, 'mtable', 'mtable', 0, false, false, false);
+  MSTYLE = $ElementName(new ElementName, 'mstyle', 'mstyle', 0, false, false, false);
+  MGLYPH = $ElementName(new ElementName, 'mglyph', 'mglyph', 56, false, false, false);
+  MEDIAN = $ElementName(new ElementName, 'median', 'median', 0, false, false, false);
+  MUNDER = $ElementName(new ElementName, 'munder', 'munder', 0, false, false, false);
+  MARKER = $ElementName(new ElementName, 'marker', 'marker', 0, false, false, false);
+  MERROR = $ElementName(new ElementName, 'merror', 'merror', 0, false, false, false);
+  MOMENT = $ElementName(new ElementName, 'moment', 'moment', 0, false, false, false);
+  MATRIX = $ElementName(new ElementName, 'matrix', 'matrix', 0, false, false, false);
+  OPTION = $ElementName(new ElementName, 'option', 'option', 28, false, false, false);
+  OBJECT_0 = $ElementName(new ElementName, 'object', 'object', 63, false, true, false);
+  OUTPUT = $ElementName(new ElementName, 'output', 'output', 62, false, false, false);
+  PRIMES = $ElementName(new ElementName, 'primes', 'primes', 0, false, false, false);
+  SOURCE = $ElementName(new ElementName, 'source', 'source', 55, false, false, false);
+  STRIKE = $ElementName(new ElementName, 'strike', 'strike', 45, false, false, false);
+  STRONG = $ElementName(new ElementName, 'strong', 'strong', 45, false, false, false);
+  SWITCH = $ElementName(new ElementName, 'switch', 'switch', 0, false, false, false);
+  SYMBOL = $ElementName(new ElementName, 'symbol', 'symbol', 0, false, false, false);
+  SPACER = $ElementName(new ElementName, 'spacer', 'spacer', 49, true, false, false);
+  SELECT = $ElementName(new ElementName, 'select', 'select', 32, true, false, false);
+  SUBSET = $ElementName(new ElementName, 'subset', 'subset', 0, false, false, false);
+  SCRIPT = $ElementName(new ElementName, 'script', 'script', 31, true, false, false);
+  TBREAK = $ElementName(new ElementName, 'tbreak', 'tbreak', 0, false, false, false);
+  VECTOR = $ElementName(new ElementName, 'vector', 'vector', 0, false, false, false);
+  ARTICLE = $ElementName(new ElementName, 'article', 'article', 51, true, false, false);
+  ANIMATE = $ElementName(new ElementName, 'animate', 'animate', 0, false, false, false);
+  ARCSECH = $ElementName(new ElementName, 'arcsech', 'arcsech', 0, false, false, false);
+  ARCCSCH = $ElementName(new ElementName, 'arccsch', 'arccsch', 0, false, false, false);
+  ARCTANH = $ElementName(new ElementName, 'arctanh', 'arctanh', 0, false, false, false);
+  ARCSINH = $ElementName(new ElementName, 'arcsinh', 'arcsinh', 0, false, false, false);
+  ARCCOSH = $ElementName(new ElementName, 'arccosh', 'arccosh', 0, false, false, false);
+  ARCCOTH = $ElementName(new ElementName, 'arccoth', 'arccoth', 0, false, false, false);
+  ACRONYM = $ElementName(new ElementName, 'acronym', 'acronym', 0, false, false, false);
+  ADDRESS = $ElementName(new ElementName, 'address', 'address', 51, true, false, false);
+  BGSOUND = $ElementName(new ElementName, 'bgsound', 'bgsound', 16, true, false, false);
+  COMMAND = $ElementName(new ElementName, 'command', 'command', 54, true, false, false);
+  COMPOSE = $ElementName(new ElementName, 'compose', 'compose', 0, false, false, false);
+  CEILING = $ElementName(new ElementName, 'ceiling', 'ceiling', 0, false, false, false);
+  CSYMBOL = $ElementName(new ElementName, 'csymbol', 'csymbol', 0, false, false, false);
+  CAPTION = $ElementName(new ElementName, 'caption', 'caption', 6, false, true, false);
+  DISCARD = $ElementName(new ElementName, 'discard', 'discard', 0, false, false, false);
+  DECLARE_0 = $ElementName(new ElementName, 'declare', 'declare', 0, false, false, false);
+  DETAILS = $ElementName(new ElementName, 'details', 'details', 51, true, false, false);
+  ELLIPSE = $ElementName(new ElementName, 'ellipse', 'ellipse', 0, false, false, false);
+  FEFUNCA = $ElementName(new ElementName, 'fefunca', 'feFuncA', 0, false, false, false);
+  FEFUNCB = $ElementName(new ElementName, 'fefuncb', 'feFuncB', 0, false, false, false);
+  FEBLEND = $ElementName(new ElementName, 'feblend', 'feBlend', 0, false, false, false);
+  FEFLOOD = $ElementName(new ElementName, 'feflood', 'feFlood', 0, false, false, false);
+  FEIMAGE = $ElementName(new ElementName, 'feimage', 'feImage', 0, false, false, false);
+  FEMERGE = $ElementName(new ElementName, 'femerge', 'feMerge', 0, false, false, false);
+  FEFUNCG = $ElementName(new ElementName, 'fefuncg', 'feFuncG', 0, false, false, false);
+  FEFUNCR = $ElementName(new ElementName, 'fefuncr', 'feFuncR', 0, false, false, false);
+  HANDLER = $ElementName(new ElementName, 'handler', 'handler', 0, false, false, false);
+  INVERSE = $ElementName(new ElementName, 'inverse', 'inverse', 0, false, false, false);
+  IMPLIES = $ElementName(new ElementName, 'implies', 'implies', 0, false, false, false);
+  ISINDEX = $ElementName(new ElementName, 'isindex', 'isindex', 14, true, false, false);
+  LOGBASE = $ElementName(new ElementName, 'logbase', 'logbase', 0, false, false, false);
+  LISTING = $ElementName(new ElementName, 'listing', 'listing', 44, true, false, false);
+  MFENCED = $ElementName(new ElementName, 'mfenced', 'mfenced', 0, false, false, false);
+  MPADDED = $ElementName(new ElementName, 'mpadded', 'mpadded', 0, false, false, false);
+  MARQUEE = $ElementName(new ElementName, 'marquee', 'marquee', 43, false, true, false);
+  MACTION = $ElementName(new ElementName, 'maction', 'maction', 0, false, false, false);
+  MSUBSUP = $ElementName(new ElementName, 'msubsup', 'msubsup', 0, false, false, false);
+  NOEMBED = $ElementName(new ElementName, 'noembed', 'noembed', 60, true, false, false);
+  POLYGON = $ElementName(new ElementName, 'polygon', 'polygon', 0, false, false, false);
+  PATTERN_0 = $ElementName(new ElementName, 'pattern', 'pattern', 0, false, false, false);
+  PRODUCT = $ElementName(new ElementName, 'product', 'product', 0, false, false, false);
+  SETDIFF = $ElementName(new ElementName, 'setdiff', 'setdiff', 0, false, false, false);
+  SECTION = $ElementName(new ElementName, 'section', 'section', 51, true, false, false);
+  TENDSTO = $ElementName(new ElementName, 'tendsto', 'tendsto', 0, false, false, false);
+  UPLIMIT = $ElementName(new ElementName, 'uplimit', 'uplimit', 0, false, false, false);
+  ALTGLYPH = $ElementName(new ElementName, 'altglyph', 'altGlyph', 0, false, false, false);
+  BASEFONT = $ElementName(new ElementName, 'basefont', 'basefont', 16, true, false, false);
+  CLIPPATH = $ElementName(new ElementName, 'clippath', 'clipPath', 0, false, false, false);
+  CODOMAIN = $ElementName(new ElementName, 'codomain', 'codomain', 0, false, false, false);
+  COLGROUP = $ElementName(new ElementName, 'colgroup', 'colgroup', 8, true, false, false);
+  DATAGRID = $ElementName(new ElementName, 'datagrid', 'datagrid', 51, true, false, false);
+  EMPTYSET = $ElementName(new ElementName, 'emptyset', 'emptyset', 0, false, false, false);
+  FACTOROF = $ElementName(new ElementName, 'factorof', 'factorof', 0, false, false, false);
+  FIELDSET = $ElementName(new ElementName, 'fieldset', 'fieldset', 61, true, false, false);
+  FRAMESET = $ElementName(new ElementName, 'frameset', 'frameset', 11, true, false, false);
+  FEOFFSET = $ElementName(new ElementName, 'feoffset', 'feOffset', 0, false, false, false);
+  GLYPHREF_0 = $ElementName(new ElementName, 'glyphref', 'glyphRef', 0, false, false, false);
+  INTERVAL = $ElementName(new ElementName, 'interval', 'interval', 0, false, false, false);
+  INTEGERS = $ElementName(new ElementName, 'integers', 'integers', 0, false, false, false);
+  INFINITY = $ElementName(new ElementName, 'infinity', 'infinity', 0, false, false, false);
+  LISTENER = $ElementName(new ElementName, 'listener', 'listener', 0, false, false, false);
+  LOWLIMIT = $ElementName(new ElementName, 'lowlimit', 'lowlimit', 0, false, false, false);
+  METADATA = $ElementName(new ElementName, 'metadata', 'metadata', 0, false, false, false);
+  MENCLOSE = $ElementName(new ElementName, 'menclose', 'menclose', 0, false, false, false);
+  MPHANTOM = $ElementName(new ElementName, 'mphantom', 'mphantom', 0, false, false, false);
+  NOFRAMES = $ElementName(new ElementName, 'noframes', 'noframes', 25, true, false, false);
+  NOSCRIPT = $ElementName(new ElementName, 'noscript', 'noscript', 26, true, false, false);
+  OPTGROUP = $ElementName(new ElementName, 'optgroup', 'optgroup', 27, true, false, false);
+  POLYLINE = $ElementName(new ElementName, 'polyline', 'polyline', 0, false, false, false);
+  PREFETCH = $ElementName(new ElementName, 'prefetch', 'prefetch', 0, false, false, false);
+  PROGRESS = $ElementName(new ElementName, 'progress', 'progress', 0, false, false, false);
+  PRSUBSET = $ElementName(new ElementName, 'prsubset', 'prsubset', 0, false, false, false);
+  QUOTIENT = $ElementName(new ElementName, 'quotient', 'quotient', 0, false, false, false);
+  SELECTOR = $ElementName(new ElementName, 'selector', 'selector', 0, false, false, false);
+  TEXTAREA = $ElementName(new ElementName, 'textarea', 'textarea', 35, true, false, false);
+  TEXTPATH = $ElementName(new ElementName, 'textpath', 'textPath', 0, false, false, false);
+  VARIANCE = $ElementName(new ElementName, 'variance', 'variance', 0, false, false, false);
+  ANIMATION = $ElementName(new ElementName, 'animation', 'animation', 0, false, false, false);
+  CONJUGATE = $ElementName(new ElementName, 'conjugate', 'conjugate', 0, false, false, false);
+  CONDITION = $ElementName(new ElementName, 'condition', 'condition', 0, false, false, false);
+  COMPLEXES = $ElementName(new ElementName, 'complexes', 'complexes', 0, false, false, false);
+  FONT_FACE = $ElementName(new ElementName, 'font-face', 'font-face', 0, false, false, false);
+  FACTORIAL = $ElementName(new ElementName, 'factorial', 'factorial', 0, false, false, false);
+  INTERSECT = $ElementName(new ElementName, 'intersect', 'intersect', 0, false, false, false);
+  IMAGINARY = $ElementName(new ElementName, 'imaginary', 'imaginary', 0, false, false, false);
+  LAPLACIAN = $ElementName(new ElementName, 'laplacian', 'laplacian', 0, false, false, false);
+  MATRIXROW = $ElementName(new ElementName, 'matrixrow', 'matrixrow', 0, false, false, false);
+  NOTSUBSET = $ElementName(new ElementName, 'notsubset', 'notsubset', 0, false, false, false);
+  OTHERWISE = $ElementName(new ElementName, 'otherwise', 'otherwise', 0, false, false, false);
+  PIECEWISE = $ElementName(new ElementName, 'piecewise', 'piecewise', 0, false, false, false);
+  PLAINTEXT = $ElementName(new ElementName, 'plaintext', 'plaintext', 30, true, false, false);
+  RATIONALS = $ElementName(new ElementName, 'rationals', 'rationals', 0, false, false, false);
+  SEMANTICS = $ElementName(new ElementName, 'semantics', 'semantics', 0, false, false, false);
+  TRANSPOSE = $ElementName(new ElementName, 'transpose', 'transpose', 0, false, false, false);
+  ANNOTATION = $ElementName(new ElementName, 'annotation', 'annotation', 0, false, false, false);
+  BLOCKQUOTE = $ElementName(new ElementName, 'blockquote', 'blockquote', 50, true, false, false);
+  DIVERGENCE = $ElementName(new ElementName, 'divergence', 'divergence', 0, false, false, false);
+  EULERGAMMA = $ElementName(new ElementName, 'eulergamma', 'eulergamma', 0, false, false, false);
+  EQUIVALENT = $ElementName(new ElementName, 'equivalent', 'equivalent', 0, false, false, false);
+  IMAGINARYI = $ElementName(new ElementName, 'imaginaryi', 'imaginaryi', 0, false, false, false);
+  MALIGNMARK = $ElementName(new ElementName, 'malignmark', 'malignmark', 56, false, false, false);
+  MUNDEROVER = $ElementName(new ElementName, 'munderover', 'munderover', 0, false, false, false);
+  MLABELEDTR = $ElementName(new ElementName, 'mlabeledtr', 'mlabeledtr', 0, false, false, false);
+  NOTANUMBER = $ElementName(new ElementName, 'notanumber', 'notanumber', 0, false, false, false);
+  SOLIDCOLOR = $ElementName(new ElementName, 'solidcolor', 'solidcolor', 0, false, false, false);
+  ALTGLYPHDEF = $ElementName(new ElementName, 'altglyphdef', 'altGlyphDef', 0, false, false, false);
+  DETERMINANT = $ElementName(new ElementName, 'determinant', 'determinant', 0, false, false, false);
+  FEMERGENODE = $ElementName(new ElementName, 'femergenode', 'feMergeNode', 0, false, false, false);
+  FECOMPOSITE = $ElementName(new ElementName, 'fecomposite', 'feComposite', 0, false, false, false);
+  FESPOTLIGHT = $ElementName(new ElementName, 'fespotlight', 'feSpotLight', 0, false, false, false);
+  MALIGNGROUP = $ElementName(new ElementName, 'maligngroup', 'maligngroup', 0, false, false, false);
+  MPRESCRIPTS = $ElementName(new ElementName, 'mprescripts', 'mprescripts', 0, false, false, false);
+  MOMENTABOUT = $ElementName(new ElementName, 'momentabout', 'momentabout', 0, false, false, false);
+  NOTPRSUBSET = $ElementName(new ElementName, 'notprsubset', 'notprsubset', 0, false, false, false);
+  PARTIALDIFF = $ElementName(new ElementName, 'partialdiff', 'partialdiff', 0, false, false, false);
+  ALTGLYPHITEM = $ElementName(new ElementName, 'altglyphitem', 'altGlyphItem', 0, false, false, false);
+  ANIMATECOLOR = $ElementName(new ElementName, 'animatecolor', 'animateColor', 0, false, false, false);
+  DATATEMPLATE = $ElementName(new ElementName, 'datatemplate', 'datatemplate', 0, false, false, false);
+  EXPONENTIALE = $ElementName(new ElementName, 'exponentiale', 'exponentiale', 0, false, false, false);
+  FETURBULENCE = $ElementName(new ElementName, 'feturbulence', 'feTurbulence', 0, false, false, false);
+  FEPOINTLIGHT = $ElementName(new ElementName, 'fepointlight', 'fePointLight', 0, false, false, false);
+  FEMORPHOLOGY = $ElementName(new ElementName, 'femorphology', 'feMorphology', 0, false, false, false);
+  OUTERPRODUCT = $ElementName(new ElementName, 'outerproduct', 'outerproduct', 0, false, false, false);
+  ANIMATEMOTION = $ElementName(new ElementName, 'animatemotion', 'animateMotion', 0, false, false, false);
+  COLOR_PROFILE_0 = $ElementName(new ElementName, 'color-profile', 'color-profile', 0, false, false, false);
+  FONT_FACE_SRC = $ElementName(new ElementName, 'font-face-src', 'font-face-src', 0, false, false, false);
+  FONT_FACE_URI = $ElementName(new ElementName, 'font-face-uri', 'font-face-uri', 0, false, false, false);
+  FOREIGNOBJECT = $ElementName(new ElementName, 'foreignobject', 'foreignObject', 59, false, false, false);
+  FECOLORMATRIX = $ElementName(new ElementName, 'fecolormatrix', 'feColorMatrix', 0, false, false, false);
+  MISSING_GLYPH = $ElementName(new ElementName, 'missing-glyph', 'missing-glyph', 0, false, false, false);
+  MMULTISCRIPTS = $ElementName(new ElementName, 'mmultiscripts', 'mmultiscripts', 0, false, false, false);
+  SCALARPRODUCT = $ElementName(new ElementName, 'scalarproduct', 'scalarproduct', 0, false, false, false);
+  VECTORPRODUCT = $ElementName(new ElementName, 'vectorproduct', 'vectorproduct', 0, false, false, false);
+  ANNOTATION_XML = $ElementName(new ElementName, 'annotation-xml', 'annotation-xml', 58, false, false, false);
+  DEFINITION_SRC = $ElementName(new ElementName, 'definition-src', 'definition-src', 0, false, false, false);
+  FONT_FACE_NAME = $ElementName(new ElementName, 'font-face-name', 'font-face-name', 0, false, false, false);
+  FEGAUSSIANBLUR = $ElementName(new ElementName, 'fegaussianblur', 'feGaussianBlur', 0, false, false, false);
+  FEDISTANTLIGHT = $ElementName(new ElementName, 'fedistantlight', 'feDistantLight', 0, false, false, false);
+  LINEARGRADIENT = $ElementName(new ElementName, 'lineargradient', 'linearGradient', 0, false, false, false);
+  NATURALNUMBERS = $ElementName(new ElementName, 'naturalnumbers', 'naturalnumbers', 0, false, false, false);
+  RADIALGRADIENT = $ElementName(new ElementName, 'radialgradient', 'radialGradient', 0, false, false, false);
+  ANIMATETRANSFORM = $ElementName(new ElementName, 'animatetransform', 'animateTransform', 0, false, false, false);
+  CARTESIANPRODUCT = $ElementName(new ElementName, 'cartesianproduct', 'cartesianproduct', 0, false, false, false);
+  FONT_FACE_FORMAT = $ElementName(new ElementName, 'font-face-format', 'font-face-format', 0, false, false, false);
+  FECONVOLVEMATRIX = $ElementName(new ElementName, 'feconvolvematrix', 'feConvolveMatrix', 0, false, false, false);
+  FEDIFFUSELIGHTING = $ElementName(new ElementName, 'fediffuselighting', 'feDiffuseLighting', 0, false, false, false);
+  FEDISPLACEMENTMAP = $ElementName(new ElementName, 'fedisplacementmap', 'feDisplacementMap', 0, false, false, false);
+  FESPECULARLIGHTING = $ElementName(new ElementName, 'fespecularlighting', 'feSpecularLighting', 0, false, false, false);
+  DOMAINOFAPPLICATION = $ElementName(new ElementName, 'domainofapplication', 'domainofapplication', 0, false, false, false);
+  FECOMPONENTTRANSFER = $ElementName(new ElementName, 'fecomponenttransfer', 'feComponentTransfer', 0, false, false, false);
+  ELEMENT_NAMES = initValues(_3Lnu_validator_htmlparser_impl_ElementName_2_classLit, 61, 14, [A, B, G, I, P, Q, S, U, BR, CI, CN, DD, DL, DT, EM, EQ, FN, H1, H2, H3, H4, H5, H6, GT, HR, IN_0, LI, LN, LT, MI, MN, MO, MS, OL, OR, PI, RP, RT_0, TD, TH, TR, TT, UL, AND, ARG, ABS, BIG, BDO, CSC, COL, COS, COT, DEL, DFN, DIR_0, DIV, EXP, GCD, GEQ, IMG, INS, INT, KBD, LOG, LCM, LEQ, MTD, MIN_0, MAP, MTR, MAX_0, NEQ, NOT, NAV, PRE, REM, SUB, SEC, SVG, SUM, SIN, SEP, SUP, SET, TAN, USE, VAR, WBR, XMP, XOR, AREA, ABBR_0, BASE_0, BVAR, BODY, CARD, CODE_0, CITE_0, CSCH, COSH, COTH, CURL, DESC, DIFF, DEFS, FORM_0, FONT, GRAD, HEAD, HTML_0, LINE, LINK_0, LIST_0, META, MSUB, MODE_0, MATH, MARK, MASK_0, MEAN, MSUP, MENU, MROW, NONE, NOBR, NEST, PATH_0, PLUS, RULE, REAL, RELN, RECT, ROOT, RUBY, SECH, SINH, SPAN_0, SAMP, STOP, SDEV, TIME, TRUE, TREF, TANH, TEXT_0, VIEW, ASIDE, AUDIO, APPLY, EMBED, FRAME_0, FALSE, FLOOR, GLYPH, HKERN, IMAGE, IDENT, INPUT, LABEL_0, LIMIT, MFRAC, MPATH, METER, MOVER, MINUS, MROOT, MSQRT, MTEXT, NOTIN, PIECE, PARAM, POWER, REALS, STYLE_0, SMALL, THEAD, TABLE, TITLE_0, TSPAN, TIMES, TFOOT, TBODY, UNION, VKERN, VIDEO, ARCSEC, ARCCSC, ARCTAN, ARCSIN, ARCCOS, APPLET, ARCCOT, APPROX, BUTTON, CIRCLE, CENTER, CURSOR_0, CANVAS, DIVIDE, DEGREE, DOMAIN, EXISTS, FETILE, FIGURE, FORALL, FILTER_0, FOOTER, HGROUP, HEADER, IFRAME, KEYGEN, LAMBDA, LEGEND, MSPACE, MTABLE, MSTYLE, MGLYPH, MEDIAN, MUNDER, MARKER, MERROR, MOMENT, MATRIX, OPTION, OBJECT_0, OUTPUT, PRIMES, SOURCE, STRIKE, STRONG, SWITCH, SYMBOL, SPACER, SELECT, SUBSET, SCRIPT, TBREAK, VECTOR, ARTICLE, ANIMATE, ARCSECH, ARCCSCH, ARCTANH, ARCSINH, ARCCOSH, ARCCOTH, ACRONYM, ADDRESS, BGSOUND, COMMAND, COMPOSE, CEILING, CSYMBOL, CAPTION, DISCARD, DECLARE_0, DETAILS, ELLIPSE, FEFUNCA, FEFUNCB, FEBLEND, FEFLOOD, FEIMAGE, FEMERGE, FEFUNCG, FEFUNCR, HANDLER, INVERSE, IMPLIES, ISINDEX, LOGBASE, LISTING, MFENCED, MPADDED, MARQUEE, MACTION, MSUBSUP, NOEMBED, POLYGON, PATTERN_0, PRODUCT, SETDIFF, SECTION, TENDSTO, UPLIMIT, ALTGLYPH, BASEFONT, CLIPPATH, CODOMAIN, COLGROUP, DATAGRID, EMPTYSET, FACTOROF, FIELDSET, FRAMESET, FEOFFSET, GLYPHREF_0, INTERVAL, INTEGERS, INFINITY, LISTENER, LOWLIMIT, METADATA, MENCLOSE, MPHANTOM, NOFRAMES, NOSCRIPT, OPTGROUP, POLYLINE, PREFETCH, PROGRESS, PRSUBSET, QUOTIENT, SELECTOR, TEXTAREA, TEXTPATH, VARIANCE, ANIMATION, CONJUGATE, CONDITION, COMPLEXES, FONT_FACE, FACTORIAL, INTERSECT, IMAGINARY, LAPLACIAN, MATRIXROW, NOTSUBSET, OTHERWISE, PIECEWISE, PLAINTEXT, RATIONALS, SEMANTICS, TRANSPOSE, ANNOTATION, BLOCKQUOTE, DIVERGENCE, EULERGAMMA, EQUIVALENT, IMAGINARYI, MALIGNMARK, MUNDEROVER, MLABELEDTR, NOTANUMBER, SOLIDCOLOR, ALTGLYPHDEF, DETERMINANT, FEMERGENODE, FECOMPOSITE, FESPOTLIGHT, MALIGNGROUP, MPRESCRIPTS, MOMENTABOUT, NOTPRSUBSET, PARTIALDIFF, ALTGLYPHITEM, ANIMATECOLOR, DATATEMPLATE, EXPONENTIALE, FETURBULENCE, FEPOINTLIGHT, FEMORPHOLOGY, OUTERPRODUCT, ANIMATEMOTION, COLOR_PROFILE_0, FONT_FACE_SRC, FONT_FACE_URI, FOREIGNOBJECT, FECOLORMATRIX, MISSING_GLYPH, MMULTISCRIPTS, SCALARPRODUCT, VECTORPRODUCT, ANNOTATION_XML, DEFINITION_SRC, FONT_FACE_NAME, FEGAUSSIANBLUR, FEDISTANTLIGHT, LINEARGRADIENT, NATURALNUMBERS, RADIALGRADIENT, ANIMATETRANSFORM, CARTESIANPRODUCT, FONT_FACE_FORMAT, FECONVOLVEMATRIX, FEDIFFUSELIGHTING, FEDISPLACEMENTMAP, FESPECULARLIGHTING, DOMAINOFAPPLICATION, FECOMPONENTTRANSFER]);
+  ELEMENT_HASHES = initValues(_3I_classLit, 49, -1, [1057, 1090, 1255, 1321, 1552, 1585, 1651, 1717, 68162, 68899, 69059, 69764, 70020, 70276, 71077, 71205, 72134, 72232, 72264, 72296, 72328, 72360, 72392, 73351, 74312, 75209, 78124, 78284, 78476, 79149, 79309, 79341, 79469, 81295, 81487, 82224, 84498, 84626, 86164, 86292, 86612, 86676, 87445, 3183041, 3186241, 3198017, 3218722, 3226754, 3247715, 3256803, 3263971, 3264995, 3289252, 3291332, 3295524, 3299620, 3326725, 3379303, 3392679, 3448233, 3460553, 3461577, 3510347, 3546604, 3552364, 3556524, 3576461, 3586349, 3588141, 3590797, 3596333, 3622062, 3625454, 3627054, 3675728, 3749042, 3771059, 3771571, 3776211, 3782323, 3782963, 3784883, 3785395, 3788979, 3815476, 3839605, 3885110, 3917911, 3948984, 3951096, 135304769, 135858241, 136498210, 136906434, 137138658, 137512995, 137531875, 137548067, 137629283, 137645539, 137646563, 137775779, 138529956, 138615076, 139040932, 140954086, 141179366, 141690439, 142738600, 143013512, 146979116, 147175724, 147475756, 147902637, 147936877, 148017645, 148131885, 148228141, 148229165, 148309165, 148395629, 148551853, 148618829, 149076462, 149490158, 149572782, 151277616, 151639440, 153268914, 153486514, 153563314, 153750706, 153763314, 153914034, 154406067, 154417459, 154600979, 154678323, 154680979, 154866835, 155366708, 155375188, 155391572, 155465780, 155869364, 158045494, 168988979, 169321621, 169652752, 173151309, 174240818, 174247297, 174669292, 175391532, 176638123, 177380397, 177879204, 177886734, 180753473, 181020073, 181503558, 181686320, 181999237, 181999311, 182048201, 182074866, 182078003, 182083764, 182920847, 184716457, 184976961, 185145071, 187281445, 187872052, 188100653, 188875944, 188919873, 188920457, 189203987, 189371817, 189414886, 189567458, 190266670, 191318187, 191337609, 202479203, 202493027, 202835587, 202843747, 203013219, 203036048, 203045987, 203177552, 203898516, 204648562, 205067918, 205078130, 205096654, 205689142, 205690439, 205988909, 207213161, 207794484, 207800999, 208023602, 208213644, 208213647, 210261490, 210310273, 210940978, 213325049, 213946445, 214055079, 215125040, 215134273, 215135028, 215237420, 215418148, 215553166, 215553394, 215563858, 215627949, 215754324, 217529652, 217713834, 217732628, 218731945, 221417045, 221424946, 221493746, 221515401, 221658189, 221844577, 221908140, 221910626, 221921586, 222659762, 225001091, 236105833, 236113965, 236194995, 236195427, 236206132, 236206387, 236211683, 236212707, 236381647, 236571826, 237124271, 238172205, 238210544, 238270764, 238435405, 238501172, 239224867, 239257644, 239710497, 240307721, 241208789, 241241557, 241318060, 241319404, 241343533, 241344069, 241405397, 241765845, 243864964, 244502085, 244946220, 245109902, 247647266, 247707956, 248648814, 248648836, 248682161, 248986932, 249058914, 249697357, 252132601, 252135604, 252317348, 255007012, 255278388, 256365156, 257566121, 269763372, 271202790, 271863856, 272049197, 272127474, 272770631, 274339449, 274939471, 275388004, 275388005, 275388006, 275977800, 278267602, 278513831, 278712622, 281613765, 281683369, 282120228, 282250732, 282508942, 283743649, 283787570, 284710386, 285391148, 285478533, 285854898, 285873762, 286931113, 288964227, 289445441, 289689648, 291671489, 303512884, 305319975, 305610036, 305764101, 308448294, 308675890, 312085683, 312264750, 315032867, 316391000, 317331042, 317902135, 318950711, 319447220, 321499182, 322538804, 323145200, 337067316, 337826293, 339905989, 340833697, 341457068, 345302593, 349554733, 349771471, 349786245, 350819405, 356072847, 370349192, 373962798, 375558638, 375574835, 376053993, 383276530, 383373833, 383407586, 384439906, 386079012, 404133513, 404307343, 407031852, 408072233, 409112005, 409608425, 409771500, 419040932, 437730612, 439529766, 442616365, 442813037, 443157674, 443295316, 450118444, 450482697, 456789668, 459935396, 471217869, 474073645, 476230702, 476665218, 476717289, 483014825, 485083298, 489306281, 538364390, 540675748, 543819186, 543958612, 576960820, 577242548, 610515252, 642202932, 644420819]);
+}
+
+function $ElementName(this$static, name_0, camelCaseName, group, special, scoping, fosterParenting){
+  $clinit_125();
+  this$static.name_0 = name_0;
+  this$static.camelCaseName = camelCaseName;
+  this$static.group = group;
+  this$static.special = special;
+  this$static.scoping = scoping;
+  this$static.fosterParenting = fosterParenting;
+  this$static.custom = false;
+  return this$static;
+}
+
+function $ElementName_0(this$static, name_0){
+  $clinit_125();
+  this$static.name_0 = name_0;
+  this$static.camelCaseName = name_0;
+  this$static.group = 0;
+  this$static.special = false;
+  this$static.scoping = false;
+  this$static.fosterParenting = false;
+  this$static.custom = true;
+  return this$static;
+}
+
+function bufToHash_0(buf, len){
+  var hash, i, j;
+  hash = len;
+  hash <<= 5;
+  hash += buf[0] - 96;
+  j = len;
+  for (i = 0; i < 4 && j > 0; ++i) {
+    --j;
+    hash <<= 5;
+    hash += buf[j] - 96;
+  }
+  return hash;
+}
+
+function elementNameByBuffer(buf, offset, length_0){
+  var end, end_0;
+  $clinit_125();
+  var elementName, hash, index, name_0;
+  hash = bufToHash_0(buf, length_0);
+  index = binarySearch(ELEMENT_HASHES, hash);
+  if (index < 0) {
+    return $ElementName_0(new ElementName, String((end = offset + length_0 , __checkBounds(buf.length, offset, end) , __valueOf(buf, offset, end))));
+  }
+   else {
+    elementName = ELEMENT_NAMES[index];
+    name_0 = elementName.name_0;
+    if (!localEqualsBuffer(name_0, buf, offset, length_0)) {
+      return $ElementName_0(new ElementName, String((end_0 = offset + length_0 , __checkBounds(buf.length, offset, end_0) , __valueOf(buf, offset, end_0))));
+    }
+    return elementName;
+  }
+}
+
+function getClass_68(){
+  return Lnu_validator_htmlparser_impl_ElementName_2_classLit;
+}
+
+function ElementName(){
+}
+
+_ = ElementName.prototype = new Object_0;
+_.getClass$ = getClass_68;
+_.typeId$ = 40;
+_.camelCaseName = null;
+_.custom = false;
+_.fosterParenting = false;
+_.group = 0;
+_.name_0 = null;
+_.scoping = false;
+_.special = false;
+var A, ABBR_0, ABS, ACRONYM, ADDRESS, ALTGLYPH, ALTGLYPHDEF, ALTGLYPHITEM, AND, ANIMATE, ANIMATECOLOR, ANIMATEMOTION, ANIMATETRANSFORM, ANIMATION, ANNOTATION, ANNOTATION_XML, APPLET, APPLY, APPROX, ARCCOS, ARCCOSH, ARCCOT, ARCCOTH, ARCCSC, ARCCSCH, ARCSEC, ARCSECH, ARCSIN, ARCSINH, ARCTAN, ARCTANH, AREA, ARG, ARTICLE, ASIDE, AUDIO, B, BASE_0, BASEFONT, BDO, BGSOUND, BIG, BLOCKQUOTE, BODY, BR, BUTTON, BVAR, CANVAS, CAPTION, CARD, CARTESIANPRODUCT, CEILING, CENTER, CI, CIRCLE, CITE_0, CLIPPATH, CN, CODE_0, CODOMAIN, COL, COLGROUP, COLOR_PROFILE_0, COMMAND, COMPLEXES, COMPOSE, CONDITION, CONJUGATE, COS, COSH, COT, COTH, CSC, CSCH, CSYMBOL, CURL, CURSOR_0, DATAGRID, DATATEMPLATE, DD, DECLARE_0, DEFINITION_SRC, DEFS, DEGREE, DEL, DESC, DETAILS, DETERMINANT, DFN, DIFF, DIR_0, DISCARD, DIV, DIVERGENCE, DIVIDE, DL, DOMAIN, DOMAINOFAPPLICATION, DT, ELEMENT_HASHES, ELEMENT_NAMES, ELLIPSE, EM, EMBED, EMPTYSET, EQ, EQUIVALENT, EULERGAMMA, EXISTS, EXP, EXPONENTIALE, FACTORIAL, FACTOROF, FALSE, FEBLEND, FECOLORMATRIX, FECOMPONENTTRANSFER, FECOMPOSITE, FECONVOLVEMATRIX, FEDIFFUSELIGHTING, FEDISPLACEMENTMAP, FEDISTANTLIGHT, FEFLOOD, FEFUNCA, FEFUNCB, FEFUNCG, FEFUNCR, FEGAUSSIANBLUR, FEIMAGE, FEMERGE, FEMERGENODE, FEMORPHOLOGY, FEOFFSET, FEPOINTLIGHT, FESPECULARLIGHTING, FESPOTLIGHT, FETILE, FETURBULENCE, FIELDSET, FIGURE, FILTER_0, FLOOR, FN, FONT, FONT_FACE, FONT_FACE_FORMAT, FONT_FACE_NAME, FONT_FACE_SRC, FONT_FACE_URI, FOOTER, FORALL, FOREIGNOBJECT, FORM_0, FRAME_0, FRAMESET, G, GCD, GEQ, GLYPH, GLYPHREF_0, GRAD, GT, H1, H2, H3, H4, H5, H6, HANDLER, HEAD, HEADER, HGROUP, HKERN, HR, HTML_0, I, IDENT, IFRAME, IMAGE, IMAGINARY, IMAGINARYI, IMG, IMPLIES, IN_0, INFINITY, INPUT, INS, INT, INTEGERS, INTERSECT, INTERVAL, INVERSE, ISINDEX, KBD, KEYGEN, LABEL_0, LAMBDA, LAPLACIAN, LCM, LEGEND, LEQ, LI, LIMIT, LINE, LINEARGRADIENT, LINK_0, LIST_0, LISTENER, LISTING, LN, LOG, LOGBASE, LOWLIMIT, LT, MACTION, MALIGNGROUP, MALIGNMARK, MAP, MARK, MARKER, MARQUEE, MASK_0, MATH, MATRIX, MATRIXROW, MAX_0, MEAN, MEDIAN, MENCLOSE, MENU, MERROR, META, METADATA, METER, MFENCED, MFRAC, MGLYPH, MI, MIN_0, MINUS, MISSING_GLYPH, MLABELEDTR, MMULTISCRIPTS, MN, MO, MODE_0, MOMENT, MOMENTABOUT, MOVER, MPADDED, MPATH, MPHANTOM, MPRESCRIPTS, MROOT, MROW, MS, MSPACE, MSQRT, MSTYLE, MSUB, MSUBSUP, MSUP, MTABLE, MTD, MTEXT, MTR, MUNDER, MUNDEROVER, NATURALNUMBERS, NAV, NEQ, NEST, NOBR, NOEMBED, NOFRAMES, NONE, NOSCRIPT, NOT, NOTANUMBER, NOTIN, NOTPRSUBSET, NOTSUBSET, OBJECT_0, OL, OPTGROUP, OPTION, OR, OTHERWISE, OUTERPRODUCT, OUTPUT, P, PARAM, PARTIALDIFF, PATH_0, PATTERN_0, PI, PIECE, PIECEWISE, PLAINTEXT, PLUS, POLYGON, POLYLINE, POWER, PRE, PREFETCH, PRIMES, PRODUCT, PROGRESS, PRSUBSET, Q, QUOTIENT, RADIALGRADIENT, RATIONALS, REAL, REALS, RECT, RELN, REM, ROOT, RP, RT_0, RUBY, RULE, S, SAMP, SCALARPRODUCT, SCRIPT, SDEV, SEC, SECH, SECTION, SELECT, SELECTOR, SEMANTICS, SEP, SET, SETDIFF, SIN, SINH, SMALL, SOLIDCOLOR, SOURCE, SPACER, SPAN_0, STOP, STRIKE, STRONG, STYLE_0, SUB, SUBSET, SUM, SUP, SVG, SWITCH, SYMBOL, TABLE, TAN, TANH, TBODY, TBREAK, TD, TENDSTO, TEXT_0, TEXTAREA, TEXTPATH, TFOOT, TH, THEAD, TIME, TIMES, TITLE_0, TR, TRANSPOSE, TREF, TRUE, TSPAN, TT, U, UL, UNION, UPLIMIT, USE, VAR, VARIANCE, VECTOR, VECTORPRODUCT, VIDEO, VIEW, VKERN, WBR, XMP, XOR;
+function $clinit_126(){
+  $clinit_126 = nullMethod;
+  LT_GT = initValues(_3C_classLit, 47, -1, [60, 62]);
+  LT_SOLIDUS = initValues(_3C_classLit, 47, -1, [60, 47]);
+  RSQB_RSQB = initValues(_3C_classLit, 47, -1, [93, 93]);
+  REPLACEMENT_CHARACTER_0 = initValues(_3C_classLit, 47, -1, [65533]);
+  SPACE = initValues(_3C_classLit, 47, -1, [32]);
+  LF = initValues(_3C_classLit, 47, -1, [10]);
+  CDATA_LSQB = $toCharArray('CDATA[');
+  OCTYPE = $toCharArray('octype');
+  UBLIC = $toCharArray('ublic');
+  YSTEM = $toCharArray('ystem');
+  TITLE_ARR = initValues(_3C_classLit, 47, -1, [116, 105, 116, 108, 101]);
+  SCRIPT_ARR = initValues(_3C_classLit, 47, -1, [115, 99, 114, 105, 112, 116]);
+  STYLE_ARR = initValues(_3C_classLit, 47, -1, [115, 116, 121, 108, 101]);
+  PLAINTEXT_ARR = initValues(_3C_classLit, 47, -1, [112, 108, 97, 105, 110, 116, 101, 120, 116]);
+  XMP_ARR = initValues(_3C_classLit, 47, -1, [120, 109, 112]);
+  TEXTAREA_ARR = initValues(_3C_classLit, 47, -1, [116, 101, 120, 116, 97, 114, 101, 97]);
+  IFRAME_ARR = initValues(_3C_classLit, 47, -1, [105, 102, 114, 97, 109, 101]);
+  NOEMBED_ARR = initValues(_3C_classLit, 47, -1, [110, 111, 101, 109, 98, 101, 100]);
+  NOSCRIPT_ARR = initValues(_3C_classLit, 47, -1, [110, 111, 115, 99, 114, 105, 112, 116]);
+  NOFRAMES_ARR = initValues(_3C_classLit, 47, -1, [110, 111, 102, 114, 97, 109, 101, 115]);
+}
+
+function $addAttributeWithValue(this$static){
+  var val;
+  this$static.metaBoundaryPassed && ($clinit_125() , META) == this$static.tagName && ($clinit_124() , CHARSET) == this$static.attributeName;
+  if (this$static.attributeName) {
+    val = valueOf_0(this$static.longStrBuf, 0, this$static.longStrBufLen);
+    !this$static.endTag && this$static.html4 && this$static.html4ModeCompatibleWithXhtml1Schemata && $isCaseFolded(this$static.attributeName) && (val = newAsciiLowerCaseStringFromString(val));
+    $addAttribute(this$static.attributes, this$static.attributeName, val, this$static.xmlnsPolicy);
+    this$static.attributeName = null;
+  }
+}
+
+function $addAttributeWithoutValue(this$static){
+  this$static.metaBoundaryPassed && ($clinit_124() , CHARSET) == this$static.attributeName && ($clinit_125() , META) == this$static.tagName;
+  if (this$static.attributeName) {
+    if (this$static.html4) {
+      $isBoolean(this$static.attributeName)?this$static.html4ModeCompatibleWithXhtml1Schemata?$addAttribute(this$static.attributes, this$static.attributeName, this$static.attributeName.local[0], this$static.xmlnsPolicy):$addAttribute(this$static.attributes, this$static.attributeName, '', this$static.xmlnsPolicy):$addAttribute(this$static.attributes, this$static.attributeName, '', this$static.xmlnsPolicy);
+    }
+     else {
+      (($clinit_124() , SRC) == this$static.attributeName || HREF == this$static.attributeName) && $warn('Attribute \u201C' + this$static.attributeName.local[0] + '\u201D without an explicit value seen. The attribute may be dropped by IE7.');
+      $addAttribute(this$static.attributes, this$static.attributeName, '', this$static.xmlnsPolicy);
+    }
+    this$static.attributeName = null;
+  }
+}
+
+function $adjustDoubleHyphenAndAppendToLongStrBufAndErr(this$static, c){
+  switch (this$static.commentPolicy.ordinal) {
+    case 2:
+      --this$static.longStrBufLen;
+      $appendLongStrBuf(this$static, 32);
+      $appendLongStrBuf(this$static, 45);
+    case 0:
+      $appendLongStrBuf(this$static, c);
+      break;
+    case 1:
+      $fatal_1(this$static, 'The document is not mappable to XML 1.0 due to two consecutive hyphens in a comment.');
+  }
+}
+
+function $appendLongStrBuf(this$static, c){
+  var newBuf;
+  if (this$static.longStrBufLen == this$static.longStrBuf.length) {
+    newBuf = initDim(_3C_classLit, 47, -1, this$static.longStrBufLen + (this$static.longStrBufLen >> 1), 1);
+    arraycopy(this$static.longStrBuf, 0, newBuf, 0, this$static.longStrBuf.length);
+    this$static.longStrBuf = newBuf;
+  }
+  this$static.longStrBuf[this$static.longStrBufLen++] = c;
+}
+
+function $appendLongStrBuf_0(this$static, buffer, offset, length_0){
+  var newBuf, reqLen;
+  reqLen = this$static.longStrBufLen + length_0;
+  if (this$static.longStrBuf.length < reqLen) {
+    newBuf = initDim(_3C_classLit, 47, -1, reqLen + (reqLen >> 1), 1);
+    arraycopy(this$static.longStrBuf, 0, newBuf, 0, this$static.longStrBuf.length);
+    this$static.longStrBuf = newBuf;
+  }
+  arraycopy(buffer, offset, this$static.longStrBuf, this$static.longStrBufLen, length_0);
+  this$static.longStrBufLen = reqLen;
+}
+
+function $appendSecondHyphenToBogusComment(this$static){
+  switch (this$static.commentPolicy.ordinal) {
+    case 2:
+      $appendLongStrBuf(this$static, 32);
+    case 0:
+      $appendLongStrBuf(this$static, 45);
+      break;
+    case 1:
+      $fatal_1(this$static, 'The document is not mappable to XML 1.0 due to two consecutive hyphens in a comment.');
+  }
+}
+
+function $appendStrBuf(this$static, c){
+  var newBuf;
+  if (this$static.strBufLen == this$static.strBuf.length) {
+    newBuf = initDim(_3C_classLit, 47, -1, this$static.strBuf.length + 1024, 1);
+    arraycopy(this$static.strBuf, 0, newBuf, 0, this$static.strBuf.length);
+    this$static.strBuf = newBuf;
+  }
+  this$static.strBuf[this$static.strBufLen++] = c;
+}
+
+function $attributeNameComplete(this$static){
+  this$static.attributeName = nameByBuffer(this$static.strBuf, 0, this$static.strBufLen, this$static.namePolicy != ($clinit_115() , ALLOW));
+  !this$static.attributes && (this$static.attributes = $HtmlAttributes(new HtmlAttributes, this$static.mappingLangToXmlLang));
+  if ($contains(this$static.attributes, this$static.attributeName)) {
+    $err('Duplicate attribute \u201C' + this$static.attributeName.local[0] + '\u201D.');
+    this$static.attributeName = null;
+  }
+}
+
+function $emitCarriageReturn(this$static, buf, pos){
+  this$static.nextCharOnNewLine = true;
+  this$static.lastCR = true;
+  $flushChars(this$static, buf, pos);
+  $characters(this$static.tokenHandler, LF, 0, 1);
+  this$static.cstart = 2147483647;
+}
+
+function $emitCurrentTagToken(this$static, selfClosing, pos){
+  var attrs;
+  this$static.cstart = pos + 1;
+  this$static.stateSave = 0;
+  attrs = !this$static.attributes?($clinit_128() , EMPTY_ATTRIBUTES):this$static.attributes;
+  this$static.endTag?$endTag(this$static.tokenHandler, this$static.tagName):$startTag(this$static.tokenHandler, this$static.tagName, attrs, selfClosing);
+  this$static.tagName = null;
+  this$static.newAttributesEachTime?(this$static.attributes = null):$clear_0(this$static.attributes, this$static.mappingLangToXmlLang);
+  return this$static.stateSave;
+}
+
+function $emitDoctypeToken(this$static, pos){
+  this$static.cstart = pos + 1;
+  $doctype(this$static.tokenHandler, this$static.doctypeName, this$static.publicIdentifier, this$static.systemIdentifier, this$static.forceQuirks);
+  this$static.doctypeName = null;
+  this$static.publicIdentifier = null;
+  this$static.systemIdentifier = null;
+}
+
+function $emitOrAppendOne(this$static, val, returnState){
+  (returnState & -2) != 0?$appendLongStrBuf(this$static, val[0]):$characters(this$static.tokenHandler, val, 0, 1);
+}
+
+function $emitOrAppendTwo(this$static, val, returnState){
+  if ((returnState & -2) != 0) {
+    $appendLongStrBuf(this$static, val[0]);
+    $appendLongStrBuf(this$static, val[1]);
+  }
+   else {
+    $characters(this$static.tokenHandler, val, 0, 2);
+  }
+}
+
+function $emitStrBuf(this$static){
+  this$static.strBufLen > 0 && $characters(this$static.tokenHandler, this$static.strBuf, 0, this$static.strBufLen);
+}
+
+function $emptyAttributes(this$static){
+  if (this$static.newAttributesEachTime) {
+    return $HtmlAttributes(new HtmlAttributes, this$static.mappingLangToXmlLang);
+  }
+   else {
+    return $clinit_128() , EMPTY_ATTRIBUTES;
+  }
+}
+
+function $end(this$static){
+  this$static.strBuf = null;
+  this$static.longStrBuf = null;
+  this$static.doctypeName = null;
+  this$static.systemIdentifier != null && (this$static.systemIdentifier = null);
+  this$static.publicIdentifier != null && (this$static.publicIdentifier = null);
+  !!this$static.tagName && (this$static.tagName = null);
+  !!this$static.attributeName && (this$static.attributeName = null);
+  $endTokenization(this$static.tokenHandler);
+  if (this$static.attributes) {
+    $clear_0(this$static.attributes, this$static.mappingLangToXmlLang);
+    this$static.attributes = null;
+  }
+}
+
+function $endTagExpectationToArray(this$static){
+  switch (this$static.endTagExpectation.group) {
+    case 36:
+      this$static.endTagExpectationAsArray = TITLE_ARR;
+      return;
+    case 31:
+      this$static.endTagExpectationAsArray = SCRIPT_ARR;
+      return;
+    case 33:
+      this$static.endTagExpectationAsArray = STYLE_ARR;
+      return;
+    case 30:
+      this$static.endTagExpectationAsArray = PLAINTEXT_ARR;
+      return;
+    case 38:
+      this$static.endTagExpectationAsArray = XMP_ARR;
+      return;
+    case 35:
+      this$static.endTagExpectationAsArray = TEXTAREA_ARR;
+      return;
+    case 47:
+      this$static.endTagExpectationAsArray = IFRAME_ARR;
+      return;
+    case 60:
+      this$static.endTagExpectationAsArray = NOEMBED_ARR;
+      return;
+    case 26:
+      this$static.endTagExpectationAsArray = NOSCRIPT_ARR;
+      return;
+    case 25:
+      this$static.endTagExpectationAsArray = NOFRAMES_ARR;
+      return;
+    default:return;
+  }
+}
+
+function $eof_0(this$static){
+  var candidateArr, ch, i, returnState, state, val;
+  state = this$static.stateSave;
+  returnState = this$static.returnStateSave;
+  eofloop: for (;;) {
+    switch (state) {
+      case 53:
+      case 65:
+        $characters(this$static.tokenHandler, LT_GT, 0, 1);
+        break eofloop;
+      case 4:
+        $characters(this$static.tokenHandler, LT_GT, 0, 1);
+        break eofloop;
+      case 61:
+        $characters(this$static.tokenHandler, LT_GT, 0, 1);
+        break eofloop;
+      case 37:
+        $characters(this$static.tokenHandler, LT_SOLIDUS, 0, 2);
+        $emitStrBuf(this$static);
+        break eofloop;
+      case 5:
+        $characters(this$static.tokenHandler, LT_SOLIDUS, 0, 2);
+        break eofloop;
+      case 6:
+        break eofloop;
+      case 7:
+      case 14:
+      case 48:
+        break eofloop;
+      case 8:
+        break eofloop;
+      case 9:
+      case 10:
+        break eofloop;
+      case 11:
+      case 12:
+      case 13:
+        break eofloop;
+      case 15:
+        this$static.wantsComments && $comment(this$static.tokenHandler, this$static.longStrBuf, 0, this$static.longStrBufLen - 0);
+        this$static.cstart = 1;
+        break eofloop;
+      case 59:
+        $maybeAppendSpaceToBogusComment(this$static);
+        this$static.wantsComments && $comment(this$static.tokenHandler, this$static.longStrBuf, 0, this$static.longStrBufLen - 0);
+        this$static.cstart = 1;
+        break eofloop;
+      case 16:
+        this$static.longStrBufLen = 0;
+        this$static.wantsComments && $comment(this$static.tokenHandler, this$static.longStrBuf, 0, this$static.longStrBufLen - 0);
+        this$static.cstart = 1;
+        break eofloop;
+      case 38:
+        this$static.wantsComments && $comment(this$static.tokenHandler, this$static.longStrBuf, 0, this$static.longStrBufLen - 0);
+        this$static.cstart = 1;
+        break eofloop;
+      case 39:
+        if (this$static.index < 6) {
+          this$static.wantsComments && $comment(this$static.tokenHandler, this$static.longStrBuf, 0, this$static.longStrBufLen - 0);
+          this$static.cstart = 1;
+        }
+         else {
+          this$static.doctypeName = '';
+          this$static.systemIdentifier != null && (this$static.systemIdentifier = null);
+          this$static.publicIdentifier != null && (this$static.publicIdentifier = null);
+          this$static.forceQuirks = true;
+          $emitDoctypeToken(this$static, 0);
+          break eofloop;
+        }
+
+        break eofloop;
+      case 30:
+      case 32:
+      case 35:
+        this$static.wantsComments && $comment(this$static.tokenHandler, this$static.longStrBuf, 0, this$static.longStrBufLen - 0);
+        this$static.cstart = 1;
+        break eofloop;
+      case 34:
+        this$static.wantsComments && $comment(this$static.tokenHandler, this$static.longStrBuf, 0, this$static.longStrBufLen - 2);
+        this$static.cstart = 1;
+        break eofloop;
+      case 33:
+      case 31:
+        this$static.wantsComments && $comment(this$static.tokenHandler, this$static.longStrBuf, 0, this$static.longStrBufLen - 1);
+        this$static.cstart = 1;
+        break eofloop;
+      case 36:
+        this$static.wantsComments && $comment(this$static.tokenHandler, this$static.longStrBuf, 0, this$static.longStrBufLen - 3);
+        this$static.cstart = 1;
+        break eofloop;
+      case 17:
+      case 18:
+        this$static.forceQuirks = true;
+        $emitDoctypeToken(this$static, 0);
+        break eofloop;
+      case 19:
+        this$static.doctypeName = String(valueOf_0(this$static.strBuf, 0, this$static.strBufLen));
+        this$static.forceQuirks = true;
+        $emitDoctypeToken(this$static, 0);
+        break eofloop;
+      case 40:
+      case 41:
+      case 20:
+      case 62:
+      case 64:
+      case 21:
+        this$static.forceQuirks = true;
+        $emitDoctypeToken(this$static, 0);
+        break eofloop;
+      case 22:
+      case 23:
+        this$static.forceQuirks = true;
+        this$static.publicIdentifier = valueOf_0(this$static.longStrBuf, 0, this$static.longStrBufLen);
+        $emitDoctypeToken(this$static, 0);
+        break eofloop;
+      case 24:
+      case 25:
+      case 63:
+        this$static.forceQuirks = true;
+        $emitDoctypeToken(this$static, 0);
+        break eofloop;
+      case 26:
+      case 27:
+        this$static.forceQuirks = true;
+        this$static.systemIdentifier = valueOf_0(this$static.longStrBuf, 0, this$static.longStrBufLen);
+        $emitDoctypeToken(this$static, 0);
+        break eofloop;
+      case 28:
+        this$static.forceQuirks = true;
+        $emitDoctypeToken(this$static, 0);
+        break eofloop;
+      case 29:
+        $emitDoctypeToken(this$static, 0);
+        break eofloop;
+      case 42:
+        (returnState & -2) != 0?$appendLongStrBuf_0(this$static, this$static.strBuf, 0, this$static.strBufLen):$emitStrBuf(this$static);
+        state = returnState;
+        continue;
+      case 72:
+        (returnState & -2) != 0?$appendLongStrBuf_0(this$static, this$static.strBuf, 0, this$static.strBufLen):$emitStrBuf(this$static);
+        state = returnState;
+        continue;
+      case 44:
+        outer: for (;;) {
+          ++this$static.entCol;
+          hiloop: for (;;) {
+            if (this$static.hi == -1) {
+              break hiloop;
+            }
+            if (this$static.entCol == ($clinit_131() , NAMES)[this$static.hi].length) {
+              break hiloop;
+            }
+            if (this$static.entCol > NAMES[this$static.hi].length) {
+              break outer;
+            }
+             else if (0 < NAMES[this$static.hi][this$static.entCol]) {
+              --this$static.hi;
+            }
+             else {
+              break hiloop;
+            }
+          }
+          loloop: for (;;) {
+            if (this$static.hi < this$static.lo) {
+              break outer;
+            }
+            if (this$static.entCol == ($clinit_131() , NAMES)[this$static.lo].length) {
+              this$static.candidate = this$static.lo;
+              this$static.strBufMark = this$static.strBufLen;
+              ++this$static.lo;
+            }
+             else if (this$static.entCol > NAMES[this$static.lo].length) {
+              break outer;
+            }
+             else if (0 > NAMES[this$static.lo][this$static.entCol]) {
+              ++this$static.lo;
+            }
+             else {
+              break loloop;
+            }
+          }
+          if (this$static.hi < this$static.lo) {
+            break outer;
+          }
+          continue;
+        }
+
+        if (this$static.candidate == -1) {
+          (returnState & -2) != 0?$appendLongStrBuf_0(this$static, this$static.strBuf, 0, this$static.strBufLen):$emitStrBuf(this$static);
+          state = returnState;
+          continue eofloop;
+        }
+         else {
+          candidateArr = ($clinit_131() , NAMES)[this$static.candidate];
+          if (candidateArr.length == 0 || candidateArr[candidateArr.length - 1] != 59) {
+            if ((returnState & -2) != 0) {
+              this$static.strBufMark == this$static.strBufLen?(ch = 0):(ch = this$static.strBuf[this$static.strBufMark]);
+              if (ch >= 48 && ch <= 57 || ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122) {
+                $appendLongStrBuf_0(this$static, this$static.strBuf, 0, this$static.strBufLen);
+                state = returnState;
+                continue eofloop;
+              }
+            }
+          }
+          val = VALUES_0[this$static.candidate];
+          (val[0] & 64512) == 55296?$emitOrAppendTwo(this$static, val, returnState):((returnState & -2) != 0?$appendLongStrBuf(this$static, val[0]):$characters(this$static.tokenHandler, val, 0, 1) , undefined);
+          if (this$static.strBufMark < this$static.strBufLen) {
+            if ((returnState & -2) != 0) {
+              for (i = this$static.strBufMark; i < this$static.strBufLen; ++i) {
+                $appendLongStrBuf(this$static, this$static.strBuf[i]);
+              }
+            }
+             else {
+              $characters(this$static.tokenHandler, this$static.strBuf, this$static.strBufMark, this$static.strBufLen - this$static.strBufMark);
+            }
+          }
+          state = returnState;
+          continue eofloop;
+        }
+
+      case 43:
+      case 46:
+      case 45:
+        if (!this$static.seenDigits) {
+          $err('No digits after \u201C' + valueOf_0(this$static.strBuf, 0, this$static.strBufLen) + '\u201D.');
+          (returnState & -2) != 0?$appendLongStrBuf_0(this$static, this$static.strBuf, 0, this$static.strBufLen):$emitStrBuf(this$static);
+          state = returnState;
+          continue;
+        }
+
+        $handleNcrValue(this$static, returnState);
+        state = returnState;
+        continue;
+      case 0:
+      default:break eofloop;
+    }
+  }
+  $eof(this$static.tokenHandler);
+  return;
+}
+
+function $err(){
+  return;
+}
+
+function $fatal_1(this$static, message){
+  var spe;
+  spe = $SAXParseException(new SAXParseException, message, this$static);
+  throw spe;
+}
+
+function $handleNcrValue(this$static, returnState){
+  var ch, val;
+  if (this$static.value <= 65535) {
+    if (this$static.value >= 128 && this$static.value <= 159) {
+      val = ($clinit_131() , WINDOWS_1252)[this$static.value - 128];
+      (returnState & -2) != 0?$appendLongStrBuf(this$static, val[0]):$characters(this$static.tokenHandler, val, 0, 1);
+    }
+     else if (this$static.value == 12 && this$static.contentSpacePolicy != ($clinit_115() , ALLOW)) {
+      this$static.contentSpacePolicy == ($clinit_115() , ALTER_INFOSET)?$emitOrAppendOne(this$static, SPACE, returnState):this$static.contentSpacePolicy == FATAL && $fatal_1(this$static, 'A character reference expanded to a form feed which is not legal XML 1.0 white space.');
+    }
+     else if (this$static.value == 0) {
+      $emitOrAppendOne(this$static, REPLACEMENT_CHARACTER_0, returnState);
+    }
+     else if ((this$static.value & 63488) == 55296) {
+      $emitOrAppendOne(this$static, REPLACEMENT_CHARACTER_0, returnState);
+    }
+     else {
+      ch = this$static.value & 65535;
+      this$static.value == 13 || (this$static.value <= 8 || this$static.value == 11 || this$static.value >= 14 && this$static.value <= 31?(ch = $errNcrControlChar(this$static, ch)):this$static.value >= 64976 && this$static.value <= 65007 || ((this$static.value & 65534) == 65534?(ch = $errNcrNonCharacter(this$static, ch)):this$static.value >= 127 && this$static.value <= 159 && $err('Character reference expands to a control character (' + $toUPlusString(this$static.value & 65535) + ').')));
+      this$static.bmpChar[0] = ch;
+      $emitOrAppendOne(this$static, this$static.bmpChar, returnState);
+    }
+  }
+   else if (this$static.value <= 1114111) {
+    (this$static.value & 65534) == 65534 && $err('Character reference expands to an astral non-character (' + $toUPlusString(this$static.value) + ').');
+    this$static.astralChar[0] = 55232 + (this$static.value >> 10) & 65535;
+    this$static.astralChar[1] = 56320 + (this$static.value & 1023) & 65535;
+    $emitOrAppendTwo(this$static, this$static.astralChar, returnState);
+  }
+   else {
+    $emitOrAppendOne(this$static, REPLACEMENT_CHARACTER_0, returnState);
+  }
+}
+
+function $initDoctypeFields(this$static){
+  this$static.doctypeName = '';
+  this$static.systemIdentifier != null && (this$static.systemIdentifier = null);
+  this$static.publicIdentifier != null && (this$static.publicIdentifier = null);
+  this$static.forceQuirks = false;
+}
+
+function $maybeAppendSpaceToBogusComment(this$static){
+  switch (this$static.commentPolicy.ordinal) {
+    case 2:
+      $appendLongStrBuf(this$static, 32);
+      break;
+    case 1:
+      $fatal_1(this$static, 'The document is not mappable to XML 1.0 due to a trailing hyphen in a comment.');
+  }
+}
+
+function $setStateAndEndTagExpectation(this$static, specialTokenizerState){
+  var asArray;
+  this$static.stateSave = specialTokenizerState;
+  if (specialTokenizerState == 0) {
+    return;
+  }
+  asArray = null.nullMethod();
+  this$static.endTagExpectation = elementNameByBuffer(asArray, 0, null.nullField);
+  $endTagExpectationToArray(this$static);
+}
+
+function $setStateAndEndTagExpectation_0(this$static, specialTokenizerState, endTagExpectation){
+  this$static.stateSave = specialTokenizerState;
+  this$static.endTagExpectation = endTagExpectation;
+  $endTagExpectationToArray(this$static);
+}
+
+function $setXmlnsPolicy(this$static, xmlnsPolicy){
+  if (xmlnsPolicy == ($clinit_115() , FATAL)) {
+    throw $IllegalArgumentException(new IllegalArgumentException, "Can't use FATAL here.");
+  }
+  this$static.xmlnsPolicy = xmlnsPolicy;
+}
+
+function $start_0(this$static){
+  this$static.confident = false;
+  this$static.strBuf = initDim(_3C_classLit, 47, -1, 64, 1);
+  this$static.longStrBuf = initDim(_3C_classLit, 47, -1, 1024, 1);
+  this$static.html4 = false;
+  this$static.metaBoundaryPassed = false;
+  this$static.wantsComments = this$static.tokenHandler.wantingComments;
+  !this$static.newAttributesEachTime && (this$static.attributes = $HtmlAttributes(new HtmlAttributes, this$static.mappingLangToXmlLang));
+  this$static.strBufLen = 0;
+  this$static.longStrBufLen = 0;
+  this$static.stateSave = 0;
+  this$static.lastCR = false;
+  this$static.index = 0;
+  this$static.forceQuirks = false;
+  this$static.additional = 0;
+  this$static.entCol = -1;
+  this$static.firstCharKey = -1;
+  this$static.lo = 0;
+  this$static.hi = ($clinit_131() , NAMES).length - 1;
+  this$static.candidate = -1;
+  this$static.strBufMark = 0;
+  this$static.prevValue = -1;
+  this$static.value = 0;
+  this$static.seenDigits = false;
+  this$static.endTag = false;
+  this$static.shouldSuspend = false;
+  $initDoctypeFields(this$static);
+  !!this$static.tagName && (this$static.tagName = null);
+  !!this$static.attributeName && (this$static.attributeName = null);
+  this$static.newAttributesEachTime && !!this$static.attributes && (this$static.attributes = null);
+  $startTokenization(this$static.tokenHandler, this$static);
+  this$static.alreadyComplainedAboutNonAscii = false;
+  this$static.line = this$static.linePrev = 0;
+  this$static.col = this$static.colPrev = 1;
+  this$static.nextCharOnNewLine = true;
+  this$static.prev = 0;
+  this$static.alreadyWarnedAboutPrivateUseCharacters = false;
+}
+
+function $stateLoop(this$static, state, c, pos, buf, reconsume, returnState, endPos){
+  var candidateArr, ch, e, folded, hilo, i, row, val;
+  stateloop: for (;;) {
+    switch (state) {
+      case 0:
+        dataloop: for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          switch (c) {
+            case 38:
+              $flushChars(this$static, buf, pos);
+              this$static.strBuf[0] = c;
+              this$static.strBufLen = 1;
+              this$static.additional = 0;
+              $LocatorImpl(new LocatorImpl, this$static);
+              returnState = state;
+              state = 42;
+              continue stateloop;
+            case 60:
+              $flushChars(this$static, buf, pos);
+              state = 4;
+              break dataloop;
+            case 0:
+              $flushChars(this$static, buf, pos);
+              $zeroOriginatingReplacementCharacter(this$static.tokenHandler);
+              this$static.cstart = pos + 1;
+              continue;
+            case 13:
+              $emitCarriageReturn(this$static, buf, pos);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            default:continue;
+          }
+        }
+
+      case 4:
+        tagopenloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          if (c >= 65 && c <= 90) {
+            this$static.endTag = false;
+            this$static.strBuf[0] = c + 32 & 65535;
+            this$static.strBufLen = 1;
+            state = 6;
+            break tagopenloop;
+          }
+           else if (c >= 97 && c <= 122) {
+            this$static.endTag = false;
+            this$static.strBuf[0] = c;
+            this$static.strBufLen = 1;
+            state = 6;
+            break tagopenloop;
+          }
+          switch (c) {
+            case 33:
+              state = 16;
+              continue stateloop;
+            case 47:
+              state = 5;
+              continue stateloop;
+            case 63:
+              this$static.longStrBuf[0] = c;
+              this$static.longStrBufLen = 1;
+              state = 15;
+              continue stateloop;
+            case 62:
+              $characters(this$static.tokenHandler, LT_GT, 0, 2);
+              this$static.cstart = pos + 1;
+              state = 0;
+              continue stateloop;
+            default:$characters(this$static.tokenHandler, LT_GT, 0, 1);
+              this$static.cstart = pos;
+              state = 0;
+              reconsume = true;
+              continue stateloop;
+          }
+        }
+
+      case 6:
+        tagnameloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              this$static.tagName = elementNameByBuffer(this$static.strBuf, 0, this$static.strBufLen);
+              state = 7;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              this$static.tagName = elementNameByBuffer(this$static.strBuf, 0, this$static.strBufLen);
+              state = 7;
+              break tagnameloop;
+            case 47:
+              this$static.tagName = elementNameByBuffer(this$static.strBuf, 0, this$static.strBufLen);
+              state = 48;
+              continue stateloop;
+            case 62:
+              this$static.tagName = elementNameByBuffer(this$static.strBuf, 0, this$static.strBufLen);
+              state = $emitCurrentTagToken(this$static, false, pos);
+              if (this$static.shouldSuspend) {
+                break stateloop;
+              }
+
+              continue stateloop;
+            case 0:
+              c = 65533;
+            default:c >= 65 && c <= 90 && (c += 32);
+              $appendStrBuf(this$static, c);
+              continue;
+          }
+        }
+
+      case 7:
+        beforeattributenameloop: for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              continue;
+            case 47:
+              state = 48;
+              continue stateloop;
+            case 62:
+              state = $emitCurrentTagToken(this$static, false, pos);
+              if (this$static.shouldSuspend) {
+                break stateloop;
+              }
+
+              continue stateloop;
+            case 0:
+              c = 65533;
+            case 34:
+            case 39:
+            case 60:
+            case 61:
+            default:c >= 65 && c <= 90 && (c += 32);
+              this$static.strBuf[0] = c;
+              this$static.strBufLen = 1;
+              state = 8;
+              break beforeattributenameloop;
+          }
+        }
+
+      case 8:
+        attributenameloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              $attributeNameComplete(this$static);
+              state = 9;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              $attributeNameComplete(this$static);
+              state = 9;
+              continue stateloop;
+            case 47:
+              $attributeNameComplete(this$static);
+              $addAttributeWithoutValue(this$static);
+              state = 48;
+              continue stateloop;
+            case 61:
+              $attributeNameComplete(this$static);
+              state = 10;
+              break attributenameloop;
+            case 62:
+              $attributeNameComplete(this$static);
+              $addAttributeWithoutValue(this$static);
+              state = $emitCurrentTagToken(this$static, false, pos);
+              if (this$static.shouldSuspend) {
+                break stateloop;
+              }
+
+              continue stateloop;
+            case 0:
+              c = 65533;
+            case 34:
+            case 39:
+            case 60:
+            default:c >= 65 && c <= 90 && (c += 32);
+              $appendStrBuf(this$static, c);
+              continue;
+          }
+        }
+
+      case 10:
+        beforeattributevalueloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              continue;
+            case 34:
+              this$static.longStrBufLen = 0;
+              state = 11;
+              break beforeattributevalueloop;
+            case 38:
+              this$static.longStrBufLen = 0;
+              state = 13;
+              reconsume = true;
+              continue stateloop;
+            case 39:
+              this$static.longStrBufLen = 0;
+              state = 12;
+              continue stateloop;
+            case 62:
+              $addAttributeWithoutValue(this$static);
+              state = $emitCurrentTagToken(this$static, false, pos);
+              if (this$static.shouldSuspend) {
+                break stateloop;
+              }
+
+              continue stateloop;
+            case 0:
+              c = 65533;
+            case 60:
+            case 61:
+            case 96:
+              $errLtOrEqualsOrGraveInUnquotedAttributeOrNull(c);
+            default:this$static.longStrBuf[0] = c;
+              this$static.longStrBufLen = 1;
+              state = 13;
+              continue stateloop;
+          }
+        }
+
+      case 11:
+        attributevaluedoublequotedloop: for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          switch (c) {
+            case 34:
+              $addAttributeWithValue(this$static);
+              state = 14;
+              break attributevaluedoublequotedloop;
+            case 38:
+              this$static.strBuf[0] = c;
+              this$static.strBufLen = 1;
+              this$static.additional = 34;
+              $LocatorImpl(new LocatorImpl, this$static);
+              returnState = state;
+              state = 42;
+              continue stateloop;
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              $appendLongStrBuf(this$static, 10);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+              $appendLongStrBuf(this$static, 10);
+              continue;
+            case 0:
+              c = 65533;
+            default:$appendLongStrBuf(this$static, c);
+              continue;
+          }
+        }
+
+      case 14:
+        afterattributevaluequotedloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              state = 7;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              state = 7;
+              continue stateloop;
+            case 47:
+              state = 48;
+              break afterattributevaluequotedloop;
+            case 62:
+              state = $emitCurrentTagToken(this$static, false, pos);
+              if (this$static.shouldSuspend) {
+                break stateloop;
+              }
+
+              continue stateloop;
+            default:state = 7;
+              reconsume = true;
+              continue stateloop;
+          }
+        }
+
+      case 48:
+        if (++pos == endPos) {
+          break stateloop;
+        }
+
+        c = $checkChar(this$static, buf, pos);
+        switch (c) {
+          case 62:
+            state = $emitCurrentTagToken(this$static, true, pos);
+            if (this$static.shouldSuspend) {
+              break stateloop;
+            }
+
+            continue stateloop;
+          default:state = 7;
+            reconsume = true;
+            continue stateloop;
+        }
+
+      case 13:
+        for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              $addAttributeWithValue(this$static);
+              state = 7;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              $addAttributeWithValue(this$static);
+              state = 7;
+              continue stateloop;
+            case 38:
+              this$static.strBuf[0] = c;
+              this$static.strBufLen = 1;
+              this$static.additional = 62;
+              $LocatorImpl(new LocatorImpl, this$static);
+              returnState = state;
+              state = 42;
+              continue stateloop;
+            case 62:
+              $addAttributeWithValue(this$static);
+              state = $emitCurrentTagToken(this$static, false, pos);
+              if (this$static.shouldSuspend) {
+                break stateloop;
+              }
+
+              continue stateloop;
+            case 0:
+              c = 65533;
+            case 60:
+            case 34:
+            case 39:
+            case 61:
+            case 96:
+              $errUnquotedAttributeValOrNull(c);
+            default:$appendLongStrBuf(this$static, c);
+              continue;
+          }
+        }
+
+      case 9:
+        for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              continue;
+            case 47:
+              $addAttributeWithoutValue(this$static);
+              state = 48;
+              continue stateloop;
+            case 61:
+              state = 10;
+              continue stateloop;
+            case 62:
+              $addAttributeWithoutValue(this$static);
+              state = $emitCurrentTagToken(this$static, false, pos);
+              if (this$static.shouldSuspend) {
+                break stateloop;
+              }
+
+              continue stateloop;
+            case 0:
+              c = 65533;
+            case 34:
+            case 39:
+            case 60:
+            default:$addAttributeWithoutValue(this$static);
+              c >= 65 && c <= 90 && (c += 32);
+              this$static.strBuf[0] = c;
+              this$static.strBufLen = 1;
+              state = 8;
+              continue stateloop;
+          }
+        }
+
+      case 16:
+        markupdeclarationopenloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 45:
+              this$static.longStrBuf[0] = c;
+              this$static.longStrBufLen = 1;
+              state = 38;
+              break markupdeclarationopenloop;
+            case 100:
+            case 68:
+              this$static.longStrBuf[0] = c;
+              this$static.longStrBufLen = 1;
+              this$static.index = 0;
+              state = 39;
+              continue stateloop;
+            case 91:
+              if (this$static.tokenHandler.inForeign) {
+                this$static.longStrBuf[0] = c;
+                this$static.longStrBufLen = 1;
+                this$static.index = 0;
+                state = 49;
+                continue stateloop;
+              }
+
+            default:this$static.longStrBufLen = 0;
+              state = 15;
+              reconsume = true;
+              continue stateloop;
+          }
+        }
+
+      case 38:
+        markupdeclarationhyphenloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 0:
+              break stateloop;
+            case 45:
+              this$static.longStrBufLen = 0;
+              state = 30;
+              break markupdeclarationhyphenloop;
+            default:state = 15;
+              reconsume = true;
+              continue stateloop;
+          }
+        }
+
+      case 30:
+        commentstartloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 45:
+              $appendLongStrBuf(this$static, c);
+              state = 31;
+              continue stateloop;
+            case 62:
+              this$static.wantsComments && $comment(this$static.tokenHandler, this$static.longStrBuf, 0, this$static.longStrBufLen - 0);
+              this$static.cstart = pos + 1;
+              state = 0;
+              continue stateloop;
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              $appendLongStrBuf(this$static, 10);
+              state = 32;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+              $appendLongStrBuf(this$static, 10);
+              state = 32;
+              break commentstartloop;
+            case 0:
+              c = 65533;
+            default:$appendLongStrBuf(this$static, c);
+              state = 32;
+              break commentstartloop;
+          }
+        }
+
+      case 32:
+        commentloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 45:
+              $appendLongStrBuf(this$static, c);
+              state = 33;
+              break commentloop;
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              $appendLongStrBuf(this$static, 10);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+              $appendLongStrBuf(this$static, 10);
+              continue;
+            case 0:
+              c = 65533;
+            default:$appendLongStrBuf(this$static, c);
+              continue;
+          }
+        }
+
+      case 33:
+        commentenddashloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 45:
+              $appendLongStrBuf(this$static, c);
+              state = 34;
+              break commentenddashloop;
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              $appendLongStrBuf(this$static, 10);
+              state = 32;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+              $appendLongStrBuf(this$static, 10);
+              state = 32;
+              continue stateloop;
+            case 0:
+              c = 65533;
+            default:$appendLongStrBuf(this$static, c);
+              state = 32;
+              continue stateloop;
+          }
+        }
+
+      case 34:
+        commentendloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 62:
+              this$static.wantsComments && $comment(this$static.tokenHandler, this$static.longStrBuf, 0, this$static.longStrBufLen - 2);
+              this$static.cstart = pos + 1;
+              state = 0;
+              continue stateloop;
+            case 45:
+              $adjustDoubleHyphenAndAppendToLongStrBufAndErr(this$static, c);
+              continue;
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              $adjustDoubleHyphenAndAppendToLongStrBufAndErr(this$static, 10);
+              state = 32;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+              $adjustDoubleHyphenAndAppendToLongStrBufAndErr(this$static, 10);
+              state = 32;
+              continue stateloop;
+            case 33:
+              $appendLongStrBuf(this$static, c);
+              state = 36;
+              continue stateloop;
+            case 0:
+              c = 65533;
+            default:$adjustDoubleHyphenAndAppendToLongStrBufAndErr(this$static, c);
+              state = 32;
+              continue stateloop;
+          }
+        }
+
+      case 35:
+        for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 62:
+              this$static.wantsComments && $comment(this$static.tokenHandler, this$static.longStrBuf, 0, this$static.longStrBufLen - 0);
+              this$static.cstart = pos + 1;
+              state = 0;
+              continue stateloop;
+            case 45:
+              $appendLongStrBuf(this$static, c);
+              state = 33;
+              continue stateloop;
+            case 32:
+            case 9:
+            case 12:
+              $appendLongStrBuf(this$static, c);
+              continue;
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              $appendLongStrBuf(this$static, 10);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+              $appendLongStrBuf(this$static, 10);
+              continue;
+            case 0:
+              c = 65533;
+            default:$appendLongStrBuf(this$static, c);
+              state = 32;
+              continue stateloop;
+          }
+        }
+
+      case 36:
+        for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 62:
+              this$static.wantsComments && $comment(this$static.tokenHandler, this$static.longStrBuf, 0, this$static.longStrBufLen - 3);
+              this$static.cstart = pos + 1;
+              state = 0;
+              continue stateloop;
+            case 45:
+              $appendLongStrBuf(this$static, c);
+              state = 33;
+              continue stateloop;
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              $appendLongStrBuf(this$static, 10);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+              $appendLongStrBuf(this$static, 10);
+              continue;
+            case 0:
+              c = 65533;
+            default:$appendLongStrBuf(this$static, c);
+              state = 32;
+              continue stateloop;
+          }
+        }
+
+      case 31:
+        if (++pos == endPos) {
+          break stateloop;
+        }
+
+        c = $checkChar(this$static, buf, pos);
+        switch (c) {
+          case 45:
+            $appendLongStrBuf(this$static, c);
+            state = 34;
+            continue stateloop;
+          case 62:
+            this$static.wantsComments && $comment(this$static.tokenHandler, this$static.longStrBuf, 0, this$static.longStrBufLen - 1);
+            this$static.cstart = pos + 1;
+            state = 0;
+            continue stateloop;
+          case 13:
+            this$static.nextCharOnNewLine = true;
+            this$static.lastCR = true;
+            $appendLongStrBuf(this$static, 10);
+            state = 32;
+            break stateloop;
+          case 10:
+            this$static.nextCharOnNewLine = true;
+            $appendLongStrBuf(this$static, 10);
+            state = 32;
+            continue stateloop;
+          case 0:
+            c = 65533;
+          default:$appendLongStrBuf(this$static, c);
+            state = 32;
+            continue stateloop;
+        }
+
+      case 49:
+        for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          if (this$static.index < 6) {
+            if (c == CDATA_LSQB[this$static.index]) {
+              $appendLongStrBuf(this$static, c);
+            }
+             else {
+              state = 15;
+              reconsume = true;
+              continue stateloop;
+            }
+            ++this$static.index;
+            continue;
+          }
+           else {
+            this$static.cstart = pos;
+            state = 50;
+            reconsume = true;
+            break;
+          }
+        }
+
+      case 50:
+        cdatasectionloop: for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          switch (c) {
+            case 93:
+              $flushChars(this$static, buf, pos);
+              state = 51;
+              break cdatasectionloop;
+            case 0:
+              $flushChars(this$static, buf, pos);
+              $zeroOriginatingReplacementCharacter(this$static.tokenHandler);
+              this$static.cstart = pos + 1;
+              continue;
+            case 13:
+              $emitCarriageReturn(this$static, buf, pos);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            default:continue;
+          }
+        }
+
+      case 51:
+        cdatarsqb: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 93:
+              state = 52;
+              break cdatarsqb;
+            default:$characters(this$static.tokenHandler, RSQB_RSQB, 0, 1);
+              this$static.cstart = pos;
+              state = 50;
+              reconsume = true;
+              continue stateloop;
+          }
+        }
+
+      case 52:
+        if (++pos == endPos) {
+          break stateloop;
+        }
+
+        c = $checkChar(this$static, buf, pos);
+        switch (c) {
+          case 62:
+            this$static.cstart = pos + 1;
+            state = 0;
+            continue stateloop;
+          default:$characters(this$static.tokenHandler, RSQB_RSQB, 0, 2);
+            this$static.cstart = pos;
+            state = 50;
+            reconsume = true;
+            continue stateloop;
+        }
+
+      case 12:
+        attributevaluesinglequotedloop: for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          switch (c) {
+            case 39:
+              $addAttributeWithValue(this$static);
+              state = 14;
+              continue stateloop;
+            case 38:
+              this$static.strBuf[0] = c;
+              this$static.strBufLen = 1;
+              this$static.additional = 39;
+              $LocatorImpl(new LocatorImpl, this$static);
+              returnState = state;
+              state = 42;
+              break attributevaluesinglequotedloop;
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              $appendLongStrBuf(this$static, 10);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+              $appendLongStrBuf(this$static, 10);
+              continue;
+            case 0:
+              c = 65533;
+            default:$appendLongStrBuf(this$static, c);
+              continue;
+          }
+        }
+
+      case 42:
+        if (++pos == endPos) {
+          break stateloop;
+        }
+
+        c = $checkChar(this$static, buf, pos);
+        if (c == 0) {
+          break stateloop;
+        }
+
+        switch (c) {
+          case 32:
+          case 9:
+          case 10:
+          case 13:
+          case 12:
+          case 60:
+          case 38:
+            (returnState & -2) != 0?$appendLongStrBuf_0(this$static, this$static.strBuf, 0, this$static.strBufLen):$emitStrBuf(this$static);
+            (returnState & -2) == 0 && (this$static.cstart = pos);
+            state = returnState;
+            reconsume = true;
+            continue stateloop;
+          case 35:
+            $appendStrBuf(this$static, 35);
+            state = 43;
+            continue stateloop;
+          default:if (c == this$static.additional) {
+              (returnState & -2) != 0?$appendLongStrBuf_0(this$static, this$static.strBuf, 0, this$static.strBufLen):$emitStrBuf(this$static);
+              state = returnState;
+              reconsume = true;
+              continue stateloop;
+            }
+
+            if (c >= 97 && c <= 122) {
+              this$static.firstCharKey = c - 97 + 26;
+            }
+             else if (c >= 65 && c <= 90) {
+              this$static.firstCharKey = c - 65;
+            }
+             else {
+              (returnState & -2) != 0?$appendLongStrBuf_0(this$static, this$static.strBuf, 0, this$static.strBufLen):$emitStrBuf(this$static);
+              (returnState & -2) == 0 && (this$static.cstart = pos);
+              state = returnState;
+              reconsume = true;
+              continue stateloop;
+            }
+
+            $appendStrBuf(this$static, c);
+            state = 72;
+        }
+
+      case 72:
+        {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          if (c == 0) {
+            break stateloop;
+          }
+          hilo = 0;
+          if (c <= 122) {
+            row = ($clinit_132() , HILO_ACCEL)[c];
+            row != null && (hilo = row[this$static.firstCharKey]);
+          }
+          if (hilo == 0) {
+            (returnState & -2) != 0?$appendLongStrBuf_0(this$static, this$static.strBuf, 0, this$static.strBufLen):$emitStrBuf(this$static);
+            (returnState & -2) == 0 && (this$static.cstart = pos);
+            state = returnState;
+            reconsume = true;
+            continue stateloop;
+          }
+          $appendStrBuf(this$static, c);
+          this$static.lo = hilo & 65535;
+          this$static.hi = hilo >> 16;
+          this$static.entCol = -1;
+          this$static.candidate = -1;
+          this$static.strBufMark = 0;
+          state = 44;
+        }
+
+      case 44:
+        outer: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          if (c == 0) {
+            break stateloop;
+          }
+          ++this$static.entCol;
+          loloop: for (;;) {
+            if (this$static.hi < this$static.lo) {
+              break outer;
+            }
+            if (this$static.entCol == ($clinit_131() , NAMES)[this$static.lo].length) {
+              this$static.candidate = this$static.lo;
+              this$static.strBufMark = this$static.strBufLen;
+              ++this$static.lo;
+            }
+             else if (this$static.entCol > NAMES[this$static.lo].length) {
+              break outer;
+            }
+             else if (c > NAMES[this$static.lo][this$static.entCol]) {
+              ++this$static.lo;
+            }
+             else {
+              break loloop;
+            }
+          }
+          hiloop: for (;;) {
+            if (this$static.hi < this$static.lo) {
+              break outer;
+            }
+            if (this$static.entCol == ($clinit_131() , NAMES)[this$static.hi].length) {
+              break hiloop;
+            }
+            if (this$static.entCol > NAMES[this$static.hi].length) {
+              break outer;
+            }
+             else if (c < NAMES[this$static.hi][this$static.entCol]) {
+              --this$static.hi;
+            }
+             else {
+              break hiloop;
+            }
+          }
+          if (this$static.hi < this$static.lo) {
+            break outer;
+          }
+          $appendStrBuf(this$static, c);
+          continue;
+        }
+
+        if (this$static.candidate == -1) {
+          (returnState & -2) != 0?$appendLongStrBuf_0(this$static, this$static.strBuf, 0, this$static.strBufLen):$emitStrBuf(this$static);
+          (returnState & -2) == 0 && (this$static.cstart = pos);
+          state = returnState;
+          reconsume = true;
+          continue stateloop;
+        }
+         else {
+          candidateArr = ($clinit_131() , NAMES)[this$static.candidate];
+          if (candidateArr.length == 0 || candidateArr[candidateArr.length - 1] != 59) {
+            if ((returnState & -2) != 0) {
+              this$static.strBufMark == this$static.strBufLen?(ch = c):(ch = this$static.strBuf[this$static.strBufMark]);
+              if (ch == 61 || ch >= 48 && ch <= 57 || ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122) {
+                $appendLongStrBuf_0(this$static, this$static.strBuf, 0, this$static.strBufLen);
+                state = returnState;
+                reconsume = true;
+                continue stateloop;
+              }
+            }
+          }
+          val = VALUES_0[this$static.candidate];
+          (val[0] & 64512) == 55296?$emitOrAppendTwo(this$static, val, returnState):((returnState & -2) != 0?$appendLongStrBuf(this$static, val[0]):$characters(this$static.tokenHandler, val, 0, 1) , undefined);
+          if (this$static.strBufMark < this$static.strBufLen) {
+            if ((returnState & -2) != 0) {
+              for (i = this$static.strBufMark; i < this$static.strBufLen; ++i) {
+                $appendLongStrBuf(this$static, this$static.strBuf[i]);
+              }
+            }
+             else {
+              $characters(this$static.tokenHandler, this$static.strBuf, this$static.strBufMark, this$static.strBufLen - this$static.strBufMark);
+            }
+          }
+          (returnState & -2) == 0 && (this$static.cstart = pos);
+          state = returnState;
+          reconsume = true;
+          continue stateloop;
+        }
+
+      case 43:
+        if (++pos == endPos) {
+          break stateloop;
+        }
+
+        c = $checkChar(this$static, buf, pos);
+        this$static.prevValue = -1;
+        this$static.value = 0;
+        this$static.seenDigits = false;
+        switch (c) {
+          case 120:
+          case 88:
+            $appendStrBuf(this$static, c);
+            state = 45;
+            continue stateloop;
+          default:state = 46;
+            reconsume = true;
+        }
+
+      case 46:
+        decimalloop: for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          this$static.value < this$static.prevValue && (this$static.value = 1114112);
+          this$static.prevValue = this$static.value;
+          if (c >= 48 && c <= 57) {
+            this$static.seenDigits = true;
+            this$static.value *= 10;
+            this$static.value += c - 48;
+            continue;
+          }
+           else if (c == 59) {
+            if (this$static.seenDigits) {
+              (returnState & -2) == 0 && (this$static.cstart = pos + 1);
+              state = 47;
+              break decimalloop;
+            }
+             else {
+              $err('No digits after \u201C' + valueOf_0(this$static.strBuf, 0, this$static.strBufLen) + '\u201D.');
+              $appendStrBuf(this$static, 59);
+              (returnState & -2) != 0?$appendLongStrBuf_0(this$static, this$static.strBuf, 0, this$static.strBufLen):$emitStrBuf(this$static);
+              (returnState & -2) == 0 && (this$static.cstart = pos + 1);
+              state = returnState;
+              continue stateloop;
+            }
+          }
+           else {
+            if (this$static.seenDigits) {
+              (returnState & -2) == 0 && (this$static.cstart = pos);
+              state = 47;
+              reconsume = true;
+              break decimalloop;
+            }
+             else {
+              $err('No digits after \u201C' + valueOf_0(this$static.strBuf, 0, this$static.strBufLen) + '\u201D.');
+              (returnState & -2) != 0?$appendLongStrBuf_0(this$static, this$static.strBuf, 0, this$static.strBufLen):$emitStrBuf(this$static);
+              (returnState & -2) == 0 && (this$static.cstart = pos);
+              state = returnState;
+              reconsume = true;
+              continue stateloop;
+            }
+          }
+        }
+
+      case 47:
+        $handleNcrValue(this$static, returnState);
+        state = returnState;
+        continue stateloop;
+      case 45:
+        for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          this$static.value < this$static.prevValue && (this$static.value = 1114112);
+          this$static.prevValue = this$static.value;
+          if (c >= 48 && c <= 57) {
+            this$static.seenDigits = true;
+            this$static.value *= 16;
+            this$static.value += c - 48;
+            continue;
+          }
+           else if (c >= 65 && c <= 70) {
+            this$static.seenDigits = true;
+            this$static.value *= 16;
+            this$static.value += c - 65 + 10;
+            continue;
+          }
+           else if (c >= 97 && c <= 102) {
+            this$static.seenDigits = true;
+            this$static.value *= 16;
+            this$static.value += c - 97 + 10;
+            continue;
+          }
+           else if (c == 59) {
+            if (this$static.seenDigits) {
+              (returnState & -2) == 0 && (this$static.cstart = pos + 1);
+              state = 47;
+              continue stateloop;
+            }
+             else {
+              $err('No digits after \u201C' + valueOf_0(this$static.strBuf, 0, this$static.strBufLen) + '\u201D.');
+              $appendStrBuf(this$static, 59);
+              (returnState & -2) != 0?$appendLongStrBuf_0(this$static, this$static.strBuf, 0, this$static.strBufLen):$emitStrBuf(this$static);
+              (returnState & -2) == 0 && (this$static.cstart = pos + 1);
+              state = returnState;
+              continue stateloop;
+            }
+          }
+           else {
+            if (this$static.seenDigits) {
+              (returnState & -2) == 0 && (this$static.cstart = pos);
+              state = 47;
+              reconsume = true;
+              continue stateloop;
+            }
+             else {
+              $err('No digits after \u201C' + valueOf_0(this$static.strBuf, 0, this$static.strBufLen) + '\u201D.');
+              (returnState & -2) != 0?$appendLongStrBuf_0(this$static, this$static.strBuf, 0, this$static.strBufLen):$emitStrBuf(this$static);
+              (returnState & -2) == 0 && (this$static.cstart = pos);
+              state = returnState;
+              reconsume = true;
+              continue stateloop;
+            }
+          }
+        }
+
+      case 3:
+        plaintextloop: for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          switch (c) {
+            case 0:
+              $flushChars(this$static, buf, pos);
+              $zeroOriginatingReplacementCharacter(this$static.tokenHandler);
+              this$static.cstart = pos + 1;
+              continue;
+            case 13:
+              $emitCarriageReturn(this$static, buf, pos);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            default:continue;
+          }
+        }
+
+      case 5:
+        if (++pos == endPos) {
+          break stateloop;
+        }
+
+        c = $checkChar(this$static, buf, pos);
+        switch (c) {
+          case 62:
+            this$static.cstart = pos + 1;
+            state = 0;
+            continue stateloop;
+          case 13:
+            this$static.nextCharOnNewLine = true;
+            this$static.lastCR = true;
+            this$static.longStrBuf[0] = 10;
+            this$static.longStrBufLen = 1;
+            state = 15;
+            break stateloop;
+          case 10:
+            this$static.nextCharOnNewLine = true;
+            this$static.longStrBuf[0] = 10;
+            this$static.longStrBufLen = 1;
+            state = 15;
+            continue stateloop;
+          case 0:
+            c = 65533;
+          default:c >= 65 && c <= 90 && (c += 32);
+            if (c >= 97 && c <= 122) {
+              this$static.endTag = true;
+              this$static.strBuf[0] = c;
+              this$static.strBufLen = 1;
+              state = 6;
+              continue stateloop;
+            }
+             else {
+              this$static.longStrBuf[0] = c;
+              this$static.longStrBufLen = 1;
+              state = 15;
+              continue stateloop;
+            }
+
+        }
+
+      case 1:
+        rcdataloop: for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          switch (c) {
+            case 38:
+              $flushChars(this$static, buf, pos);
+              this$static.strBuf[0] = c;
+              this$static.strBufLen = 1;
+              this$static.additional = 0;
+              returnState = state;
+              state = 42;
+              continue stateloop;
+            case 60:
+              $flushChars(this$static, buf, pos);
+              returnState = state;
+              state = 61;
+              continue stateloop;
+            case 0:
+              $flushChars(this$static, buf, pos);
+              $zeroOriginatingReplacementCharacter(this$static.tokenHandler);
+              this$static.cstart = pos + 1;
+              continue;
+            case 13:
+              $emitCarriageReturn(this$static, buf, pos);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            default:continue;
+          }
+        }
+
+      case 60:
+        rawtextloop: for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          switch (c) {
+            case 60:
+              $flushChars(this$static, buf, pos);
+              returnState = state;
+              state = 61;
+              break rawtextloop;
+            case 0:
+              $flushChars(this$static, buf, pos);
+              $zeroOriginatingReplacementCharacter(this$static.tokenHandler);
+              this$static.cstart = pos + 1;
+              continue;
+            case 13:
+              $emitCarriageReturn(this$static, buf, pos);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            default:continue;
+          }
+        }
+
+      case 61:
+        rawtextrcdatalessthansignloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 47:
+              this$static.index = 0;
+              this$static.strBufLen = 0;
+              state = 37;
+              break rawtextrcdatalessthansignloop;
+            default:$characters(this$static.tokenHandler, LT_GT, 0, 1);
+              this$static.cstart = pos;
+              state = returnState;
+              reconsume = true;
+              continue stateloop;
+          }
+        }
+
+      case 37:
+        for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          if (this$static.index < this$static.endTagExpectationAsArray.length) {
+            e = this$static.endTagExpectationAsArray[this$static.index];
+            folded = c;
+            c >= 65 && c <= 90 && (folded += 32);
+            if (folded != e) {
+              this$static.html4 && (this$static.index > 0 || folded >= 97 && folded <= 122) && ($clinit_125() , IFRAME) != this$static.endTagExpectation;
+              $characters(this$static.tokenHandler, LT_SOLIDUS, 0, 2);
+              $emitStrBuf(this$static);
+              this$static.cstart = pos;
+              state = returnState;
+              reconsume = true;
+              continue stateloop;
+            }
+            $appendStrBuf(this$static, c);
+            ++this$static.index;
+            continue;
+          }
+           else {
+            this$static.endTag = true;
+            this$static.tagName = this$static.endTagExpectation;
+            switch (c) {
+              case 13:
+                this$static.nextCharOnNewLine = true;
+                this$static.lastCR = true;
+                state = 7;
+                break stateloop;
+              case 10:
+                this$static.nextCharOnNewLine = true;
+              case 32:
+              case 9:
+              case 12:
+                state = 7;
+                continue stateloop;
+              case 47:
+                state = 48;
+                continue stateloop;
+              case 62:
+                state = $emitCurrentTagToken(this$static, false, pos);
+                if (this$static.shouldSuspend) {
+                  break stateloop;
+                }
+
+                continue stateloop;
+              default:$characters(this$static.tokenHandler, LT_SOLIDUS, 0, 2);
+                $emitStrBuf(this$static);
+                c == 0?($flushChars(this$static, buf, pos) , $zeroOriginatingReplacementCharacter(this$static.tokenHandler) , this$static.cstart = pos + 1 , undefined):(this$static.cstart = pos);
+                state = returnState;
+                continue stateloop;
+            }
+          }
+        }
+
+      case 15:
+        boguscommentloop: for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          switch (c) {
+            case 62:
+              this$static.wantsComments && $comment(this$static.tokenHandler, this$static.longStrBuf, 0, this$static.longStrBufLen - 0);
+              this$static.cstart = pos + 1;
+              state = 0;
+              continue stateloop;
+            case 45:
+              $appendLongStrBuf(this$static, c);
+              state = 59;
+              break boguscommentloop;
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              $appendLongStrBuf(this$static, 10);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+              $appendLongStrBuf(this$static, 10);
+              continue;
+            case 0:
+              c = 65533;
+            default:$appendLongStrBuf(this$static, c);
+              continue;
+          }
+        }
+
+      case 59:
+        boguscommenthyphenloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 62:
+              $maybeAppendSpaceToBogusComment(this$static);
+              this$static.wantsComments && $comment(this$static.tokenHandler, this$static.longStrBuf, 0, this$static.longStrBufLen - 0);
+              this$static.cstart = pos + 1;
+              state = 0;
+              continue stateloop;
+            case 45:
+              $appendSecondHyphenToBogusComment(this$static);
+              continue boguscommenthyphenloop;
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              $appendLongStrBuf(this$static, 10);
+              state = 15;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+              $appendLongStrBuf(this$static, 10);
+              state = 15;
+              continue stateloop;
+            case 0:
+              c = 65533;
+            default:$appendLongStrBuf(this$static, c);
+              state = 15;
+              continue stateloop;
+          }
+        }
+
+      case 2:
+        scriptdataloop: for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          switch (c) {
+            case 60:
+              $flushChars(this$static, buf, pos);
+              returnState = state;
+              state = 53;
+              break scriptdataloop;
+            case 0:
+              $flushChars(this$static, buf, pos);
+              $zeroOriginatingReplacementCharacter(this$static.tokenHandler);
+              this$static.cstart = pos + 1;
+              continue;
+            case 13:
+              $emitCarriageReturn(this$static, buf, pos);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            default:continue;
+          }
+        }
+
+      case 53:
+        scriptdatalessthansignloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 47:
+              this$static.index = 0;
+              this$static.strBufLen = 0;
+              state = 37;
+              continue stateloop;
+            case 33:
+              $characters(this$static.tokenHandler, LT_GT, 0, 1);
+              this$static.cstart = pos;
+              state = 54;
+              break scriptdatalessthansignloop;
+            default:$characters(this$static.tokenHandler, LT_GT, 0, 1);
+              this$static.cstart = pos;
+              state = 2;
+              reconsume = true;
+              continue stateloop;
+          }
+        }
+
+      case 54:
+        scriptdataescapestartloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 45:
+              state = 55;
+              break scriptdataescapestartloop;
+            default:state = 2;
+              reconsume = true;
+              continue stateloop;
+          }
+        }
+
+      case 55:
+        scriptdataescapestartdashloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 45:
+              state = 58;
+              break scriptdataescapestartdashloop;
+            default:state = 2;
+              reconsume = true;
+              continue stateloop;
+          }
+        }
+
+      case 58:
+        scriptdataescapeddashdashloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 45:
+              continue;
+            case 60:
+              $flushChars(this$static, buf, pos);
+              state = 65;
+              continue stateloop;
+            case 62:
+              state = 2;
+              continue stateloop;
+            case 0:
+              $flushChars(this$static, buf, pos);
+              $zeroOriginatingReplacementCharacter(this$static.tokenHandler);
+              this$static.cstart = pos + 1;
+              state = 56;
+              break scriptdataescapeddashdashloop;
+            case 13:
+              $emitCarriageReturn(this$static, buf, pos);
+              state = 56;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            default:state = 56;
+              break scriptdataescapeddashdashloop;
+          }
+        }
+
+      case 56:
+        scriptdataescapedloop: for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          switch (c) {
+            case 45:
+              state = 57;
+              break scriptdataescapedloop;
+            case 60:
+              $flushChars(this$static, buf, pos);
+              state = 65;
+              continue stateloop;
+            case 0:
+              $flushChars(this$static, buf, pos);
+              $zeroOriginatingReplacementCharacter(this$static.tokenHandler);
+              this$static.cstart = pos + 1;
+              continue;
+            case 13:
+              $emitCarriageReturn(this$static, buf, pos);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            default:continue;
+          }
+        }
+
+      case 57:
+        scriptdataescapeddashloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 45:
+              state = 58;
+              continue stateloop;
+            case 60:
+              $flushChars(this$static, buf, pos);
+              state = 65;
+              break scriptdataescapeddashloop;
+            case 0:
+              $flushChars(this$static, buf, pos);
+              $zeroOriginatingReplacementCharacter(this$static.tokenHandler);
+              this$static.cstart = pos + 1;
+              state = 56;
+              continue stateloop;
+            case 13:
+              $emitCarriageReturn(this$static, buf, pos);
+              state = 56;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            default:state = 56;
+              continue stateloop;
+          }
+        }
+
+      case 65:
+        scriptdataescapedlessthanloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 47:
+              this$static.index = 0;
+              this$static.strBufLen = 0;
+              returnState = 56;
+              state = 37;
+              continue stateloop;
+            case 83:
+            case 115:
+              $characters(this$static.tokenHandler, LT_GT, 0, 1);
+              this$static.cstart = pos;
+              this$static.index = 1;
+              state = 66;
+              break scriptdataescapedlessthanloop;
+            default:$characters(this$static.tokenHandler, LT_GT, 0, 1);
+              this$static.cstart = pos;
+              reconsume = true;
+              state = 56;
+              continue stateloop;
+          }
+        }
+
+      case 66:
+        scriptdatadoubleescapestartloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          if (this$static.index < 6) {
+            folded = c;
+            c >= 65 && c <= 90 && (folded += 32);
+            if (folded != SCRIPT_ARR[this$static.index]) {
+              reconsume = true;
+              state = 56;
+              continue stateloop;
+            }
+            ++this$static.index;
+            continue;
+          }
+          switch (c) {
+            case 13:
+              $emitCarriageReturn(this$static, buf, pos);
+              state = 67;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+            case 47:
+            case 62:
+              state = 67;
+              break scriptdatadoubleescapestartloop;
+            default:reconsume = true;
+              state = 56;
+              continue stateloop;
+          }
+        }
+
+      case 67:
+        scriptdatadoubleescapedloop: for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          switch (c) {
+            case 45:
+              state = 69;
+              break scriptdatadoubleescapedloop;
+            case 60:
+              state = 68;
+              continue stateloop;
+            case 0:
+              $flushChars(this$static, buf, pos);
+              $zeroOriginatingReplacementCharacter(this$static.tokenHandler);
+              this$static.cstart = pos + 1;
+              continue;
+            case 13:
+              $emitCarriageReturn(this$static, buf, pos);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            default:continue;
+          }
+        }
+
+      case 69:
+        scriptdatadoubleescapeddashloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 45:
+              state = 70;
+              break scriptdatadoubleescapeddashloop;
+            case 60:
+              state = 68;
+              continue stateloop;
+            case 0:
+              $flushChars(this$static, buf, pos);
+              $zeroOriginatingReplacementCharacter(this$static.tokenHandler);
+              this$static.cstart = pos + 1;
+              state = 67;
+              continue stateloop;
+            case 13:
+              $emitCarriageReturn(this$static, buf, pos);
+              state = 67;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            default:state = 67;
+              continue stateloop;
+          }
+        }
+
+      case 70:
+        scriptdatadoubleescapeddashdashloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 45:
+              continue;
+            case 60:
+              state = 68;
+              break scriptdatadoubleescapeddashdashloop;
+            case 62:
+              state = 2;
+              continue stateloop;
+            case 0:
+              $flushChars(this$static, buf, pos);
+              $zeroOriginatingReplacementCharacter(this$static.tokenHandler);
+              this$static.cstart = pos + 1;
+              state = 67;
+              continue stateloop;
+            case 13:
+              $emitCarriageReturn(this$static, buf, pos);
+              state = 67;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            default:state = 67;
+              continue stateloop;
+          }
+        }
+
+      case 68:
+        scriptdatadoubleescapedlessthanloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 47:
+              this$static.index = 0;
+              state = 71;
+              break scriptdatadoubleescapedlessthanloop;
+            default:reconsume = true;
+              state = 67;
+              continue stateloop;
+          }
+        }
+
+      case 71:
+        scriptdatadoubleescapeendloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          if (this$static.index < 6) {
+            folded = c;
+            c >= 65 && c <= 90 && (folded += 32);
+            if (folded != SCRIPT_ARR[this$static.index]) {
+              reconsume = true;
+              state = 67;
+              continue stateloop;
+            }
+            ++this$static.index;
+            continue;
+          }
+          switch (c) {
+            case 13:
+              $emitCarriageReturn(this$static, buf, pos);
+              state = 56;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+            case 47:
+            case 62:
+              state = 56;
+              continue stateloop;
+            default:reconsume = true;
+              state = 67;
+              continue stateloop;
+          }
+        }
+
+      case 39:
+        markupdeclarationdoctypeloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          if (this$static.index < 6) {
+            folded = c;
+            c >= 65 && c <= 90 && (folded += 32);
+            if (folded == OCTYPE[this$static.index]) {
+              $appendLongStrBuf(this$static, c);
+            }
+             else {
+              state = 15;
+              reconsume = true;
+              continue stateloop;
+            }
+            ++this$static.index;
+            continue;
+          }
+           else {
+            state = 17;
+            reconsume = true;
+            break markupdeclarationdoctypeloop;
+          }
+        }
+
+      case 17:
+        doctypeloop: for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          $initDoctypeFields(this$static);
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              state = 18;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              state = 18;
+              break doctypeloop;
+            default:state = 18;
+              reconsume = true;
+              break doctypeloop;
+          }
+        }
+
+      case 18:
+        beforedoctypenameloop: for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              continue;
+            case 62:
+              this$static.forceQuirks = true;
+              $emitDoctypeToken(this$static, pos);
+              state = 0;
+              continue stateloop;
+            case 0:
+              c = 65533;
+            default:c >= 65 && c <= 90 && (c += 32);
+              this$static.strBuf[0] = c;
+              this$static.strBufLen = 1;
+              state = 19;
+              break beforedoctypenameloop;
+          }
+        }
+
+      case 19:
+        doctypenameloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              this$static.doctypeName = String(valueOf_0(this$static.strBuf, 0, this$static.strBufLen));
+              state = 20;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              this$static.doctypeName = String(valueOf_0(this$static.strBuf, 0, this$static.strBufLen));
+              state = 20;
+              break doctypenameloop;
+            case 62:
+              this$static.doctypeName = String(valueOf_0(this$static.strBuf, 0, this$static.strBufLen));
+              $emitDoctypeToken(this$static, pos);
+              state = 0;
+              continue stateloop;
+            case 0:
+              c = 65533;
+            default:c >= 65 && c <= 90 && (c += 32);
+              $appendStrBuf(this$static, c);
+              continue;
+          }
+        }
+
+      case 20:
+        afterdoctypenameloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              continue;
+            case 62:
+              $emitDoctypeToken(this$static, pos);
+              state = 0;
+              continue stateloop;
+            case 112:
+            case 80:
+              this$static.index = 0;
+              state = 40;
+              break afterdoctypenameloop;
+            case 115:
+            case 83:
+              this$static.index = 0;
+              state = 41;
+              continue stateloop;
+            default:this$static.forceQuirks = true;
+              state = 29;
+              continue stateloop;
+          }
+        }
+
+      case 40:
+        doctypeublicloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          if (this$static.index < 5) {
+            folded = c;
+            c >= 65 && c <= 90 && (folded += 32);
+            if (folded != UBLIC[this$static.index]) {
+              this$static.forceQuirks = true;
+              state = 29;
+              reconsume = true;
+              continue stateloop;
+            }
+            ++this$static.index;
+            continue;
+          }
+           else {
+            state = 62;
+            reconsume = true;
+            break doctypeublicloop;
+          }
+        }
+
+      case 62:
+        afterdoctypepublickeywordloop: for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              state = 21;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              state = 21;
+              break afterdoctypepublickeywordloop;
+            case 34:
+              this$static.longStrBufLen = 0;
+              state = 22;
+              continue stateloop;
+            case 39:
+              this$static.longStrBufLen = 0;
+              state = 23;
+              continue stateloop;
+            case 62:
+              this$static.forceQuirks = true;
+              $emitDoctypeToken(this$static, pos);
+              state = 0;
+              continue stateloop;
+            default:this$static.forceQuirks = true;
+              state = 29;
+              continue stateloop;
+          }
+        }
+
+      case 21:
+        beforedoctypepublicidentifierloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              continue;
+            case 34:
+              this$static.longStrBufLen = 0;
+              state = 22;
+              break beforedoctypepublicidentifierloop;
+            case 39:
+              this$static.longStrBufLen = 0;
+              state = 23;
+              continue stateloop;
+            case 62:
+              this$static.forceQuirks = true;
+              $emitDoctypeToken(this$static, pos);
+              state = 0;
+              continue stateloop;
+            default:this$static.forceQuirks = true;
+              state = 29;
+              continue stateloop;
+          }
+        }
+
+      case 22:
+        doctypepublicidentifierdoublequotedloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 34:
+              this$static.publicIdentifier = valueOf_0(this$static.longStrBuf, 0, this$static.longStrBufLen);
+              state = 24;
+              break doctypepublicidentifierdoublequotedloop;
+            case 62:
+              this$static.forceQuirks = true;
+              this$static.publicIdentifier = valueOf_0(this$static.longStrBuf, 0, this$static.longStrBufLen);
+              $emitDoctypeToken(this$static, pos);
+              state = 0;
+              continue stateloop;
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              $appendLongStrBuf(this$static, 10);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+              $appendLongStrBuf(this$static, 10);
+              continue;
+            case 0:
+              c = 65533;
+            default:$appendLongStrBuf(this$static, c);
+              continue;
+          }
+        }
+
+      case 24:
+        afterdoctypepublicidentifierloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              state = 63;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              state = 63;
+              break afterdoctypepublicidentifierloop;
+            case 62:
+              $emitDoctypeToken(this$static, pos);
+              state = 0;
+              continue stateloop;
+            case 34:
+              this$static.longStrBufLen = 0;
+              state = 26;
+              continue stateloop;
+            case 39:
+              this$static.longStrBufLen = 0;
+              state = 27;
+              continue stateloop;
+            default:this$static.forceQuirks = true;
+              state = 29;
+              continue stateloop;
+          }
+        }
+
+      case 63:
+        betweendoctypepublicandsystemidentifiersloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              continue;
+            case 62:
+              $emitDoctypeToken(this$static, pos);
+              state = 0;
+              continue stateloop;
+            case 34:
+              this$static.longStrBufLen = 0;
+              state = 26;
+              break betweendoctypepublicandsystemidentifiersloop;
+            case 39:
+              this$static.longStrBufLen = 0;
+              state = 27;
+              continue stateloop;
+            default:this$static.forceQuirks = true;
+              state = 29;
+              continue stateloop;
+          }
+        }
+
+      case 26:
+        doctypesystemidentifierdoublequotedloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 34:
+              this$static.systemIdentifier = valueOf_0(this$static.longStrBuf, 0, this$static.longStrBufLen);
+              state = 28;
+              continue stateloop;
+            case 62:
+              this$static.forceQuirks = true;
+              this$static.systemIdentifier = valueOf_0(this$static.longStrBuf, 0, this$static.longStrBufLen);
+              $emitDoctypeToken(this$static, pos);
+              state = 0;
+              continue stateloop;
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              $appendLongStrBuf(this$static, 10);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+              $appendLongStrBuf(this$static, 10);
+              continue;
+            case 0:
+              c = 65533;
+            default:$appendLongStrBuf(this$static, c);
+              continue;
+          }
+        }
+
+      case 28:
+        afterdoctypesystemidentifierloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              continue;
+            case 62:
+              $emitDoctypeToken(this$static, pos);
+              state = 0;
+              continue stateloop;
+            default:this$static.forceQuirks = false;
+              state = 29;
+              break afterdoctypesystemidentifierloop;
+          }
+        }
+
+      case 29:
+        for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          switch (c) {
+            case 62:
+              $emitDoctypeToken(this$static, pos);
+              state = 0;
+              continue stateloop;
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            default:continue;
+          }
+        }
+
+      case 41:
+        doctypeystemloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          if (this$static.index < 5) {
+            folded = c;
+            c >= 65 && c <= 90 && (folded += 32);
+            if (folded != YSTEM[this$static.index]) {
+              this$static.forceQuirks = true;
+              state = 29;
+              reconsume = true;
+              continue stateloop;
+            }
+            ++this$static.index;
+            continue stateloop;
+          }
+           else {
+            state = 64;
+            reconsume = true;
+            break doctypeystemloop;
+          }
+        }
+
+      case 64:
+        afterdoctypesystemkeywordloop: for (;;) {
+          if (reconsume) {
+            reconsume = false;
+          }
+           else {
+            if (++pos == endPos) {
+              break stateloop;
+            }
+            c = $checkChar(this$static, buf, pos);
+          }
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              state = 25;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              state = 25;
+              break afterdoctypesystemkeywordloop;
+            case 34:
+              this$static.longStrBufLen = 0;
+              state = 26;
+              continue stateloop;
+            case 39:
+              this$static.longStrBufLen = 0;
+              state = 27;
+              continue stateloop;
+            case 62:
+              this$static.forceQuirks = true;
+              $emitDoctypeToken(this$static, pos);
+              state = 0;
+              continue stateloop;
+            default:this$static.forceQuirks = true;
+              state = 29;
+              continue stateloop;
+          }
+        }
+
+      case 25:
+        beforedoctypesystemidentifierloop: for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+            case 32:
+            case 9:
+            case 12:
+              continue;
+            case 34:
+              this$static.longStrBufLen = 0;
+              state = 26;
+              continue stateloop;
+            case 39:
+              this$static.longStrBufLen = 0;
+              state = 27;
+              break beforedoctypesystemidentifierloop;
+            case 62:
+              this$static.forceQuirks = true;
+              $emitDoctypeToken(this$static, pos);
+              state = 0;
+              continue stateloop;
+            default:this$static.forceQuirks = true;
+              state = 29;
+              continue stateloop;
+          }
+        }
+
+      case 27:
+        for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 39:
+              this$static.systemIdentifier = valueOf_0(this$static.longStrBuf, 0, this$static.longStrBufLen);
+              state = 28;
+              continue stateloop;
+            case 62:
+              this$static.forceQuirks = true;
+              this$static.systemIdentifier = valueOf_0(this$static.longStrBuf, 0, this$static.longStrBufLen);
+              $emitDoctypeToken(this$static, pos);
+              state = 0;
+              continue stateloop;
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              $appendLongStrBuf(this$static, 10);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+              $appendLongStrBuf(this$static, 10);
+              continue;
+            case 0:
+              c = 65533;
+            default:$appendLongStrBuf(this$static, c);
+              continue;
+          }
+        }
+
+      case 23:
+        for (;;) {
+          if (++pos == endPos) {
+            break stateloop;
+          }
+          c = $checkChar(this$static, buf, pos);
+          switch (c) {
+            case 39:
+              this$static.publicIdentifier = valueOf_0(this$static.longStrBuf, 0, this$static.longStrBufLen);
+              state = 24;
+              continue stateloop;
+            case 62:
+              this$static.forceQuirks = true;
+              this$static.publicIdentifier = valueOf_0(this$static.longStrBuf, 0, this$static.longStrBufLen);
+              $emitDoctypeToken(this$static, pos);
+              state = 0;
+              continue stateloop;
+            case 13:
+              this$static.nextCharOnNewLine = true;
+              this$static.lastCR = true;
+              $appendLongStrBuf(this$static, 10);
+              break stateloop;
+            case 10:
+              this$static.nextCharOnNewLine = true;
+              $appendLongStrBuf(this$static, 10);
+              continue;
+            case 0:
+              c = 65533;
+            default:$appendLongStrBuf(this$static, c);
+              continue;
+          }
+        }
+
+    }
+  }
+  $flushChars(this$static, buf, pos);
+  this$static.stateSave = state;
+  this$static.returnStateSave = returnState;
+  return pos;
+}
+
+function $tokenizeBuffer(this$static, buffer){
+  var pos, returnState, start, state;
+  state = this$static.stateSave;
+  returnState = this$static.returnStateSave;
+  this$static.shouldSuspend = false;
+  this$static.lastCR = false;
+  start = buffer.start;
+  pos = start - 1;
+  switch (state) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 60:
+    case 50:
+    case 56:
+    case 54:
+    case 55:
+    case 57:
+    case 58:
+    case 66:
+    case 67:
+    case 68:
+    case 69:
+    case 70:
+    case 71:
+      this$static.cstart = start;
+      break;
+    default:this$static.cstart = 2147483647;
+  }
+  pos = $stateLoop(this$static, state, 0, pos, buffer.buffer, false, returnState, buffer.end);
+  pos == buffer.end?(buffer.start = pos):(buffer.start = pos + 1);
+  return this$static.lastCR;
+}
+
+function $warn(){
+  return;
+}
+
+function getClass_69(){
+  return Lnu_validator_htmlparser_impl_Tokenizer_2_classLit;
+}
+
+function newAsciiLowerCaseStringFromString(str){
+  var buf, c, i;
+  if (str == null) {
+    return null;
+  }
+  buf = initDim(_3C_classLit, 47, -1, str.length, 1);
+  for (i = 0; i < str.length; ++i) {
+    c = str.charCodeAt(i);
+    c >= 65 && c <= 90 && (c += 32);
+    buf[i] = c;
+  }
+  return String.fromCharCode.apply(null, buf);
+}
+
+function Tokenizer(){
+}
+
+_ = Tokenizer.prototype = new Object_0;
+_.getClass$ = getClass_69;
+_.typeId$ = 0;
+_.additional = 0;
+_.astralChar = null;
+_.attributeName = null;
+_.attributes = null;
+_.bmpChar = null;
+_.candidate = 0;
+_.confident = false;
+_.cstart = 0;
+_.doctypeName = null;
+_.endTag = false;
+_.endTagExpectation = null;
+_.endTagExpectationAsArray = null;
+_.entCol = 0;
+_.firstCharKey = 0;
+_.forceQuirks = false;
+_.hi = 0;
+_.html4 = false;
+_.html4ModeCompatibleWithXhtml1Schemata = false;
+_.index = 0;
+_.lastCR = false;
+_.lo = 0;
+_.longStrBuf = null;
+_.longStrBufLen = 0;
+_.mappingLangToXmlLang = 0;
+_.metaBoundaryPassed = false;
+_.newAttributesEachTime = false;
+_.prevValue = 0;
+_.publicIdentifier = null;
+_.returnStateSave = 0;
+_.seenDigits = false;
+_.shouldSuspend = false;
+_.stateSave = 0;
+_.strBuf = null;
+_.strBufLen = 0;
+_.strBufMark = 0;
+_.systemIdentifier = null;
+_.tagName = null;
+_.tokenHandler = null;
+_.value = 0;
+_.wantsComments = false;
+var CDATA_LSQB, IFRAME_ARR, LF, LT_GT, LT_SOLIDUS, NOEMBED_ARR, NOFRAMES_ARR, NOSCRIPT_ARR, OCTYPE, PLAINTEXT_ARR, REPLACEMENT_CHARACTER_0, RSQB_RSQB, SCRIPT_ARR, SPACE, STYLE_ARR, TEXTAREA_ARR, TITLE_ARR, UBLIC, XMP_ARR, YSTEM;
+function $clinit_127(){
+  $clinit_127 = nullMethod;
+  $clinit_126();
+}
+
+function $ErrorReportingTokenizer(this$static, tokenHandler){
+  $clinit_127();
+  this$static.contentSpacePolicy = ($clinit_115() , ALTER_INFOSET);
+  this$static.commentPolicy = ALTER_INFOSET;
+  this$static.xmlnsPolicy = ALTER_INFOSET;
+  this$static.namePolicy = ALTER_INFOSET;
+  this$static.tokenHandler = tokenHandler;
+  this$static.newAttributesEachTime = false;
+  this$static.bmpChar = initDim(_3C_classLit, 47, -1, 1, 1);
+  this$static.astralChar = initDim(_3C_classLit, 47, -1, 2, 1);
+  this$static.tagName = null;
+  this$static.attributeName = null;
+  this$static.doctypeName = null;
+  this$static.publicIdentifier = null;
+  this$static.systemIdentifier = null;
+  this$static.attributes = null;
+  this$static.contentNonXmlCharPolicy = ALTER_INFOSET;
+  return this$static;
+}
+
+function $checkChar(this$static, buf, pos){
+  var c, intVal;
+  this$static.linePrev = this$static.line;
+  this$static.colPrev = this$static.col;
+  if (this$static.nextCharOnNewLine) {
+    ++this$static.line;
+    this$static.col = 1;
+    this$static.nextCharOnNewLine = false;
+  }
+   else {
+    ++this$static.col;
+  }
+  c = buf[pos];
+  !this$static.confident && !this$static.alreadyComplainedAboutNonAscii && c > 127 && (this$static.alreadyComplainedAboutNonAscii = true);
+  switch (c) {
+    case 0:
+    case 9:
+    case 13:
+    case 10:
+      break;
+    case 12:
+      if (this$static.contentNonXmlCharPolicy == ($clinit_115() , FATAL)) {
+        $fatal_1(this$static, 'This document is not mappable to XML 1.0 without data loss due to ' + $toUPlusString(c) + ' which is not a legal XML 1.0 character.');
+      }
+       else {
+        this$static.contentNonXmlCharPolicy == ALTER_INFOSET && (c = buf[pos] = 32);
+        $warn('This document is not mappable to XML 1.0 without data loss due to ' + $toUPlusString(c) + ' which is not a legal XML 1.0 character.');
+      }
+
+      break;
+    default:if ((c & 64512) == 56320) {
+        if ((this$static.prev & 64512) == 55296) {
+          intVal = (this$static.prev << 10) + c + -56613888;
+          (intVal >= 983040 && intVal <= 1048573 || intVal >= 1048576 && intVal <= 1114109) && (!this$static.alreadyWarnedAboutPrivateUseCharacters && (this$static.alreadyWarnedAboutPrivateUseCharacters = true) , undefined);
+        }
+      }
+       else if (c < 32 || (c & 65534) == 65534) {
+        switch (this$static.contentNonXmlCharPolicy.ordinal) {
+          case 1:
+            $fatal_1(this$static, 'Forbidden code point ' + $toUPlusString(c) + '.');
+            break;
+          case 2:
+            c = buf[pos] = 65533;
+          case 0:
+            $err('Forbidden code point ' + $toUPlusString(c) + '.');
+        }
+      }
+       else 
+        c >= 127 && c <= 159 || c >= 64976 && c <= 65007?$err('Forbidden code point ' + $toUPlusString(c) + '.'):c >= 57344 && c <= 63743 && (!this$static.alreadyWarnedAboutPrivateUseCharacters && (this$static.alreadyWarnedAboutPrivateUseCharacters = true) , undefined);
+  }
+  this$static.prev = c;
+  return c;
+}
+
+function $errLtOrEqualsOrGraveInUnquotedAttributeOrNull(c){
+  switch (c) {
+    case 61:
+      return;
+    case 60:
+      return;
+    case 96:
+      return;
+  }
+}
+
+function $errNcrControlChar(this$static, ch){
+  switch (this$static.contentNonXmlCharPolicy.ordinal) {
+    case 1:
+      $fatal_1(this$static, 'Character reference expands to a control character (' + $toUPlusString(this$static.value & 65535) + ').');
+      break;
+    case 2:
+      ch = 65533;
+    case 0:
+      $err('Character reference expands to a control character (' + $toUPlusString(this$static.value & 65535) + ').');
+  }
+  return ch;
+}
+
+function $errNcrNonCharacter(this$static, ch){
+  switch (this$static.contentNonXmlCharPolicy.ordinal) {
+    case 1:
+      $fatal_1(this$static, 'Character reference expands to a non-character (' + $toUPlusString(this$static.value & 65535) + ').');
+      break;
+    case 2:
+      ch = 65533;
+    case 0:
+      $err('Character reference expands to a non-character (' + $toUPlusString(this$static.value & 65535) + ').');
+  }
+  return ch;
+}
+
+function $errUnquotedAttributeValOrNull(c){
+  switch (c) {
+    case 60:
+      return;
+    case 96:
+      return;
+    case 65533:
+      return;
+    default:return;
+  }
+}
+
+function $flushChars(this$static, buf, pos){
+  var currCol, currLine;
+  if (pos > this$static.cstart) {
+    currLine = this$static.line;
+    currCol = this$static.col;
+    this$static.line = this$static.linePrev;
+    this$static.col = this$static.colPrev;
+    $characters(this$static.tokenHandler, buf, this$static.cstart, pos - this$static.cstart);
+    this$static.line = currLine;
+    this$static.col = currCol;
+  }
+  this$static.cstart = 2147483647;
+}
+
+function $getColumnNumber(this$static){
+  if (this$static.col > 0) {
+    return this$static.col;
+  }
+   else {
+    return -1;
+  }
+}
+
+function $getLineNumber(this$static){
+  if (this$static.line > 0) {
+    return this$static.line;
+  }
+   else {
+    return -1;
+  }
+}
+
+function $toUPlusString(c){
+  var hexString;
+  hexString = toPowerOfTwoString(c, 4);
+  switch (hexString.length) {
+    case 1:
+      return 'U+000' + hexString;
+    case 2:
+      return 'U+00' + hexString;
+    case 3:
+      return 'U+0' + hexString;
+    default:return 'U+' + hexString;
+  }
+}
+
+function getClass_70(){
+  return Lnu_validator_htmlparser_impl_ErrorReportingTokenizer_2_classLit;
+}
+
+function ErrorReportingTokenizer(){
+}
+
+_ = ErrorReportingTokenizer.prototype = new Tokenizer;
+_.getClass$ = getClass_70;
+_.typeId$ = 0;
+_.alreadyComplainedAboutNonAscii = false;
+_.alreadyWarnedAboutPrivateUseCharacters = false;
+_.col = 0;
+_.colPrev = 0;
+_.line = 0;
+_.linePrev = 0;
+_.nextCharOnNewLine = false;
+_.prev = 0;
+function $clinit_128(){
+  $clinit_128 = nullMethod;
+  EMPTY_ATTRIBUTENAMES = initDim(_3Lnu_validator_htmlparser_impl_AttributeName_2_classLit, 60, 13, 0, 0);
+  EMPTY_STRINGS = initDim(_3Ljava_lang_String_2_classLit, 56, 1, 0, 0);
+  EMPTY_ATTRIBUTES = $HtmlAttributes(new HtmlAttributes, 0);
+}
+
+function $HtmlAttributes(this$static, mode){
+  $clinit_128();
+  this$static.mode = mode;
+  this$static.length_0 = 0;
+  this$static.names = initDim(_3Lnu_validator_htmlparser_impl_AttributeName_2_classLit, 60, 13, 5, 0);
+  this$static.values = initDim(_3Ljava_lang_String_2_classLit, 56, 1, 5, 0);
+  this$static.xmlnsLength = 0;
+  this$static.xmlnsNames = EMPTY_ATTRIBUTENAMES;
+  this$static.xmlnsValues = EMPTY_STRINGS;
+  return this$static;
+}
+
+function $addAttribute(this$static, name_0, value, xmlnsPolicy){
+  var newLen, newNames, newValues;
+  name_0 == ($clinit_124() , ID);
+  if (name_0.xmlns) {
+    if (this$static.xmlnsNames.length == this$static.xmlnsLength) {
+      newLen = this$static.xmlnsLength == 0?2:this$static.xmlnsLength << 1;
+      newNames = initDim(_3Lnu_validator_htmlparser_impl_AttributeName_2_classLit, 60, 13, newLen, 0);
+      arraycopy(this$static.xmlnsNames, 0, newNames, 0, this$static.xmlnsNames.length);
+      this$static.xmlnsNames = newNames;
+      newValues = initDim(_3Ljava_lang_String_2_classLit, 56, 1, newLen, 0);
+      arraycopy(this$static.xmlnsValues, 0, newValues, 0, this$static.xmlnsValues.length);
+      this$static.xmlnsValues = newValues;
+    }
+    this$static.xmlnsNames[this$static.xmlnsLength] = name_0;
+    this$static.xmlnsValues[this$static.xmlnsLength] = value;
+    ++this$static.xmlnsLength;
+    switch (xmlnsPolicy.ordinal) {
+      case 1:
+        throw $SAXException(new SAXException, 'Saw an xmlns attribute.');
+      case 2:
+        return;
+    }
+  }
+  if (this$static.names.length == this$static.length_0) {
+    newLen = this$static.length_0 << 1;
+    newNames = initDim(_3Lnu_validator_htmlparser_impl_AttributeName_2_classLit, 60, 13, newLen, 0);
+    arraycopy(this$static.names, 0, newNames, 0, this$static.names.length);
+    this$static.names = newNames;
+    newValues = initDim(_3Ljava_lang_String_2_classLit, 56, 1, newLen, 0);
+    arraycopy(this$static.values, 0, newValues, 0, this$static.values.length);
+    this$static.values = newValues;
+  }
+  this$static.names[this$static.length_0] = name_0;
+  this$static.values[this$static.length_0] = value;
+  ++this$static.length_0;
+}
+
+function $clear_0(this$static, m){
+  var i;
+  for (i = 0; i < this$static.length_0; ++i) {
+    setCheck(this$static.names, i, null);
+    setCheck(this$static.values, i, null);
+  }
+  this$static.length_0 = 0;
+  this$static.mode = m;
+  for (i = 0; i < this$static.xmlnsLength; ++i) {
+    setCheck(this$static.xmlnsNames, i, null);
+    setCheck(this$static.xmlnsValues, i, null);
+  }
+  this$static.xmlnsLength = 0;
+}
+
+function $clearWithoutReleasingContents(this$static){
+  var i;
+  for (i = 0; i < this$static.length_0; ++i) {
+    setCheck(this$static.names, i, null);
+    setCheck(this$static.values, i, null);
+  }
+  this$static.length_0 = 0;
+}
+
+function $cloneAttributes(this$static){
+  var clone, i;
+  clone = $HtmlAttributes(new HtmlAttributes, 0);
+  for (i = 0; i < this$static.length_0; ++i) {
+    $addAttribute(clone, this$static.names[i], this$static.values[i], ($clinit_115() , ALLOW));
+  }
+  for (i = 0; i < this$static.xmlnsLength; ++i) {
+    $addAttribute(clone, this$static.xmlnsNames[i], this$static.xmlnsValues[i], ($clinit_115() , ALLOW));
+  }
+  return clone;
+}
+
+function $contains(this$static, name_0){
+  var i;
+  for (i = 0; i < this$static.length_0; ++i) {
+    if (name_0.local[0] == this$static.names[i].local[0]) {
+      return true;
+    }
+  }
+  for (i = 0; i < this$static.xmlnsLength; ++i) {
+    if (name_0.local[0] == this$static.xmlnsNames[i].local[0]) {
+      return true;
+    }
+  }
+  return false;
+}
+
+function $getAttributeName(this$static, index){
+  if (index < this$static.length_0 && index >= 0) {
+    return this$static.names[index];
+  }
+   else {
+    return null;
+  }
+}
+
+function $getIndex(this$static, name_0){
+  var i;
+  for (i = 0; i < this$static.length_0; ++i) {
+    if (this$static.names[i] == name_0) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+function $getLocalName(this$static, index){
+  if (index < this$static.length_0 && index >= 0) {
+    return this$static.names[index].local[this$static.mode];
+  }
+   else {
+    return null;
+  }
+}
+
+function $getURI(this$static, index){
+  if (index < this$static.length_0 && index >= 0) {
+    return this$static.names[index].uri[this$static.mode];
+  }
+   else {
+    return null;
+  }
+}
+
+function $getValue_0(this$static, index){
+  if (index < this$static.length_0 && index >= 0) {
+    return this$static.values[index];
+  }
+   else {
+    return null;
+  }
+}
+
+function $getValue_1(this$static, name_0){
+  var index;
+  index = $getIndex(this$static, name_0);
+  if (index == -1) {
+    return null;
+  }
+   else {
+    return $getValue_0(this$static, index);
+  }
+}
+
+function $processNonNcNames(this$static, treeBuilder, namePolicy){
+  var attName, i, name_0;
+  for (i = 0; i < this$static.length_0; ++i) {
+    attName = this$static.names[i];
+    if (!attName.ncname[this$static.mode]) {
+      name_0 = attName.local[this$static.mode];
+      switch (namePolicy.ordinal) {
+        case 2:
+          this$static.names[i] = ($clinit_124() , $AttributeName_0(new AttributeName, ALL_NO_NS, SAME_LOCAL(escapeName(name_0)), ALL_NO_PREFIX, ALL_NCNAME, false));
+        case 0:
+          attName != ($clinit_124() , XML_LANG);
+          break;
+        case 1:
+          $fatal_0(treeBuilder, 'Attribute \u201C' + name_0 + '\u201D is not serializable as XML 1.0.');
+      }
+    }
+  }
+}
+
+function getClass_71(){
+  return Lnu_validator_htmlparser_impl_HtmlAttributes_2_classLit;
+}
+
+function HtmlAttributes(){
+}
+
+_ = HtmlAttributes.prototype = new Object_0;
+_.getClass$ = getClass_71;
+_.typeId$ = 0;
+_.length_0 = 0;
+_.mode = 0;
+_.names = null;
+_.values = null;
+_.xmlnsLength = 0;
+_.xmlnsNames = null;
+_.xmlnsValues = null;
+var EMPTY_ATTRIBUTENAMES, EMPTY_ATTRIBUTES, EMPTY_STRINGS;
+function $LocatorImpl(this$static, locator){
+  $getColumnNumber(locator);
+  $getLineNumber(locator);
+  return this$static;
+}
+
+function getClass_72(){
+  return Lnu_validator_htmlparser_impl_LocatorImpl_2_classLit;
+}
+
+function LocatorImpl(){
+}
+
+_ = LocatorImpl.prototype = new Object_0;
+_.getClass$ = getClass_72;
+_.typeId$ = 0;
+function $clinit_130(){
+  $clinit_130 = nullMethod;
+  HEX_TABLE = $toCharArray('0123456789ABCDEF');
+}
+
+function appendUHexTo(sb, c){
+  var i;
+  sb.impl.string += 'U';
+  for (i = 0; i < 6; ++i) {
+    $append_1(sb, HEX_TABLE[(c & 15728640) >> 20]);
+    c <<= 4;
+  }
+}
+
+function escapeName(str){
+  $clinit_130();
+  var c, i, next, sb;
+  sb = $StringBuilder(new StringBuilder);
+  for (i = 0; i < str.length; ++i) {
+    c = str.charCodeAt(i);
+    if ((c & 64512) == 55296) {
+      next = str.charCodeAt(++i);
+      appendUHexTo(sb, (c << 10) + next + -56613888);
+    }
+     else 
+      i == 0 && !(c >= 65 && c <= 90 || c >= 97 && c <= 122 || c >= 192 && c <= 214 || c >= 216 && c <= 246 || c >= 248 && c <= 255 || c >= 256 && c <= 305 || c >= 308 && c <= 318 || c >= 321 && c <= 328 || c >= 330 && c <= 382 || c >= 384 && c <= 451 || c >= 461 && c <= 496 || c >= 500 && c <= 501 || c >= 506 && c <= 535 || c >= 592 && c <= 680 || c >= 699 && c <= 705 || c == 902 || c >= 904 && c <= 906 || c == 908 || c >= 910 && c <= 929 || c >= 931 && c <= 974 || c >= 976 && c <= 982 || c == 986 || c == 988 || c == 990 || c == 992 || c >= 994 && c <= 1011 || c >= 1025 && c <= 1036 || c >= 1038 && c <= 1103 || c >= 1105 && c <= 1116 || c >= 1118 && c <= 1153 || c >= 1168 && c <= 1220 || c >= 1223 && c <= 1224 || c >= 1227 && c <= 1228 || c >= 1232 && c <= 1259 || c >= 1262 && c <= 1269 || c >= 1272 && c <= 1273 || c >= 1329 && c <= 1366 || c == 1369 || c >= 1377 && c <= 1414 || c >= 1488 && c <= 1514 || c >= 1520 && c <= 1522 || c >= 1569 && c <= 1594 || c >= 1601 && c <= 1610 || c >= 1649 && c <= 1719 || c >= 1722 && c <= 1726 || c >= 1728 && c <= 1742 || c >= 1744 && c <= 1747 || c == 1749 || c >= 1765 && c <= 1766 || c >= 2309 && c <= 2361 || c == 2365 || c >= 2392 && c <= 2401 || c >= 2437 && c <= 2444 || c >= 2447 && c <= 2448 || c >= 2451 && c <= 2472 || c >= 2474 && c <= 2480 || c == 2482 || c >= 2486 && c <= 2489 || c >= 2524 && c <= 2525 || c >= 2527 && c <= 2529 || c >= 2544 && c <= 2545 || c >= 2565 && c <= 2570 || c >= 2575 && c <= 2576 || c >= 2579 && c <= 2600 || c >= 2602 && c <= 2608 || c >= 2610 && c <= 2611 || c >= 2613 && c <= 2614 || c >= 2616 && c <= 2617 || c >= 2649 && c <= 2652 || c == 2654 || c >= 2674 && c <= 2676 || c >= 2693 && c <= 2699 || c == 2701 || c >= 2703 && c <= 2705 || c >= 2707 && c <= 2728 || c >= 2730 && c <= 2736 || c >= 2738 && c <= 2739 || c >= 2741 && c <= 2745 || c == 2749 || c == 2784 || c >= 2821 && c <= 2828 || c >= 2831 && c <= 2832 || c >= 2835 && c <= 2856 || c >= 2858 && c <= 2864 || c >= 2866 && c <= 2867 || c >= 2870 && c <= 2873 || c == 2877 || c >= 2908 && c <= 2909 || c >= 2911 && c <= 2913 || c >= 2949 && c <= 2954 || c >= 2958 && c <= 2960 || c >= 2962 && c <= 2965 || c >= 2969 && c <= 2970 || c == 2972 || c >= 2974 && c <= 2975 || c >= 2979 && c <= 2980 || c >= 2984 && c <= 2986 || c >= 2990 && c <= 2997 || c >= 2999 && c <= 3001 || c >= 3077 && c <= 3084 || c >= 3086 && c <= 3088 || c >= 3090 && c <= 3112 || c >= 3114 && c <= 3123 || c >= 3125 && c <= 3129 || c >= 3168 && c <= 3169 || c >= 3205 && c <= 3212 || c >= 3214 && c <= 3216 || c >= 3218 && c <= 3240 || c >= 3242 && c <= 3251 || c >= 3253 && c <= 3257 || c == 3294 || c >= 3296 && c <= 3297 || c >= 3333 && c <= 3340 || c >= 3342 && c <= 3344 || c >= 3346 && c <= 3368 || c >= 3370 && c <= 3385 || c >= 3424 && c <= 3425 || c >= 3585 && c <= 3630 || c == 3632 || c >= 3634 && c <= 3635 || c >= 3648 && c <= 3653 || c >= 3713 && c <= 3714 || c == 3716 || c >= 3719 && c <= 3720 || c == 3722 || c == 3725 || c >= 3732 && c <= 3735 || c >= 3737 && c <= 3743 || c >= 3745 && c <= 3747 || c == 3749 || c == 3751 || c >= 3754 && c <= 3755 || c >= 3757 && c <= 3758 || c == 3760 || c >= 3762 && c <= 3763 || c == 3773 || c >= 3776 && c <= 3780 || c >= 3904 && c <= 3911 || c >= 3913 && c <= 3945 || c >= 4256 && c <= 4293 || c >= 4304 && c <= 4342 || c == 4352 || c >= 4354 && c <= 4355 || c >= 4357 && c <= 4359 || c == 4361 || c >= 4363 && c <= 4364 || c >= 4366 && c <= 4370 || c == 4412 || c == 4414 || c == 4416 || c == 4428 || c == 4430 || c == 4432 || c >= 4436 && c <= 4437 || c == 4441 || c >= 4447 && c <= 4449 || c == 4451 || c == 4453 || c == 4455 || c == 4457 || c >= 4461 && c <= 4462 || c >= 4466 && c <= 4467 || c == 4469 || c == 4510 || c == 4520 || c == 4523 || c >= 4526 && c <= 4527 || c >= 4535 && c <= 4536 || c == 4538 || c >= 4540 && c <= 4546 || c == 4587 || c == 4592 || c == 4601 || c >= 7680 && c <= 7835 || c >= 7840 && c <= 7929 || c >= 7936 && c <= 7957 || c >= 7960 && c <= 7965 || c >= 7968 && c <= 8005 || c >= 8008 && c <= 8013 || c >= 8016 && c <= 8023 || c == 8025 || c == 8027 || c == 8029 || c >= 8031 && c <= 8061 || c >= 8064 && c <= 8116 || c >= 8118 && c <= 8124 || c == 8126 || c >= 8130 && c <= 8132 || c >= 8134 && c <= 8140 || c >= 8144 && c <= 8147 || c >= 8150 && c <= 8155 || c >= 8160 && c <= 8172 || c >= 8178 && c <= 8180 || c >= 8182 && c <= 8188 || c == 8486 || c >= 8490 && c <= 8491 || c == 8494 || c >= 8576 && c <= 8578 || c >= 12353 && c <= 12436 || c >= 12449 && c <= 12538 || c >= 12549 && c <= 12588 || c >= 44032 && c <= 55203 || c >= 19968 && c <= 40869 || c == 12295 || c >= 12321 && c <= 12329 || c == 95)?appendUHexTo(sb, c):i != 0 && !(c >= 48 && c <= 57 || c >= 1632 && c <= 1641 || c >= 1776 && c <= 1785 || c >= 2406 && c <= 2415 || c >= 2534 && c <= 2543 || c >= 2662 && c <= 2671 || c >= 2790 && c <= 2799 || c >= 2918 && c <= 2927 || c >= 3047 && c <= 3055 || c >= 3174 && c <= 3183 || c >= 3302 && c <= 3311 || c >= 3430 && c <= 3439 || c >= 3664 && c <= 3673 || c >= 3792 && c <= 3801 || c >= 3872 && c <= 3881 || c >= 65 && c <= 90 || c >= 97 && c <= 122 || c >= 192 && c <= 214 || c >= 216 && c <= 246 || c >= 248 && c <= 255 || c >= 256 && c <= 305 || c >= 308 && c <= 318 || c >= 321 && c <= 328 || c >= 330 && c <= 382 || c >= 384 && c <= 451 || c >= 461 && c <= 496 || c >= 500 && c <= 501 || c >= 506 && c <= 535 || c >= 592 && c <= 680 || c >= 699 && c <= 705 || c == 902 || c >= 904 && c <= 906 || c == 908 || c >= 910 && c <= 929 || c >= 931 && c <= 974 || c >= 976 && c <= 982 || c == 986 || c == 988 || c == 990 || c == 992 || c >= 994 && c <= 1011 || c >= 1025 && c <= 1036 || c >= 1038 && c <= 1103 || c >= 1105 && c <= 1116 || c >= 1118 && c <= 1153 || c >= 1168 && c <= 1220 || c >= 1223 && c <= 1224 || c >= 1227 && c <= 1228 || c >= 1232 && c <= 1259 || c >= 1262 && c <= 1269 || c >= 1272 && c <= 1273 || c >= 1329 && c <= 1366 || c == 1369 || c >= 1377 && c <= 1414 || c >= 1488 && c <= 1514 || c >= 1520 && c <= 1522 || c >= 1569 && c <= 1594 || c >= 1601 && c <= 1610 || c >= 1649 && c <= 1719 || c >= 1722 && c <= 1726 || c >= 1728 && c <= 1742 || c >= 1744 && c <= 1747 || c == 1749 || c >= 1765 && c <= 1766 || c >= 2309 && c <= 2361 || c == 2365 || c >= 2392 && c <= 2401 || c >= 2437 && c <= 2444 || c >= 2447 && c <= 2448 || c >= 2451 && c <= 2472 || c >= 2474 && c <= 2480 || c == 2482 || c >= 2486 && c <= 2489 || c >= 2524 && c <= 2525 || c >= 2527 && c <= 2529 || c >= 2544 && c <= 2545 || c >= 2565 && c <= 2570 || c >= 2575 && c <= 2576 || c >= 2579 && c <= 2600 || c >= 2602 && c <= 2608 || c >= 2610 && c <= 2611 || c >= 2613 && c <= 2614 || c >= 2616 && c <= 2617 || c >= 2649 && c <= 2652 || c == 2654 || c >= 2674 && c <= 2676 || c >= 2693 && c <= 2699 || c == 2701 || c >= 2703 && c <= 2705 || c >= 2707 && c <= 2728 || c >= 2730 && c <= 2736 || c >= 2738 && c <= 2739 || c >= 2741 && c <= 2745 || c == 2749 || c == 2784 || c >= 2821 && c <= 2828 || c >= 2831 && c <= 2832 || c >= 2835 && c <= 2856 || c >= 2858 && c <= 2864 || c >= 2866 && c <= 2867 || c >= 2870 && c <= 2873 || c == 2877 || c >= 2908 && c <= 2909 || c >= 2911 && c <= 2913 || c >= 2949 && c <= 2954 || c >= 2958 && c <= 2960 || c >= 2962 && c <= 2965 || c >= 2969 && c <= 2970 || c == 2972 || c >= 2974 && c <= 2975 || c >= 2979 && c <= 2980 || c >= 2984 && c <= 2986 || c >= 2990 && c <= 2997 || c >= 2999 && c <= 3001 || c >= 3077 && c <= 3084 || c >= 3086 && c <= 3088 || c >= 3090 && c <= 3112 || c >= 3114 && c <= 3123 || c >= 3125 && c <= 3129 || c >= 3168 && c <= 3169 || c >= 3205 && c <= 3212 || c >= 3214 && c <= 3216 || c >= 3218 && c <= 3240 || c >= 3242 && c <= 3251 || c >= 3253 && c <= 3257 || c == 3294 || c >= 3296 && c <= 3297 || c >= 3333 && c <= 3340 || c >= 3342 && c <= 3344 || c >= 3346 && c <= 3368 || c >= 3370 && c <= 3385 || c >= 3424 && c <= 3425 || c >= 3585 && c <= 3630 || c == 3632 || c >= 3634 && c <= 3635 || c >= 3648 && c <= 3653 || c >= 3713 && c <= 3714 || c == 3716 || c >= 3719 && c <= 3720 || c == 3722 || c == 3725 || c >= 3732 && c <= 3735 || c >= 3737 && c <= 3743 || c >= 3745 && c <= 3747 || c == 3749 || c == 3751 || c >= 3754 && c <= 3755 || c >= 3757 && c <= 3758 || c == 3760 || c >= 3762 && c <= 3763 || c == 3773 || c >= 3776 && c <= 3780 || c >= 3904 && c <= 3911 || c >= 3913 && c <= 3945 || c >= 4256 && c <= 4293 || c >= 4304 && c <= 4342 || c == 4352 || c >= 4354 && c <= 4355 || c >= 4357 && c <= 4359 || c == 4361 || c >= 4363 && c <= 4364 || c >= 4366 && c <= 4370 || c == 4412 || c == 4414 || c == 4416 || c == 4428 || c == 4430 || c == 4432 || c >= 4436 && c <= 4437 || c == 4441 || c >= 4447 && c <= 4449 || c == 4451 || c == 4453 || c == 4455 || c == 4457 || c >= 4461 && c <= 4462 || c >= 4466 && c <= 4467 || c == 4469 || c == 4510 || c == 4520 || c == 4523 || c >= 4526 && c <= 4527 || c >= 4535 && c <= 4536 || c == 4538 || c >= 4540 && c <= 4546 || c == 4587 || c == 4592 || c == 4601 || c >= 7680 && c <= 7835 || c >= 7840 && c <= 7929 || c >= 7936 && c <= 7957 || c >= 7960 && c <= 7965 || c >= 7968 && c <= 8005 || c >= 8008 && c <= 8013 || c >= 8016 && c <= 8023 || c == 8025 || c == 8027 || c == 8029 || c >= 8031 && c <= 8061 || c >= 8064 && c <= 8116 || c >= 8118 && c <= 8124 || c == 8126 || c >= 8130 && c <= 8132 || c >= 8134 && c <= 8140 || c >= 8144 && c <= 8147 || c >= 8150 && c <= 8155 || c >= 8160 && c <= 8172 || c >= 8178 && c <= 8180 || c >= 8182 && c <= 8188 || c == 8486 || c >= 8490 && c <= 8491 || c == 8494 || c >= 8576 && c <= 8578 || c >= 12353 && c <= 12436 || c >= 12449 && c <= 12538 || c >= 12549 && c <= 12588 || c >= 44032 && c <= 55203 || c >= 19968 && c <= 40869 || c == 12295 || c >= 12321 && c <= 12329 || c == 95 || c == 46 || c == 45 || c >= 768 && c <= 837 || c >= 864 && c <= 865 || c >= 1155 && c <= 1158 || c >= 1425 && c <= 1441 || c >= 1443 && c <= 1465 || c >= 1467 && c <= 1469 || c == 1471 || c >= 1473 && c <= 1474 || c == 1476 || c >= 1611 && c <= 1618 || c == 1648 || c >= 1750 && c <= 1756 || c >= 1757 && c <= 1759 || c >= 1760 && c <= 1764 || c >= 1767 && c <= 1768 || c >= 1770 && c <= 1773 || c >= 2305 && c <= 2307 || c == 2364 || c >= 2366 && c <= 2380 || c == 2381 || c >= 2385 && c <= 2388 || c >= 2402 && c <= 2403 || c >= 2433 && c <= 2435 || c == 2492 || c == 2494 || c == 2495 || c >= 2496 && c <= 2500 || c >= 2503 && c <= 2504 || c >= 2507 && c <= 2509 || c == 2519 || c >= 2530 && c <= 2531 || c == 2562 || c == 2620 || c == 2622 || c == 2623 || c >= 2624 && c <= 2626 || c >= 2631 && c <= 2632 || c >= 2635 && c <= 2637 || c >= 2672 && c <= 2673 || c >= 2689 && c <= 2691 || c == 2748 || c >= 2750 && c <= 2757 || c >= 2759 && c <= 2761 || c >= 2763 && c <= 2765 || c >= 2817 && c <= 2819 || c == 2876 || c >= 2878 && c <= 2883 || c >= 2887 && c <= 2888 || c >= 2891 && c <= 2893 || c >= 2902 && c <= 2903 || c >= 2946 && c <= 2947 || c >= 3006 && c <= 3010 || c >= 3014 && c <= 3016 || c >= 3018 && c <= 3021 || c == 3031 || c >= 3073 && c <= 3075 || c >= 3134 && c <= 3140 || c >= 3142 && c <= 3144 || c >= 3146 && c <= 3149 || c >= 3157 && c <= 3158 || c >= 3202 && c <= 3203 || c >= 3262 && c <= 3268 || c >= 3270 && c <= 3272 || c >= 3274 && c <= 3277 || c >= 3285 && c <= 3286 || c >= 3330 && c <= 3331 || c >= 3390 && c <= 3395 || c >= 3398 && c <= 3400 || c >= 3402 && c <= 3405 || c == 3415 || c == 3633 || c >= 3636 && c <= 3642 || c >= 3655 && c <= 3662 || c == 3761 || c >= 3764 && c <= 3769 || c >= 3771 && c <= 3772 || c >= 3784 && c <= 3789 || c >= 3864 && c <= 3865 || c == 3893 || c == 3895 || c == 3897 || c == 3902 || c == 3903 || c >= 3953 && c <= 3972 || c >= 3974 && c <= 3979 || c >= 3984 && c <= 3989 || c == 3991 || c >= 3993 && c <= 4013 || c >= 4017 && c <= 4023 || c == 4025 || c >= 8400 && c <= 8412 || c == 8417 || c >= 12330 && c <= 12335 || c == 12441 || c == 12442 || c == 183 || c == 720 || c == 721 || c == 903 || c == 1600 || c == 3654 || c == 3782 || c == 12293 || c >= 12337 && c <= 12341 || c >= 12445 && c <= 12446 || c >= 12540 && c <= 12542)?appendUHexTo(sb, c):(sb.impl.string += String.fromCharCode(c) , undefined);
+  }
+  return String(sb.impl.string);
+}
+
+function isNCName(str){
+  $clinit_130();
+  var i, len;
+  if (str == null) {
+    return false;
+  }
+   else {
+    len = str.length;
+    switch (len) {
+      case 0:
+        return false;
+      case 1:
+        return isNCNameStart(str.charCodeAt(0));
+      default:if (!isNCNameStart(str.charCodeAt(0))) {
+          return false;
+        }
+
+        for (i = 1; i < len; ++i) {
+          if (!isNCNameTrail(str.charCodeAt(i))) {
+            return false;
+          }
+        }
+
+    }
+    return true;
+  }
+}
+
+function isNCNameStart(c){
+  return c >= 65 && c <= 90 || c >= 97 && c <= 122 || c >= 192 && c <= 214 || c >= 216 && c <= 246 || c >= 248 && c <= 255 || c >= 256 && c <= 305 || c >= 308 && c <= 318 || c >= 321 && c <= 328 || c >= 330 && c <= 382 || c >= 384 && c <= 451 || c >= 461 && c <= 496 || c >= 500 && c <= 501 || c >= 506 && c <= 535 || c >= 592 && c <= 680 || c >= 699 && c <= 705 || c == 902 || c >= 904 && c <= 906 || c == 908 || c >= 910 && c <= 929 || c >= 931 && c <= 974 || c >= 976 && c <= 982 || c == 986 || c == 988 || c == 990 || c == 992 || c >= 994 && c <= 1011 || c >= 1025 && c <= 1036 || c >= 1038 && c <= 1103 || c >= 1105 && c <= 1116 || c >= 1118 && c <= 1153 || c >= 1168 && c <= 1220 || c >= 1223 && c <= 1224 || c >= 1227 && c <= 1228 || c >= 1232 && c <= 1259 || c >= 1262 && c <= 1269 || c >= 1272 && c <= 1273 || c >= 1329 && c <= 1366 || c == 1369 || c >= 1377 && c <= 1414 || c >= 1488 && c <= 1514 || c >= 1520 && c <= 1522 || c >= 1569 && c <= 1594 || c >= 1601 && c <= 1610 || c >= 1649 && c <= 1719 || c >= 1722 && c <= 1726 || c >= 1728 && c <= 1742 || c >= 1744 && c <= 1747 || c == 1749 || c >= 1765 && c <= 1766 || c >= 2309 && c <= 2361 || c == 2365 || c >= 2392 && c <= 2401 || c >= 2437 && c <= 2444 || c >= 2447 && c <= 2448 || c >= 2451 && c <= 2472 || c >= 2474 && c <= 2480 || c == 2482 || c >= 2486 && c <= 2489 || c >= 2524 && c <= 2525 || c >= 2527 && c <= 2529 || c >= 2544 && c <= 2545 || c >= 2565 && c <= 2570 || c >= 2575 && c <= 2576 || c >= 2579 && c <= 2600 || c >= 2602 && c <= 2608 || c >= 2610 && c <= 2611 || c >= 2613 && c <= 2614 || c >= 2616 && c <= 2617 || c >= 2649 && c <= 2652 || c == 2654 || c >= 2674 && c <= 2676 || c >= 2693 && c <= 2699 || c == 2701 || c >= 2703 && c <= 2705 || c >= 2707 && c <= 2728 || c >= 2730 && c <= 2736 || c >= 2738 && c <= 2739 || c >= 2741 && c <= 2745 || c == 2749 || c == 2784 || c >= 2821 && c <= 2828 || c >= 2831 && c <= 2832 || c >= 2835 && c <= 2856 || c >= 2858 && c <= 2864 || c >= 2866 && c <= 2867 || c >= 2870 && c <= 2873 || c == 2877 || c >= 2908 && c <= 2909 || c >= 2911 && c <= 2913 || c >= 2949 && c <= 2954 || c >= 2958 && c <= 2960 || c >= 2962 && c <= 2965 || c >= 2969 && c <= 2970 || c == 2972 || c >= 2974 && c <= 2975 || c >= 2979 && c <= 2980 || c >= 2984 && c <= 2986 || c >= 2990 && c <= 2997 || c >= 2999 && c <= 3001 || c >= 3077 && c <= 3084 || c >= 3086 && c <= 3088 || c >= 3090 && c <= 3112 || c >= 3114 && c <= 3123 || c >= 3125 && c <= 3129 || c >= 3168 && c <= 3169 || c >= 3205 && c <= 3212 || c >= 3214 && c <= 3216 || c >= 3218 && c <= 3240 || c >= 3242 && c <= 3251 || c >= 3253 && c <= 3257 || c == 3294 || c >= 3296 && c <= 3297 || c >= 3333 && c <= 3340 || c >= 3342 && c <= 3344 || c >= 3346 && c <= 3368 || c >= 3370 && c <= 3385 || c >= 3424 && c <= 3425 || c >= 3585 && c <= 3630 || c == 3632 || c >= 3634 && c <= 3635 || c >= 3648 && c <= 3653 || c >= 3713 && c <= 3714 || c == 3716 || c >= 3719 && c <= 3720 || c == 3722 || c == 3725 || c >= 3732 && c <= 3735 || c >= 3737 && c <= 3743 || c >= 3745 && c <= 3747 || c == 3749 || c == 3751 || c >= 3754 && c <= 3755 || c >= 3757 && c <= 3758 || c == 3760 || c >= 3762 && c <= 3763 || c == 3773 || c >= 3776 && c <= 3780 || c >= 3904 && c <= 3911 || c >= 3913 && c <= 3945 || c >= 4256 && c <= 4293 || c >= 4304 && c <= 4342 || c == 4352 || c >= 4354 && c <= 4355 || c >= 4357 && c <= 4359 || c == 4361 || c >= 4363 && c <= 4364 || c >= 4366 && c <= 4370 || c == 4412 || c == 4414 || c == 4416 || c == 4428 || c == 4430 || c == 4432 || c >= 4436 && c <= 4437 || c == 4441 || c >= 4447 && c <= 4449 || c == 4451 || c == 4453 || c == 4455 || c == 4457 || c >= 4461 && c <= 4462 || c >= 4466 && c <= 4467 || c == 4469 || c == 4510 || c == 4520 || c == 4523 || c >= 4526 && c <= 4527 || c >= 4535 && c <= 4536 || c == 4538 || c >= 4540 && c <= 4546 || c == 4587 || c == 4592 || c == 4601 || c >= 7680 && c <= 7835 || c >= 7840 && c <= 7929 || c >= 7936 && c <= 7957 || c >= 7960 && c <= 7965 || c >= 7968 && c <= 8005 || c >= 8008 && c <= 8013 || c >= 8016 && c <= 8023 || c == 8025 || c == 8027 || c == 8029 || c >= 8031 && c <= 8061 || c >= 8064 && c <= 8116 || c >= 8118 && c <= 8124 || c == 8126 || c >= 8130 && c <= 8132 || c >= 8134 && c <= 8140 || c >= 8144 && c <= 8147 || c >= 8150 && c <= 8155 || c >= 8160 && c <= 8172 || c >= 8178 && c <= 8180 || c >= 8182 && c <= 8188 || c == 8486 || c >= 8490 && c <= 8491 || c == 8494 || c >= 8576 && c <= 8578 || c >= 12353 && c <= 12436 || c >= 12449 && c <= 12538 || c >= 12549 && c <= 12588 || c >= 44032 && c <= 55203 || c >= 19968 && c <= 40869 || c == 12295 || c >= 12321 && c <= 12329 || c == 95;
+}
+
+function isNCNameTrail(c){
+  return c >= 48 && c <= 57 || c >= 1632 && c <= 1641 || c >= 1776 && c <= 1785 || c >= 2406 && c <= 2415 || c >= 2534 && c <= 2543 || c >= 2662 && c <= 2671 || c >= 2790 && c <= 2799 || c >= 2918 && c <= 2927 || c >= 3047 && c <= 3055 || c >= 3174 && c <= 3183 || c >= 3302 && c <= 3311 || c >= 3430 && c <= 3439 || c >= 3664 && c <= 3673 || c >= 3792 && c <= 3801 || c >= 3872 && c <= 3881 || c >= 65 && c <= 90 || c >= 97 && c <= 122 || c >= 192 && c <= 214 || c >= 216 && c <= 246 || c >= 248 && c <= 255 || c >= 256 && c <= 305 || c >= 308 && c <= 318 || c >= 321 && c <= 328 || c >= 330 && c <= 382 || c >= 384 && c <= 451 || c >= 461 && c <= 496 || c >= 500 && c <= 501 || c >= 506 && c <= 535 || c >= 592 && c <= 680 || c >= 699 && c <= 705 || c == 902 || c >= 904 && c <= 906 || c == 908 || c >= 910 && c <= 929 || c >= 931 && c <= 974 || c >= 976 && c <= 982 || c == 986 || c == 988 || c == 990 || c == 992 || c >= 994 && c <= 1011 || c >= 1025 && c <= 1036 || c >= 1038 && c <= 1103 || c >= 1105 && c <= 1116 || c >= 1118 && c <= 1153 || c >= 1168 && c <= 1220 || c >= 1223 && c <= 1224 || c >= 1227 && c <= 1228 || c >= 1232 && c <= 1259 || c >= 1262 && c <= 1269 || c >= 1272 && c <= 1273 || c >= 1329 && c <= 1366 || c == 1369 || c >= 1377 && c <= 1414 || c >= 1488 && c <= 1514 || c >= 1520 && c <= 1522 || c >= 1569 && c <= 1594 || c >= 1601 && c <= 1610 || c >= 1649 && c <= 1719 || c >= 1722 && c <= 1726 || c >= 1728 && c <= 1742 || c >= 1744 && c <= 1747 || c == 1749 || c >= 1765 && c <= 1766 || c >= 2309 && c <= 2361 || c == 2365 || c >= 2392 && c <= 2401 || c >= 2437 && c <= 2444 || c >= 2447 && c <= 2448 || c >= 2451 && c <= 2472 || c >= 2474 && c <= 2480 || c == 2482 || c >= 2486 && c <= 2489 || c >= 2524 && c <= 2525 || c >= 2527 && c <= 2529 || c >= 2544 && c <= 2545 || c >= 2565 && c <= 2570 || c >= 2575 && c <= 2576 || c >= 2579 && c <= 2600 || c >= 2602 && c <= 2608 || c >= 2610 && c <= 2611 || c >= 2613 && c <= 2614 || c >= 2616 && c <= 2617 || c >= 2649 && c <= 2652 || c == 2654 || c >= 2674 && c <= 2676 || c >= 2693 && c <= 2699 || c == 2701 || c >= 2703 && c <= 2705 || c >= 2707 && c <= 2728 || c >= 2730 && c <= 2736 || c >= 2738 && c <= 2739 || c >= 2741 && c <= 2745 || c == 2749 || c == 2784 || c >= 2821 && c <= 2828 || c >= 2831 && c <= 2832 || c >= 2835 && c <= 2856 || c >= 2858 && c <= 2864 || c >= 2866 && c <= 2867 || c >= 2870 && c <= 2873 || c == 2877 || c >= 2908 && c <= 2909 || c >= 2911 && c <= 2913 || c >= 2949 && c <= 2954 || c >= 2958 && c <= 2960 || c >= 2962 && c <= 2965 || c >= 2969 && c <= 2970 || c == 2972 || c >= 2974 && c <= 2975 || c >= 2979 && c <= 2980 || c >= 2984 && c <= 2986 || c >= 2990 && c <= 2997 || c >= 2999 && c <= 3001 || c >= 3077 && c <= 3084 || c >= 3086 && c <= 3088 || c >= 3090 && c <= 3112 || c >= 3114 && c <= 3123 || c >= 3125 && c <= 3129 || c >= 3168 && c <= 3169 || c >= 3205 && c <= 3212 || c >= 3214 && c <= 3216 || c >= 3218 && c <= 3240 || c >= 3242 && c <= 3251 || c >= 3253 && c <= 3257 || c == 3294 || c >= 3296 && c <= 3297 || c >= 3333 && c <= 3340 || c >= 3342 && c <= 3344 || c >= 3346 && c <= 3368 || c >= 3370 && c <= 3385 || c >= 3424 && c <= 3425 || c >= 3585 && c <= 3630 || c == 3632 || c >= 3634 && c <= 3635 || c >= 3648 && c <= 3653 || c >= 3713 && c <= 3714 || c == 3716 || c >= 3719 && c <= 3720 || c == 3722 || c == 3725 || c >= 3732 && c <= 3735 || c >= 3737 && c <= 3743 || c >= 3745 && c <= 3747 || c == 3749 || c == 3751 || c >= 3754 && c <= 3755 || c >= 3757 && c <= 3758 || c == 3760 || c >= 3762 && c <= 3763 || c == 3773 || c >= 3776 && c <= 3780 || c >= 3904 && c <= 3911 || c >= 3913 && c <= 3945 || c >= 4256 && c <= 4293 || c >= 4304 && c <= 4342 || c == 4352 || c >= 4354 && c <= 4355 || c >= 4357 && c <= 4359 || c == 4361 || c >= 4363 && c <= 4364 || c >= 4366 && c <= 4370 || c == 4412 || c == 4414 || c == 4416 || c == 4428 || c == 4430 || c == 4432 || c >= 4436 && c <= 4437 || c == 4441 || c >= 4447 && c <= 4449 || c == 4451 || c == 4453 || c == 4455 || c == 4457 || c >= 4461 && c <= 4462 || c >= 4466 && c <= 4467 || c == 4469 || c == 4510 || c == 4520 || c == 4523 || c >= 4526 && c <= 4527 || c >= 4535 && c <= 4536 || c == 4538 || c >= 4540 && c <= 4546 || c == 4587 || c == 4592 || c == 4601 || c >= 7680 && c <= 7835 || c >= 7840 && c <= 7929 || c >= 7936 && c <= 7957 || c >= 7960 && c <= 7965 || c >= 7968 && c <= 8005 || c >= 8008 && c <= 8013 || c >= 8016 && c <= 8023 || c == 8025 || c == 8027 || c == 8029 || c >= 8031 && c <= 8061 || c >= 8064 && c <= 8116 || c >= 8118 && c <= 8124 || c == 8126 || c >= 8130 && c <= 8132 || c >= 8134 && c <= 8140 || c >= 8144 && c <= 8147 || c >= 8150 && c <= 8155 || c >= 8160 && c <= 8172 || c >= 8178 && c <= 8180 || c >= 8182 && c <= 8188 || c == 8486 || c >= 8490 && c <= 8491 || c == 8494 || c >= 8576 && c <= 8578 || c >= 12353 && c <= 12436 || c >= 12449 && c <= 12538 || c >= 12549 && c <= 12588 || c >= 44032 && c <= 55203 || c >= 19968 && c <= 40869 || c == 12295 || c >= 12321 && c <= 12329 || c == 95 || c == 46 || c == 45 || c >= 768 && c <= 837 || c >= 864 && c <= 865 || c >= 1155 && c <= 1158 || c >= 1425 && c <= 1441 || c >= 1443 && c <= 1465 || c >= 1467 && c <= 1469 || c == 1471 || c >= 1473 && c <= 1474 || c == 1476 || c >= 1611 && c <= 1618 || c == 1648 || c >= 1750 && c <= 1756 || c >= 1757 && c <= 1759 || c >= 1760 && c <= 1764 || c >= 1767 && c <= 1768 || c >= 1770 && c <= 1773 || c >= 2305 && c <= 2307 || c == 2364 || c >= 2366 && c <= 2380 || c == 2381 || c >= 2385 && c <= 2388 || c >= 2402 && c <= 2403 || c >= 2433 && c <= 2435 || c == 2492 || c == 2494 || c == 2495 || c >= 2496 && c <= 2500 || c >= 2503 && c <= 2504 || c >= 2507 && c <= 2509 || c == 2519 || c >= 2530 && c <= 2531 || c == 2562 || c == 2620 || c == 2622 || c == 2623 || c >= 2624 && c <= 2626 || c >= 2631 && c <= 2632 || c >= 2635 && c <= 2637 || c >= 2672 && c <= 2673 || c >= 2689 && c <= 2691 || c == 2748 || c >= 2750 && c <= 2757 || c >= 2759 && c <= 2761 || c >= 2763 && c <= 2765 || c >= 2817 && c <= 2819 || c == 2876 || c >= 2878 && c <= 2883 || c >= 2887 && c <= 2888 || c >= 2891 && c <= 2893 || c >= 2902 && c <= 2903 || c >= 2946 && c <= 2947 || c >= 3006 && c <= 3010 || c >= 3014 && c <= 3016 || c >= 3018 && c <= 3021 || c == 3031 || c >= 3073 && c <= 3075 || c >= 3134 && c <= 3140 || c >= 3142 && c <= 3144 || c >= 3146 && c <= 3149 || c >= 3157 && c <= 3158 || c >= 3202 && c <= 3203 || c >= 3262 && c <= 3268 || c >= 3270 && c <= 3272 || c >= 3274 && c <= 3277 || c >= 3285 && c <= 3286 || c >= 3330 && c <= 3331 || c >= 3390 && c <= 3395 || c >= 3398 && c <= 3400 || c >= 3402 && c <= 3405 || c == 3415 || c == 3633 || c >= 3636 && c <= 3642 || c >= 3655 && c <= 3662 || c == 3761 || c >= 3764 && c <= 3769 || c >= 3771 && c <= 3772 || c >= 3784 && c <= 3789 || c >= 3864 && c <= 3865 || c == 3893 || c == 3895 || c == 3897 || c == 3902 || c == 3903 || c >= 3953 && c <= 3972 || c >= 3974 && c <= 3979 || c >= 3984 && c <= 3989 || c == 3991 || c >= 3993 && c <= 4013 || c >= 4017 && c <= 4023 || c == 4025 || c >= 8400 && c <= 8412 || c == 8417 || c >= 12330 && c <= 12335 || c == 12441 || c == 12442 || c == 183 || c == 720 || c == 721 || c == 903 || c == 1600 || c == 3654 || c == 3782 || c == 12293 || c >= 12337 && c <= 12341 || c >= 12445 && c <= 12446 || c >= 12540 && c <= 12542;
+}
+
+var HEX_TABLE;
+function $clinit_131(){
+  $clinit_131 = nullMethod;
+  NAMES = initValues(_3_3B_classLit, 63, 16, [toByteArray('lig'), toByteArray('lig;'), toByteArray('P'), toByteArray('P;'), toByteArray('cute'), toByteArray('cute;'), toByteArray('reve;'), toByteArray('irc'), toByteArray('irc;'), toByteArray('y;'), toByteArray('r;'), toByteArray('rave'), toByteArray('rave;'), toByteArray('pha;'), toByteArray('acr;'), toByteArray('d;'), toByteArray('gon;'), toByteArray('pf;'), toByteArray('plyFunction;'), toByteArray('ing'), toByteArray('ing;'), toByteArray('cr;'), toByteArray('sign;'), toByteArray('ilde'), toByteArray('ilde;'), toByteArray('ml'), toByteArray('ml;'), toByteArray('ckslash;'), toByteArray('rv;'), toByteArray('rwed;'), toByteArray('y;'), toByteArray('cause;'), toByteArray('rnoullis;'), toByteArray('ta;'), toByteArray('r;'), toByteArray('pf;'), toByteArray('eve;'), toByteArray('cr;'), toByteArray('mpeq;'), toByteArray('cy;'), toByteArray('PY'), toByteArray('PY;'), toByteArray('cute;'), toByteArray('p;'), toByteArray('pitalDifferentialD;'), toByteArray('yleys;'), toByteArray('aron;'), toByteArray('edil'), toByteArray('edil;'), toByteArray('irc;'), toByteArray('onint;'), toByteArray('ot;'), toByteArray('dilla;'), toByteArray('nterDot;'), toByteArray('r;'), toByteArray('i;'), toByteArray('rcleDot;'), toByteArray('rcleMinus;'), toByteArray('rclePlus;'), toByteArray('rcleTimes;'), toByteArray('ockwiseContourIntegral;'), toByteArray('oseCurlyDoubleQuote;'), toByteArray('oseCurlyQuote;'), toByteArray('lon;'), toByteArray('lone;'), toByteArray('ngruent;'), toByteArray('nint;'), toByteArray('ntourIntegral;'), toByteArray('pf;'), toByteArray('product;'), toByteArray('unterClockwiseContourIntegral;'), toByteArray('oss;'), toByteArray('cr;'), toByteArray('p;'), toByteArray('pCap;'), toByteArray(';'), toByteArray('otrahd;'), toByteArray('cy;'), toByteArray('cy;'), toByteArray('cy;'), toByteArray('gger;'), toByteArray('rr;'), toByteArray('shv;'), toByteArray('aron;'), toByteArray('y;'), toByteArray('l;'), toByteArray('lta;'), toByteArray('r;'), toByteArray('acriticalAcute;'), toByteArray('acriticalDot;'), toByteArray('acriticalDoubleAcute;'), toByteArray('acriticalGrave;'), toByteArray('acriticalTilde;'), toByteArray('amond;'), toByteArray('fferentialD;'), toByteArray('pf;'), toByteArray('t;'), toByteArray('tDot;'), toByteArray('tEqual;'), toByteArray('ubleContourIntegral;'), toByteArray('ubleDot;'), toByteArray('ubleDownArrow;'), toByteArray('ubleLeftArrow;'), toByteArray('ubleLeftRightArrow;'), toByteArray('ubleLeftTee;'), toByteArray('ubleLongLeftArrow;'), toByteArray('ubleLongLeftRightArrow;'), toByteArray('ubleLongRightArrow;'), toByteArray('ubleRightArrow;'), toByteArray('ubleRightTee;'), toByteArray('ubleUpArrow;'), toByteArray('ubleUpDownArrow;'), toByteArray('ubleVerticalBar;'), toByteArray('wnArrow;'), toByteArray('wnArrowBar;'), toByteArray('wnArrowUpArrow;'), toByteArray('wnBreve;'), toByteArray('wnLeftRightVector;'), toByteArray('wnLeftTeeVector;'), toByteArray('wnLeftVector;'), toByteArray('wnLeftVectorBar;'), toByteArray('wnRightTeeVector;'), toByteArray('wnRightVector;'), toByteArray('wnRightVectorBar;'), toByteArray('wnTee;'), toByteArray('wnTeeArrow;'), toByteArray('wnarrow;'), toByteArray('cr;'), toByteArray('trok;'), toByteArray('G;'), toByteArray('H'), toByteArray('H;'), toByteArray('cute'), toByteArray('cute;'), toByteArray('aron;'), toByteArray('irc'), toByteArray('irc;'), toByteArray('y;'), toByteArray('ot;'), toByteArray('r;'), toByteArray('rave'), toByteArray('rave;'), toByteArray('ement;'), toByteArray('acr;'), toByteArray('ptySmallSquare;'), toByteArray('ptyVerySmallSquare;'), toByteArray('gon;'), toByteArray('pf;'), toByteArray('silon;'), toByteArray('ual;'), toByteArray('ualTilde;'), toByteArray('uilibrium;'), toByteArray('cr;'), toByteArray('im;'), toByteArray('a;'), toByteArray('ml'), toByteArray('ml;'), toByteArray('ists;'), toByteArray('ponentialE;'), toByteArray('y;'), toByteArray('r;'), toByteArray('lledSmallSquare;'), toByteArray('lledVerySmallSquare;'), toByteArray('pf;'), toByteArray('rAll;'), toByteArray('uriertrf;'), toByteArray('cr;'), toByteArray('cy;'), toByteArray(''), toByteArray(';'), toByteArray('mma;'), toByteArray('mmad;'), toByteArray('reve;'), toByteArray('edil;'), toByteArray('irc;'), toByteArray('y;'), toByteArray('ot;'), toByteArray('r;'), toByteArray(';'), toByteArray('pf;'), toByteArray('eaterEqual;'), toByteArray('eaterEqualLess;'), toByteArray('eaterFullEqual;'), toByteArray('eaterGreater;'), toByteArray('eaterLess;'), toByteArray('eaterSlantEqual;'), toByteArray('eaterTilde;'), toByteArray('cr;'), toByteArray(';'), toByteArray('RDcy;'), toByteArray('cek;'), toByteArray('t;'), toByteArray('irc;'), toByteArray('r;'), toByteArray('lbertSpace;'), toByteArray('pf;'), toByteArray('rizontalLine;'), toByteArray('cr;'), toByteArray('trok;'), toByteArray('mpDownHump;'), toByteArray('mpEqual;'), toByteArray('cy;'), toByteArray('lig;'), toByteArray('cy;'), toByteArray('cute'), toByteArray('cute;'), toByteArray('irc'), toByteArray('irc;'), toByteArray('y;'), toByteArray('ot;'), toByteArray('r;'), toByteArray('rave'), toByteArray('rave;'), toByteArray(';'), toByteArray('acr;'), toByteArray('aginaryI;'), toByteArray('plies;'), toByteArray('t;'), toByteArray('tegral;'), toByteArray('tersection;'), toByteArray('visibleComma;'), toByteArray('visibleTimes;'), toByteArray('gon;'), toByteArray('pf;'), toByteArray('ta;'), toByteArray('cr;'), toByteArray('ilde;'), toByteArray('kcy;'), toByteArray('ml'), toByteArray('ml;'), toByteArray('irc;'), toByteArray('y;'), toByteArray('r;'), toByteArray('pf;'), toByteArray('cr;'), toByteArray('ercy;'), toByteArray('kcy;'), toByteArray('cy;'), toByteArray('cy;'), toByteArray('ppa;'), toByteArray('edil;'), toByteArray('y;'), toByteArray('r;'), toByteArray('pf;'), toByteArray('cr;'), toByteArray('cy;'), toByteArray(''), toByteArray(';'), toByteArray('cute;'), toByteArray('mbda;'), toByteArray('ng;'), toByteArray('placetrf;'), toByteArray('rr;'), toByteArray('aron;'), toByteArray('edil;'), toByteArray('y;'), toByteArray('ftAngleBracket;'), toByteArray('ftArrow;'), toByteArray('ftArrowBar;'), toByteArray('ftArrowRightArrow;'), toByteArray('ftCeiling;'), toByteArray('ftDoubleBracket;'), toByteArray('ftDownTeeVector;'), toByteArray('ftDownVector;'), toByteArray('ftDownVectorBar;'), toByteArray('ftFloor;'), toByteArray('ftRightArrow;'), toByteArray('ftRightVector;'), toByteArray('ftTee;'), toByteArray('ftTeeArrow;'), toByteArray('ftTeeVector;'), toByteArray('ftTriangle;'), toByteArray('ftTriangleBar;'), toByteArray('ftTriangleEqual;'), toByteArray('ftUpDownVector;'), toByteArray('ftUpTeeVector;'), toByteArray('ftUpVector;'), toByteArray('ftUpVectorBar;'), toByteArray('ftVector;'), toByteArray('ftVectorBar;'), toByteArray('ftarrow;'), toByteArray('ftrightarrow;'), toByteArray('ssEqualGreater;'), toByteArray('ssFullEqual;'), toByteArray('ssGreater;'), toByteArray('ssLess;'), toByteArray('ssSlantEqual;'), toByteArray('ssTilde;'), toByteArray('r;'), toByteArray(';'), toByteArray('eftarrow;'), toByteArray('idot;'), toByteArray('ngLeftArrow;'), toByteArray('ngLeftRightArrow;'), toByteArray('ngRightArrow;'), toByteArray('ngleftarrow;'), toByteArray('ngleftrightarrow;'), toByteArray('ngrightarrow;'), toByteArray('pf;'), toByteArray('werLeftArrow;'), toByteArray('werRightArrow;'), toByteArray('cr;'), toByteArray('h;'), toByteArray('trok;'), toByteArray(';'), toByteArray('p;'), toByteArray('y;'), toByteArray('diumSpace;'), toByteArray('llintrf;'), toByteArray('r;'), toByteArray('nusPlus;'), toByteArray('pf;'), toByteArray('cr;'), toByteArray(';'), toByteArray('cy;'), toByteArray('cute;'), toByteArray('aron;'), toByteArray('edil;'), toByteArray('y;'), toByteArray('gativeMediumSpace;'), toByteArray('gativeThickSpace;'), toByteArray('gativeThinSpace;'), toByteArray('gativeVeryThinSpace;'), toByteArray('stedGreaterGreater;'), toByteArray('stedLessLess;'), toByteArray('wLine;'), toByteArray('r;'), toByteArray('Break;'), toByteArray('nBreakingSpace;'), toByteArray('pf;'), toByteArray('t;'), toByteArray('tCongruent;'), toByteArray('tCupCap;'), toByteArray('tDoubleVerticalBar;'), toByteArray('tElement;'), toByteArray('tEqual;'), toByteArray('tExists;'), toByteArray('tGreater;'), toByteArray('tGreaterEqual;'), toByteArray('tGreaterLess;'), toByteArray('tGreaterTilde;'), toByteArray('tLeftTriangle;'), toByteArray('tLeftTriangleEqual;'), toByteArray('tLess;'), toByteArray('tLessEqual;'), toByteArray('tLessGreater;'), toByteArray('tLessTilde;'), toByteArray('tPrecedes;'), toByteArray('tPrecedesSlantEqual;'), toByteArray('tReverseElement;'), toByteArray('tRightTriangle;'), toByteArray('tRightTriangleEqual;'), toByteArray('tSquareSubsetEqual;'), toByteArray('tSquareSupersetEqual;'), toByteArray('tSubsetEqual;'), toByteArray('tSucceeds;'), toByteArray('tSucceedsSlantEqual;'), toByteArray('tSupersetEqual;'), toByteArray('tTilde;'), toByteArray('tTildeEqual;'), toByteArray('tTildeFullEqual;'), toByteArray('tTildeTilde;'), toByteArray('tVerticalBar;'), toByteArray('cr;'), toByteArray('ilde'), toByteArray('ilde;'), toByteArray(';'), toByteArray('lig;'), toByteArray('cute'), toByteArray('cute;'), toByteArray('irc'), toByteArray('irc;'), toByteArray('y;'), toByteArray('blac;'), toByteArray('r;'), toByteArray('rave'), toByteArray('rave;'), toByteArray('acr;'), toByteArray('ega;'), toByteArray('icron;'), toByteArray('pf;'), toByteArray('enCurlyDoubleQuote;'), toByteArray('enCurlyQuote;'), toByteArray(';'), toByteArray('cr;'), toByteArray('lash'), toByteArray('lash;'), toByteArray('ilde'), toByteArray('ilde;'), toByteArray('imes;'), toByteArray('ml'), toByteArray('ml;'), toByteArray('erBar;'), toByteArray('erBrace;'), toByteArray('erBracket;'), toByteArray('erParenthesis;'), toByteArray('rtialD;'), toByteArray('y;'), toByteArray('r;'), toByteArray('i;'), toByteArray(';'), toByteArray('usMinus;'), toByteArray('incareplane;'), toByteArray('pf;'), toByteArray(';'), toByteArray('ecedes;'), toByteArray('ecedesEqual;'), toByteArray('ecedesSlantEqual;'), toByteArray('ecedesTilde;'), toByteArray('ime;'), toByteArray('oduct;'), toByteArray('oportion;'), toByteArray('oportional;'), toByteArray('cr;'), toByteArray('i;'), toByteArray('OT'), toByteArray('OT;'), toByteArray('r;'), toByteArray('pf;'), toByteArray('cr;'), toByteArray('arr;'), toByteArray('G'), toByteArray('G;'), toByteArray('cute;'), toByteArray('ng;'), toByteArray('rr;'), toByteArray('rrtl;'), toByteArray('aron;'), toByteArray('edil;'), toByteArray('y;'), toByteArray(';'), toByteArray('verseElement;'), toByteArray('verseEquilibrium;'), toByteArray('verseUpEquilibrium;'), toByteArray('r;'), toByteArray('o;'), toByteArray('ghtAngleBracket;'), toByteArray('ghtArrow;'), toByteArray('ghtArrowBar;'), toByteArray('ghtArrowLeftArrow;'), toByteArray('ghtCeiling;'), toByteArray('ghtDoubleBracket;'), toByteArray('ghtDownTeeVector;'), toByteArray('ghtDownVector;'), toByteArray('ghtDownVectorBar;'), toByteArray('ghtFloor;'), toByteArray('ghtTee;'), toByteArray('ghtTeeArrow;'), toByteArray('ghtTeeVector;'), toByteArray('ghtTriangle;'), toByteArray('ghtTriangleBar;'), toByteArray('ghtTriangleEqual;'), toByteArray('ghtUpDownVector;'), toByteArray('ghtUpTeeVector;'), toByteArray('ghtUpVector;'), toByteArray('ghtUpVectorBar;'), toByteArray('ghtVector;'), toByteArray('ghtVectorBar;'), toByteArray('ghtarrow;'), toByteArray('pf;'), toByteArray('undImplies;'), toByteArray('ightarrow;'), toByteArray('cr;'), toByteArray('h;'), toByteArray('leDelayed;'), toByteArray('CHcy;'), toByteArray('cy;'), toByteArray('FTcy;'), toByteArray('cute;'), toByteArray(';'), toByteArray('aron;'), toByteArray('edil;'), toByteArray('irc;'), toByteArray('y;'), toByteArray('r;'), toByteArray('ortDownArrow;'), toByteArray('ortLeftArrow;'), toByteArray('ortRightArrow;'), toByteArray('ortUpArrow;'), toByteArray('gma;'), toByteArray('allCircle;'), toByteArray('pf;'), toByteArray('rt;'), toByteArray('uare;'), toByteArray('uareIntersection;'), toByteArray('uareSubset;'), toByteArray('uareSubsetEqual;'), toByteArray('uareSuperset;'), toByteArray('uareSupersetEqual;'), toByteArray('uareUnion;'), toByteArray('cr;'), toByteArray('ar;'), toByteArray('b;'), toByteArray('bset;'), toByteArray('bsetEqual;'), toByteArray('cceeds;'), toByteArray('cceedsEqual;'), toByteArray('cceedsSlantEqual;'), toByteArray('cceedsTilde;'), toByteArray('chThat;'), toByteArray('m;'), toByteArray('p;'), toByteArray('perset;'), toByteArray('persetEqual;'), toByteArray('pset;'), toByteArray('ORN'), toByteArray('ORN;'), toByteArray('ADE;'), toByteArray('Hcy;'), toByteArray('cy;'), toByteArray('b;'), toByteArray('u;'), toByteArray('aron;'), toByteArray('edil;'), toByteArray('y;'), toByteArray('r;'), toByteArray('erefore;'), toByteArray('eta;'), toByteArray('inSpace;'), toByteArray('lde;'), toByteArray('ldeEqual;'), toByteArray('ldeFullEqual;'), toByteArray('ldeTilde;'), toByteArray('pf;'), toByteArray('ipleDot;'), toByteArray('cr;'), toByteArray('trok;'), toByteArray('cute'), toByteArray('cute;'), toByteArray('rr;'), toByteArray('rrocir;'), toByteArray('rcy;'), toByteArray('reve;'), toByteArray('irc'), toByteArray('irc;'), toByteArray('y;'), toByteArray('blac;'), toByteArray('r;'), toByteArray('rave'), toByteArray('rave;'), toByteArray('acr;'), toByteArray('derBar;'), toByteArray('derBrace;'), toByteArray('derBracket;'), toByteArray('derParenthesis;'), toByteArray('ion;'), toByteArray('ionPlus;'), toByteArray('gon;'), toByteArray('pf;'), toByteArray('Arrow;'), toByteArray('ArrowBar;'), toByteArray('ArrowDownArrow;'), toByteArray('DownArrow;'), toByteArray('Equilibrium;'), toByteArray('Tee;'), toByteArray('TeeArrow;'), toByteArray('arrow;'), toByteArray('downarrow;'), toByteArray('perLeftArrow;'), toByteArray('perRightArrow;'), toByteArray('si;'), toByteArray('silon;'), toByteArray('ing;'), toByteArray('cr;'), toByteArray('ilde;'), toByteArray('ml'), toByteArray('ml;'), toByteArray('ash;'), toByteArray('ar;'), toByteArray('y;'), toByteArray('ash;'), toByteArray('ashl;'), toByteArray('e;'), toByteArray('rbar;'), toByteArray('rt;'), toByteArray('rticalBar;'), toByteArray('rticalLine;'), toByteArray('rticalSeparator;'), toByteArray('rticalTilde;'), toByteArray('ryThinSpace;'), toByteArray('r;'), toByteArray('pf;'), toByteArray('cr;'), toByteArray('dash;'), toByteArray('irc;'), toByteArray('dge;'), toByteArray('r;'), toByteArray('pf;'), toByteArray('cr;'), toByteArray('r;'), toByteArray(';'), toByteArray('pf;'), toByteArray('cr;'), toByteArray('cy;'), toByteArray('cy;'), toByteArray('cy;'), toByteArray('cute'), toByteArray('cute;'), toByteArray('irc;'), toByteArray('y;'), toByteArray('r;'), toByteArray('pf;'), toByteArray('cr;'), toByteArray('ml;'), toByteArray('cy;'), toByteArray('cute;'), toByteArray('aron;'), toByteArray('y;'), toByteArray('ot;'), toByteArray('roWidthSpace;'), toByteArray('ta;'), toByteArray('r;'), toByteArray('pf;'), toByteArray('cr;'), toByteArray('cute'), toByteArray('cute;'), toByteArray('reve;'), toByteArray(';'), toByteArray('d;'), toByteArray('irc'), toByteArray('irc;'), toByteArray('ute'), toByteArray('ute;'), toByteArray('y;'), toByteArray('lig'), toByteArray('lig;'), toByteArray(';'), toByteArray('r;'), toByteArray('rave'), toByteArray('rave;'), toByteArray('efsym;'), toByteArray('eph;'), toByteArray('pha;'), toByteArray('acr;'), toByteArray('alg;'), toByteArray('p'), toByteArray('p;'), toByteArray('d;'), toByteArray('dand;'), toByteArray('dd;'), toByteArray('dslope;'), toByteArray('dv;'), toByteArray('g;'), toByteArray('ge;'), toByteArray('gle;'), toByteArray('gmsd;'), toByteArray('gmsdaa;'), toByteArray('gmsdab;'), toByteArray('gmsdac;'), toByteArray('gmsdad;'), toByteArray('gmsdae;'), toByteArray('gmsdaf;'), toByteArray('gmsdag;'), toByteArray('gmsdah;'), toByteArray('grt;'), toByteArray('grtvb;'), toByteArray('grtvbd;'), toByteArray('gsph;'), toByteArray('gst;'), toByteArray('gzarr;'), toByteArray('gon;'), toByteArray('pf;'), toByteArray(';'), toByteArray('E;'), toByteArray('acir;'), toByteArray('e;'), toByteArray('id;'), toByteArray('os;'), toByteArray('prox;'), toByteArray('proxeq;'), toByteArray('ing'), toByteArray('ing;'), toByteArray('cr;'), toByteArray('t;'), toByteArray('ymp;'), toByteArray('ympeq;'), toByteArray('ilde'), toByteArray('ilde;'), toByteArray('ml'), toByteArray('ml;'), toByteArray('conint;'), toByteArray('int;'), toByteArray('ot;'), toByteArray('ckcong;'), toByteArray('ckepsilon;'), toByteArray('ckprime;'), toByteArray('cksim;'), toByteArray('cksimeq;'), toByteArray('rvee;'), toByteArray('rwed;'), toByteArray('rwedge;'), toByteArray('rk;'), toByteArray('rktbrk;'), toByteArray('ong;'), toByteArray('y;'), toByteArray('quo;'), toByteArray('caus;'), toByteArray('cause;'), toByteArray('mptyv;'), toByteArray('psi;'), toByteArray('rnou;'), toByteArray('ta;'), toByteArray('th;'), toByteArray('tween;'), toByteArray('r;'), toByteArray('gcap;'), toByteArray('gcirc;'), toByteArray('gcup;'), toByteArray('godot;'), toByteArray('goplus;'), toByteArray('gotimes;'), toByteArray('gsqcup;'), toByteArray('gstar;'), toByteArray('gtriangledown;'), toByteArray('gtriangleup;'), toByteArray('guplus;'), toByteArray('gvee;'), toByteArray('gwedge;'), toByteArray('arow;'), toByteArray('acklozenge;'), toByteArray('acksquare;'), toByteArray('acktriangle;'), toByteArray('acktriangledown;'), toByteArray('acktriangleleft;'), toByteArray('acktriangleright;'), toByteArray('ank;'), toByteArray('k12;'), toByteArray('k14;'), toByteArray('k34;'), toByteArray('ock;'), toByteArray('ot;'), toByteArray('pf;'), toByteArray('t;'), toByteArray('ttom;'), toByteArray('wtie;'), toByteArray('xDL;'), toByteArray('xDR;'), toByteArray('xDl;'), toByteArray('xDr;'), toByteArray('xH;'), toByteArray('xHD;'), toByteArray('xHU;'), toByteArray('xHd;'), toByteArray('xHu;'), toByteArray('xUL;'), toByteArray('xUR;'), toByteArray('xUl;'), toByteArray('xUr;'), toByteArray('xV;'), toByteArray('xVH;'), toByteArray('xVL;'), toByteArray('xVR;'), toByteArray('xVh;'), toByteArray('xVl;'), toByteArray('xVr;'), toByteArray('xbox;'), toByteArray('xdL;'), toByteArray('xdR;'), toByteArray('xdl;'), toByteArray('xdr;'), toByteArray('xh;'), toByteArray('xhD;'), toByteArray('xhU;'), toByteArray('xhd;'), toByteArray('xhu;'), toByteArray('xminus;'), toByteArray('xplus;'), toByteArray('xtimes;'), toByteArray('xuL;'), toByteArray('xuR;'), toByteArray('xul;'), toByteArray('xur;'), toByteArray('xv;'), toByteArray('xvH;'), toByteArray('xvL;'), toByteArray('xvR;'), toByteArray('xvh;'), toByteArray('xvl;'), toByteArray('xvr;'), toByteArray('rime;'), toByteArray('eve;'), toByteArray('vbar'), toByteArray('vbar;'), toByteArray('cr;'), toByteArray('emi;'), toByteArray('im;'), toByteArray('ime;'), toByteArray('ol;'), toByteArray('olb;'), toByteArray('olhsub;'), toByteArray('ll;'), toByteArray('llet;'), toByteArray('mp;'), toByteArray('mpE;'), toByteArray('mpe;'), toByteArray('mpeq;'), toByteArray('cute;'), toByteArray('p;'), toByteArray('pand;'), toByteArray('pbrcup;'), toByteArray('pcap;'), toByteArray('pcup;'), toByteArray('pdot;'), toByteArray('ret;'), toByteArray('ron;'), toByteArray('aps;'), toByteArray('aron;'), toByteArray('edil'), toByteArray('edil;'), toByteArray('irc;'), toByteArray('ups;'), toByteArray('upssm;'), toByteArray('ot;'), toByteArray('dil'), toByteArray('dil;'), toByteArray('mptyv;'), toByteArray('nt'), toByteArray('nt;'), toByteArray('nterdot;'), toByteArray('r;'), toByteArray('cy;'), toByteArray('eck;'), toByteArray('eckmark;'), toByteArray('i;'), toByteArray('r;'), toByteArray('rE;'), toByteArray('rc;'), toByteArray('rceq;'), toByteArray('rclearrowleft;'), toByteArray('rclearrowright;'), toByteArray('rcledR;'), toByteArray('rcledS;'), toByteArray('rcledast;'), toByteArray('rcledcirc;'), toByteArray('rcleddash;'), toByteArray('re;'), toByteArray('rfnint;'), toByteArray('rmid;'), toByteArray('rscir;'), toByteArray('ubs;'), toByteArray('ubsuit;'), toByteArray('lon;'), toByteArray('lone;'), toByteArray('loneq;'), toByteArray('mma;'), toByteArray('mmat;'), toByteArray('mp;'), toByteArray('mpfn;'), toByteArray('mplement;'), toByteArray('mplexes;'), toByteArray('ng;'), toByteArray('ngdot;'), toByteArray('nint;'), toByteArray('pf;'), toByteArray('prod;'), toByteArray('py'), toByteArray('py;'), toByteArray('pysr;'), toByteArray('arr;'), toByteArray('oss;'), toByteArray('cr;'), toByteArray('ub;'), toByteArray('ube;'), toByteArray('up;'), toByteArray('upe;'), toByteArray('dot;'), toByteArray('darrl;'), toByteArray('darrr;'), toByteArray('epr;'), toByteArray('esc;'), toByteArray('larr;'), toByteArray('larrp;'), toByteArray('p;'), toByteArray('pbrcap;'), toByteArray('pcap;'), toByteArray('pcup;'), toByteArray('pdot;'), toByteArray('por;'), toByteArray('rarr;'), toByteArray('rarrm;'), toByteArray('rlyeqprec;'), toByteArray('rlyeqsucc;'), toByteArray('rlyvee;'), toByteArray('rlywedge;'), toByteArray('rren'), toByteArray('rren;'), toByteArray('rvearrowleft;'), toByteArray('rvearrowright;'), toByteArray('vee;'), toByteArray('wed;'), toByteArray('conint;'), toByteArray('int;'), toByteArray('lcty;'), toByteArray('rr;'), toByteArray('ar;'), toByteArray('gger;'), toByteArray('leth;'), toByteArray('rr;'), toByteArray('sh;'), toByteArray('shv;'), toByteArray('karow;'), toByteArray('lac;'), toByteArray('aron;'), toByteArray('y;'), toByteArray(';'), toByteArray('agger;'), toByteArray('arr;'), toByteArray('otseq;'), toByteArray('g'), toByteArray('g;'), toByteArray('lta;'), toByteArray('mptyv;'), toByteArray('isht;'), toByteArray('r;'), toByteArray('arl;'), toByteArray('arr;'), toByteArray('am;'), toByteArray('amond;'), toByteArray('amondsuit;'), toByteArray('ams;'), toByteArray('e;'), toByteArray('gamma;'), toByteArray('sin;'), toByteArray('v;'), toByteArray('vide'), toByteArray('vide;'), toByteArray('videontimes;'), toByteArray('vonx;'), toByteArray('cy;'), toByteArray('corn;'), toByteArray('crop;'), toByteArray('llar;'), toByteArray('pf;'), toByteArray('t;'), toByteArray('teq;'), toByteArray('teqdot;'), toByteArray('tminus;'), toByteArray('tplus;'), toByteArray('tsquare;'), toByteArray('ublebarwedge;'), toByteArray('wnarrow;'), toByteArray('wndownarrows;'), toByteArray('wnharpoonleft;'), toByteArray('wnharpoonright;'), toByteArray('bkarow;'), toByteArray('corn;'), toByteArray('crop;'), toByteArray('cr;'), toByteArray('cy;'), toByteArray('ol;'), toByteArray('trok;'), toByteArray('dot;'), toByteArray('ri;'), toByteArray('rif;'), toByteArray('arr;'), toByteArray('har;'), toByteArray('angle;'), toByteArray('cy;'), toByteArray('igrarr;'), toByteArray('Dot;'), toByteArray('ot;'), toByteArray('cute'), toByteArray('cute;'), toByteArray('ster;'), toByteArray('aron;'), toByteArray('ir;'), toByteArray('irc'), toByteArray('irc;'), toByteArray('olon;'), toByteArray('y;'), toByteArray('ot;'), toByteArray(';'), toByteArray('Dot;'), toByteArray('r;'), toByteArray(';'), toByteArray('rave'), toByteArray('rave;'), toByteArray('s;'), toByteArray('sdot;'), toByteArray(';'), toByteArray('inters;'), toByteArray('l;'), toByteArray('s;'), toByteArray('sdot;'), toByteArray('acr;'), toByteArray('pty;'), toByteArray('ptyset;'), toByteArray('ptyv;'), toByteArray('sp13;'), toByteArray('sp14;'), toByteArray('sp;'), toByteArray('g;'), toByteArray('sp;'), toByteArray('gon;'), toByteArray('pf;'), toByteArray('ar;'), toByteArray('arsl;'), toByteArray('lus;'), toByteArray('si;'), toByteArray('silon;'), toByteArray('siv;'), toByteArray('circ;'), toByteArray('colon;'), toByteArray('sim;'), toByteArray('slantgtr;'), toByteArray('slantless;'), toByteArray('uals;'), toByteArray('uest;'), toByteArray('uiv;'), toByteArray('uivDD;'), toByteArray('vparsl;'), toByteArray('Dot;'), toByteArray('arr;'), toByteArray('cr;'), toByteArray('dot;'), toByteArray('im;'), toByteArray('a;'), toByteArray('h'), toByteArray('h;'), toByteArray('ml'), toByteArray('ml;'), toByteArray('ro;'), toByteArray('cl;'), toByteArray('ist;'), toByteArray('pectation;'), toByteArray('ponentiale;'), toByteArray('llingdotseq;'), toByteArray('y;'), toByteArray('male;'), toByteArray('ilig;'), toByteArray('lig;'), toByteArray('llig;'), toByteArray('r;'), toByteArray('lig;'), toByteArray('at;'), toByteArray('lig;'), toByteArray('tns;'), toByteArray('of;'), toByteArray('pf;'), toByteArray('rall;'), toByteArray('rk;'), toByteArray('rkv;'), toByteArray('artint;'), toByteArray('ac12'), toByteArray('ac12;'), toByteArray('ac13;'), toByteArray('ac14'), toByteArray('ac14;'), toByteArray('ac15;'), toByteArray('ac16;'), toByteArray('ac18;'), toByteArray('ac23;'), toByteArray('ac25;'), toByteArray('ac34'), toByteArray('ac34;'), toByteArray('ac35;'), toByteArray('ac38;'), toByteArray('ac45;'), toByteArray('ac56;'), toByteArray('ac58;'), toByteArray('ac78;'), toByteArray('asl;'), toByteArray('own;'), toByteArray('cr;'), toByteArray(';'), toByteArray('l;'), toByteArray('cute;'), toByteArray('mma;'), toByteArray('mmad;'), toByteArray('p;'), toByteArray('reve;'), toByteArray('irc;'), toByteArray('y;'), toByteArray('ot;'), toByteArray(';'), toByteArray('l;'), toByteArray('q;'), toByteArray('qq;'), toByteArray('qslant;'), toByteArray('s;'), toByteArray('scc;'), toByteArray('sdot;'), toByteArray('sdoto;'), toByteArray('sdotol;'), toByteArray('sles;'), toByteArray('r;'), toByteArray(';'), toByteArray('g;'), toByteArray('mel;'), toByteArray('cy;'), toByteArray(';'), toByteArray('E;'), toByteArray('a;'), toByteArray('j;'), toByteArray('E;'), toByteArray('ap;'), toByteArray('approx;'), toByteArray('e;'), toByteArray('eq;'), toByteArray('eqq;'), toByteArray('sim;'), toByteArray('pf;'), toByteArray('ave;'), toByteArray('cr;'), toByteArray('im;'), toByteArray('ime;'), toByteArray('iml;'), toByteArray(''), toByteArray(';'), toByteArray('cc;'), toByteArray('cir;'), toByteArray('dot;'), toByteArray('lPar;'), toByteArray('quest;'), toByteArray('rapprox;'), toByteArray('rarr;'), toByteArray('rdot;'), toByteArray('reqless;'), toByteArray('reqqless;'), toByteArray('rless;'), toByteArray('rsim;'), toByteArray('rr;'), toByteArray('irsp;'), toByteArray('lf;'), toByteArray('milt;'), toByteArray('rdcy;'), toByteArray('rr;'), toByteArray('rrcir;'), toByteArray('rrw;'), toByteArray('ar;'), toByteArray('irc;'), toByteArray('arts;'), toByteArray('artsuit;'), toByteArray('llip;'), toByteArray('rcon;'), toByteArray('r;'), toByteArray('searow;'), toByteArray('swarow;'), toByteArray('arr;'), toByteArray('mtht;'), toByteArray('okleftarrow;'), toByteArray('okrightarrow;'), toByteArray('pf;'), toByteArray('rbar;'), toByteArray('cr;'), toByteArray('lash;'), toByteArray('trok;'), toByteArray('bull;'), toByteArray('phen;'), toByteArray('cute'), toByteArray('cute;'), toByteArray(';'), toByteArray('irc'), toByteArray('irc;'), toByteArray('y;'), toByteArray('cy;'), toByteArray('xcl'), toByteArray('xcl;'), toByteArray('f;'), toByteArray('r;'), toByteArray('rave'), toByteArray('rave;'), toByteArray(';'), toByteArray('iint;'), toByteArray('int;'), toByteArray('nfin;'), toByteArray('ota;'), toByteArray('lig;'), toByteArray('acr;'), toByteArray('age;'), toByteArray('agline;'), toByteArray('agpart;'), toByteArray('ath;'), toByteArray('of;'), toByteArray('ped;'), toByteArray(';'), toByteArray('care;'), toByteArray('fin;'), toByteArray('fintie;'), toByteArray('odot;'), toByteArray('t;'), toByteArray('tcal;'), toByteArray('tegers;'), toByteArray('tercal;'), toByteArray('tlarhk;'), toByteArray('tprod;'), toByteArray('cy;'), toByteArray('gon;'), toByteArray('pf;'), toByteArray('ta;'), toByteArray('rod;'), toByteArray('uest'), toByteArray('uest;'), toByteArray('cr;'), toByteArray('in;'), toByteArray('inE;'), toByteArray('indot;'), toByteArray('ins;'), toByteArray('insv;'), toByteArray('inv;'), toByteArray(';'), toByteArray('ilde;'), toByteArray('kcy;'), toByteArray('ml'), toByteArray('ml;'), toByteArray('irc;'), toByteArray('y;'), toByteArray('r;'), toByteArray('ath;'), toByteArray('pf;'), toByteArray('cr;'), toByteArray('ercy;'), toByteArray('kcy;'), toByteArray('ppa;'), toByteArray('ppav;'), toByteArray('edil;'), toByteArray('y;'), toByteArray('r;'), toByteArray('reen;'), toByteArray('cy;'), toByteArray('cy;'), toByteArray('pf;'), toByteArray('cr;'), toByteArray('arr;'), toByteArray('rr;'), toByteArray('tail;'), toByteArray('arr;'), toByteArray(';'), toByteArray('g;'), toByteArray('ar;'), toByteArray('cute;'), toByteArray('emptyv;'), toByteArray('gran;'), toByteArray('mbda;'), toByteArray('ng;'), toByteArray('ngd;'), toByteArray('ngle;'), toByteArray('p;'), toByteArray('quo'), toByteArray('quo;'), toByteArray('rr;'), toByteArray('rrb;'), toByteArray('rrbfs;'), toByteArray('rrfs;'), toByteArray('rrhk;'), toByteArray('rrlp;'), toByteArray('rrpl;'), toByteArray('rrsim;'), toByteArray('rrtl;'), toByteArray('t;'), toByteArray('tail;'), toByteArray('te;'), toByteArray('arr;'), toByteArray('brk;'), toByteArray('race;'), toByteArray('rack;'), toByteArray('rke;'), toByteArray('rksld;'), toByteArray('rkslu;'), toByteArray('aron;'), toByteArray('edil;'), toByteArray('eil;'), toByteArray('ub;'), toByteArray('y;'), toByteArray('ca;'), toByteArray('quo;'), toByteArray('quor;'), toByteArray('rdhar;'), toByteArray('rushar;'), toByteArray('sh;'), toByteArray(';'), toByteArray('ftarrow;'), toByteArray('ftarrowtail;'), toByteArray('ftharpoondown;'), toByteArray('ftharpoonup;'), toByteArray('ftleftarrows;'), toByteArray('ftrightarrow;'), toByteArray('ftrightarrows;'), toByteArray('ftrightharpoons;'), toByteArray('ftrightsquigarrow;'), toByteArray('ftthreetimes;'), toByteArray('g;'), toByteArray('q;'), toByteArray('qq;'), toByteArray('qslant;'), toByteArray('s;'), toByteArray('scc;'), toByteArray('sdot;'), toByteArray('sdoto;'), toByteArray('sdotor;'), toByteArray('sges;'), toByteArray('ssapprox;'), toByteArray('ssdot;'), toByteArray('sseqgtr;'), toByteArray('sseqqgtr;'), toByteArray('ssgtr;'), toByteArray('sssim;'), toByteArray('isht;'), toByteArray('loor;'), toByteArray('r;'), toByteArray(';'), toByteArray('E;'), toByteArray('ard;'), toByteArray('aru;'), toByteArray('arul;'), toByteArray('blk;'), toByteArray('cy;'), toByteArray(';'), toByteArray('arr;'), toByteArray('corner;'), toByteArray('hard;'), toByteArray('tri;'), toByteArray('idot;'), toByteArray('oust;'), toByteArray('oustache;'), toByteArray('E;'), toByteArray('ap;'), toByteArray('approx;'), toByteArray('e;'), toByteArray('eq;'), toByteArray('eqq;'), toByteArray('sim;'), toByteArray('ang;'), toByteArray('arr;'), toByteArray('brk;'), toByteArray('ngleftarrow;'), toByteArray('ngleftrightarrow;'), toByteArray('ngmapsto;'), toByteArray('ngrightarrow;'), toByteArray('oparrowleft;'), toByteArray('oparrowright;'), toByteArray('par;'), toByteArray('pf;'), toByteArray('plus;'), toByteArray('times;'), toByteArray('wast;'), toByteArray('wbar;'), toByteArray('z;'), toByteArray('zenge;'), toByteArray('zf;'), toByteArray('ar;'), toByteArray('arlt;'), toByteArray('arr;'), toByteArray('corner;'), toByteArray('har;'), toByteArray('hard;'), toByteArray('m;'), toByteArray('tri;'), toByteArray('aquo;'), toByteArray('cr;'), toByteArray('h;'), toByteArray('im;'), toByteArray('ime;'), toByteArray('img;'), toByteArray('qb;'), toByteArray('quo;'), toByteArray('quor;'), toByteArray('trok;'), toByteArray(''), toByteArray(';'), toByteArray('cc;'), toByteArray('cir;'), toByteArray('dot;'), toByteArray('hree;'), toByteArray('imes;'), toByteArray('larr;'), toByteArray('quest;'), toByteArray('rPar;'), toByteArray('ri;'), toByteArray('rie;'), toByteArray('rif;'), toByteArray('rdshar;'), toByteArray('ruhar;'), toByteArray('Dot;'), toByteArray('cr'), toByteArray('cr;'), toByteArray('le;'), toByteArray('lt;'), toByteArray('ltese;'), toByteArray('p;'), toByteArray('psto;'), toByteArray('pstodown;'), toByteArray('pstoleft;'), toByteArray('pstoup;'), toByteArray('rker;'), toByteArray('omma;'), toByteArray('y;'), toByteArray('ash;'), toByteArray('asuredangle;'), toByteArray('r;'), toByteArray('o;'), toByteArray('cro'), toByteArray('cro;'), toByteArray('d;'), toByteArray('dast;'), toByteArray('dcir;'), toByteArray('ddot'), toByteArray('ddot;'), toByteArray('nus;'), toByteArray('nusb;'), toByteArray('nusd;'), toByteArray('nusdu;'), toByteArray('cp;'), toByteArray('dr;'), toByteArray('plus;'), toByteArray('dels;'), toByteArray('pf;'), toByteArray(';'), toByteArray('cr;'), toByteArray('tpos;'), toByteArray(';'), toByteArray('ltimap;'), toByteArray('map;'), toByteArray('eftarrow;'), toByteArray('eftrightarrow;'), toByteArray('ightarrow;'), toByteArray('Dash;'), toByteArray('dash;'), toByteArray('bla;'), toByteArray('cute;'), toByteArray('p;'), toByteArray('pos;'), toByteArray('pprox;'), toByteArray('tur;'), toByteArray('tural;'), toByteArray('turals;'), toByteArray('sp'), toByteArray('sp;'), toByteArray('ap;'), toByteArray('aron;'), toByteArray('edil;'), toByteArray('ong;'), toByteArray('up;'), toByteArray('y;'), toByteArray('ash;'), toByteArray(';'), toByteArray('Arr;'), toByteArray('arhk;'), toByteArray('arr;'), toByteArray('arrow;'), toByteArray('quiv;'), toByteArray('sear;'), toByteArray('xist;'), toByteArray('xists;'), toByteArray('r;'), toByteArray('e;'), toByteArray('eq;'), toByteArray('sim;'), toByteArray('t;'), toByteArray('tr;'), toByteArray('Arr;'), toByteArray('arr;'), toByteArray('par;'), toByteArray(';'), toByteArray('s;'), toByteArray('sd;'), toByteArray('v;'), toByteArray('cy;'), toByteArray('Arr;'), toByteArray('arr;'), toByteArray('dr;'), toByteArray('e;'), toByteArray('eftarrow;'), toByteArray('eftrightarrow;'), toByteArray('eq;'), toByteArray('ess;'), toByteArray('sim;'), toByteArray('t;'), toByteArray('tri;'), toByteArray('trie;'), toByteArray('id;'), toByteArray('pf;'), toByteArray('t'), toByteArray('t;'), toByteArray('tin;'), toByteArray('tinva;'), toByteArray('tinvb;'), toByteArray('tinvc;'), toByteArray('tni;'), toByteArray('tniva;'), toByteArray('tnivb;'), toByteArray('tnivc;'), toByteArray('ar;'), toByteArray('arallel;'), toByteArray('olint;'), toByteArray('r;'), toByteArray('rcue;'), toByteArray('rec;'), toByteArray('Arr;'), toByteArray('arr;'), toByteArray('ightarrow;'), toByteArray('tri;'), toByteArray('trie;'), toByteArray('c;'), toByteArray('ccue;'), toByteArray('cr;'), toByteArray('hortmid;'), toByteArray('hortparallel;'), toByteArray('im;'), toByteArray('ime;'), toByteArray('imeq;'), toByteArray('mid;'), toByteArray('par;'), toByteArray('qsube;'), toByteArray('qsupe;'), toByteArray('ub;'), toByteArray('ube;'), toByteArray('ubseteq;'), toByteArray('ucc;'), toByteArray('up;'), toByteArray('upe;'), toByteArray('upseteq;'), toByteArray('gl;'), toByteArray('ilde'), toByteArray('ilde;'), toByteArray('lg;'), toByteArray('riangleleft;'), toByteArray('rianglelefteq;'), toByteArray('riangleright;'), toByteArray('rianglerighteq;'), toByteArray(';'), toByteArray('m;'), toByteArray('mero;'), toByteArray('msp;'), toByteArray('Dash;'), toByteArray('Harr;'), toByteArray('dash;'), toByteArray('infin;'), toByteArray('lArr;'), toByteArray('rArr;'), toByteArray('Arr;'), toByteArray('arhk;'), toByteArray('arr;'), toByteArray('arrow;'), toByteArray('near;'), toByteArray(';'), toByteArray('cute'), toByteArray('cute;'), toByteArray('st;'), toByteArray('ir;'), toByteArray('irc'), toByteArray('irc;'), toByteArray('y;'), toByteArray('ash;'), toByteArray('blac;'), toByteArray('iv;'), toByteArray('ot;'), toByteArray('sold;'), toByteArray('lig;'), toByteArray('cir;'), toByteArray('r;'), toByteArray('on;'), toByteArray('rave'), toByteArray('rave;'), toByteArray('t;'), toByteArray('bar;'), toByteArray('m;'), toByteArray('nt;'), toByteArray('arr;'), toByteArray('cir;'), toByteArray('cross;'), toByteArray('ine;'), toByteArray('t;'), toByteArray('acr;'), toByteArray('ega;'), toByteArray('icron;'), toByteArray('id;'), toByteArray('inus;'), toByteArray('pf;'), toByteArray('ar;'), toByteArray('erp;'), toByteArray('lus;'), toByteArray(';'), toByteArray('arr;'), toByteArray('d;'), toByteArray('der;'), toByteArray('derof;'), toByteArray('df'), toByteArray('df;'), toByteArray('dm'), toByteArray('dm;'), toByteArray('igof;'), toByteArray('or;'), toByteArray('slope;'), toByteArray('v;'), toByteArray('cr;'), toByteArray('lash'), toByteArray('lash;'), toByteArray('ol;'), toByteArray('ilde'), toByteArray('ilde;'), toByteArray('imes;'), toByteArray('imesas;'), toByteArray('ml'), toByteArray('ml;'), toByteArray('bar;'), toByteArray('r;'), toByteArray('ra'), toByteArray('ra;'), toByteArray('rallel;'), toByteArray('rsim;'), toByteArray('rsl;'), toByteArray('rt;'), toByteArray('y;'), toByteArray('rcnt;'), toByteArray('riod;'), toByteArray('rmil;'), toByteArray('rp;'), toByteArray('rtenk;'), toByteArray('r;'), toByteArray('i;'), toByteArray('iv;'), toByteArray('mmat;'), toByteArray('one;'), toByteArray(';'), toByteArray('tchfork;'), toByteArray('v;'), toByteArray('anck;'), toByteArray('anckh;'), toByteArray('ankv;'), toByteArray('us;'), toByteArray('usacir;'), toByteArray('usb;'), toByteArray('uscir;'), toByteArray('usdo;'), toByteArray('usdu;'), toByteArray('use;'), toByteArray('usmn'), toByteArray('usmn;'), toByteArray('ussim;'), toByteArray('ustwo;'), toByteArray(';'), toByteArray('intint;'), toByteArray('pf;'), toByteArray('und'), toByteArray('und;'), toByteArray(';'), toByteArray('E;'), toByteArray('ap;'), toByteArray('cue;'), toByteArray('e;'), toByteArray('ec;'), toByteArray('ecapprox;'), toByteArray('eccurlyeq;'), toByteArray('eceq;'), toByteArray('ecnapprox;'), toByteArray('ecneqq;'), toByteArray('ecnsim;'), toByteArray('ecsim;'), toByteArray('ime;'), toByteArray('imes;'), toByteArray('nE;'), toByteArray('nap;'), toByteArray('nsim;'), toByteArray('od;'), toByteArray('ofalar;'), toByteArray('ofline;'), toByteArray('ofsurf;'), toByteArray('op;'), toByteArray('opto;'), toByteArray('sim;'), toByteArray('urel;'), toByteArray('cr;'), toByteArray('i;'), toByteArray('ncsp;'), toByteArray('r;'), toByteArray('nt;'), toByteArray('pf;'), toByteArray('rime;'), toByteArray('cr;'), toByteArray('aternions;'), toByteArray('atint;'), toByteArray('est;'), toByteArray('esteq;'), toByteArray('ot'), toByteArray('ot;'), toByteArray('arr;'), toByteArray('rr;'), toByteArray('tail;'), toByteArray('arr;'), toByteArray('ar;'), toByteArray('cute;'), toByteArray('dic;'), toByteArray('emptyv;'), toByteArray('ng;'), toByteArray('ngd;'), toByteArray('nge;'), toByteArray('ngle;'), toByteArray('quo'), toByteArray('quo;'), toByteArray('rr;'), toByteArray('rrap;'), toByteArray('rrb;'), toByteArray('rrbfs;'), toByteArray('rrc;'), toByteArray('rrfs;'), toByteArray('rrhk;'), toByteArray('rrlp;'), toByteArray('rrpl;'), toByteArray('rrsim;'), toByteArray('rrtl;'), toByteArray('rrw;'), toByteArray('tail;'), toByteArray('tio;'), toByteArray('tionals;'), toByteArray('arr;'), toByteArray('brk;'), toByteArray('race;'), toByteArray('rack;'), toByteArray('rke;'), toByteArray('rksld;'), toByteArray('rkslu;'), toByteArray('aron;'), toByteArray('edil;'), toByteArray('eil;'), toByteArray('ub;'), toByteArray('y;'), toByteArray('ca;'), toByteArray('ldhar;'), toByteArray('quo;'), toByteArray('quor;'), toByteArray('sh;'), toByteArray('al;'), toByteArray('aline;'), toByteArray('alpart;'), toByteArray('als;'), toByteArray('ct;'), toByteArray('g'), toByteArray('g;'), toByteArray('isht;'), toByteArray('loor;'), toByteArray('r;'), toByteArray('ard;'), toByteArray('aru;'), toByteArray('arul;'), toByteArray('o;'), toByteArray('ov;'), toByteArray('ghtarrow;'), toByteArray('ghtarrowtail;'), toByteArray('ghtharpoondown;'), toByteArray('ghtharpoonup;'), toByteArray('ghtleftarrows;'), toByteArray('ghtleftharpoons;'), toByteArray('ghtrightarrows;'), toByteArray('ghtsquigarrow;'), toByteArray('ghtthreetimes;'), toByteArray('ng;'), toByteArray('singdotseq;'), toByteArray('arr;'), toByteArray('har;'), toByteArray('m;'), toByteArray('oust;'), toByteArray('oustache;'), toByteArray('mid;'), toByteArray('ang;'), toByteArray('arr;'), toByteArray('brk;'), toByteArray('par;'), toByteArray('pf;'), toByteArray('plus;'), toByteArray('times;'), toByteArray('ar;'), toByteArray('argt;'), toByteArray('polint;'), toByteArray('arr;'), toByteArray('aquo;'), toByteArray('cr;'), toByteArray('h;'), toByteArray('qb;'), toByteArray('quo;'), toByteArray('quor;'), toByteArray('hree;'), toByteArray('imes;'), toByteArray('ri;'), toByteArray('rie;'), toByteArray('rif;'), toByteArray('riltri;'), toByteArray('luhar;'), toByteArray(';'), toByteArray('cute;'), toByteArray('quo;'), toByteArray(';'), toByteArray('E;'), toByteArray('ap;'), toByteArray('aron;'), toByteArray('cue;'), toByteArray('e;'), toByteArray('edil;'), toByteArray('irc;'), toByteArray('nE;'), toByteArray('nap;'), toByteArray('nsim;'), toByteArray('polint;'), toByteArray('sim;'), toByteArray('y;'), toByteArray('ot;'), toByteArray('otb;'), toByteArray('ote;'), toByteArray('Arr;'), toByteArray('arhk;'), toByteArray('arr;'), toByteArray('arrow;'), toByteArray('ct'), toByteArray('ct;'), toByteArray('mi;'), toByteArray('swar;'), toByteArray('tminus;'), toByteArray('tmn;'), toByteArray('xt;'), toByteArray('r;'), toByteArray('rown;'), toByteArray('arp;'), toByteArray('chcy;'), toByteArray('cy;'), toByteArray('ortmid;'), toByteArray('ortparallel;'), toByteArray('y'), toByteArray('y;'), toByteArray('gma;'), toByteArray('gmaf;'), toByteArray('gmav;'), toByteArray('m;'), toByteArray('mdot;'), toByteArray('me;'), toByteArray('meq;'), toByteArray('mg;'), toByteArray('mgE;'), toByteArray('ml;'), toByteArray('mlE;'), toByteArray('mne;'), toByteArray('mplus;'), toByteArray('mrarr;'), toByteArray('arr;'), toByteArray('allsetminus;'), toByteArray('ashp;'), toByteArray('eparsl;'), toByteArray('id;'), toByteArray('ile;'), toByteArray('t;'), toByteArray('te;'), toByteArray('ftcy;'), toByteArray('l;'), toByteArray('lb;'), toByteArray('lbar;'), toByteArray('pf;'), toByteArray('ades;'), toByteArray('adesuit;'), toByteArray('ar;'), toByteArray('cap;'), toByteArray('cup;'), toByteArray('sub;'), toByteArray('sube;'), toByteArray('subset;'), toByteArray('subseteq;'), toByteArray('sup;'), toByteArray('supe;'), toByteArray('supset;'), toByteArray('supseteq;'), toByteArray('u;'), toByteArray('uare;'), toByteArray('uarf;'), toByteArray('uf;'), toByteArray('arr;'), toByteArray('cr;'), toByteArray('etmn;'), toByteArray('mile;'), toByteArray('tarf;'), toByteArray('ar;'), toByteArray('arf;'), toByteArray('raightepsilon;'), toByteArray('raightphi;'), toByteArray('rns;'), toByteArray('b;'), toByteArray('bE;'), toByteArray('bdot;'), toByteArray('be;'), toByteArray('bedot;'), toByteArray('bmult;'), toByteArray('bnE;'), toByteArray('bne;'), toByteArray('bplus;'), toByteArray('brarr;'), toByteArray('bset;'), toByteArray('bseteq;'), toByteArray('bseteqq;'), toByteArray('bsetneq;'), toByteArray('bsetneqq;'), toByteArray('bsim;'), toByteArray('bsub;'), toByteArray('bsup;'), toByteArray('cc;'), toByteArray('ccapprox;'), toByteArray('cccurlyeq;'), toByteArray('cceq;'), toByteArray('ccnapprox;'), toByteArray('ccneqq;'), toByteArray('ccnsim;'), toByteArray('ccsim;'), toByteArray('m;'), toByteArray('ng;'), toByteArray('p1'), toByteArray('p1;'), toByteArray('p2'), toByteArray('p2;'), toByteArray('p3'), toByteArray('p3;'), toByteArray('p;'), toByteArray('pE;'), toByteArray('pdot;'), toByteArray('pdsub;'), toByteArray('pe;'), toByteArray('pedot;'), toByteArray('phsol;'), toByteArray('phsub;'), toByteArray('plarr;'), toByteArray('pmult;'), toByteArray('pnE;'), toByteArray('pne;'), toByteArray('pplus;'), toByteArray('pset;'), toByteArray('pseteq;'), toByteArray('pseteqq;'), toByteArray('psetneq;'), toByteArray('psetneqq;'), toByteArray('psim;'), toByteArray('psub;'), toByteArray('psup;'), toByteArray('Arr;'), toByteArray('arhk;'), toByteArray('arr;'), toByteArray('arrow;'), toByteArray('nwar;'), toByteArray('lig'), toByteArray('lig;'), toByteArray('rget;'), toByteArray('u;'), toByteArray('rk;'), toByteArray('aron;'), toByteArray('edil;'), toByteArray('y;'), toByteArray('ot;'), toByteArray('lrec;'), toByteArray('r;'), toByteArray('ere4;'), toByteArray('erefore;'), toByteArray('eta;'), toByteArray('etasym;'), toByteArray('etav;'), toByteArray('ickapprox;'), toByteArray('icksim;'), toByteArray('insp;'), toByteArray('kap;'), toByteArray('ksim;'), toByteArray('orn'), toByteArray('orn;'), toByteArray('lde;'), toByteArray('mes'), toByteArray('mes;'), toByteArray('mesb;'), toByteArray('mesbar;'), toByteArray('mesd;'), toByteArray('nt;'), toByteArray('ea;'), toByteArray('p;'), toByteArray('pbot;'), toByteArray('pcir;'), toByteArray('pf;'), toByteArray('pfork;'), toByteArray('sa;'), toByteArray('rime;'), toByteArray('ade;'), toByteArray('iangle;'), toByteArray('iangledown;'), toByteArray('iangleleft;'), toByteArray('ianglelefteq;'), toByteArray('iangleq;'), toByteArray('iangleright;'), toByteArray('ianglerighteq;'), toByteArray('idot;'), toByteArray('ie;'), toByteArray('iminus;'), toByteArray('iplus;'), toByteArray('isb;'), toByteArray('itime;'), toByteArray('pezium;'), toByteArray('cr;'), toByteArray('cy;'), toByteArray('hcy;'), toByteArray('trok;'), toByteArray('ixt;'), toByteArray('oheadleftarrow;'), toByteArray('oheadrightarrow;'), toByteArray('rr;'), toByteArray('ar;'), toByteArray('cute'), toByteArray('cute;'), toByteArray('rr;'), toByteArray('rcy;'), toByteArray('reve;'), toByteArray('irc'), toByteArray('irc;'), toByteArray('y;'), toByteArray('arr;'), toByteArray('blac;'), toByteArray('har;'), toByteArray('isht;'), toByteArray('r;'), toByteArray('rave'), toByteArray('rave;'), toByteArray('arl;'), toByteArray('arr;'), toByteArray('blk;'), toByteArray('corn;'), toByteArray('corner;'), toByteArray('crop;'), toByteArray('tri;'), toByteArray('acr;'), toByteArray('l'), toByteArray('l;'), toByteArray('gon;'), toByteArray('pf;'), toByteArray('arrow;'), toByteArray('downarrow;'), toByteArray('harpoonleft;'), toByteArray('harpoonright;'), toByteArray('lus;'), toByteArray('si;'), toByteArray('sih;'), toByteArray('silon;'), toByteArray('uparrows;'), toByteArray('corn;'), toByteArray('corner;'), toByteArray('crop;'), toByteArray('ing;'), toByteArray('tri;'), toByteArray('cr;'), toByteArray('dot;'), toByteArray('ilde;'), toByteArray('ri;'), toByteArray('rif;'), toByteArray('arr;'), toByteArray('ml'), toByteArray('ml;'), toByteArray('angle;'), toByteArray('rr;'), toByteArray('ar;'), toByteArray('arv;'), toByteArray('ash;'), toByteArray('ngrt;'), toByteArray('repsilon;'), toByteArray('rkappa;'), toByteArray('rnothing;'), toByteArray('rphi;'), toByteArray('rpi;'), toByteArray('rpropto;'), toByteArray('rr;'), toByteArray('rrho;'), toByteArray('rsigma;'), toByteArray('rtheta;'), toByteArray('rtriangleleft;'), toByteArray('rtriangleright;'), toByteArray('y;'), toByteArray('ash;'), toByteArray('e;'), toByteArray('ebar;'), toByteArray('eeq;'), toByteArray('llip;'), toByteArray('rbar;'), toByteArray('rt;'), toByteArray('r;'), toByteArray('tri;'), toByteArray('pf;'), toByteArray('rop;'), toByteArray('tri;'), toByteArray('cr;'), toByteArray('igzag;'), toByteArray('irc;'), toByteArray('dbar;'), toByteArray('dge;'), toByteArray('dgeq;'), toByteArray('ierp;'), toByteArray('r;'), toByteArray('pf;'), toByteArray(';'), toByteArray(';'), toByteArray('eath;'), toByteArray('cr;'), toByteArray('ap;'), toByteArray('irc;'), toByteArray('up;'), toByteArray('tri;'), toByteArray('r;'), toByteArray('Arr;'), toByteArray('arr;'), toByteArray(';'), toByteArray('Arr;'), toByteArray('arr;'), toByteArray('ap;'), toByteArray('is;'), toByteArray('dot;'), toByteArray('pf;'), toByteArray('plus;'), toByteArray('time;'), toByteArray('Arr;'), toByteArray('arr;'), toByteArray('cr;'), toByteArray('qcup;'), toByteArray('plus;'), toByteArray('tri;'), toByteArray('ee;'), toByteArray('edge;'), toByteArray('cute'), toByteArray('cute;'), toByteArray('cy;'), toByteArray('irc;'), toByteArray('y;'), toByteArray('n'), toByteArray('n;'), toByteArray('r;'), toByteArray('cy;'), toByteArray('pf;'), toByteArray('cr;'), toByteArray('cy;'), toByteArray('ml'), toByteArray('ml;'), toByteArray('cute;'), toByteArray('aron;'), toByteArray('y;'), toByteArray('ot;'), toByteArray('etrf;'), toByteArray('ta;'), toByteArray('r;'), toByteArray('cy;'), toByteArray('grarr;'), toByteArray('pf;'), toByteArray('cr;'), toByteArray('j;'), toByteArray('nj;')]);
+  VALUES_0 = initValues(_3_3C_classLit, 64, 17, [initValues(_3C_classLit, 47, -1, [198]), initValues(_3C_classLit, 47, -1, [198]), initValues(_3C_classLit, 47, -1, [38]), initValues(_3C_classLit, 47, -1, [38]), initValues(_3C_classLit, 47, -1, [193]), initValues(_3C_classLit, 47, -1, [193]), initValues(_3C_classLit, 47, -1, [258]), initValues(_3C_classLit, 47, -1, [194]), initValues(_3C_classLit, 47, -1, [194]), initValues(_3C_classLit, 47, -1, [1040]), initValues(_3C_classLit, 47, -1, [55349, 56580]), initValues(_3C_classLit, 47, -1, [192]), initValues(_3C_classLit, 47, -1, [192]), initValues(_3C_classLit, 47, -1, [913]), initValues(_3C_classLit, 47, -1, [256]), initValues(_3C_classLit, 47, -1, [10835]), initValues(_3C_classLit, 47, -1, [260]), initValues(_3C_classLit, 47, -1, [55349, 56632]), initValues(_3C_classLit, 47, -1, [8289]), initValues(_3C_classLit, 47, -1, [197]), initValues(_3C_classLit, 47, -1, [197]), initValues(_3C_classLit, 47, -1, [55349, 56476]), initValues(_3C_classLit, 47, -1, [8788]), initValues(_3C_classLit, 47, -1, [195]), initValues(_3C_classLit, 47, -1, [195]), initValues(_3C_classLit, 47, -1, [196]), initValues(_3C_classLit, 47, -1, [196]), initValues(_3C_classLit, 47, -1, [8726]), initValues(_3C_classLit, 47, -1, [10983]), initValues(_3C_classLit, 47, -1, [8966]), initValues(_3C_classLit, 47, -1, [1041]), initValues(_3C_classLit, 47, -1, [8757]), initValues(_3C_classLit, 47, -1, [8492]), initValues(_3C_classLit, 47, -1, [914]), initValues(_3C_classLit, 47, -1, [55349, 56581]), initValues(_3C_classLit, 47, -1, [55349, 56633]), initValues(_3C_classLit, 47, -1, [728]), initValues(_3C_classLit, 47, -1, [8492]), initValues(_3C_classLit, 47, -1, [8782]), initValues(_3C_classLit, 47, -1, [1063]), initValues(_3C_classLit, 47, -1, [169]), initValues(_3C_classLit, 47, -1, [169]), initValues(_3C_classLit, 47, -1, [262]), initValues(_3C_classLit, 47, -1, [8914]), initValues(_3C_classLit, 47, -1, [8517]), initValues(_3C_classLit, 47, -1, [8493]), initValues(_3C_classLit, 47, -1, [268]), initValues(_3C_classLit, 47, -1, [199]), initValues(_3C_classLit, 47, -1, [199]), initValues(_3C_classLit, 47, -1, [264]), initValues(_3C_classLit, 47, -1, [8752]), initValues(_3C_classLit, 47, -1, [266]), initValues(_3C_classLit, 47, -1, [184]), initValues(_3C_classLit, 47, -1, [183]), initValues(_3C_classLit, 47, -1, [8493]), initValues(_3C_classLit, 47, -1, [935]), initValues(_3C_classLit, 47, -1, [8857]), initValues(_3C_classLit, 47, -1, [8854]), initValues(_3C_classLit, 47, -1, [8853]), initValues(_3C_classLit, 47, -1, [8855]), initValues(_3C_classLit, 47, -1, [8754]), initValues(_3C_classLit, 47, -1, [8221]), initValues(_3C_classLit, 47, -1, [8217]), initValues(_3C_classLit, 47, -1, [8759]), initValues(_3C_classLit, 47, -1, [10868]), initValues(_3C_classLit, 47, -1, [8801]), initValues(_3C_classLit, 47, -1, [8751]), initValues(_3C_classLit, 47, -1, [8750]), initValues(_3C_classLit, 47, -1, [8450]), initValues(_3C_classLit, 47, -1, [8720]), initValues(_3C_classLit, 47, -1, [8755]), initValues(_3C_classLit, 47, -1, [10799]), initValues(_3C_classLit, 47, -1, [55349, 56478]), initValues(_3C_classLit, 47, -1, [8915]), initValues(_3C_classLit, 47, -1, [8781]), initValues(_3C_classLit, 47, -1, [8517]), initValues(_3C_classLit, 47, -1, [10513]), initValues(_3C_classLit, 47, -1, [1026]), initValues(_3C_classLit, 47, -1, [1029]), initValues(_3C_classLit, 47, -1, [1039]), initValues(_3C_classLit, 47, -1, [8225]), initValues(_3C_classLit, 47, -1, [8609]), initValues(_3C_classLit, 47, -1, [10980]), initValues(_3C_classLit, 47, -1, [270]), initValues(_3C_classLit, 47, -1, [1044]), initValues(_3C_classLit, 47, -1, [8711]), initValues(_3C_classLit, 47, -1, [916]), initValues(_3C_classLit, 47, -1, [55349, 56583]), initValues(_3C_classLit, 47, -1, [180]), initValues(_3C_classLit, 47, -1, [729]), initValues(_3C_classLit, 47, -1, [733]), initValues(_3C_classLit, 47, -1, [96]), initValues(_3C_classLit, 47, -1, [732]), initValues(_3C_classLit, 47, -1, [8900]), initValues(_3C_classLit, 47, -1, [8518]), initValues(_3C_classLit, 47, -1, [55349, 56635]), initValues(_3C_classLit, 47, -1, [168]), initValues(_3C_classLit, 47, -1, [8412]), initValues(_3C_classLit, 47, -1, [8784]), initValues(_3C_classLit, 47, -1, [8751]), initValues(_3C_classLit, 47, -1, [168]), initValues(_3C_classLit, 47, -1, [8659]), initValues(_3C_classLit, 47, -1, [8656]), initValues(_3C_classLit, 47, -1, [8660]), initValues(_3C_classLit, 47, -1, [10980]), initValues(_3C_classLit, 47, -1, [10232]), initValues(_3C_classLit, 47, -1, [10234]), initValues(_3C_classLit, 47, -1, [10233]), initValues(_3C_classLit, 47, -1, [8658]), initValues(_3C_classLit, 47, -1, [8872]), initValues(_3C_classLit, 47, -1, [8657]), initValues(_3C_classLit, 47, -1, [8661]), initValues(_3C_classLit, 47, -1, [8741]), initValues(_3C_classLit, 47, -1, [8595]), initValues(_3C_classLit, 47, -1, [10515]), initValues(_3C_classLit, 47, -1, [8693]), initValues(_3C_classLit, 47, -1, [785]), initValues(_3C_classLit, 47, -1, [10576]), initValues(_3C_classLit, 47, -1, [10590]), initValues(_3C_classLit, 47, -1, [8637]), initValues(_3C_classLit, 47, -1, [10582]), initValues(_3C_classLit, 47, -1, [10591]), initValues(_3C_classLit, 47, -1, [8641]), initValues(_3C_classLit, 47, -1, [10583]), initValues(_3C_classLit, 47, -1, [8868]), initValues(_3C_classLit, 47, -1, [8615]), initValues(_3C_classLit, 47, -1, [8659]), initValues(_3C_classLit, 47, -1, [55349, 56479]), initValues(_3C_classLit, 47, -1, [272]), initValues(_3C_classLit, 47, -1, [330]), initValues(_3C_classLit, 47, -1, [208]), initValues(_3C_classLit, 47, -1, [208]), initValues(_3C_classLit, 47, -1, [201]), initValues(_3C_classLit, 47, -1, [201]), initValues(_3C_classLit, 47, -1, [282]), initValues(_3C_classLit, 47, -1, [202]), initValues(_3C_classLit, 47, -1, [202]), initValues(_3C_classLit, 47, -1, [1069]), initValues(_3C_classLit, 47, -1, [278]), initValues(_3C_classLit, 47, -1, [55349, 56584]), initValues(_3C_classLit, 47, -1, [200]), initValues(_3C_classLit, 47, -1, [200]), initValues(_3C_classLit, 47, -1, [8712]), initValues(_3C_classLit, 47, -1, [274]), initValues(_3C_classLit, 47, -1, [9723]), initValues(_3C_classLit, 47, -1, [9643]), initValues(_3C_classLit, 47, -1, [280]), initValues(_3C_classLit, 47, -1, [55349, 56636]), initValues(_3C_classLit, 47, -1, [917]), initValues(_3C_classLit, 47, -1, [10869]), initValues(_3C_classLit, 47, -1, [8770]), initValues(_3C_classLit, 47, -1, [8652]), initValues(_3C_classLit, 47, -1, [8496]), initValues(_3C_classLit, 47, -1, [10867]), initValues(_3C_classLit, 47, -1, [919]), initValues(_3C_classLit, 47, -1, [203]), initValues(_3C_classLit, 47, -1, [203]), initValues(_3C_classLit, 47, -1, [8707]), initValues(_3C_classLit, 47, -1, [8519]), initValues(_3C_classLit, 47, -1, [1060]), initValues(_3C_classLit, 47, -1, [55349, 56585]), initValues(_3C_classLit, 47, -1, [9724]), initValues(_3C_classLit, 47, -1, [9642]), initValues(_3C_classLit, 47, -1, [55349, 56637]), initValues(_3C_classLit, 47, -1, [8704]), initValues(_3C_classLit, 47, -1, [8497]), initValues(_3C_classLit, 47, -1, [8497]), initValues(_3C_classLit, 47, -1, [1027]), initValues(_3C_classLit, 47, -1, [62]), initValues(_3C_classLit, 47, -1, [62]), initValues(_3C_classLit, 47, -1, [915]), initValues(_3C_classLit, 47, -1, [988]), initValues(_3C_classLit, 47, -1, [286]), initValues(_3C_classLit, 47, -1, [290]), initValues(_3C_classLit, 47, -1, [284]), initValues(_3C_classLit, 47, -1, [1043]), initValues(_3C_classLit, 47, -1, [288]), initValues(_3C_classLit, 47, -1, [55349, 56586]), initValues(_3C_classLit, 47, -1, [8921]), initValues(_3C_classLit, 47, -1, [55349, 56638]), initValues(_3C_classLit, 47, -1, [8805]), initValues(_3C_classLit, 47, -1, [8923]), initValues(_3C_classLit, 47, -1, [8807]), initValues(_3C_classLit, 47, -1, [10914]), initValues(_3C_classLit, 47, -1, [8823]), initValues(_3C_classLit, 47, -1, [10878]), initValues(_3C_classLit, 47, -1, [8819]), initValues(_3C_classLit, 47, -1, [55349, 56482]), initValues(_3C_classLit, 47, -1, [8811]), initValues(_3C_classLit, 47, -1, [1066]), initValues(_3C_classLit, 47, -1, [711]), initValues(_3C_classLit, 47, -1, [94]), initValues(_3C_classLit, 47, -1, [292]), initValues(_3C_classLit, 47, -1, [8460]), initValues(_3C_classLit, 47, -1, [8459]), initValues(_3C_classLit, 47, -1, [8461]), initValues(_3C_classLit, 47, -1, [9472]), initValues(_3C_classLit, 47, -1, [8459]), initValues(_3C_classLit, 47, -1, [294]), initValues(_3C_classLit, 47, -1, [8782]), initValues(_3C_classLit, 47, -1, [8783]), initValues(_3C_classLit, 47, -1, [1045]), initValues(_3C_classLit, 47, -1, [306]), initValues(_3C_classLit, 47, -1, [1025]), initValues(_3C_classLit, 47, -1, [205]), initValues(_3C_classLit, 47, -1, [205]), initValues(_3C_classLit, 47, -1, [206]), initValues(_3C_classLit, 47, -1, [206]), initValues(_3C_classLit, 47, -1, [1048]), initValues(_3C_classLit, 47, -1, [304]), initValues(_3C_classLit, 47, -1, [8465]), initValues(_3C_classLit, 47, -1, [204]), initValues(_3C_classLit, 47, -1, [204]), initValues(_3C_classLit, 47, -1, [8465]), initValues(_3C_classLit, 47, -1, [298]), initValues(_3C_classLit, 47, -1, [8520]), initValues(_3C_classLit, 47, -1, [8658]), initValues(_3C_classLit, 47, -1, [8748]), initValues(_3C_classLit, 47, -1, [8747]), initValues(_3C_classLit, 47, -1, [8898]), initValues(_3C_classLit, 47, -1, [8291]), initValues(_3C_classLit, 47, -1, [8290]), initValues(_3C_classLit, 47, -1, [302]), initValues(_3C_classLit, 47, -1, [55349, 56640]), initValues(_3C_classLit, 47, -1, [921]), initValues(_3C_classLit, 47, -1, [8464]), initValues(_3C_classLit, 47, -1, [296]), initValues(_3C_classLit, 47, -1, [1030]), initValues(_3C_classLit, 47, -1, [207]), initValues(_3C_classLit, 47, -1, [207]), initValues(_3C_classLit, 47, -1, [308]), initValues(_3C_classLit, 47, -1, [1049]), initValues(_3C_classLit, 47, -1, [55349, 56589]), initValues(_3C_classLit, 47, -1, [55349, 56641]), initValues(_3C_classLit, 47, -1, [55349, 56485]), initValues(_3C_classLit, 47, -1, [1032]), initValues(_3C_classLit, 47, -1, [1028]), initValues(_3C_classLit, 47, -1, [1061]), initValues(_3C_classLit, 47, -1, [1036]), initValues(_3C_classLit, 47, -1, [922]), initValues(_3C_classLit, 47, -1, [310]), initValues(_3C_classLit, 47, -1, [1050]), initValues(_3C_classLit, 47, -1, [55349, 56590]), initValues(_3C_classLit, 47, -1, [55349, 56642]), initValues(_3C_classLit, 47, -1, [55349, 56486]), initValues(_3C_classLit, 47, -1, [1033]), initValues(_3C_classLit, 47, -1, [60]), initValues(_3C_classLit, 47, -1, [60]), initValues(_3C_classLit, 47, -1, [313]), initValues(_3C_classLit, 47, -1, [923]), initValues(_3C_classLit, 47, -1, [10218]), initValues(_3C_classLit, 47, -1, [8466]), initValues(_3C_classLit, 47, -1, [8606]), initValues(_3C_classLit, 47, -1, [317]), initValues(_3C_classLit, 47, -1, [315]), initValues(_3C_classLit, 47, -1, [1051]), initValues(_3C_classLit, 47, -1, [10216]), initValues(_3C_classLit, 47, -1, [8592]), initValues(_3C_classLit, 47, -1, [8676]), initValues(_3C_classLit, 47, -1, [8646]), initValues(_3C_classLit, 47, -1, [8968]), initValues(_3C_classLit, 47, -1, [10214]), initValues(_3C_classLit, 47, -1, [10593]), initValues(_3C_classLit, 47, -1, [8643]), initValues(_3C_classLit, 47, -1, [10585]), initValues(_3C_classLit, 47, -1, [8970]), initValues(_3C_classLit, 47, -1, [8596]), initValues(_3C_classLit, 47, -1, [10574]), initValues(_3C_classLit, 47, -1, [8867]), initValues(_3C_classLit, 47, -1, [8612]), initValues(_3C_classLit, 47, -1, [10586]), initValues(_3C_classLit, 47, -1, [8882]), initValues(_3C_classLit, 47, -1, [10703]), initValues(_3C_classLit, 47, -1, [8884]), initValues(_3C_classLit, 47, -1, [10577]), initValues(_3C_classLit, 47, -1, [10592]), initValues(_3C_classLit, 47, -1, [8639]), initValues(_3C_classLit, 47, -1, [10584]), initValues(_3C_classLit, 47, -1, [8636]), initValues(_3C_classLit, 47, -1, [10578]), initValues(_3C_classLit, 47, -1, [8656]), initValues(_3C_classLit, 47, -1, [8660]), initValues(_3C_classLit, 47, -1, [8922]), initValues(_3C_classLit, 47, -1, [8806]), initValues(_3C_classLit, 47, -1, [8822]), initValues(_3C_classLit, 47, -1, [10913]), initValues(_3C_classLit, 47, -1, [10877]), initValues(_3C_classLit, 47, -1, [8818]), initValues(_3C_classLit, 47, -1, [55349, 56591]), initValues(_3C_classLit, 47, -1, [8920]), initValues(_3C_classLit, 47, -1, [8666]), initValues(_3C_classLit, 47, -1, [319]), initValues(_3C_classLit, 47, -1, [10229]), initValues(_3C_classLit, 47, -1, [10231]), initValues(_3C_classLit, 47, -1, [10230]), initValues(_3C_classLit, 47, -1, [10232]), initValues(_3C_classLit, 47, -1, [10234]), initValues(_3C_classLit, 47, -1, [10233]), initValues(_3C_classLit, 47, -1, [55349, 56643]), initValues(_3C_classLit, 47, -1, [8601]), initValues(_3C_classLit, 47, -1, [8600]), initValues(_3C_classLit, 47, -1, [8466]), initValues(_3C_classLit, 47, -1, [8624]), initValues(_3C_classLit, 47, -1, [321]), initValues(_3C_classLit, 47, -1, [8810]), initValues(_3C_classLit, 47, -1, [10501]), initValues(_3C_classLit, 47, -1, [1052]), initValues(_3C_classLit, 47, -1, [8287]), initValues(_3C_classLit, 47, -1, [8499]), initValues(_3C_classLit, 47, -1, [55349, 56592]), initValues(_3C_classLit, 47, -1, [8723]), initValues(_3C_classLit, 47, -1, [55349, 56644]), initValues(_3C_classLit, 47, -1, [8499]), initValues(_3C_classLit, 47, -1, [924]), initValues(_3C_classLit, 47, -1, [1034]), initValues(_3C_classLit, 47, -1, [323]), initValues(_3C_classLit, 47, -1, [327]), initValues(_3C_classLit, 47, -1, [325]), initValues(_3C_classLit, 47, -1, [1053]), initValues(_3C_classLit, 47, -1, [8203]), initValues(_3C_classLit, 47, -1, [8203]), initValues(_3C_classLit, 47, -1, [8203]), initValues(_3C_classLit, 47, -1, [8203]), initValues(_3C_classLit, 47, -1, [8811]), initValues(_3C_classLit, 47, -1, [8810]), initValues(_3C_classLit, 47, -1, [10]), initValues(_3C_classLit, 47, -1, [55349, 56593]), initValues(_3C_classLit, 47, -1, [8288]), initValues(_3C_classLit, 47, -1, [160]), initValues(_3C_classLit, 47, -1, [8469]), initValues(_3C_classLit, 47, -1, [10988]), initValues(_3C_classLit, 47, -1, [8802]), initValues(_3C_classLit, 47, -1, [8813]), initValues(_3C_classLit, 47, -1, [8742]), initValues(_3C_classLit, 47, -1, [8713]), initValues(_3C_classLit, 47, -1, [8800]), initValues(_3C_classLit, 47, -1, [8708]), initValues(_3C_classLit, 47, -1, [8815]), initValues(_3C_classLit, 47, -1, [8817]), initValues(_3C_classLit, 47, -1, [8825]), initValues(_3C_classLit, 47, -1, [8821]), initValues(_3C_classLit, 47, -1, [8938]), initValues(_3C_classLit, 47, -1, [8940]), initValues(_3C_classLit, 47, -1, [8814]), initValues(_3C_classLit, 47, -1, [8816]), initValues(_3C_classLit, 47, -1, [8824]), initValues(_3C_classLit, 47, -1, [8820]), initValues(_3C_classLit, 47, -1, [8832]), initValues(_3C_classLit, 47, -1, [8928]), initValues(_3C_classLit, 47, -1, [8716]), initValues(_3C_classLit, 47, -1, [8939]), initValues(_3C_classLit, 47, -1, [8941]), initValues(_3C_classLit, 47, -1, [8930]), initValues(_3C_classLit, 47, -1, [8931]), initValues(_3C_classLit, 47, -1, [8840]), initValues(_3C_classLit, 47, -1, [8833]), initValues(_3C_classLit, 47, -1, [8929]), initValues(_3C_classLit, 47, -1, [8841]), initValues(_3C_classLit, 47, -1, [8769]), initValues(_3C_classLit, 47, -1, [8772]), initValues(_3C_classLit, 47, -1, [8775]), initValues(_3C_classLit, 47, -1, [8777]), initValues(_3C_classLit, 47, -1, [8740]), initValues(_3C_classLit, 47, -1, [55349, 56489]), initValues(_3C_classLit, 47, -1, [209]), initValues(_3C_classLit, 47, -1, [209]), initValues(_3C_classLit, 47, -1, [925]), initValues(_3C_classLit, 47, -1, [338]), initValues(_3C_classLit, 47, -1, [211]), initValues(_3C_classLit, 47, -1, [211]), initValues(_3C_classLit, 47, -1, [212]), initValues(_3C_classLit, 47, -1, [212]), initValues(_3C_classLit, 47, -1, [1054]), initValues(_3C_classLit, 47, -1, [336]), initValues(_3C_classLit, 47, -1, [55349, 56594]), initValues(_3C_classLit, 47, -1, [210]), initValues(_3C_classLit, 47, -1, [210]), initValues(_3C_classLit, 47, -1, [332]), initValues(_3C_classLit, 47, -1, [937]), initValues(_3C_classLit, 47, -1, [927]), initValues(_3C_classLit, 47, -1, [55349, 56646]), initValues(_3C_classLit, 47, -1, [8220]), initValues(_3C_classLit, 47, -1, [8216]), initValues(_3C_classLit, 47, -1, [10836]), initValues(_3C_classLit, 47, -1, [55349, 56490]), initValues(_3C_classLit, 47, -1, [216]), initValues(_3C_classLit, 47, -1, [216]), initValues(_3C_classLit, 47, -1, [213]), initValues(_3C_classLit, 47, -1, [213]), initValues(_3C_classLit, 47, -1, [10807]), initValues(_3C_classLit, 47, -1, [214]), initValues(_3C_classLit, 47, -1, [214]), initValues(_3C_classLit, 47, -1, [8254]), initValues(_3C_classLit, 47, -1, [9182]), initValues(_3C_classLit, 47, -1, [9140]), initValues(_3C_classLit, 47, -1, [9180]), initValues(_3C_classLit, 47, -1, [8706]), initValues(_3C_classLit, 47, -1, [1055]), initValues(_3C_classLit, 47, -1, [55349, 56595]), initValues(_3C_classLit, 47, -1, [934]), initValues(_3C_classLit, 47, -1, [928]), initValues(_3C_classLit, 47, -1, [177]), initValues(_3C_classLit, 47, -1, [8460]), initValues(_3C_classLit, 47, -1, [8473]), initValues(_3C_classLit, 47, -1, [10939]), initValues(_3C_classLit, 47, -1, [8826]), initValues(_3C_classLit, 47, -1, [10927]), initValues(_3C_classLit, 47, -1, [8828]), initValues(_3C_classLit, 47, -1, [8830]), initValues(_3C_classLit, 47, -1, [8243]), initValues(_3C_classLit, 47, -1, [8719]), initValues(_3C_classLit, 47, -1, [8759]), initValues(_3C_classLit, 47, -1, [8733]), initValues(_3C_classLit, 47, -1, [55349, 56491]), initValues(_3C_classLit, 47, -1, [936]), initValues(_3C_classLit, 47, -1, [34]), initValues(_3C_classLit, 47, -1, [34]), initValues(_3C_classLit, 47, -1, [55349, 56596]), initValues(_3C_classLit, 47, -1, [8474]), initValues(_3C_classLit, 47, -1, [55349, 56492]), initValues(_3C_classLit, 47, -1, [10512]), initValues(_3C_classLit, 47, -1, [174]), initValues(_3C_classLit, 47, -1, [174]), initValues(_3C_classLit, 47, -1, [340]), initValues(_3C_classLit, 47, -1, [10219]), initValues(_3C_classLit, 47, -1, [8608]), initValues(_3C_classLit, 47, -1, [10518]), initValues(_3C_classLit, 47, -1, [344]), initValues(_3C_classLit, 47, -1, [342]), initValues(_3C_classLit, 47, -1, [1056]), initValues(_3C_classLit, 47, -1, [8476]), initValues(_3C_classLit, 47, -1, [8715]), initValues(_3C_classLit, 47, -1, [8651]), initValues(_3C_classLit, 47, -1, [10607]), initValues(_3C_classLit, 47, -1, [8476]), initValues(_3C_classLit, 47, -1, [929]), initValues(_3C_classLit, 47, -1, [10217]), initValues(_3C_classLit, 47, -1, [8594]), initValues(_3C_classLit, 47, -1, [8677]), initValues(_3C_classLit, 47, -1, [8644]), initValues(_3C_classLit, 47, -1, [8969]), initValues(_3C_classLit, 47, -1, [10215]), initValues(_3C_classLit, 47, -1, [10589]), initValues(_3C_classLit, 47, -1, [8642]), initValues(_3C_classLit, 47, -1, [10581]), initValues(_3C_classLit, 47, -1, [8971]), initValues(_3C_classLit, 47, -1, [8866]), initValues(_3C_classLit, 47, -1, [8614]), initValues(_3C_classLit, 47, -1, [10587]), initValues(_3C_classLit, 47, -1, [8883]), initValues(_3C_classLit, 47, -1, [10704]), initValues(_3C_classLit, 47, -1, [8885]), initValues(_3C_classLit, 47, -1, [10575]), initValues(_3C_classLit, 47, -1, [10588]), initValues(_3C_classLit, 47, -1, [8638]), initValues(_3C_classLit, 47, -1, [10580]), initValues(_3C_classLit, 47, -1, [8640]), initValues(_3C_classLit, 47, -1, [10579]), initValues(_3C_classLit, 47, -1, [8658]), initValues(_3C_classLit, 47, -1, [8477]), initValues(_3C_classLit, 47, -1, [10608]), initValues(_3C_classLit, 47, -1, [8667]), initValues(_3C_classLit, 47, -1, [8475]), initValues(_3C_classLit, 47, -1, [8625]), initValues(_3C_classLit, 47, -1, [10740]), initValues(_3C_classLit, 47, -1, [1065]), initValues(_3C_classLit, 47, -1, [1064]), initValues(_3C_classLit, 47, -1, [1068]), initValues(_3C_classLit, 47, -1, [346]), initValues(_3C_classLit, 47, -1, [10940]), initValues(_3C_classLit, 47, -1, [352]), initValues(_3C_classLit, 47, -1, [350]), initValues(_3C_classLit, 47, -1, [348]), initValues(_3C_classLit, 47, -1, [1057]), initValues(_3C_classLit, 47, -1, [55349, 56598]), initValues(_3C_classLit, 47, -1, [8595]), initValues(_3C_classLit, 47, -1, [8592]), initValues(_3C_classLit, 47, -1, [8594]), initValues(_3C_classLit, 47, -1, [8593]), initValues(_3C_classLit, 47, -1, [931]), initValues(_3C_classLit, 47, -1, [8728]), initValues(_3C_classLit, 47, -1, [55349, 56650]), initValues(_3C_classLit, 47, -1, [8730]), initValues(_3C_classLit, 47, -1, [9633]), initValues(_3C_classLit, 47, -1, [8851]), initValues(_3C_classLit, 47, -1, [8847]), initValues(_3C_classLit, 47, -1, [8849]), initValues(_3C_classLit, 47, -1, [8848]), initValues(_3C_classLit, 47, -1, [8850]), initValues(_3C_classLit, 47, -1, [8852]), initValues(_3C_classLit, 47, -1, [55349, 56494]), initValues(_3C_classLit, 47, -1, [8902]), initValues(_3C_classLit, 47, -1, [8912]), initValues(_3C_classLit, 47, -1, [8912]), initValues(_3C_classLit, 47, -1, [8838]), initValues(_3C_classLit, 47, -1, [8827]), initValues(_3C_classLit, 47, -1, [10928]), initValues(_3C_classLit, 47, -1, [8829]), initValues(_3C_classLit, 47, -1, [8831]), initValues(_3C_classLit, 47, -1, [8715]), initValues(_3C_classLit, 47, -1, [8721]), initValues(_3C_classLit, 47, -1, [8913]), initValues(_3C_classLit, 47, -1, [8835]), initValues(_3C_classLit, 47, -1, [8839]), initValues(_3C_classLit, 47, -1, [8913]), initValues(_3C_classLit, 47, -1, [222]), initValues(_3C_classLit, 47, -1, [222]), initValues(_3C_classLit, 47, -1, [8482]), initValues(_3C_classLit, 47, -1, [1035]), initValues(_3C_classLit, 47, -1, [1062]), initValues(_3C_classLit, 47, -1, [9]), initValues(_3C_classLit, 47, -1, [932]), initValues(_3C_classLit, 47, -1, [356]), initValues(_3C_classLit, 47, -1, [354]), initValues(_3C_classLit, 47, -1, [1058]), initValues(_3C_classLit, 47, -1, [55349, 56599]), initValues(_3C_classLit, 47, -1, [8756]), initValues(_3C_classLit, 47, -1, [920]), initValues(_3C_classLit, 47, -1, [8201]), initValues(_3C_classLit, 47, -1, [8764]), initValues(_3C_classLit, 47, -1, [8771]), initValues(_3C_classLit, 47, -1, [8773]), initValues(_3C_classLit, 47, -1, [8776]), initValues(_3C_classLit, 47, -1, [55349, 56651]), initValues(_3C_classLit, 47, -1, [8411]), initValues(_3C_classLit, 47, -1, [55349, 56495]), initValues(_3C_classLit, 47, -1, [358]), initValues(_3C_classLit, 47, -1, [218]), initValues(_3C_classLit, 47, -1, [218]), initValues(_3C_classLit, 47, -1, [8607]), initValues(_3C_classLit, 47, -1, [10569]), initValues(_3C_classLit, 47, -1, [1038]), initValues(_3C_classLit, 47, -1, [364]), initValues(_3C_classLit, 47, -1, [219]), initValues(_3C_classLit, 47, -1, [219]), initValues(_3C_classLit, 47, -1, [1059]), initValues(_3C_classLit, 47, -1, [368]), initValues(_3C_classLit, 47, -1, [55349, 56600]), initValues(_3C_classLit, 47, -1, [217]), initValues(_3C_classLit, 47, -1, [217]), initValues(_3C_classLit, 47, -1, [362]), initValues(_3C_classLit, 47, -1, [95]), initValues(_3C_classLit, 47, -1, [9183]), initValues(_3C_classLit, 47, -1, [9141]), initValues(_3C_classLit, 47, -1, [9181]), initValues(_3C_classLit, 47, -1, [8899]), initValues(_3C_classLit, 47, -1, [8846]), initValues(_3C_classLit, 47, -1, [370]), initValues(_3C_classLit, 47, -1, [55349, 56652]), initValues(_3C_classLit, 47, -1, [8593]), initValues(_3C_classLit, 47, -1, [10514]), initValues(_3C_classLit, 47, -1, [8645]), initValues(_3C_classLit, 47, -1, [8597]), initValues(_3C_classLit, 47, -1, [10606]), initValues(_3C_classLit, 47, -1, [8869]), initValues(_3C_classLit, 47, -1, [8613]), initValues(_3C_classLit, 47, -1, [8657]), initValues(_3C_classLit, 47, -1, [8661]), initValues(_3C_classLit, 47, -1, [8598]), initValues(_3C_classLit, 47, -1, [8599]), initValues(_3C_classLit, 47, -1, [978]), initValues(_3C_classLit, 47, -1, [933]), initValues(_3C_classLit, 47, -1, [366]), initValues(_3C_classLit, 47, -1, [55349, 56496]), initValues(_3C_classLit, 47, -1, [360]), initValues(_3C_classLit, 47, -1, [220]), initValues(_3C_classLit, 47, -1, [220]), initValues(_3C_classLit, 47, -1, [8875]), initValues(_3C_classLit, 47, -1, [10987]), initValues(_3C_classLit, 47, -1, [1042]), initValues(_3C_classLit, 47, -1, [8873]), initValues(_3C_classLit, 47, -1, [10982]), initValues(_3C_classLit, 47, -1, [8897]), initValues(_3C_classLit, 47, -1, [8214]), initValues(_3C_classLit, 47, -1, [8214]), initValues(_3C_classLit, 47, -1, [8739]), initValues(_3C_classLit, 47, -1, [124]), initValues(_3C_classLit, 47, -1, [10072]), initValues(_3C_classLit, 47, -1, [8768]), initValues(_3C_classLit, 47, -1, [8202]), initValues(_3C_classLit, 47, -1, [55349, 56601]), initValues(_3C_classLit, 47, -1, [55349, 56653]), initValues(_3C_classLit, 47, -1, [55349, 56497]), initValues(_3C_classLit, 47, -1, [8874]), initValues(_3C_classLit, 47, -1, [372]), initValues(_3C_classLit, 47, -1, [8896]), initValues(_3C_classLit, 47, -1, [55349, 56602]), initValues(_3C_classLit, 47, -1, [55349, 56654]), initValues(_3C_classLit, 47, -1, [55349, 56498]), initValues(_3C_classLit, 47, -1, [55349, 56603]), initValues(_3C_classLit, 47, -1, [926]), initValues(_3C_classLit, 47, -1, [55349, 56655]), initValues(_3C_classLit, 47, -1, [55349, 56499]), initValues(_3C_classLit, 47, -1, [1071]), initValues(_3C_classLit, 47, -1, [1031]), initValues(_3C_classLit, 47, -1, [1070]), initValues(_3C_classLit, 47, -1, [221]), initValues(_3C_classLit, 47, -1, [221]), initValues(_3C_classLit, 47, -1, [374]), initValues(_3C_classLit, 47, -1, [1067]), initValues(_3C_classLit, 47, -1, [55349, 56604]), initValues(_3C_classLit, 47, -1, [55349, 56656]), initValues(_3C_classLit, 47, -1, [55349, 56500]), initValues(_3C_classLit, 47, -1, [376]), initValues(_3C_classLit, 47, -1, [1046]), initValues(_3C_classLit, 47, -1, [377]), initValues(_3C_classLit, 47, -1, [381]), initValues(_3C_classLit, 47, -1, [1047]), initValues(_3C_classLit, 47, -1, [379]), initValues(_3C_classLit, 47, -1, [8203]), initValues(_3C_classLit, 47, -1, [918]), initValues(_3C_classLit, 47, -1, [8488]), initValues(_3C_classLit, 47, -1, [8484]), initValues(_3C_classLit, 47, -1, [55349, 56501]), initValues(_3C_classLit, 47, -1, [225]), initValues(_3C_classLit, 47, -1, [225]), initValues(_3C_classLit, 47, -1, [259]), initValues(_3C_classLit, 47, -1, [8766]), initValues(_3C_classLit, 47, -1, [8767]), initValues(_3C_classLit, 47, -1, [226]), initValues(_3C_classLit, 47, -1, [226]), initValues(_3C_classLit, 47, -1, [180]), initValues(_3C_classLit, 47, -1, [180]), initValues(_3C_classLit, 47, -1, [1072]), initValues(_3C_classLit, 47, -1, [230]), initValues(_3C_classLit, 47, -1, [230]), initValues(_3C_classLit, 47, -1, [8289]), initValues(_3C_classLit, 47, -1, [55349, 56606]), initValues(_3C_classLit, 47, -1, [224]), initValues(_3C_classLit, 47, -1, [224]), initValues(_3C_classLit, 47, -1, [8501]), initValues(_3C_classLit, 47, -1, [8501]), initValues(_3C_classLit, 47, -1, [945]), initValues(_3C_classLit, 47, -1, [257]), initValues(_3C_classLit, 47, -1, [10815]), initValues(_3C_classLit, 47, -1, [38]), initValues(_3C_classLit, 47, -1, [38]), initValues(_3C_classLit, 47, -1, [8743]), initValues(_3C_classLit, 47, -1, [10837]), initValues(_3C_classLit, 47, -1, [10844]), initValues(_3C_classLit, 47, -1, [10840]), initValues(_3C_classLit, 47, -1, [10842]), initValues(_3C_classLit, 47, -1, [8736]), initValues(_3C_classLit, 47, -1, [10660]), initValues(_3C_classLit, 47, -1, [8736]), initValues(_3C_classLit, 47, -1, [8737]), initValues(_3C_classLit, 47, -1, [10664]), initValues(_3C_classLit, 47, -1, [10665]), initValues(_3C_classLit, 47, -1, [10666]), initValues(_3C_classLit, 47, -1, [10667]), initValues(_3C_classLit, 47, -1, [10668]), initValues(_3C_classLit, 47, -1, [10669]), initValues(_3C_classLit, 47, -1, [10670]), initValues(_3C_classLit, 47, -1, [10671]), initValues(_3C_classLit, 47, -1, [8735]), initValues(_3C_classLit, 47, -1, [8894]), initValues(_3C_classLit, 47, -1, [10653]), initValues(_3C_classLit, 47, -1, [8738]), initValues(_3C_classLit, 47, -1, [197]), initValues(_3C_classLit, 47, -1, [9084]), initValues(_3C_classLit, 47, -1, [261]), initValues(_3C_classLit, 47, -1, [55349, 56658]), initValues(_3C_classLit, 47, -1, [8776]), initValues(_3C_classLit, 47, -1, [10864]), initValues(_3C_classLit, 47, -1, [10863]), initValues(_3C_classLit, 47, -1, [8778]), initValues(_3C_classLit, 47, -1, [8779]), initValues(_3C_classLit, 47, -1, [39]), initValues(_3C_classLit, 47, -1, [8776]), initValues(_3C_classLit, 47, -1, [8778]), initValues(_3C_classLit, 47, -1, [229]), initValues(_3C_classLit, 47, -1, [229]), initValues(_3C_classLit, 47, -1, [55349, 56502]), initValues(_3C_classLit, 47, -1, [42]), initValues(_3C_classLit, 47, -1, [8776]), initValues(_3C_classLit, 47, -1, [8781]), initValues(_3C_classLit, 47, -1, [227]), initValues(_3C_classLit, 47, -1, [227]), initValues(_3C_classLit, 47, -1, [228]), initValues(_3C_classLit, 47, -1, [228]), initValues(_3C_classLit, 47, -1, [8755]), initValues(_3C_classLit, 47, -1, [10769]), initValues(_3C_classLit, 47, -1, [10989]), initValues(_3C_classLit, 47, -1, [8780]), initValues(_3C_classLit, 47, -1, [1014]), initValues(_3C_classLit, 47, -1, [8245]), initValues(_3C_classLit, 47, -1, [8765]), initValues(_3C_classLit, 47, -1, [8909]), initValues(_3C_classLit, 47, -1, [8893]), initValues(_3C_classLit, 47, -1, [8965]), initValues(_3C_classLit, 47, -1, [8965]), initValues(_3C_classLit, 47, -1, [9141]), initValues(_3C_classLit, 47, -1, [9142]), initValues(_3C_classLit, 47, -1, [8780]), initValues(_3C_classLit, 47, -1, [1073]), initValues(_3C_classLit, 47, -1, [8222]), initValues(_3C_classLit, 47, -1, [8757]), initValues(_3C_classLit, 47, -1, [8757]), initValues(_3C_classLit, 47, -1, [10672]), initValues(_3C_classLit, 47, -1, [1014]), initValues(_3C_classLit, 47, -1, [8492]), initValues(_3C_classLit, 47, -1, [946]), initValues(_3C_classLit, 47, -1, [8502]), initValues(_3C_classLit, 47, -1, [8812]), initValues(_3C_classLit, 47, -1, [55349, 56607]), initValues(_3C_classLit, 47, -1, [8898]), initValues(_3C_classLit, 47, -1, [9711]), initValues(_3C_classLit, 47, -1, [8899]), initValues(_3C_classLit, 47, -1, [10752]), initValues(_3C_classLit, 47, -1, [10753]), initValues(_3C_classLit, 47, -1, [10754]), initValues(_3C_classLit, 47, -1, [10758]), initValues(_3C_classLit, 47, -1, [9733]), initValues(_3C_classLit, 47, -1, [9661]), initValues(_3C_classLit, 47, -1, [9651]), initValues(_3C_classLit, 47, -1, [10756]), initValues(_3C_classLit, 47, -1, [8897]), initValues(_3C_classLit, 47, -1, [8896]), initValues(_3C_classLit, 47, -1, [10509]), initValues(_3C_classLit, 47, -1, [10731]), initValues(_3C_classLit, 47, -1, [9642]), initValues(_3C_classLit, 47, -1, [9652]), initValues(_3C_classLit, 47, -1, [9662]), initValues(_3C_classLit, 47, -1, [9666]), initValues(_3C_classLit, 47, -1, [9656]), initValues(_3C_classLit, 47, -1, [9251]), initValues(_3C_classLit, 47, -1, [9618]), initValues(_3C_classLit, 47, -1, [9617]), initValues(_3C_classLit, 47, -1, [9619]), initValues(_3C_classLit, 47, -1, [9608]), initValues(_3C_classLit, 47, -1, [8976]), initValues(_3C_classLit, 47, -1, [55349, 56659]), initValues(_3C_classLit, 47, -1, [8869]), initValues(_3C_classLit, 47, -1, [8869]), initValues(_3C_classLit, 47, -1, [8904]), initValues(_3C_classLit, 47, -1, [9559]), initValues(_3C_classLit, 47, -1, [9556]), initValues(_3C_classLit, 47, -1, [9558]), initValues(_3C_classLit, 47, -1, [9555]), initValues(_3C_classLit, 47, -1, [9552]), initValues(_3C_classLit, 47, -1, [9574]), initValues(_3C_classLit, 47, -1, [9577]), initValues(_3C_classLit, 47, -1, [9572]), initValues(_3C_classLit, 47, -1, [9575]), initValues(_3C_classLit, 47, -1, [9565]), initValues(_3C_classLit, 47, -1, [9562]), initValues(_3C_classLit, 47, -1, [9564]), initValues(_3C_classLit, 47, -1, [9561]), initValues(_3C_classLit, 47, -1, [9553]), initValues(_3C_classLit, 47, -1, [9580]), initValues(_3C_classLit, 47, -1, [9571]), initValues(_3C_classLit, 47, -1, [9568]), initValues(_3C_classLit, 47, -1, [9579]), initValues(_3C_classLit, 47, -1, [9570]), initValues(_3C_classLit, 47, -1, [9567]), initValues(_3C_classLit, 47, -1, [10697]), initValues(_3C_classLit, 47, -1, [9557]), initValues(_3C_classLit, 47, -1, [9554]), initValues(_3C_classLit, 47, -1, [9488]), initValues(_3C_classLit, 47, -1, [9484]), initValues(_3C_classLit, 47, -1, [9472]), initValues(_3C_classLit, 47, -1, [9573]), initValues(_3C_classLit, 47, -1, [9576]), initValues(_3C_classLit, 47, -1, [9516]), initValues(_3C_classLit, 47, -1, [9524]), initValues(_3C_classLit, 47, -1, [8863]), initValues(_3C_classLit, 47, -1, [8862]), initValues(_3C_classLit, 47, -1, [8864]), initValues(_3C_classLit, 47, -1, [9563]), initValues(_3C_classLit, 47, -1, [9560]), initValues(_3C_classLit, 47, -1, [9496]), initValues(_3C_classLit, 47, -1, [9492]), initValues(_3C_classLit, 47, -1, [9474]), initValues(_3C_classLit, 47, -1, [9578]), initValues(_3C_classLit, 47, -1, [9569]), initValues(_3C_classLit, 47, -1, [9566]), initValues(_3C_classLit, 47, -1, [9532]), initValues(_3C_classLit, 47, -1, [9508]), initValues(_3C_classLit, 47, -1, [9500]), initValues(_3C_classLit, 47, -1, [8245]), initValues(_3C_classLit, 47, -1, [728]), initValues(_3C_classLit, 47, -1, [166]), initValues(_3C_classLit, 47, -1, [166]), initValues(_3C_classLit, 47, -1, [55349, 56503]), initValues(_3C_classLit, 47, -1, [8271]), initValues(_3C_classLit, 47, -1, [8765]), initValues(_3C_classLit, 47, -1, [8909]), initValues(_3C_classLit, 47, -1, [92]), initValues(_3C_classLit, 47, -1, [10693]), initValues(_3C_classLit, 47, -1, [10184]), initValues(_3C_classLit, 47, -1, [8226]), initValues(_3C_classLit, 47, -1, [8226]), initValues(_3C_classLit, 47, -1, [8782]), initValues(_3C_classLit, 47, -1, [10926]), initValues(_3C_classLit, 47, -1, [8783]), initValues(_3C_classLit, 47, -1, [8783]), initValues(_3C_classLit, 47, -1, [263]), initValues(_3C_classLit, 47, -1, [8745]), initValues(_3C_classLit, 47, -1, [10820]), initValues(_3C_classLit, 47, -1, [10825]), initValues(_3C_classLit, 47, -1, [10827]), initValues(_3C_classLit, 47, -1, [10823]), initValues(_3C_classLit, 47, -1, [10816]), initValues(_3C_classLit, 47, -1, [8257]), initValues(_3C_classLit, 47, -1, [711]), initValues(_3C_classLit, 47, -1, [10829]), initValues(_3C_classLit, 47, -1, [269]), initValues(_3C_classLit, 47, -1, [231]), initValues(_3C_classLit, 47, -1, [231]), initValues(_3C_classLit, 47, -1, [265]), initValues(_3C_classLit, 47, -1, [10828]), initValues(_3C_classLit, 47, -1, [10832]), initValues(_3C_classLit, 47, -1, [267]), initValues(_3C_classLit, 47, -1, [184]), initValues(_3C_classLit, 47, -1, [184]), initValues(_3C_classLit, 47, -1, [10674]), initValues(_3C_classLit, 47, -1, [162]), initValues(_3C_classLit, 47, -1, [162]), initValues(_3C_classLit, 47, -1, [183]), initValues(_3C_classLit, 47, -1, [55349, 56608]), initValues(_3C_classLit, 47, -1, [1095]), initValues(_3C_classLit, 47, -1, [10003]), initValues(_3C_classLit, 47, -1, [10003]), initValues(_3C_classLit, 47, -1, [967]), initValues(_3C_classLit, 47, -1, [9675]), initValues(_3C_classLit, 47, -1, [10691]), initValues(_3C_classLit, 47, -1, [710]), initValues(_3C_classLit, 47, -1, [8791]), initValues(_3C_classLit, 47, -1, [8634]), initValues(_3C_classLit, 47, -1, [8635]), initValues(_3C_classLit, 47, -1, [174]), initValues(_3C_classLit, 47, -1, [9416]), initValues(_3C_classLit, 47, -1, [8859]), initValues(_3C_classLit, 47, -1, [8858]), initValues(_3C_classLit, 47, -1, [8861]), initValues(_3C_classLit, 47, -1, [8791]), initValues(_3C_classLit, 47, -1, [10768]), initValues(_3C_classLit, 47, -1, [10991]), initValues(_3C_classLit, 47, -1, [10690]), initValues(_3C_classLit, 47, -1, [9827]), initValues(_3C_classLit, 47, -1, [9827]), initValues(_3C_classLit, 47, -1, [58]), initValues(_3C_classLit, 47, -1, [8788]), initValues(_3C_classLit, 47, -1, [8788]), initValues(_3C_classLit, 47, -1, [44]), initValues(_3C_classLit, 47, -1, [64]), initValues(_3C_classLit, 47, -1, [8705]), initValues(_3C_classLit, 47, -1, [8728]), initValues(_3C_classLit, 47, -1, [8705]), initValues(_3C_classLit, 47, -1, [8450]), initValues(_3C_classLit, 47, -1, [8773]), initValues(_3C_classLit, 47, -1, [10861]), initValues(_3C_classLit, 47, -1, [8750]), initValues(_3C_classLit, 47, -1, [55349, 56660]), initValues(_3C_classLit, 47, -1, [8720]), initValues(_3C_classLit, 47, -1, [169]), initValues(_3C_classLit, 47, -1, [169]), initValues(_3C_classLit, 47, -1, [8471]), initValues(_3C_classLit, 47, -1, [8629]), initValues(_3C_classLit, 47, -1, [10007]), initValues(_3C_classLit, 47, -1, [55349, 56504]), initValues(_3C_classLit, 47, -1, [10959]), initValues(_3C_classLit, 47, -1, [10961]), initValues(_3C_classLit, 47, -1, [10960]), initValues(_3C_classLit, 47, -1, [10962]), initValues(_3C_classLit, 47, -1, [8943]), initValues(_3C_classLit, 47, -1, [10552]), initValues(_3C_classLit, 47, -1, [10549]), initValues(_3C_classLit, 47, -1, [8926]), initValues(_3C_classLit, 47, -1, [8927]), initValues(_3C_classLit, 47, -1, [8630]), initValues(_3C_classLit, 47, -1, [10557]), initValues(_3C_classLit, 47, -1, [8746]), initValues(_3C_classLit, 47, -1, [10824]), initValues(_3C_classLit, 47, -1, [10822]), initValues(_3C_classLit, 47, -1, [10826]), initValues(_3C_classLit, 47, -1, [8845]), initValues(_3C_classLit, 47, -1, [10821]), initValues(_3C_classLit, 47, -1, [8631]), initValues(_3C_classLit, 47, -1, [10556]), initValues(_3C_classLit, 47, -1, [8926]), initValues(_3C_classLit, 47, -1, [8927]), initValues(_3C_classLit, 47, -1, [8910]), initValues(_3C_classLit, 47, -1, [8911]), initValues(_3C_classLit, 47, -1, [164]), initValues(_3C_classLit, 47, -1, [164]), initValues(_3C_classLit, 47, -1, [8630]), initValues(_3C_classLit, 47, -1, [8631]), initValues(_3C_classLit, 47, -1, [8910]), initValues(_3C_classLit, 47, -1, [8911]), initValues(_3C_classLit, 47, -1, [8754]), initValues(_3C_classLit, 47, -1, [8753]), initValues(_3C_classLit, 47, -1, [9005]), initValues(_3C_classLit, 47, -1, [8659]), initValues(_3C_classLit, 47, -1, [10597]), initValues(_3C_classLit, 47, -1, [8224]), initValues(_3C_classLit, 47, -1, [8504]), initValues(_3C_classLit, 47, -1, [8595]), initValues(_3C_classLit, 47, -1, [8208]), initValues(_3C_classLit, 47, -1, [8867]), initValues(_3C_classLit, 47, -1, [10511]), initValues(_3C_classLit, 47, -1, [733]), initValues(_3C_classLit, 47, -1, [271]), initValues(_3C_classLit, 47, -1, [1076]), initValues(_3C_classLit, 47, -1, [8518]), initValues(_3C_classLit, 47, -1, [8225]), initValues(_3C_classLit, 47, -1, [8650]), initValues(_3C_classLit, 47, -1, [10871]), initValues(_3C_classLit, 47, -1, [176]), initValues(_3C_classLit, 47, -1, [176]), initValues(_3C_classLit, 47, -1, [948]), initValues(_3C_classLit, 47, -1, [10673]), initValues(_3C_classLit, 47, -1, [10623]), initValues(_3C_classLit, 47, -1, [55349, 56609]), initValues(_3C_classLit, 47, -1, [8643]), initValues(_3C_classLit, 47, -1, [8642]), initValues(_3C_classLit, 47, -1, [8900]), initValues(_3C_classLit, 47, -1, [8900]), initValues(_3C_classLit, 47, -1, [9830]), initValues(_3C_classLit, 47, -1, [9830]), initValues(_3C_classLit, 47, -1, [168]), initValues(_3C_classLit, 47, -1, [989]), initValues(_3C_classLit, 47, -1, [8946]), initValues(_3C_classLit, 47, -1, [247]), initValues(_3C_classLit, 47, -1, [247]), initValues(_3C_classLit, 47, -1, [247]), initValues(_3C_classLit, 47, -1, [8903]), initValues(_3C_classLit, 47, -1, [8903]), initValues(_3C_classLit, 47, -1, [1106]), initValues(_3C_classLit, 47, -1, [8990]), initValues(_3C_classLit, 47, -1, [8973]), initValues(_3C_classLit, 47, -1, [36]), initValues(_3C_classLit, 47, -1, [55349, 56661]), initValues(_3C_classLit, 47, -1, [729]), initValues(_3C_classLit, 47, -1, [8784]), initValues(_3C_classLit, 47, -1, [8785]), initValues(_3C_classLit, 47, -1, [8760]), initValues(_3C_classLit, 47, -1, [8724]), initValues(_3C_classLit, 47, -1, [8865]), initValues(_3C_classLit, 47, -1, [8966]), initValues(_3C_classLit, 47, -1, [8595]), initValues(_3C_classLit, 47, -1, [8650]), initValues(_3C_classLit, 47, -1, [8643]), initValues(_3C_classLit, 47, -1, [8642]), initValues(_3C_classLit, 47, -1, [10512]), initValues(_3C_classLit, 47, -1, [8991]), initValues(_3C_classLit, 47, -1, [8972]), initValues(_3C_classLit, 47, -1, [55349, 56505]), initValues(_3C_classLit, 47, -1, [1109]), initValues(_3C_classLit, 47, -1, [10742]), initValues(_3C_classLit, 47, -1, [273]), initValues(_3C_classLit, 47, -1, [8945]), initValues(_3C_classLit, 47, -1, [9663]), initValues(_3C_classLit, 47, -1, [9662]), initValues(_3C_classLit, 47, -1, [8693]), initValues(_3C_classLit, 47, -1, [10607]), initValues(_3C_classLit, 47, -1, [10662]), initValues(_3C_classLit, 47, -1, [1119]), initValues(_3C_classLit, 47, -1, [10239]), initValues(_3C_classLit, 47, -1, [10871]), initValues(_3C_classLit, 47, -1, [8785]), initValues(_3C_classLit, 47, -1, [233]), initValues(_3C_classLit, 47, -1, [233]), initValues(_3C_classLit, 47, -1, [10862]), initValues(_3C_classLit, 47, -1, [283]), initValues(_3C_classLit, 47, -1, [8790]), initValues(_3C_classLit, 47, -1, [234]), initValues(_3C_classLit, 47, -1, [234]), initValues(_3C_classLit, 47, -1, [8789]), initValues(_3C_classLit, 47, -1, [1101]), initValues(_3C_classLit, 47, -1, [279]), initValues(_3C_classLit, 47, -1, [8519]), initValues(_3C_classLit, 47, -1, [8786]), initValues(_3C_classLit, 47, -1, [55349, 56610]), initValues(_3C_classLit, 47, -1, [10906]), initValues(_3C_classLit, 47, -1, [232]), initValues(_3C_classLit, 47, -1, [232]), initValues(_3C_classLit, 47, -1, [10902]), initValues(_3C_classLit, 47, -1, [10904]), initValues(_3C_classLit, 47, -1, [10905]), initValues(_3C_classLit, 47, -1, [9191]), initValues(_3C_classLit, 47, -1, [8467]), initValues(_3C_classLit, 47, -1, [10901]), initValues(_3C_classLit, 47, -1, [10903]), initValues(_3C_classLit, 47, -1, [275]), initValues(_3C_classLit, 47, -1, [8709]), initValues(_3C_classLit, 47, -1, [8709]), initValues(_3C_classLit, 47, -1, [8709]), initValues(_3C_classLit, 47, -1, [8196]), initValues(_3C_classLit, 47, -1, [8197]), initValues(_3C_classLit, 47, -1, [8195]), initValues(_3C_classLit, 47, -1, [331]), initValues(_3C_classLit, 47, -1, [8194]), initValues(_3C_classLit, 47, -1, [281]), initValues(_3C_classLit, 47, -1, [55349, 56662]), initValues(_3C_classLit, 47, -1, [8917]), initValues(_3C_classLit, 47, -1, [10723]), initValues(_3C_classLit, 47, -1, [10865]), initValues(_3C_classLit, 47, -1, [949]), initValues(_3C_classLit, 47, -1, [949]), initValues(_3C_classLit, 47, -1, [1013]), initValues(_3C_classLit, 47, -1, [8790]), initValues(_3C_classLit, 47, -1, [8789]), initValues(_3C_classLit, 47, -1, [8770]), initValues(_3C_classLit, 47, -1, [10902]), initValues(_3C_classLit, 47, -1, [10901]), initValues(_3C_classLit, 47, -1, [61]), initValues(_3C_classLit, 47, -1, [8799]), initValues(_3C_classLit, 47, -1, [8801]), initValues(_3C_classLit, 47, -1, [10872]), initValues(_3C_classLit, 47, -1, [10725]), initValues(_3C_classLit, 47, -1, [8787]), initValues(_3C_classLit, 47, -1, [10609]), initValues(_3C_classLit, 47, -1, [8495]), initValues(_3C_classLit, 47, -1, [8784]), initValues(_3C_classLit, 47, -1, [8770]), initValues(_3C_classLit, 47, -1, [951]), initValues(_3C_classLit, 47, -1, [240]), initValues(_3C_classLit, 47, -1, [240]), initValues(_3C_classLit, 47, -1, [235]), initValues(_3C_classLit, 47, -1, [235]), initValues(_3C_classLit, 47, -1, [8364]), initValues(_3C_classLit, 47, -1, [33]), initValues(_3C_classLit, 47, -1, [8707]), initValues(_3C_classLit, 47, -1, [8496]), initValues(_3C_classLit, 47, -1, [8519]), initValues(_3C_classLit, 47, -1, [8786]), initValues(_3C_classLit, 47, -1, [1092]), initValues(_3C_classLit, 47, -1, [9792]), initValues(_3C_classLit, 47, -1, [64259]), initValues(_3C_classLit, 47, -1, [64256]), initValues(_3C_classLit, 47, -1, [64260]), initValues(_3C_classLit, 47, -1, [55349, 56611]), initValues(_3C_classLit, 47, -1, [64257]), initValues(_3C_classLit, 47, -1, [9837]), initValues(_3C_classLit, 47, -1, [64258]), initValues(_3C_classLit, 47, -1, [9649]), initValues(_3C_classLit, 47, -1, [402]), initValues(_3C_classLit, 47, -1, [55349, 56663]), initValues(_3C_classLit, 47, -1, [8704]), initValues(_3C_classLit, 47, -1, [8916]), initValues(_3C_classLit, 47, -1, [10969]), initValues(_3C_classLit, 47, -1, [10765]), initValues(_3C_classLit, 47, -1, [189]), initValues(_3C_classLit, 47, -1, [189]), initValues(_3C_classLit, 47, -1, [8531]), initValues(_3C_classLit, 47, -1, [188]), initValues(_3C_classLit, 47, -1, [188]), initValues(_3C_classLit, 47, -1, [8533]), initValues(_3C_classLit, 47, -1, [8537]), initValues(_3C_classLit, 47, -1, [8539]), initValues(_3C_classLit, 47, -1, [8532]), initValues(_3C_classLit, 47, -1, [8534]), initValues(_3C_classLit, 47, -1, [190]), initValues(_3C_classLit, 47, -1, [190]), initValues(_3C_classLit, 47, -1, [8535]), initValues(_3C_classLit, 47, -1, [8540]), initValues(_3C_classLit, 47, -1, [8536]), initValues(_3C_classLit, 47, -1, [8538]), initValues(_3C_classLit, 47, -1, [8541]), initValues(_3C_classLit, 47, -1, [8542]), initValues(_3C_classLit, 47, -1, [8260]), initValues(_3C_classLit, 47, -1, [8994]), initValues(_3C_classLit, 47, -1, [55349, 56507]), initValues(_3C_classLit, 47, -1, [8807]), initValues(_3C_classLit, 47, -1, [10892]), initValues(_3C_classLit, 47, -1, [501]), initValues(_3C_classLit, 47, -1, [947]), initValues(_3C_classLit, 47, -1, [989]), initValues(_3C_classLit, 47, -1, [10886]), initValues(_3C_classLit, 47, -1, [287]), initValues(_3C_classLit, 47, -1, [285]), initValues(_3C_classLit, 47, -1, [1075]), initValues(_3C_classLit, 47, -1, [289]), initValues(_3C_classLit, 47, -1, [8805]), initValues(_3C_classLit, 47, -1, [8923]), initValues(_3C_classLit, 47, -1, [8805]), initValues(_3C_classLit, 47, -1, [8807]), initValues(_3C_classLit, 47, -1, [10878]), initValues(_3C_classLit, 47, -1, [10878]), initValues(_3C_classLit, 47, -1, [10921]), initValues(_3C_classLit, 47, -1, [10880]), initValues(_3C_classLit, 47, -1, [10882]), initValues(_3C_classLit, 47, -1, [10884]), initValues(_3C_classLit, 47, -1, [10900]), initValues(_3C_classLit, 47, -1, [55349, 56612]), initValues(_3C_classLit, 47, -1, [8811]), initValues(_3C_classLit, 47, -1, [8921]), initValues(_3C_classLit, 47, -1, [8503]), initValues(_3C_classLit, 47, -1, [1107]), initValues(_3C_classLit, 47, -1, [8823]), initValues(_3C_classLit, 47, -1, [10898]), initValues(_3C_classLit, 47, -1, [10917]), initValues(_3C_classLit, 47, -1, [10916]), initValues(_3C_classLit, 47, -1, [8809]), initValues(_3C_classLit, 47, -1, [10890]), initValues(_3C_classLit, 47, -1, [10890]), initValues(_3C_classLit, 47, -1, [10888]), initValues(_3C_classLit, 47, -1, [10888]), initValues(_3C_classLit, 47, -1, [8809]), initValues(_3C_classLit, 47, -1, [8935]), initValues(_3C_classLit, 47, -1, [55349, 56664]), initValues(_3C_classLit, 47, -1, [96]), initValues(_3C_classLit, 47, -1, [8458]), initValues(_3C_classLit, 47, -1, [8819]), initValues(_3C_classLit, 47, -1, [10894]), initValues(_3C_classLit, 47, -1, [10896]), initValues(_3C_classLit, 47, -1, [62]), initValues(_3C_classLit, 47, -1, [62]), initValues(_3C_classLit, 47, -1, [10919]), initValues(_3C_classLit, 47, -1, [10874]), initValues(_3C_classLit, 47, -1, [8919]), initValues(_3C_classLit, 47, -1, [10645]), initValues(_3C_classLit, 47, -1, [10876]), initValues(_3C_classLit, 47, -1, [10886]), initValues(_3C_classLit, 47, -1, [10616]), initValues(_3C_classLit, 47, -1, [8919]), initValues(_3C_classLit, 47, -1, [8923]), initValues(_3C_classLit, 47, -1, [10892]), initValues(_3C_classLit, 47, -1, [8823]), initValues(_3C_classLit, 47, -1, [8819]), initValues(_3C_classLit, 47, -1, [8660]), initValues(_3C_classLit, 47, -1, [8202]), initValues(_3C_classLit, 47, -1, [189]), initValues(_3C_classLit, 47, -1, [8459]), initValues(_3C_classLit, 47, -1, [1098]), initValues(_3C_classLit, 47, -1, [8596]), initValues(_3C_classLit, 47, -1, [10568]), initValues(_3C_classLit, 47, -1, [8621]), initValues(_3C_classLit, 47, -1, [8463]), initValues(_3C_classLit, 47, -1, [293]), initValues(_3C_classLit, 47, -1, [9829]), initValues(_3C_classLit, 47, -1, [9829]), initValues(_3C_classLit, 47, -1, [8230]), initValues(_3C_classLit, 47, -1, [8889]), initValues(_3C_classLit, 47, -1, [55349, 56613]), initValues(_3C_classLit, 47, -1, [10533]), initValues(_3C_classLit, 47, -1, [10534]), initValues(_3C_classLit, 47, -1, [8703]), initValues(_3C_classLit, 47, -1, [8763]), initValues(_3C_classLit, 47, -1, [8617]), initValues(_3C_classLit, 47, -1, [8618]), initValues(_3C_classLit, 47, -1, [55349, 56665]), initValues(_3C_classLit, 47, -1, [8213]), initValues(_3C_classLit, 47, -1, [55349, 56509]), initValues(_3C_classLit, 47, -1, [8463]), initValues(_3C_classLit, 47, -1, [295]), initValues(_3C_classLit, 47, -1, [8259]), initValues(_3C_classLit, 47, -1, [8208]), initValues(_3C_classLit, 47, -1, [237]), initValues(_3C_classLit, 47, -1, [237]), initValues(_3C_classLit, 47, -1, [8291]), initValues(_3C_classLit, 47, -1, [238]), initValues(_3C_classLit, 47, -1, [238]), initValues(_3C_classLit, 47, -1, [1080]), initValues(_3C_classLit, 47, -1, [1077]), initValues(_3C_classLit, 47, -1, [161]), initValues(_3C_classLit, 47, -1, [161]), initValues(_3C_classLit, 47, -1, [8660]), initValues(_3C_classLit, 47, -1, [55349, 56614]), initValues(_3C_classLit, 47, -1, [236]), initValues(_3C_classLit, 47, -1, [236]), initValues(_3C_classLit, 47, -1, [8520]), initValues(_3C_classLit, 47, -1, [10764]), initValues(_3C_classLit, 47, -1, [8749]), initValues(_3C_classLit, 47, -1, [10716]), initValues(_3C_classLit, 47, -1, [8489]), initValues(_3C_classLit, 47, -1, [307]), initValues(_3C_classLit, 47, -1, [299]), initValues(_3C_classLit, 47, -1, [8465]), initValues(_3C_classLit, 47, -1, [8464]), initValues(_3C_classLit, 47, -1, [8465]), initValues(_3C_classLit, 47, -1, [305]), initValues(_3C_classLit, 47, -1, [8887]), initValues(_3C_classLit, 47, -1, [437]), initValues(_3C_classLit, 47, -1, [8712]), initValues(_3C_classLit, 47, -1, [8453]), initValues(_3C_classLit, 47, -1, [8734]), initValues(_3C_classLit, 47, -1, [10717]), initValues(_3C_classLit, 47, -1, [305]), initValues(_3C_classLit, 47, -1, [8747]), initValues(_3C_classLit, 47, -1, [8890]), initValues(_3C_classLit, 47, -1, [8484]), initValues(_3C_classLit, 47, -1, [8890]), initValues(_3C_classLit, 47, -1, [10775]), initValues(_3C_classLit, 47, -1, [10812]), initValues(_3C_classLit, 47, -1, [1105]), initValues(_3C_classLit, 47, -1, [303]), initValues(_3C_classLit, 47, -1, [55349, 56666]), initValues(_3C_classLit, 47, -1, [953]), initValues(_3C_classLit, 47, -1, [10812]), initValues(_3C_classLit, 47, -1, [191]), initValues(_3C_classLit, 47, -1, [191]), initValues(_3C_classLit, 47, -1, [55349, 56510]), initValues(_3C_classLit, 47, -1, [8712]), initValues(_3C_classLit, 47, -1, [8953]), initValues(_3C_classLit, 47, -1, [8949]), initValues(_3C_classLit, 47, -1, [8948]), initValues(_3C_classLit, 47, -1, [8947]), initValues(_3C_classLit, 47, -1, [8712]), initValues(_3C_classLit, 47, -1, [8290]), initValues(_3C_classLit, 47, -1, [297]), initValues(_3C_classLit, 47, -1, [1110]), initValues(_3C_classLit, 47, -1, [239]), initValues(_3C_classLit, 47, -1, [239]), initValues(_3C_classLit, 47, -1, [309]), initValues(_3C_classLit, 47, -1, [1081]), initValues(_3C_classLit, 47, -1, [55349, 56615]), initValues(_3C_classLit, 47, -1, [567]), initValues(_3C_classLit, 47, -1, [55349, 56667]), initValues(_3C_classLit, 47, -1, [55349, 56511]), initValues(_3C_classLit, 47, -1, [1112]), initValues(_3C_classLit, 47, -1, [1108]), initValues(_3C_classLit, 47, -1, [954]), initValues(_3C_classLit, 47, -1, [1008]), initValues(_3C_classLit, 47, -1, [311]), initValues(_3C_classLit, 47, -1, [1082]), initValues(_3C_classLit, 47, -1, [55349, 56616]), initValues(_3C_classLit, 47, -1, [312]), initValues(_3C_classLit, 47, -1, [1093]), initValues(_3C_classLit, 47, -1, [1116]), initValues(_3C_classLit, 47, -1, [55349, 56668]), initValues(_3C_classLit, 47, -1, [55349, 56512]), initValues(_3C_classLit, 47, -1, [8666]), initValues(_3C_classLit, 47, -1, [8656]), initValues(_3C_classLit, 47, -1, [10523]), initValues(_3C_classLit, 47, -1, [10510]), initValues(_3C_classLit, 47, -1, [8806]), initValues(_3C_classLit, 47, -1, [10891]), initValues(_3C_classLit, 47, -1, [10594]), initValues(_3C_classLit, 47, -1, [314]), initValues(_3C_classLit, 47, -1, [10676]), initValues(_3C_classLit, 47, -1, [8466]), initValues(_3C_classLit, 47, -1, [955]), initValues(_3C_classLit, 47, -1, [10216]), initValues(_3C_classLit, 47, -1, [10641]), initValues(_3C_classLit, 47, -1, [10216]), initValues(_3C_classLit, 47, -1, [10885]), initValues(_3C_classLit, 47, -1, [171]), initValues(_3C_classLit, 47, -1, [171]), initValues(_3C_classLit, 47, -1, [8592]), initValues(_3C_classLit, 47, -1, [8676]), initValues(_3C_classLit, 47, -1, [10527]), initValues(_3C_classLit, 47, -1, [10525]), initValues(_3C_classLit, 47, -1, [8617]), initValues(_3C_classLit, 47, -1, [8619]), initValues(_3C_classLit, 47, -1, [10553]), initValues(_3C_classLit, 47, -1, [10611]), initValues(_3C_classLit, 47, -1, [8610]), initValues(_3C_classLit, 47, -1, [10923]), initValues(_3C_classLit, 47, -1, [10521]), initValues(_3C_classLit, 47, -1, [10925]), initValues(_3C_classLit, 47, -1, [10508]), initValues(_3C_classLit, 47, -1, [10098]), initValues(_3C_classLit, 47, -1, [123]), initValues(_3C_classLit, 47, -1, [91]), initValues(_3C_classLit, 47, -1, [10635]), initValues(_3C_classLit, 47, -1, [10639]), initValues(_3C_classLit, 47, -1, [10637]), initValues(_3C_classLit, 47, -1, [318]), initValues(_3C_classLit, 47, -1, [316]), initValues(_3C_classLit, 47, -1, [8968]), initValues(_3C_classLit, 47, -1, [123]), initValues(_3C_classLit, 47, -1, [1083]), initValues(_3C_classLit, 47, -1, [10550]), initValues(_3C_classLit, 47, -1, [8220]), initValues(_3C_classLit, 47, -1, [8222]), initValues(_3C_classLit, 47, -1, [10599]), initValues(_3C_classLit, 47, -1, [10571]), initValues(_3C_classLit, 47, -1, [8626]), initValues(_3C_classLit, 47, -1, [8804]), initValues(_3C_classLit, 47, -1, [8592]), initValues(_3C_classLit, 47, -1, [8610]), initValues(_3C_classLit, 47, -1, [8637]), initValues(_3C_classLit, 47, -1, [8636]), initValues(_3C_classLit, 47, -1, [8647]), initValues(_3C_classLit, 47, -1, [8596]), initValues(_3C_classLit, 47, -1, [8646]), initValues(_3C_classLit, 47, -1, [8651]), initValues(_3C_classLit, 47, -1, [8621]), initValues(_3C_classLit, 47, -1, [8907]), initValues(_3C_classLit, 47, -1, [8922]), initValues(_3C_classLit, 47, -1, [8804]), initValues(_3C_classLit, 47, -1, [8806]), initValues(_3C_classLit, 47, -1, [10877]), initValues(_3C_classLit, 47, -1, [10877]), initValues(_3C_classLit, 47, -1, [10920]), initValues(_3C_classLit, 47, -1, [10879]), initValues(_3C_classLit, 47, -1, [10881]), initValues(_3C_classLit, 47, -1, [10883]), initValues(_3C_classLit, 47, -1, [10899]), initValues(_3C_classLit, 47, -1, [10885]), initValues(_3C_classLit, 47, -1, [8918]), initValues(_3C_classLit, 47, -1, [8922]), initValues(_3C_classLit, 47, -1, [10891]), initValues(_3C_classLit, 47, -1, [8822]), initValues(_3C_classLit, 47, -1, [8818]), initValues(_3C_classLit, 47, -1, [10620]), initValues(_3C_classLit, 47, -1, [8970]), initValues(_3C_classLit, 47, -1, [55349, 56617]), initValues(_3C_classLit, 47, -1, [8822]), initValues(_3C_classLit, 47, -1, [10897]), initValues(_3C_classLit, 47, -1, [8637]), initValues(_3C_classLit, 47, -1, [8636]), initValues(_3C_classLit, 47, -1, [10602]), initValues(_3C_classLit, 47, -1, [9604]), initValues(_3C_classLit, 47, -1, [1113]), initValues(_3C_classLit, 47, -1, [8810]), initValues(_3C_classLit, 47, -1, [8647]), initValues(_3C_classLit, 47, -1, [8990]), initValues(_3C_classLit, 47, -1, [10603]), initValues(_3C_classLit, 47, -1, [9722]), initValues(_3C_classLit, 47, -1, [320]), initValues(_3C_classLit, 47, -1, [9136]), initValues(_3C_classLit, 47, -1, [9136]), initValues(_3C_classLit, 47, -1, [8808]), initValues(_3C_classLit, 47, -1, [10889]), initValues(_3C_classLit, 47, -1, [10889]), initValues(_3C_classLit, 47, -1, [10887]), initValues(_3C_classLit, 47, -1, [10887]), initValues(_3C_classLit, 47, -1, [8808]), initValues(_3C_classLit, 47, -1, [8934]), initValues(_3C_classLit, 47, -1, [10220]), initValues(_3C_classLit, 47, -1, [8701]), initValues(_3C_classLit, 47, -1, [10214]), initValues(_3C_classLit, 47, -1, [10229]), initValues(_3C_classLit, 47, -1, [10231]), initValues(_3C_classLit, 47, -1, [10236]), initValues(_3C_classLit, 47, -1, [10230]), initValues(_3C_classLit, 47, -1, [8619]), initValues(_3C_classLit, 47, -1, [8620]), initValues(_3C_classLit, 47, -1, [10629]), initValues(_3C_classLit, 47, -1, [55349, 56669]), initValues(_3C_classLit, 47, -1, [10797]), initValues(_3C_classLit, 47, -1, [10804]), initValues(_3C_classLit, 47, -1, [8727]), initValues(_3C_classLit, 47, -1, [95]), initValues(_3C_classLit, 47, -1, [9674]), initValues(_3C_classLit, 47, -1, [9674]), initValues(_3C_classLit, 47, -1, [10731]), initValues(_3C_classLit, 47, -1, [40]), initValues(_3C_classLit, 47, -1, [10643]), initValues(_3C_classLit, 47, -1, [8646]), initValues(_3C_classLit, 47, -1, [8991]), initValues(_3C_classLit, 47, -1, [8651]), initValues(_3C_classLit, 47, -1, [10605]), initValues(_3C_classLit, 47, -1, [8206]), initValues(_3C_classLit, 47, -1, [8895]), initValues(_3C_classLit, 47, -1, [8249]), initValues(_3C_classLit, 47, -1, [55349, 56513]), initValues(_3C_classLit, 47, -1, [8624]), initValues(_3C_classLit, 47, -1, [8818]), initValues(_3C_classLit, 47, -1, [10893]), initValues(_3C_classLit, 47, -1, [10895]), initValues(_3C_classLit, 47, -1, [91]), initValues(_3C_classLit, 47, -1, [8216]), initValues(_3C_classLit, 47, -1, [8218]), initValues(_3C_classLit, 47, -1, [322]), initValues(_3C_classLit, 47, -1, [60]), initValues(_3C_classLit, 47, -1, [60]), initValues(_3C_classLit, 47, -1, [10918]), initValues(_3C_classLit, 47, -1, [10873]), initValues(_3C_classLit, 47, -1, [8918]), initValues(_3C_classLit, 47, -1, [8907]), initValues(_3C_classLit, 47, -1, [8905]), initValues(_3C_classLit, 47, -1, [10614]), initValues(_3C_classLit, 47, -1, [10875]), initValues(_3C_classLit, 47, -1, [10646]), initValues(_3C_classLit, 47, -1, [9667]), initValues(_3C_classLit, 47, -1, [8884]), initValues(_3C_classLit, 47, -1, [9666]), initValues(_3C_classLit, 47, -1, [10570]), initValues(_3C_classLit, 47, -1, [10598]), initValues(_3C_classLit, 47, -1, [8762]), initValues(_3C_classLit, 47, -1, [175]), initValues(_3C_classLit, 47, -1, [175]), initValues(_3C_classLit, 47, -1, [9794]), initValues(_3C_classLit, 47, -1, [10016]), initValues(_3C_classLit, 47, -1, [10016]), initValues(_3C_classLit, 47, -1, [8614]), initValues(_3C_classLit, 47, -1, [8614]), initValues(_3C_classLit, 47, -1, [8615]), initValues(_3C_classLit, 47, -1, [8612]), initValues(_3C_classLit, 47, -1, [8613]), initValues(_3C_classLit, 47, -1, [9646]), initValues(_3C_classLit, 47, -1, [10793]), initValues(_3C_classLit, 47, -1, [1084]), initValues(_3C_classLit, 47, -1, [8212]), initValues(_3C_classLit, 47, -1, [8737]), initValues(_3C_classLit, 47, -1, [55349, 56618]), initValues(_3C_classLit, 47, -1, [8487]), initValues(_3C_classLit, 47, -1, [181]), initValues(_3C_classLit, 47, -1, [181]), initValues(_3C_classLit, 47, -1, [8739]), initValues(_3C_classLit, 47, -1, [42]), initValues(_3C_classLit, 47, -1, [10992]), initValues(_3C_classLit, 47, -1, [183]), initValues(_3C_classLit, 47, -1, [183]), initValues(_3C_classLit, 47, -1, [8722]), initValues(_3C_classLit, 47, -1, [8863]), initValues(_3C_classLit, 47, -1, [8760]), initValues(_3C_classLit, 47, -1, [10794]), initValues(_3C_classLit, 47, -1, [10971]), initValues(_3C_classLit, 47, -1, [8230]), initValues(_3C_classLit, 47, -1, [8723]), initValues(_3C_classLit, 47, -1, [8871]), initValues(_3C_classLit, 47, -1, [55349, 56670]), initValues(_3C_classLit, 47, -1, [8723]), initValues(_3C_classLit, 47, -1, [55349, 56514]), initValues(_3C_classLit, 47, -1, [8766]), initValues(_3C_classLit, 47, -1, [956]), initValues(_3C_classLit, 47, -1, [8888]), initValues(_3C_classLit, 47, -1, [8888]), initValues(_3C_classLit, 47, -1, [8653]), initValues(_3C_classLit, 47, -1, [8654]), initValues(_3C_classLit, 47, -1, [8655]), initValues(_3C_classLit, 47, -1, [8879]), initValues(_3C_classLit, 47, -1, [8878]), initValues(_3C_classLit, 47, -1, [8711]), initValues(_3C_classLit, 47, -1, [324]), initValues(_3C_classLit, 47, -1, [8777]), initValues(_3C_classLit, 47, -1, [329]), initValues(_3C_classLit, 47, -1, [8777]), initValues(_3C_classLit, 47, -1, [9838]), initValues(_3C_classLit, 47, -1, [9838]), initValues(_3C_classLit, 47, -1, [8469]), initValues(_3C_classLit, 47, -1, [160]), initValues(_3C_classLit, 47, -1, [160]), initValues(_3C_classLit, 47, -1, [10819]), initValues(_3C_classLit, 47, -1, [328]), initValues(_3C_classLit, 47, -1, [326]), initValues(_3C_classLit, 47, -1, [8775]), initValues(_3C_classLit, 47, -1, [10818]), initValues(_3C_classLit, 47, -1, [1085]), initValues(_3C_classLit, 47, -1, [8211]), initValues(_3C_classLit, 47, -1, [8800]), initValues(_3C_classLit, 47, -1, [8663]), initValues(_3C_classLit, 47, -1, [10532]), initValues(_3C_classLit, 47, -1, [8599]), initValues(_3C_classLit, 47, -1, [8599]), initValues(_3C_classLit, 47, -1, [8802]), initValues(_3C_classLit, 47, -1, [10536]), initValues(_3C_classLit, 47, -1, [8708]), initValues(_3C_classLit, 47, -1, [8708]), initValues(_3C_classLit, 47, -1, [55349, 56619]), initValues(_3C_classLit, 47, -1, [8817]), initValues(_3C_classLit, 47, -1, [8817]), initValues(_3C_classLit, 47, -1, [8821]), initValues(_3C_classLit, 47, -1, [8815]), initValues(_3C_classLit, 47, -1, [8815]), initValues(_3C_classLit, 47, -1, [8654]), initValues(_3C_classLit, 47, -1, [8622]), initValues(_3C_classLit, 47, -1, [10994]), initValues(_3C_classLit, 47, -1, [8715]), initValues(_3C_classLit, 47, -1, [8956]), initValues(_3C_classLit, 47, -1, [8954]), initValues(_3C_classLit, 47, -1, [8715]), initValues(_3C_classLit, 47, -1, [1114]), initValues(_3C_classLit, 47, -1, [8653]), initValues(_3C_classLit, 47, -1, [8602]), initValues(_3C_classLit, 47, -1, [8229]), initValues(_3C_classLit, 47, -1, [8816]), initValues(_3C_classLit, 47, -1, [8602]), initValues(_3C_classLit, 47, -1, [8622]), initValues(_3C_classLit, 47, -1, [8816]), initValues(_3C_classLit, 47, -1, [8814]), initValues(_3C_classLit, 47, -1, [8820]), initValues(_3C_classLit, 47, -1, [8814]), initValues(_3C_classLit, 47, -1, [8938]), initValues(_3C_classLit, 47, -1, [8940]), initValues(_3C_classLit, 47, -1, [8740]), initValues(_3C_classLit, 47, -1, [55349, 56671]), initValues(_3C_classLit, 47, -1, [172]), initValues(_3C_classLit, 47, -1, [172]), initValues(_3C_classLit, 47, -1, [8713]), initValues(_3C_classLit, 47, -1, [8713]), initValues(_3C_classLit, 47, -1, [8951]), initValues(_3C_classLit, 47, -1, [8950]), initValues(_3C_classLit, 47, -1, [8716]), initValues(_3C_classLit, 47, -1, [8716]), initValues(_3C_classLit, 47, -1, [8958]), initValues(_3C_classLit, 47, -1, [8957]), initValues(_3C_classLit, 47, -1, [8742]), initValues(_3C_classLit, 47, -1, [8742]), initValues(_3C_classLit, 47, -1, [10772]), initValues(_3C_classLit, 47, -1, [8832]), initValues(_3C_classLit, 47, -1, [8928]), initValues(_3C_classLit, 47, -1, [8832]), initValues(_3C_classLit, 47, -1, [8655]), initValues(_3C_classLit, 47, -1, [8603]), initValues(_3C_classLit, 47, -1, [8603]), initValues(_3C_classLit, 47, -1, [8939]), initValues(_3C_classLit, 47, -1, [8941]), initValues(_3C_classLit, 47, -1, [8833]), initValues(_3C_classLit, 47, -1, [8929]), initValues(_3C_classLit, 47, -1, [55349, 56515]), initValues(_3C_classLit, 47, -1, [8740]), initValues(_3C_classLit, 47, -1, [8742]), initValues(_3C_classLit, 47, -1, [8769]), initValues(_3C_classLit, 47, -1, [8772]), initValues(_3C_classLit, 47, -1, [8772]), initValues(_3C_classLit, 47, -1, [8740]), initValues(_3C_classLit, 47, -1, [8742]), initValues(_3C_classLit, 47, -1, [8930]), initValues(_3C_classLit, 47, -1, [8931]), initValues(_3C_classLit, 47, -1, [8836]), initValues(_3C_classLit, 47, -1, [8840]), initValues(_3C_classLit, 47, -1, [8840]), initValues(_3C_classLit, 47, -1, [8833]), initValues(_3C_classLit, 47, -1, [8837]), initValues(_3C_classLit, 47, -1, [8841]), initValues(_3C_classLit, 47, -1, [8841]), initValues(_3C_classLit, 47, -1, [8825]), initValues(_3C_classLit, 47, -1, [241]), initValues(_3C_classLit, 47, -1, [241]), initValues(_3C_classLit, 47, -1, [8824]), initValues(_3C_classLit, 47, -1, [8938]), initValues(_3C_classLit, 47, -1, [8940]), initValues(_3C_classLit, 47, -1, [8939]), initValues(_3C_classLit, 47, -1, [8941]), initValues(_3C_classLit, 47, -1, [957]), initValues(_3C_classLit, 47, -1, [35]), initValues(_3C_classLit, 47, -1, [8470]), initValues(_3C_classLit, 47, -1, [8199]), initValues(_3C_classLit, 47, -1, [8877]), initValues(_3C_classLit, 47, -1, [10500]), initValues(_3C_classLit, 47, -1, [8876]), initValues(_3C_classLit, 47, -1, [10718]), initValues(_3C_classLit, 47, -1, [10498]), initValues(_3C_classLit, 47, -1, [10499]), initValues(_3C_classLit, 47, -1, [8662]), initValues(_3C_classLit, 47, -1, [10531]), initValues(_3C_classLit, 47, -1, [8598]), initValues(_3C_classLit, 47, -1, [8598]), initValues(_3C_classLit, 47, -1, [10535]), initValues(_3C_classLit, 47, -1, [9416]), initValues(_3C_classLit, 47, -1, [243]), initValues(_3C_classLit, 47, -1, [243]), initValues(_3C_classLit, 47, -1, [8859]), initValues(_3C_classLit, 47, -1, [8858]), initValues(_3C_classLit, 47, -1, [244]), initValues(_3C_classLit, 47, -1, [244]), initValues(_3C_classLit, 47, -1, [1086]), initValues(_3C_classLit, 47, -1, [8861]), initValues(_3C_classLit, 47, -1, [337]), initValues(_3C_classLit, 47, -1, [10808]), initValues(_3C_classLit, 47, -1, [8857]), initValues(_3C_classLit, 47, -1, [10684]), initValues(_3C_classLit, 47, -1, [339]), initValues(_3C_classLit, 47, -1, [10687]), initValues(_3C_classLit, 47, -1, [55349, 56620]), initValues(_3C_classLit, 47, -1, [731]), initValues(_3C_classLit, 47, -1, [242]), initValues(_3C_classLit, 47, -1, [242]), initValues(_3C_classLit, 47, -1, [10689]), initValues(_3C_classLit, 47, -1, [10677]), initValues(_3C_classLit, 47, -1, [937]), initValues(_3C_classLit, 47, -1, [8750]), initValues(_3C_classLit, 47, -1, [8634]), initValues(_3C_classLit, 47, -1, [10686]), initValues(_3C_classLit, 47, -1, [10683]), initValues(_3C_classLit, 47, -1, [8254]), initValues(_3C_classLit, 47, -1, [10688]), initValues(_3C_classLit, 47, -1, [333]), initValues(_3C_classLit, 47, -1, [969]), initValues(_3C_classLit, 47, -1, [959]), initValues(_3C_classLit, 47, -1, [10678]), initValues(_3C_classLit, 47, -1, [8854]), initValues(_3C_classLit, 47, -1, [55349, 56672]), initValues(_3C_classLit, 47, -1, [10679]), initValues(_3C_classLit, 47, -1, [10681]), initValues(_3C_classLit, 47, -1, [8853]), initValues(_3C_classLit, 47, -1, [8744]), initValues(_3C_classLit, 47, -1, [8635]), initValues(_3C_classLit, 47, -1, [10845]), initValues(_3C_classLit, 47, -1, [8500]), initValues(_3C_classLit, 47, -1, [8500]), initValues(_3C_classLit, 47, -1, [170]), initValues(_3C_classLit, 47, -1, [170]), initValues(_3C_classLit, 47, -1, [186]), initValues(_3C_classLit, 47, -1, [186]), initValues(_3C_classLit, 47, -1, [8886]), initValues(_3C_classLit, 47, -1, [10838]), initValues(_3C_classLit, 47, -1, [10839]), initValues(_3C_classLit, 47, -1, [10843]), initValues(_3C_classLit, 47, -1, [8500]), initValues(_3C_classLit, 47, -1, [248]), initValues(_3C_classLit, 47, -1, [248]), initValues(_3C_classLit, 47, -1, [8856]), initValues(_3C_classLit, 47, -1, [245]), initValues(_3C_classLit, 47, -1, [245]), initValues(_3C_classLit, 47, -1, [8855]), initValues(_3C_classLit, 47, -1, [10806]), initValues(_3C_classLit, 47, -1, [246]), initValues(_3C_classLit, 47, -1, [246]), initValues(_3C_classLit, 47, -1, [9021]), initValues(_3C_classLit, 47, -1, [8741]), initValues(_3C_classLit, 47, -1, [182]), initValues(_3C_classLit, 47, -1, [182]), initValues(_3C_classLit, 47, -1, [8741]), initValues(_3C_classLit, 47, -1, [10995]), initValues(_3C_classLit, 47, -1, [11005]), initValues(_3C_classLit, 47, -1, [8706]), initValues(_3C_classLit, 47, -1, [1087]), initValues(_3C_classLit, 47, -1, [37]), initValues(_3C_classLit, 47, -1, [46]), initValues(_3C_classLit, 47, -1, [8240]), initValues(_3C_classLit, 47, -1, [8869]), initValues(_3C_classLit, 47, -1, [8241]), initValues(_3C_classLit, 47, -1, [55349, 56621]), initValues(_3C_classLit, 47, -1, [966]), initValues(_3C_classLit, 47, -1, [981]), initValues(_3C_classLit, 47, -1, [8499]), initValues(_3C_classLit, 47, -1, [9742]), initValues(_3C_classLit, 47, -1, [960]), initValues(_3C_classLit, 47, -1, [8916]), initValues(_3C_classLit, 47, -1, [982]), initValues(_3C_classLit, 47, -1, [8463]), initValues(_3C_classLit, 47, -1, [8462]), initValues(_3C_classLit, 47, -1, [8463]), initValues(_3C_classLit, 47, -1, [43]), initValues(_3C_classLit, 47, -1, [10787]), initValues(_3C_classLit, 47, -1, [8862]), initValues(_3C_classLit, 47, -1, [10786]), initValues(_3C_classLit, 47, -1, [8724]), initValues(_3C_classLit, 47, -1, [10789]), initValues(_3C_classLit, 47, -1, [10866]), initValues(_3C_classLit, 47, -1, [177]), initValues(_3C_classLit, 47, -1, [177]), initValues(_3C_classLit, 47, -1, [10790]), initValues(_3C_classLit, 47, -1, [10791]), initValues(_3C_classLit, 47, -1, [177]), initValues(_3C_classLit, 47, -1, [10773]), initValues(_3C_classLit, 47, -1, [55349, 56673]), initValues(_3C_classLit, 47, -1, [163]), initValues(_3C_classLit, 47, -1, [163]), initValues(_3C_classLit, 47, -1, [8826]), initValues(_3C_classLit, 47, -1, [10931]), initValues(_3C_classLit, 47, -1, [10935]), initValues(_3C_classLit, 47, -1, [8828]), initValues(_3C_classLit, 47, -1, [10927]), initValues(_3C_classLit, 47, -1, [8826]), initValues(_3C_classLit, 47, -1, [10935]), initValues(_3C_classLit, 47, -1, [8828]), initValues(_3C_classLit, 47, -1, [10927]), initValues(_3C_classLit, 47, -1, [10937]), initValues(_3C_classLit, 47, -1, [10933]), initValues(_3C_classLit, 47, -1, [8936]), initValues(_3C_classLit, 47, -1, [8830]), initValues(_3C_classLit, 47, -1, [8242]), initValues(_3C_classLit, 47, -1, [8473]), initValues(_3C_classLit, 47, -1, [10933]), initValues(_3C_classLit, 47, -1, [10937]), initValues(_3C_classLit, 47, -1, [8936]), initValues(_3C_classLit, 47, -1, [8719]), initValues(_3C_classLit, 47, -1, [9006]), initValues(_3C_classLit, 47, -1, [8978]), initValues(_3C_classLit, 47, -1, [8979]), initValues(_3C_classLit, 47, -1, [8733]), initValues(_3C_classLit, 47, -1, [8733]), initValues(_3C_classLit, 47, -1, [8830]), initValues(_3C_classLit, 47, -1, [8880]), initValues(_3C_classLit, 47, -1, [55349, 56517]), initValues(_3C_classLit, 47, -1, [968]), initValues(_3C_classLit, 47, -1, [8200]), initValues(_3C_classLit, 47, -1, [55349, 56622]), initValues(_3C_classLit, 47, -1, [10764]), initValues(_3C_classLit, 47, -1, [55349, 56674]), initValues(_3C_classLit, 47, -1, [8279]), initValues(_3C_classLit, 47, -1, [55349, 56518]), initValues(_3C_classLit, 47, -1, [8461]), initValues(_3C_classLit, 47, -1, [10774]), initValues(_3C_classLit, 47, -1, [63]), initValues(_3C_classLit, 47, -1, [8799]), initValues(_3C_classLit, 47, -1, [34]), initValues(_3C_classLit, 47, -1, [34]), initValues(_3C_classLit, 47, -1, [8667]), initValues(_3C_classLit, 47, -1, [8658]), initValues(_3C_classLit, 47, -1, [10524]), initValues(_3C_classLit, 47, -1, [10511]), initValues(_3C_classLit, 47, -1, [10596]), initValues(_3C_classLit, 47, -1, [341]), initValues(_3C_classLit, 47, -1, [8730]), initValues(_3C_classLit, 47, -1, [10675]), initValues(_3C_classLit, 47, -1, [10217]), initValues(_3C_classLit, 47, -1, [10642]), initValues(_3C_classLit, 47, -1, [10661]), initValues(_3C_classLit, 47, -1, [10217]), initValues(_3C_classLit, 47, -1, [187]), initValues(_3C_classLit, 47, -1, [187]), initValues(_3C_classLit, 47, -1, [8594]), initValues(_3C_classLit, 47, -1, [10613]), initValues(_3C_classLit, 47, -1, [8677]), initValues(_3C_classLit, 47, -1, [10528]), initValues(_3C_classLit, 47, -1, [10547]), initValues(_3C_classLit, 47, -1, [10526]), initValues(_3C_classLit, 47, -1, [8618]), initValues(_3C_classLit, 47, -1, [8620]), initValues(_3C_classLit, 47, -1, [10565]), initValues(_3C_classLit, 47, -1, [10612]), initValues(_3C_classLit, 47, -1, [8611]), initValues(_3C_classLit, 47, -1, [8605]), initValues(_3C_classLit, 47, -1, [10522]), initValues(_3C_classLit, 47, -1, [8758]), initValues(_3C_classLit, 47, -1, [8474]), initValues(_3C_classLit, 47, -1, [10509]), initValues(_3C_classLit, 47, -1, [10099]), initValues(_3C_classLit, 47, -1, [125]), initValues(_3C_classLit, 47, -1, [93]), initValues(_3C_classLit, 47, -1, [10636]), initValues(_3C_classLit, 47, -1, [10638]), initValues(_3C_classLit, 47, -1, [10640]), initValues(_3C_classLit, 47, -1, [345]), initValues(_3C_classLit, 47, -1, [343]), initValues(_3C_classLit, 47, -1, [8969]), initValues(_3C_classLit, 47, -1, [125]), initValues(_3C_classLit, 47, -1, [1088]), initValues(_3C_classLit, 47, -1, [10551]), initValues(_3C_classLit, 47, -1, [10601]), initValues(_3C_classLit, 47, -1, [8221]), initValues(_3C_classLit, 47, -1, [8221]), initValues(_3C_classLit, 47, -1, [8627]), initValues(_3C_classLit, 47, -1, [8476]), initValues(_3C_classLit, 47, -1, [8475]), initValues(_3C_classLit, 47, -1, [8476]), initValues(_3C_classLit, 47, -1, [8477]), initValues(_3C_classLit, 47, -1, [9645]), initValues(_3C_classLit, 47, -1, [174]), initValues(_3C_classLit, 47, -1, [174]), initValues(_3C_classLit, 47, -1, [10621]), initValues(_3C_classLit, 47, -1, [8971]), initValues(_3C_classLit, 47, -1, [55349, 56623]), initValues(_3C_classLit, 47, -1, [8641]), initValues(_3C_classLit, 47, -1, [8640]), initValues(_3C_classLit, 47, -1, [10604]), initValues(_3C_classLit, 47, -1, [961]), initValues(_3C_classLit, 47, -1, [1009]), initValues(_3C_classLit, 47, -1, [8594]), initValues(_3C_classLit, 47, -1, [8611]), initValues(_3C_classLit, 47, -1, [8641]), initValues(_3C_classLit, 47, -1, [8640]), initValues(_3C_classLit, 47, -1, [8644]), initValues(_3C_classLit, 47, -1, [8652]), initValues(_3C_classLit, 47, -1, [8649]), initValues(_3C_classLit, 47, -1, [8605]), initValues(_3C_classLit, 47, -1, [8908]), initValues(_3C_classLit, 47, -1, [730]), initValues(_3C_classLit, 47, -1, [8787]), initValues(_3C_classLit, 47, -1, [8644]), initValues(_3C_classLit, 47, -1, [8652]), initValues(_3C_classLit, 47, -1, [8207]), initValues(_3C_classLit, 47, -1, [9137]), initValues(_3C_classLit, 47, -1, [9137]), initValues(_3C_classLit, 47, -1, [10990]), initValues(_3C_classLit, 47, -1, [10221]), initValues(_3C_classLit, 47, -1, [8702]), initValues(_3C_classLit, 47, -1, [10215]), initValues(_3C_classLit, 47, -1, [10630]), initValues(_3C_classLit, 47, -1, [55349, 56675]), initValues(_3C_classLit, 47, -1, [10798]), initValues(_3C_classLit, 47, -1, [10805]), initValues(_3C_classLit, 47, -1, [41]), initValues(_3C_classLit, 47, -1, [10644]), initValues(_3C_classLit, 47, -1, [10770]), initValues(_3C_classLit, 47, -1, [8649]), initValues(_3C_classLit, 47, -1, [8250]), initValues(_3C_classLit, 47, -1, [55349, 56519]), initValues(_3C_classLit, 47, -1, [8625]), initValues(_3C_classLit, 47, -1, [93]), initValues(_3C_classLit, 47, -1, [8217]), initValues(_3C_classLit, 47, -1, [8217]), initValues(_3C_classLit, 47, -1, [8908]), initValues(_3C_classLit, 47, -1, [8906]), initValues(_3C_classLit, 47, -1, [9657]), initValues(_3C_classLit, 47, -1, [8885]), initValues(_3C_classLit, 47, -1, [9656]), initValues(_3C_classLit, 47, -1, [10702]), initValues(_3C_classLit, 47, -1, [10600]), initValues(_3C_classLit, 47, -1, [8478]), initValues(_3C_classLit, 47, -1, [347]), initValues(_3C_classLit, 47, -1, [8218]), initValues(_3C_classLit, 47, -1, [8827]), initValues(_3C_classLit, 47, -1, [10932]), initValues(_3C_classLit, 47, -1, [10936]), initValues(_3C_classLit, 47, -1, [353]), initValues(_3C_classLit, 47, -1, [8829]), initValues(_3C_classLit, 47, -1, [10928]), initValues(_3C_classLit, 47, -1, [351]), initValues(_3C_classLit, 47, -1, [349]), initValues(_3C_classLit, 47, -1, [10934]), initValues(_3C_classLit, 47, -1, [10938]), initValues(_3C_classLit, 47, -1, [8937]), initValues(_3C_classLit, 47, -1, [10771]), initValues(_3C_classLit, 47, -1, [8831]), initValues(_3C_classLit, 47, -1, [1089]), initValues(_3C_classLit, 47, -1, [8901]), initValues(_3C_classLit, 47, -1, [8865]), initValues(_3C_classLit, 47, -1, [10854]), initValues(_3C_classLit, 47, -1, [8664]), initValues(_3C_classLit, 47, -1, [10533]), initValues(_3C_classLit, 47, -1, [8600]), initValues(_3C_classLit, 47, -1, [8600]), initValues(_3C_classLit, 47, -1, [167]), initValues(_3C_classLit, 47, -1, [167]), initValues(_3C_classLit, 47, -1, [59]), initValues(_3C_classLit, 47, -1, [10537]), initValues(_3C_classLit, 47, -1, [8726]), initValues(_3C_classLit, 47, -1, [8726]), initValues(_3C_classLit, 47, -1, [10038]), initValues(_3C_classLit, 47, -1, [55349, 56624]), initValues(_3C_classLit, 47, -1, [8994]), initValues(_3C_classLit, 47, -1, [9839]), initValues(_3C_classLit, 47, -1, [1097]), initValues(_3C_classLit, 47, -1, [1096]), initValues(_3C_classLit, 47, -1, [8739]), initValues(_3C_classLit, 47, -1, [8741]), initValues(_3C_classLit, 47, -1, [173]), initValues(_3C_classLit, 47, -1, [173]), initValues(_3C_classLit, 47, -1, [963]), initValues(_3C_classLit, 47, -1, [962]), initValues(_3C_classLit, 47, -1, [962]), initValues(_3C_classLit, 47, -1, [8764]), initValues(_3C_classLit, 47, -1, [10858]), initValues(_3C_classLit, 47, -1, [8771]), initValues(_3C_classLit, 47, -1, [8771]), initValues(_3C_classLit, 47, -1, [10910]), initValues(_3C_classLit, 47, -1, [10912]), initValues(_3C_classLit, 47, -1, [10909]), initValues(_3C_classLit, 47, -1, [10911]), initValues(_3C_classLit, 47, -1, [8774]), initValues(_3C_classLit, 47, -1, [10788]), initValues(_3C_classLit, 47, -1, [10610]), initValues(_3C_classLit, 47, -1, [8592]), initValues(_3C_classLit, 47, -1, [8726]), initValues(_3C_classLit, 47, -1, [10803]), initValues(_3C_classLit, 47, -1, [10724]), initValues(_3C_classLit, 47, -1, [8739]), initValues(_3C_classLit, 47, -1, [8995]), initValues(_3C_classLit, 47, -1, [10922]), initValues(_3C_classLit, 47, -1, [10924]), initValues(_3C_classLit, 47, -1, [1100]), initValues(_3C_classLit, 47, -1, [47]), initValues(_3C_classLit, 47, -1, [10692]), initValues(_3C_classLit, 47, -1, [9023]), initValues(_3C_classLit, 47, -1, [55349, 56676]), initValues(_3C_classLit, 47, -1, [9824]), initValues(_3C_classLit, 47, -1, [9824]), initValues(_3C_classLit, 47, -1, [8741]), initValues(_3C_classLit, 47, -1, [8851]), initValues(_3C_classLit, 47, -1, [8852]), initValues(_3C_classLit, 47, -1, [8847]), initValues(_3C_classLit, 47, -1, [8849]), initValues(_3C_classLit, 47, -1, [8847]), initValues(_3C_classLit, 47, -1, [8849]), initValues(_3C_classLit, 47, -1, [8848]), initValues(_3C_classLit, 47, -1, [8850]), initValues(_3C_classLit, 47, -1, [8848]), initValues(_3C_classLit, 47, -1, [8850]), initValues(_3C_classLit, 47, -1, [9633]), initValues(_3C_classLit, 47, -1, [9633]), initValues(_3C_classLit, 47, -1, [9642]), initValues(_3C_classLit, 47, -1, [9642]), initValues(_3C_classLit, 47, -1, [8594]), initValues(_3C_classLit, 47, -1, [55349, 56520]), initValues(_3C_classLit, 47, -1, [8726]), initValues(_3C_classLit, 47, -1, [8995]), initValues(_3C_classLit, 47, -1, [8902]), initValues(_3C_classLit, 47, -1, [9734]), initValues(_3C_classLit, 47, -1, [9733]), initValues(_3C_classLit, 47, -1, [1013]), initValues(_3C_classLit, 47, -1, [981]), initValues(_3C_classLit, 47, -1, [175]), initValues(_3C_classLit, 47, -1, [8834]), initValues(_3C_classLit, 47, -1, [10949]), initValues(_3C_classLit, 47, -1, [10941]), initValues(_3C_classLit, 47, -1, [8838]), initValues(_3C_classLit, 47, -1, [10947]), initValues(_3C_classLit, 47, -1, [10945]), initValues(_3C_classLit, 47, -1, [10955]), initValues(_3C_classLit, 47, -1, [8842]), initValues(_3C_classLit, 47, -1, [10943]), initValues(_3C_classLit, 47, -1, [10617]), initValues(_3C_classLit, 47, -1, [8834]), initValues(_3C_classLit, 47, -1, [8838]), initValues(_3C_classLit, 47, -1, [10949]), initValues(_3C_classLit, 47, -1, [8842]), initValues(_3C_classLit, 47, -1, [10955]), initValues(_3C_classLit, 47, -1, [10951]), initValues(_3C_classLit, 47, -1, [10965]), initValues(_3C_classLit, 47, -1, [10963]), initValues(_3C_classLit, 47, -1, [8827]), initValues(_3C_classLit, 47, -1, [10936]), initValues(_3C_classLit, 47, -1, [8829]), initValues(_3C_classLit, 47, -1, [10928]), initValues(_3C_classLit, 47, -1, [10938]), initValues(_3C_classLit, 47, -1, [10934]), initValues(_3C_classLit, 47, -1, [8937]), initValues(_3C_classLit, 47, -1, [8831]), initValues(_3C_classLit, 47, -1, [8721]), initValues(_3C_classLit, 47, -1, [9834]), initValues(_3C_classLit, 47, -1, [185]), initValues(_3C_classLit, 47, -1, [185]), initValues(_3C_classLit, 47, -1, [178]), initValues(_3C_classLit, 47, -1, [178]), initValues(_3C_classLit, 47, -1, [179]), initValues(_3C_classLit, 47, -1, [179]), initValues(_3C_classLit, 47, -1, [8835]), initValues(_3C_classLit, 47, -1, [10950]), initValues(_3C_classLit, 47, -1, [10942]), initValues(_3C_classLit, 47, -1, [10968]), initValues(_3C_classLit, 47, -1, [8839]), initValues(_3C_classLit, 47, -1, [10948]), initValues(_3C_classLit, 47, -1, [10185]), initValues(_3C_classLit, 47, -1, [10967]), initValues(_3C_classLit, 47, -1, [10619]), initValues(_3C_classLit, 47, -1, [10946]), initValues(_3C_classLit, 47, -1, [10956]), initValues(_3C_classLit, 47, -1, [8843]), initValues(_3C_classLit, 47, -1, [10944]), initValues(_3C_classLit, 47, -1, [8835]), initValues(_3C_classLit, 47, -1, [8839]), initValues(_3C_classLit, 47, -1, [10950]), initValues(_3C_classLit, 47, -1, [8843]), initValues(_3C_classLit, 47, -1, [10956]), initValues(_3C_classLit, 47, -1, [10952]), initValues(_3C_classLit, 47, -1, [10964]), initValues(_3C_classLit, 47, -1, [10966]), initValues(_3C_classLit, 47, -1, [8665]), initValues(_3C_classLit, 47, -1, [10534]), initValues(_3C_classLit, 47, -1, [8601]), initValues(_3C_classLit, 47, -1, [8601]), initValues(_3C_classLit, 47, -1, [10538]), initValues(_3C_classLit, 47, -1, [223]), initValues(_3C_classLit, 47, -1, [223]), initValues(_3C_classLit, 47, -1, [8982]), initValues(_3C_classLit, 47, -1, [964]), initValues(_3C_classLit, 47, -1, [9140]), initValues(_3C_classLit, 47, -1, [357]), initValues(_3C_classLit, 47, -1, [355]), initValues(_3C_classLit, 47, -1, [1090]), initValues(_3C_classLit, 47, -1, [8411]), initValues(_3C_classLit, 47, -1, [8981]), initValues(_3C_classLit, 47, -1, [55349, 56625]), initValues(_3C_classLit, 47, -1, [8756]), initValues(_3C_classLit, 47, -1, [8756]), initValues(_3C_classLit, 47, -1, [952]), initValues(_3C_classLit, 47, -1, [977]), initValues(_3C_classLit, 47, -1, [977]), initValues(_3C_classLit, 47, -1, [8776]), initValues(_3C_classLit, 47, -1, [8764]), initValues(_3C_classLit, 47, -1, [8201]), initValues(_3C_classLit, 47, -1, [8776]), initValues(_3C_classLit, 47, -1, [8764]), initValues(_3C_classLit, 47, -1, [254]), initValues(_3C_classLit, 47, -1, [254]), initValues(_3C_classLit, 47, -1, [732]), initValues(_3C_classLit, 47, -1, [215]), initValues(_3C_classLit, 47, -1, [215]), initValues(_3C_classLit, 47, -1, [8864]), initValues(_3C_classLit, 47, -1, [10801]), initValues(_3C_classLit, 47, -1, [10800]), initValues(_3C_classLit, 47, -1, [8749]), initValues(_3C_classLit, 47, -1, [10536]), initValues(_3C_classLit, 47, -1, [8868]), initValues(_3C_classLit, 47, -1, [9014]), initValues(_3C_classLit, 47, -1, [10993]), initValues(_3C_classLit, 47, -1, [55349, 56677]), initValues(_3C_classLit, 47, -1, [10970]), initValues(_3C_classLit, 47, -1, [10537]), initValues(_3C_classLit, 47, -1, [8244]), initValues(_3C_classLit, 47, -1, [8482]), initValues(_3C_classLit, 47, -1, [9653]), initValues(_3C_classLit, 47, -1, [9663]), initValues(_3C_classLit, 47, -1, [9667]), initValues(_3C_classLit, 47, -1, [8884]), initValues(_3C_classLit, 47, -1, [8796]), initValues(_3C_classLit, 47, -1, [9657]), initValues(_3C_classLit, 47, -1, [8885]), initValues(_3C_classLit, 47, -1, [9708]), initValues(_3C_classLit, 47, -1, [8796]), initValues(_3C_classLit, 47, -1, [10810]), initValues(_3C_classLit, 47, -1, [10809]), initValues(_3C_classLit, 47, -1, [10701]), initValues(_3C_classLit, 47, -1, [10811]), initValues(_3C_classLit, 47, -1, [9186]), initValues(_3C_classLit, 47, -1, [55349, 56521]), initValues(_3C_classLit, 47, -1, [1094]), initValues(_3C_classLit, 47, -1, [1115]), initValues(_3C_classLit, 47, -1, [359]), initValues(_3C_classLit, 47, -1, [8812]), initValues(_3C_classLit, 47, -1, [8606]), initValues(_3C_classLit, 47, -1, [8608]), initValues(_3C_classLit, 47, -1, [8657]), initValues(_3C_classLit, 47, -1, [10595]), initValues(_3C_classLit, 47, -1, [250]), initValues(_3C_classLit, 47, -1, [250]), initValues(_3C_classLit, 47, -1, [8593]), initValues(_3C_classLit, 47, -1, [1118]), initValues(_3C_classLit, 47, -1, [365]), initValues(_3C_classLit, 47, -1, [251]), initValues(_3C_classLit, 47, -1, [251]), initValues(_3C_classLit, 47, -1, [1091]), initValues(_3C_classLit, 47, -1, [8645]), initValues(_3C_classLit, 47, -1, [369]), initValues(_3C_classLit, 47, -1, [10606]), initValues(_3C_classLit, 47, -1, [10622]), initValues(_3C_classLit, 47, -1, [55349, 56626]), initValues(_3C_classLit, 47, -1, [249]), initValues(_3C_classLit, 47, -1, [249]), initValues(_3C_classLit, 47, -1, [8639]), initValues(_3C_classLit, 47, -1, [8638]), initValues(_3C_classLit, 47, -1, [9600]), initValues(_3C_classLit, 47, -1, [8988]), initValues(_3C_classLit, 47, -1, [8988]), initValues(_3C_classLit, 47, -1, [8975]), initValues(_3C_classLit, 47, -1, [9720]), initValues(_3C_classLit, 47, -1, [363]), initValues(_3C_classLit, 47, -1, [168]), initValues(_3C_classLit, 47, -1, [168]), initValues(_3C_classLit, 47, -1, [371]), initValues(_3C_classLit, 47, -1, [55349, 56678]), initValues(_3C_classLit, 47, -1, [8593]), initValues(_3C_classLit, 47, -1, [8597]), initValues(_3C_classLit, 47, -1, [8639]), initValues(_3C_classLit, 47, -1, [8638]), initValues(_3C_classLit, 47, -1, [8846]), initValues(_3C_classLit, 47, -1, [965]), initValues(_3C_classLit, 47, -1, [978]), initValues(_3C_classLit, 47, -1, [965]), initValues(_3C_classLit, 47, -1, [8648]), initValues(_3C_classLit, 47, -1, [8989]), initValues(_3C_classLit, 47, -1, [8989]), initValues(_3C_classLit, 47, -1, [8974]), initValues(_3C_classLit, 47, -1, [367]), initValues(_3C_classLit, 47, -1, [9721]), initValues(_3C_classLit, 47, -1, [55349, 56522]), initValues(_3C_classLit, 47, -1, [8944]), initValues(_3C_classLit, 47, -1, [361]), initValues(_3C_classLit, 47, -1, [9653]), initValues(_3C_classLit, 47, -1, [9652]), initValues(_3C_classLit, 47, -1, [8648]), initValues(_3C_classLit, 47, -1, [252]), initValues(_3C_classLit, 47, -1, [252]), initValues(_3C_classLit, 47, -1, [10663]), initValues(_3C_classLit, 47, -1, [8661]), initValues(_3C_classLit, 47, -1, [10984]), initValues(_3C_classLit, 47, -1, [10985]), initValues(_3C_classLit, 47, -1, [8872]), initValues(_3C_classLit, 47, -1, [10652]), initValues(_3C_classLit, 47, -1, [1013]), initValues(_3C_classLit, 47, -1, [1008]), initValues(_3C_classLit, 47, -1, [8709]), initValues(_3C_classLit, 47, -1, [981]), initValues(_3C_classLit, 47, -1, [982]), initValues(_3C_classLit, 47, -1, [8733]), initValues(_3C_classLit, 47, -1, [8597]), initValues(_3C_classLit, 47, -1, [1009]), initValues(_3C_classLit, 47, -1, [962]), initValues(_3C_classLit, 47, -1, [977]), initValues(_3C_classLit, 47, -1, [8882]), initValues(_3C_classLit, 47, -1, [8883]), initValues(_3C_classLit, 47, -1, [1074]), initValues(_3C_classLit, 47, -1, [8866]), initValues(_3C_classLit, 47, -1, [8744]), initValues(_3C_classLit, 47, -1, [8891]), initValues(_3C_classLit, 47, -1, [8794]), initValues(_3C_classLit, 47, -1, [8942]), initValues(_3C_classLit, 47, -1, [124]), initValues(_3C_classLit, 47, -1, [124]), initValues(_3C_classLit, 47, -1, [55349, 56627]), initValues(_3C_classLit, 47, -1, [8882]), initValues(_3C_classLit, 47, -1, [55349, 56679]), initValues(_3C_classLit, 47, -1, [8733]), initValues(_3C_classLit, 47, -1, [8883]), initValues(_3C_classLit, 47, -1, [55349, 56523]), initValues(_3C_classLit, 47, -1, [10650]), initValues(_3C_classLit, 47, -1, [373]), initValues(_3C_classLit, 47, -1, [10847]), initValues(_3C_classLit, 47, -1, [8743]), initValues(_3C_classLit, 47, -1, [8793]), initValues(_3C_classLit, 47, -1, [8472]), initValues(_3C_classLit, 47, -1, [55349, 56628]), initValues(_3C_classLit, 47, -1, [55349, 56680]), initValues(_3C_classLit, 47, -1, [8472]), initValues(_3C_classLit, 47, -1, [8768]), initValues(_3C_classLit, 47, -1, [8768]), initValues(_3C_classLit, 47, -1, [55349, 56524]), initValues(_3C_classLit, 47, -1, [8898]), initValues(_3C_classLit, 47, -1, [9711]), initValues(_3C_classLit, 47, -1, [8899]), initValues(_3C_classLit, 47, -1, [9661]), initValues(_3C_classLit, 47, -1, [55349, 56629]), initValues(_3C_classLit, 47, -1, [10234]), initValues(_3C_classLit, 47, -1, [10231]), initValues(_3C_classLit, 47, -1, [958]), initValues(_3C_classLit, 47, -1, [10232]), initValues(_3C_classLit, 47, -1, [10229]), initValues(_3C_classLit, 47, -1, [10236]), initValues(_3C_classLit, 47, -1, [8955]), initValues(_3C_classLit, 47, -1, [10752]), initValues(_3C_classLit, 47, -1, [55349, 56681]), initValues(_3C_classLit, 47, -1, [10753]), initValues(_3C_classLit, 47, -1, [10754]), initValues(_3C_classLit, 47, -1, [10233]), initValues(_3C_classLit, 47, -1, [10230]), initValues(_3C_classLit, 47, -1, [55349, 56525]), initValues(_3C_classLit, 47, -1, [10758]), initValues(_3C_classLit, 47, -1, [10756]), initValues(_3C_classLit, 47, -1, [9651]), initValues(_3C_classLit, 47, -1, [8897]), initValues(_3C_classLit, 47, -1, [8896]), initValues(_3C_classLit, 47, -1, [253]), initValues(_3C_classLit, 47, -1, [253]), initValues(_3C_classLit, 47, -1, [1103]), initValues(_3C_classLit, 47, -1, [375]), initValues(_3C_classLit, 47, -1, [1099]), initValues(_3C_classLit, 47, -1, [165]), initValues(_3C_classLit, 47, -1, [165]), initValues(_3C_classLit, 47, -1, [55349, 56630]), initValues(_3C_classLit, 47, -1, [1111]), initValues(_3C_classLit, 47, -1, [55349, 56682]), initValues(_3C_classLit, 47, -1, [55349, 56526]), initValues(_3C_classLit, 47, -1, [1102]), initValues(_3C_classLit, 47, -1, [255]), initValues(_3C_classLit, 47, -1, [255]), initValues(_3C_classLit, 47, -1, [378]), initValues(_3C_classLit, 47, -1, [382]), initValues(_3C_classLit, 47, -1, [1079]), initValues(_3C_classLit, 47, -1, [380]), initValues(_3C_classLit, 47, -1, [8488]), initValues(_3C_classLit, 47, -1, [950]), initValues(_3C_classLit, 47, -1, [55349, 56631]), initValues(_3C_classLit, 47, -1, [1078]), initValues(_3C_classLit, 47, -1, [8669]), initValues(_3C_classLit, 47, -1, [55349, 56683]), initValues(_3C_classLit, 47, -1, [55349, 56527]), initValues(_3C_classLit, 47, -1, [8205]), initValues(_3C_classLit, 47, -1, [8204])]);
+  WINDOWS_1252 = initValues(_3_3C_classLit, 64, 17, [initValues(_3C_classLit, 47, -1, [8364]), initValues(_3C_classLit, 47, -1, [129]), initValues(_3C_classLit, 47, -1, [8218]), initValues(_3C_classLit, 47, -1, [402]), initValues(_3C_classLit, 47, -1, [8222]), initValues(_3C_classLit, 47, -1, [8230]), initValues(_3C_classLit, 47, -1, [8224]), initValues(_3C_classLit, 47, -1, [8225]), initValues(_3C_classLit, 47, -1, [710]), initValues(_3C_classLit, 47, -1, [8240]), initValues(_3C_classLit, 47, -1, [352]), initValues(_3C_classLit, 47, -1, [8249]), initValues(_3C_classLit, 47, -1, [338]), initValues(_3C_classLit, 47, -1, [141]), initValues(_3C_classLit, 47, -1, [381]), initValues(_3C_classLit, 47, -1, [143]), initValues(_3C_classLit, 47, -1, [144]), initValues(_3C_classLit, 47, -1, [8216]), initValues(_3C_classLit, 47, -1, [8217]), initValues(_3C_classLit, 47, -1, [8220]), initValues(_3C_classLit, 47, -1, [8221]), initValues(_3C_classLit, 47, -1, [8226]), initValues(_3C_classLit, 47, -1, [8211]), initValues(_3C_classLit, 47, -1, [8212]), initValues(_3C_classLit, 47, -1, [732]), initValues(_3C_classLit, 47, -1, [8482]), initValues(_3C_classLit, 47, -1, [353]), initValues(_3C_classLit, 47, -1, [8250]), initValues(_3C_classLit, 47, -1, [339]), initValues(_3C_classLit, 47, -1, [157]), initValues(_3C_classLit, 47, -1, [382]), initValues(_3C_classLit, 47, -1, [376])]);
+}
+
+function toByteArray(str){
+  var arr, i;
+  arr = initDim(_3B_classLit, 46, -1, str.length, 1);
+  for (i = 0; i < str.length; ++i) {
+    arr[i] = str.charCodeAt(i) << 24 >> 24;
+  }
+  return arr;
+}
+
+var NAMES, VALUES_0, WINDOWS_1252;
+function $clinit_132(){
+  $clinit_132 = nullMethod;
+  HILO_ACCEL = initValues(_3_3I_classLit, 66, 19, [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, initValues(_3I_classLit, 49, -1, [0, 0, 0, 0, 0, 0, 0, 12386493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38863441, 0, 0, 0, 0, 58524541, 0, 0, 0, 73466977, 0, 0, 0, 80282823, 0, 0, 0, 0, 0, 109971084, 0, 0, 130549704, 133957628, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27525540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80348362, 0, 0, 0, 0, 0, 110036623, 0, 0, 0, 134088701, 0, 0, 0, 0]), null, initValues(_3I_classLit, 49, -1, [0, 0, 0, 4980811, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37159479, 0, 0, 0, 0, 0, 0, 0, 0, 62915519, 0, 0, 0, 0, 0, 0, 0, 89982301, 0, 0, 0, 0, 0, 0, 0, 0, 134154239, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [65536, 0, 0, 0, 0, 0, 0, 0, 13172937, 0, 0, 0, 0, 0, 24052079, 0, 0, 27656613, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69796904, 0, 0, 0, 0, 80479435, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), null, null, initValues(_3I_classLit, 49, -1, [0, 0, 2555943, 0, 0, 0, 0, 0, 0, 0, 15532269, 0, 0, 0, 0, 0, 0, 0, 30540241, 33161721, 0, 0, 0, 0, 0, 39584348, 0, 0, 0, 58590078, 0, 0, 0, 0, 0, 0, 0, 80544973, 0, 0, 0, 0, 0, 110102160, 0, 0, 130615241, 0, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38928978, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [0, 0, 0, 5046349, 0, 0, 10944679, 0, 13238474, 0, 15597806, 16056565, 0, 20578618, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), null, initValues(_3I_classLit, 49, -1, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92669317, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [196610, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [0, 0, 0, 0, 8454273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44696234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [0, 0, 2687016, 0, 0, 0, 0, 0, 13304011, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30605779, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), null, null, initValues(_3I_classLit, 49, -1, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33227259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92734855, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [0, 0, 0, 5111886, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33358332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100599295, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [0, 0, 0, 0, 8585346, 0, 11075752, 0, 0, 0, 0, 16187638, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27263391, 0, 0, 0, 0, 0, 0, 0, 38994515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92865928, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), null, null, null, initValues(_3I_classLit, 49, -1, [0, 0, 0, 5177423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), null, null, null, null, null, null, initValues(_3I_classLit, 49, -1, [327684, 1900571, 2949162, 5374032, 8716420, 0, 11206826, 12517566, 13435084, 0, 15663343, 16515320, 19988785, 20644155, 24183152, 25952652, 0, 27918759, 30671316, 33489406, 34734607, 0, 0, 0, 39125588, 39649885, 40305254, 45220523, 52691740, 58917759, 63112129, 67240962, 70059050, 73925730, 75367549, 0, 79561917, 81986766, 90703198, 93390218, 100795904, 104990268, 0, 111675025, 116590323, 126814094, 130811850, 135006208, 0, 0, 138479679, 139266125]), initValues(_3I_classLit, 49, -1, [393222, 0, 0, 0, 0, 0, 11272364, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34865683, 37225016, 0, 0, 0, 0, 40370792, 45351603, 0, 59048836, 0, 0, 70124590, 73991273, 0, 0, 0, 82445540, 0, 93521298, 0, 0, 0, 112133801, 116655860, 126879632, 130942925, 0, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [589831, 1966110, 3276846, 5505107, 8978566, 10420383, 11468973, 12583104, 13631694, 15139046, 15794416, 16711933, 20054322, 20840764, 24379762, 26018189, 0, 28115371, 30998997, 33686016, 35062293, 37290553, 38273608, 0, 39256662, 39780958, 40829545, 45482677, 53150501, 59179910, 63505348, 67306499, 70255663, 74056810, 75629695, 79037621, 79692991, 82773227, 90834281, 93914516, 101058051, 105055811, 0, 112461488, 117573365, 127076241, 131139535, 135071757, 136054812, 136906791, 138610754, 139397198]), initValues(_3I_classLit, 49, -1, [0, 0, 3342387, 0, 9044106, 0, 11534512, 0, 13697233, 0, 0, 0, 0, 0, 24445301, 0, 0, 0, 0, 0, 35127832, 37421626, 0, 0, 0, 39846496, 0, 45548215, 53216044, 59442056, 63570890, 0, 70321201, 0, 0, 0, 0, 83166448, 90899819, 93980058, 101385735, 0, 0, 112789173, 117769987, 127141780, 131336146, 135137294, 0, 136972330, 0, 139462736]), initValues(_3I_classLit, 49, -1, [0, 2162719, 3473460, 5636181, 0, 0, 0, 0, 0, 0, 0, 18809088, 20185395, 21299519, 0, 0, 0, 28377518, 0, 0, 0, 37945916, 38339145, 0, 0, 39977569, 40960624, 46072504, 53609261, 59704204, 63636427, 67372036, 71042098, 74318955, 75826307, 0, 0, 84935926, 90965356, 94569883, 101451276, 105383492, 0, 113247930, 118490886, 127207317, 0, 135530511, 136316957, 0, 138741828, 139593809]), initValues(_3I_classLit, 49, -1, [655370, 2228258, 3538998, 5701719, 9109643, 10485920, 11600049, 12648641, 13762770, 15204584, 15859954, 18874656, 20250933, 21365062, 24510838, 26083726, 27328929, 28443058, 31064538, 33751555, 35193369, 38011460, 38404682, 38601293, 39322200, 40043107, 41091698, 46138048, 53674803, 59835280, 63767500, 67634181, 71107645, 74384495, 75957382, 79103159, 79758529, 85132561, 91030893, 94635428, 101582349, 105449033, 109119105, 113444545, 118621969, 127272854, 131467221, 135596053, 136382497, 137037867, 138807366, 139659347]), initValues(_3I_classLit, 49, -1, [786443, 0, 0, 0, 9240716, 0, 11665586, 0, 13893843, 0, 0, 0, 0, 0, 24641911, 0, 0, 0, 0, 0, 35324442, 0, 0, 0, 0, 0, 41222772, 0, 0, 0, 64095182, 0, 71238718, 0, 76088456, 0, 79824066, 85263636, 0, 94963109, 101844495, 0, 0, 0, 0, 0, 131598295, 0, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [0, 0, 3604535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26149263, 0, 28508595, 31326683, 33948164, 0, 0, 0, 0, 0, 0, 0, 0, 53936948, 59966354, 0, 0, 0, 0, 0, 0, 79889603, 85525782, 91096430, 95159722, 101975571, 105711178, 0, 113772228, 119080723, 128059287, 131794905, 0, 0, 137168940, 0, 139724884]), initValues(_3I_classLit, 49, -1, [0, 0, 3866680, 6160472, 0, 10616993, 0, 12714178, 0, 0, 0, 0, 20316470, 0, 0, 26214800, 0, 30015924, 31392223, 34210311, 0, 0, 0, 38666830, 0, 0, 0, 46990017, 54919992, 60752788, 0, 67699721, 71304256, 0, 76416138, 0, 0, 0, 91817327, 95421869, 102041109, 105907790, 109184642, 114493129, 119998234, 128518051, 0, 0, 0, 137234478, 138872903, 139790421]), initValues(_3I_classLit, 49, -1, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60818336, 0, 0, 71369793, 0, 76481679, 0, 79955140, 85591322, 0, 95487409, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47055566, 0, 0, 0, 0, 0, 74515568, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [851981, 0, 4063292, 0, 9306254, 0, 0, 0, 0, 0, 0, 19005729, 0, 0, 0, 26280337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41419382, 47776463, 55051079, 60949409, 64422867, 67896330, 71631938, 0, 0, 0, 0, 85919003, 91948410, 96273842, 102368790, 106825297, 0, 114689748, 120063784, 0, 132057052, 135661590, 0, 137365551, 0, 0]), initValues(_3I_classLit, 49, -1, [917518, 0, 0, 0, 9502863, 0, 0, 0, 14155989, 0, 0, 19071267, 0, 0, 24838521, 0, 0, 0, 31457760, 0, 35389980, 0, 0, 0, 0, 0, 41681529, 0, 0, 0, 64881624, 0, 0, 0, 76940432, 79168696, 0, 86115616, 0, 96339390, 102696475, 106890847, 0, 114820823, 120522537, 0, 132253664, 0, 0, 137431089, 0, 0]), initValues(_3I_classLit, 49, -1, [983055, 0, 0, 0, 0, 0, 0, 0, 14483673, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35783197, 0, 0, 0, 0, 0, 43188861, 47842010, 0, 0, 65012703, 67961869, 72090694, 0, 77661335, 0, 0, 86574371, 92013948, 0, 0, 0, 0, 114886361, 0, 0, 0, 0, 0, 137496626, 0, 0]), initValues(_3I_classLit, 49, -1, [1114128, 2293795, 4587583, 8257631, 9633938, 10813603, 11731123, 12845251, 14680286, 15270121, 15925491, 19661092, 20382007, 23724359, 24904060, 26411410, 27394466, 30147019, 31523297, 34275851, 35914275, 38076997, 38470219, 38732367, 39387737, 40108644, 43319956, 50987739, 56165193, 61801379, 65143777, 68224014, 72156237, 74908786, 77923490, 79234233, 80020677, 87754026, 92145021, 97060287, 102762016, 107152992, 109250179, 115345114, 120850224, 128976810, 132384739, 135727127, 136448034, 137758771, 138938440, 139855958]), initValues(_3I_classLit, 49, -1, [1179666, 0, 0, 0, 9699476, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25035133, 0, 0, 0, 0, 0, 36766245, 0, 0, 0, 0, 0, 43844246, 51053323, 0, 0, 65536995, 68289554, 0, 0, 77989030, 0, 0, 87885116, 92210559, 97453514, 102958625, 0, 109315716, 115541729, 121046837, 129042353, 132974565, 135792664, 136513571, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [0, 0, 0, 0, 9896085, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32047586, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66192361, 0, 0, 0, 78120103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121964344, 0, 0, 0, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [1310739, 2359332, 4653127, 0, 0, 0, 12189876, 0, 0, 0, 0, 0, 0, 0, 25100671, 27001236, 0, 30212557, 0, 34341388, 36831794, 0, 0, 0, 0, 0, 43975326, 51249932, 56296282, 61998000, 66323443, 69600275, 72221774, 0, 0, 0, 0, 88278334, 0, 97781200, 103810596, 108856932, 0, 115607268, 122029894, 130025394, 133302254, 135858201, 136644644, 137889847, 0, 0]), initValues(_3I_classLit, 49, -1, [1441813, 2424869, 4718664, 8388735, 10027160, 10879142, 12255419, 12976325, 14745825, 15401194, 15991028, 19857709, 20447544, 23789931, 25297280, 27132317, 27460003, 30343630, 32113130, 34472461, 36897331, 38142534, 38535756, 38797904, 39453274, 40174181, 44237472, 51708687, 56623964, 62260147, 66520053, 69665831, 72483919, 75105400, 78578857, 79365306, 80086214, 88933700, 92341632, 99026389, 104072753, 108988030, 109381253, 116000485, 122292039, 130287553, 133367795, 135923738, 136710182, 138020921, 139003977, 139921495]), initValues(_3I_classLit, 49, -1, [1572887, 0, 0, 0, 10092698, 0, 12320956, 0, 14811362, 0, 0, 19923248, 0, 23921004, 25493891, 0, 0, 0, 32178667, 0, 36962868, 0, 0, 0, 0, 0, 44368548, 0, 56689505, 62456759, 66716664, 0, 73401427, 0, 78709936, 0, 0, 89785678, 0, 99550696, 104334901, 0, 0, 116393707, 122619723, 0, 133629940, 0, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [1703961, 2490406, 4849737, 0, 10223771, 0, 0, 13107399, 15007971, 15466732, 0, 0, 20513081, 23986542, 25624966, 0, 0, 30409168, 33030636, 0, 37093941, 0, 0, 0, 39518811, 0, 44499622, 52101910, 58262370, 62587834, 66913275, 0, 0, 0, 78906546, 79430844, 0, 89916763, 92538242, 99812848, 104465977, 109053568, 109774470, 116459249, 126224208, 0, 133826552, 0, 0, 138151995, 139200586, 0]), initValues(_3I_classLit, 49, -1, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25887112, 0, 0, 0, 0, 0, 0, 38208071, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100206068, 104531515, 0, 0, 0, 0, 0, 0, 0, 0, 138217533, 0, 0]), initValues(_3I_classLit, 49, -1, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44630696, 0, 58393466, 62653372, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100533754, 0, 0, 0, 0, 126551943, 130484165, 133892091, 0, 0, 138283070, 0, 140052568]), initValues(_3I_classLit, 49, -1, [0, 0, 0, 0, 10354845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67175422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116524786, 0, 0, 0, 0, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58459004, 0, 0, 0, 0, 75236475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), initValues(_3I_classLit, 49, -1, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62784445, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126683020, 0, 0, 135989275, 0, 0, 0, 0])]);
+}
+
+var HILO_ACCEL;
+function localEqualsBuffer(local, buf, offset, length_0){
+  var i;
+  if (local.length != length_0) {
+    return false;
+  }
+  for (i = 0; i < length_0; ++i) {
+    if (local.charCodeAt(i) != buf[offset + i]) {
+      return false;
+    }
+  }
+  return true;
+}
+
+function lowerCaseLiteralEqualsIgnoreAsciiCaseString(lowerCaseLiteral, string){
+  var c0, c1, i;
+  if (string == null) {
+    return false;
+  }
+  if (lowerCaseLiteral.length != string.length) {
+    return false;
+  }
+  for (i = 0; i < lowerCaseLiteral.length; ++i) {
+    c0 = lowerCaseLiteral.charCodeAt(i);
+    c1 = string.charCodeAt(i);
+    c1 >= 65 && c1 <= 90 && (c1 += 32);
+    if (c0 != c1) {
+      return false;
+    }
+  }
+  return true;
+}
+
+function lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(lowerCaseLiteral, string){
+  var c0, c1, i;
+  if (string == null) {
+    return false;
+  }
+  if (lowerCaseLiteral.length > string.length) {
+    return false;
+  }
+  for (i = 0; i < lowerCaseLiteral.length; ++i) {
+    c0 = lowerCaseLiteral.charCodeAt(i);
+    c1 = string.charCodeAt(i);
+    c1 >= 65 && c1 <= 90 && (c1 += 32);
+    if (c0 != c1) {
+      return false;
+    }
+  }
+  return true;
+}
+
+function $StackNode(this$static, group, ns, name_0, node, scoping, special, fosterParenting, popName, attributes){
+  this$static.group = group;
+  this$static.name_0 = name_0;
+  this$static.popName = popName;
+  this$static.ns = ns;
+  this$static.node = node;
+  this$static.scoping = scoping;
+  this$static.special = special;
+  this$static.fosterParenting = fosterParenting;
+  this$static.attributes = attributes;
+  this$static.refcount = 1;
+  return this$static;
+}
+
+function $StackNode_0(this$static, ns, elementName, node){
+  this$static.group = elementName.group;
+  this$static.name_0 = elementName.name_0;
+  this$static.popName = elementName.name_0;
+  this$static.ns = ns;
+  this$static.node = node;
+  this$static.scoping = elementName.scoping;
+  this$static.special = elementName.special;
+  this$static.fosterParenting = elementName.fosterParenting;
+  this$static.attributes = null;
+  this$static.refcount = 1;
+  return this$static;
+}
+
+function $StackNode_1(this$static, ns, elementName, node, attributes){
+  this$static.group = elementName.group;
+  this$static.name_0 = elementName.name_0;
+  this$static.popName = elementName.name_0;
+  this$static.ns = ns;
+  this$static.node = node;
+  this$static.scoping = elementName.scoping;
+  this$static.special = elementName.special;
+  this$static.fosterParenting = elementName.fosterParenting;
+  this$static.attributes = attributes;
+  this$static.refcount = 1;
+  return this$static;
+}
+
+function $StackNode_2(this$static, ns, elementName, node, popName){
+  this$static.group = elementName.group;
+  this$static.name_0 = elementName.name_0;
+  this$static.popName = popName;
+  this$static.ns = ns;
+  this$static.node = node;
+  this$static.scoping = elementName.scoping;
+  this$static.special = elementName.special;
+  this$static.fosterParenting = elementName.fosterParenting;
+  this$static.attributes = null;
+  this$static.refcount = 1;
+  return this$static;
+}
+
+function $StackNode_3(this$static, ns, elementName, node, popName, scoping){
+  this$static.group = elementName.group;
+  this$static.name_0 = elementName.name_0;
+  this$static.popName = popName;
+  this$static.ns = ns;
+  this$static.node = node;
+  this$static.scoping = scoping;
+  this$static.special = false;
+  this$static.fosterParenting = false;
+  this$static.attributes = null;
+  this$static.refcount = 1;
+  return this$static;
+}
+
+function getClass_73(){
+  return Lnu_validator_htmlparser_impl_StackNode_2_classLit;
+}
+
+function toString_14(){
+  return this.name_0;
+}
+
+function StackNode(){
+}
+
+_ = StackNode.prototype = new Object_0;
+_.getClass$ = getClass_73;
+_.toString$ = toString_14;
+_.typeId$ = 41;
+_.attributes = null;
+_.fosterParenting = false;
+_.group = 0;
+_.name_0 = null;
+_.node = null;
+_.ns = null;
+_.popName = null;
+_.refcount = 1;
+_.scoping = false;
+_.special = false;
+function $UTF16Buffer(this$static, buffer, start, end){
+  this$static.buffer = buffer;
+  this$static.start = start;
+  this$static.end = end;
+  return this$static;
+}
+
+function $adjust(this$static, lastWasCR){
+  lastWasCR && this$static.buffer[this$static.start] == 10 && ++this$static.start;
+}
+
+function getClass_74(){
+  return Lnu_validator_htmlparser_impl_UTF16Buffer_2_classLit;
+}
+
+function UTF16Buffer(){
+}
+
+_ = UTF16Buffer.prototype = new Object_0;
+_.getClass$ = getClass_74;
+_.typeId$ = 42;
+_.buffer = null;
+_.end = 0;
+_.start = 0;
+function $SAXException(this$static, message){
+  $fillInStackTrace();
+  this$static.detailMessage = message;
+  this$static.exception = null;
+  return this$static;
+}
+
+function $getMessage_1(this$static){
+  var message;
+  message = this$static.detailMessage;
+  if (message == null && !!this$static.exception) {
+    return $getMessage_0(this$static.exception);
+  }
+   else {
+    return message;
+  }
+}
+
+function getClass_75(){
+  return Lorg_xml_sax_SAXException_2_classLit;
+}
+
+function getMessage_1(){
+  return $getMessage_1(this);
+}
+
+function toString_15(){
+  if (this.exception) {
+    return $toString(this.exception);
+  }
+   else {
+    return $toString(this);
+  }
+}
+
+function SAXException(){
+}
+
+_ = SAXException.prototype = new Exception;
+_.getClass$ = getClass_75;
+_.getMessage = getMessage_1;
+_.toString$ = toString_15;
+_.typeId$ = 43;
+_.exception = null;
+function $SAXParseException(this$static, message, locator){
+  $fillInStackTrace();
+  this$static.detailMessage = message;
+  this$static.exception = null;
+  if (locator) {
+    $getLineNumber(locator);
+    $getColumnNumber(locator);
+  }
+  return this$static;
+}
+
+function $SAXParseException_0(this$static, message, locator, e){
+  $fillInStackTrace();
+  this$static.detailMessage = message;
+  this$static.exception = e;
+  if (locator) {
+    $getLineNumber(locator);
+    $getColumnNumber(locator);
+  }
+  return this$static;
+}
+
+function getClass_76(){
+  return Lorg_xml_sax_SAXParseException_2_classLit;
+}
+
+function SAXParseException(){
+}
+
+_ = SAXParseException.prototype = new SAXException;
+_.getClass$ = getClass_76;
+_.typeId$ = 44;
+var $entry = entry_0;
+function gwtOnLoad(errFn, modName, modBase){
+  $moduleName = modName;
+  $moduleBase = modBase;
+  if (errFn)
+    try {
+      $entry(init)();
+    }
+     catch (e) {
+      errFn(modName);
+    }
+   else {
+    $entry(init)();
+  }
+}
+
+var I_classLit = createForPrimitive('', 'int'), _3I_classLit = createForArray('', '[I', I_classLit), Ljava_lang_Object_2_classLit = createForClass('java.lang.', 'Object'), Ljava_lang_Throwable_2_classLit = createForClass('java.lang.', 'Throwable'), Ljava_lang_Exception_2_classLit = createForClass('java.lang.', 'Exception'), Ljava_lang_RuntimeException_2_classLit = createForClass('java.lang.', 'RuntimeException'), Lcom_google_gwt_core_client_Scheduler_2_classLit = createForClass('com.google.gwt.core.client.', 'Scheduler'), Lcom_google_gwt_core_client_impl_SchedulerImpl_2_classLit = createForClass('com.google.gwt.core.client.impl.', 'SchedulerImpl'), Lcom_google_gwt_core_client_impl_SchedulerImpl$1_2_classLit = createForClass('com.google.gwt.core.client.impl.', 'SchedulerImpl$1'), Lcom_google_gwt_core_client_impl_SchedulerImpl$2_2_classLit = createForClass('com.google.gwt.core.client.impl.', 'SchedulerImpl$2'), Ljava_lang_StackTraceElement_2_classLit = createForClass('java.lang.', 'StackTraceElement'), _3Ljava_lang_StackTraceElement_2_classLit = createForArray('[Ljava.lang.', 'StackTraceElement;', Ljava_lang_StackTraceElement_2_classLit), Lcom_google_gwt_core_client_impl_StringBufferImpl_2_classLit = createForClass('com.google.gwt.core.client.impl.', 'StringBufferImpl'), Lcom_google_gwt_core_client_impl_StringBufferImplAppend_2_classLit = createForClass('com.google.gwt.core.client.impl.', 'StringBufferImplAppend'), Lcom_google_gwt_core_client_JavaScriptException_2_classLit = createForClass('com.google.gwt.core.client.', 'JavaScriptException'), Lcom_google_gwt_core_client_JavaScriptObject_2_classLit = createForClass('com.google.gwt.core.client.', 'JavaScriptObject$'), Ljava_lang_String_2_classLit = createForClass('java.lang.', 'String'), _3Ljava_lang_String_2_classLit = createForArray('[Ljava.lang.', 'String;', Ljava_lang_String_2_classLit), Ljava_lang_Enum_2_classLit = createForClass('java.lang.', 'Enum'), Lcom_google_gwt_event_shared_GwtEvent_2_classLit = createForClass('com.google.gwt.event.shared.', 'GwtEvent'), Lcom_google_gwt_event_shared_GwtEvent$Type_2_classLit = createForClass('com.google.gwt.event.shared.', 'GwtEvent$Type'), Lcom_google_gwt_event_logical_shared_CloseEvent_2_classLit = createForClass('com.google.gwt.event.logical.shared.', 'CloseEvent'), Lcom_google_gwt_event_shared_DefaultHandlerRegistration_2_classLit = createForClass('com.google.gwt.event.shared.', 'DefaultHandlerRegistration'), Lcom_google_gwt_event_shared_HandlerManager_2_classLit = createForClass('com.google.gwt.event.shared.', 'HandlerManager'), Lcom_google_gwt_event_shared_HandlerManager$HandlerRegistry_2_classLit = createForClass('com.google.gwt.event.shared.', 'HandlerManager$HandlerRegistry'), Lcom_google_gwt_event_shared_HandlerManager$1_2_classLit = createForClass('com.google.gwt.event.shared.', 'HandlerManager$1'), D_classLit = createForPrimitive('', 'double'), _3D_classLit = createForArray('', '[D', D_classLit), _3_3D_classLit = createForArray('', '[[D', _3D_classLit), Lcom_google_gwt_user_client_Timer_2_classLit = createForClass('com.google.gwt.user.client.', 'Timer'), Lcom_google_gwt_user_client_Timer$1_2_classLit = createForClass('com.google.gwt.user.client.', 'Timer$1'), Lcom_google_gwt_user_client_Window$ClosingEvent_2_classLit = createForClass('com.google.gwt.user.client.', 'Window$ClosingEvent'), Lcom_google_gwt_user_client_Window$WindowHandlers_2_classLit = createForClass('com.google.gwt.user.client.', 'Window$WindowHandlers'), Ljava_lang_IndexOutOfBoundsException_2_classLit = createForClass('java.lang.', 'IndexOutOfBoundsException'), Ljava_lang_ArrayStoreException_2_classLit = createForClass('java.lang.', 'ArrayStoreException'), C_classLit = createForPrimitive('', 'char'), _3C_classLit = createForArray('', '[C', C_classLit), Ljava_lang_Class_2_classLit = createForClass('java.lang.', 'Class'), Ljava_lang_ClassCastException_2_classLit = createForClass('java.lang.', 'ClassCastException'), Ljava_lang_IllegalArgumentException_2_classLit = createForClass('java.lang.', 'IllegalArgumentException'), Ljava_lang_NullPointerException_2_classLit = createForClass('java.lang.', 'NullPointerException'), Ljava_lang_StringBuffer_2_classLit = createForClass('java.lang.', 'StringBuffer'), Ljava_lang_StringBuilder_2_classLit = createForClass('java.lang.', 'StringBuilder'), Ljava_lang_StringIndexOutOfBoundsException_2_classLit = createForClass('java.lang.', 'StringIndexOutOfBoundsException'), Ljava_lang_UnsupportedOperationException_2_classLit = createForClass('java.lang.', 'UnsupportedOperationException'), _3Ljava_lang_Object_2_classLit = createForArray('[Ljava.lang.', 'Object;', Ljava_lang_Object_2_classLit), Ljava_util_AbstractCollection_2_classLit = createForClass('java.util.', 'AbstractCollection'), Ljava_util_AbstractMap_2_classLit = createForClass('java.util.', 'AbstractMap'), Ljava_util_AbstractHashMap_2_classLit = createForClass('java.util.', 'AbstractHashMap'), Ljava_util_AbstractSet_2_classLit = createForClass('java.util.', 'AbstractSet'), Ljava_util_AbstractHashMap$EntrySet_2_classLit = createForClass('java.util.', 'AbstractHashMap$EntrySet'), Ljava_util_AbstractHashMap$EntrySetIterator_2_classLit = createForClass('java.util.', 'AbstractHashMap$EntrySetIterator'), Ljava_util_AbstractMapEntry_2_classLit = createForClass('java.util.', 'AbstractMapEntry'), Ljava_util_AbstractHashMap$MapEntryNull_2_classLit = createForClass('java.util.', 'AbstractHashMap$MapEntryNull'), Ljava_util_AbstractHashMap$MapEntryString_2_classLit = createForClass('java.util.', 'AbstractHashMap$MapEntryString'), Ljava_util_AbstractList_2_classLit = createForClass('java.util.', 'AbstractList'), Ljava_util_AbstractList$IteratorImpl_2_classLit = createForClass('java.util.', 'AbstractList$IteratorImpl'), Ljava_util_AbstractSequentialList_2_classLit = createForClass('java.util.', 'AbstractSequentialList'), Ljava_util_ArrayList_2_classLit = createForClass('java.util.', 'ArrayList'), Ljava_util_Comparators$1_2_classLit = createForClass('java.util.', 'Comparators$1'), Ljava_util_HashMap_2_classLit = createForClass('java.util.', 'HashMap'), Ljava_util_LinkedList_2_classLit = createForClass('java.util.', 'LinkedList'), Ljava_util_LinkedList$ListIteratorImpl_2_classLit = createForClass('java.util.', 'LinkedList$ListIteratorImpl'), Ljava_util_LinkedList$Node_2_classLit = createForClass('java.util.', 'LinkedList$Node'), Ljava_util_MapEntryImpl_2_classLit = createForClass('java.util.', 'MapEntryImpl'), Ljava_util_NoSuchElementException_2_classLit = createForClass('java.util.', 'NoSuchElementException'), Lnu_validator_htmlparser_common_DoctypeExpectation_2_classLit = createForEnum('nu.validator.htmlparser.common.', 'DoctypeExpectation', values_0), _3Lnu_validator_htmlparser_common_DoctypeExpectation_2_classLit = createForArray('[Lnu.validator.htmlparser.common.', 'DoctypeExpectation;', Lnu_validator_htmlparser_common_DoctypeExpectation_2_classLit), Lnu_validator_htmlparser_common_DocumentMode_2_classLit = createForEnum('nu.validator.htmlparser.common.', 'DocumentMode', values_1), _3Lnu_validator_htmlparser_common_DocumentMode_2_classLit = createForArray('[Lnu.validator.htmlparser.common.', 'DocumentMode;', Lnu_validator_htmlparser_common_DocumentMode_2_classLit), Lnu_validator_htmlparser_common_XmlViolationPolicy_2_classLit = createForEnum('nu.validator.htmlparser.common.', 'XmlViolationPolicy', values_2), _3Lnu_validator_htmlparser_common_XmlViolationPolicy_2_classLit = createForArray('[Lnu.validator.htmlparser.common.', 'XmlViolationPolicy;', Lnu_validator_htmlparser_common_XmlViolationPolicy_2_classLit), Lnu_validator_htmlparser_impl_TreeBuilder_2_classLit = createForClass('nu.validator.htmlparser.impl.', 'TreeBuilder'), Lnu_validator_htmlparser_impl_CoalescingTreeBuilder_2_classLit = createForClass('nu.validator.htmlparser.impl.', 'CoalescingTreeBuilder'), Lnu_validator_htmlparser_gwt_BrowserTreeBuilder_2_classLit = createForClass('nu.validator.htmlparser.gwt.', 'BrowserTreeBuilder'), Lnu_validator_htmlparser_gwt_BrowserTreeBuilder$ScriptHolder_2_classLit = createForClass('nu.validator.htmlparser.gwt.', 'BrowserTreeBuilder$ScriptHolder'), Lnu_validator_htmlparser_gwt_HtmlParser_2_classLit = createForClass('nu.validator.htmlparser.gwt.', 'HtmlParser'), Lnu_validator_htmlparser_gwt_HtmlParser$1_2_classLit = createForClass('nu.validator.htmlparser.gwt.', 'HtmlParser$1'), Lnu_validator_htmlparser_gwt_ParseEndListener_2_classLit = createForClass('nu.validator.htmlparser.gwt.', 'ParseEndListener'), Z_classLit = createForPrimitive('', 'boolean'), _3Z_classLit = createForArray('', '[Z', Z_classLit), Lnu_validator_htmlparser_impl_AttributeName_2_classLit = createForClass('nu.validator.htmlparser.impl.', 'AttributeName'), _3Lnu_validator_htmlparser_impl_AttributeName_2_classLit = createForArray('[Lnu.validator.htmlparser.impl.', 'AttributeName;', Lnu_validator_htmlparser_impl_AttributeName_2_classLit), Lnu_validator_htmlparser_impl_ElementName_2_classLit = createForClass('nu.validator.htmlparser.impl.', 'ElementName'), _3Lnu_validator_htmlparser_impl_ElementName_2_classLit = createForArray('[Lnu.validator.htmlparser.impl.', 'ElementName;', Lnu_validator_htmlparser_impl_ElementName_2_classLit), Lnu_validator_htmlparser_impl_Tokenizer_2_classLit = createForClass('nu.validator.htmlparser.impl.', 'Tokenizer'), Lnu_validator_htmlparser_impl_ErrorReportingTokenizer_2_classLit = createForClass('nu.validator.htmlparser.impl.', 'ErrorReportingTokenizer'), Lnu_validator_htmlparser_impl_HtmlAttributes_2_classLit = createForClass('nu.validator.htmlparser.impl.', 'HtmlAttributes'), Lnu_validator_htmlparser_impl_LocatorImpl_2_classLit = createForClass('nu.validator.htmlparser.impl.', 'LocatorImpl'), B_classLit = createForPrimitive('', 'byte'), _3B_classLit = createForArray('', '[B', B_classLit), _3_3B_classLit = createForArray('', '[[B', _3B_classLit), _3_3C_classLit = createForArray('', '[[C', _3C_classLit), _3_3I_classLit = createForArray('', '[[I', _3I_classLit), Lnu_validator_htmlparser_impl_StackNode_2_classLit = createForClass('nu.validator.htmlparser.impl.', 'StackNode'), _3Lnu_validator_htmlparser_impl_StackNode_2_classLit = createForArray('[Lnu.validator.htmlparser.impl.', 'StackNode;', Lnu_validator_htmlparser_impl_StackNode_2_classLit), Lnu_validator_htmlparser_impl_UTF16Buffer_2_classLit = createForClass('nu.validator.htmlparser.impl.', 'UTF16Buffer'), Lorg_xml_sax_SAXException_2_classLit = createForClass('org.xml.sax.', 'SAXException'), Lorg_xml_sax_SAXParseException_2_classLit = createForClass('org.xml.sax.', 'SAXParseException');
+gwtOnLoad();})();
+/**
+* DOMParser
+*/
+
+__defineParser__(function(e){
+    console.log('Error loading html 5 parser implementation');
+}, 'nu_validator_htmlparser_HtmlParser', '');
+
+/*DOMParser = function(principle, documentURI, baseURI){};
+__extend__(DOMParser.prototype,{
+    parseFromString: function(xmlstring, mimetype){
+        //console.log('DOMParser.parseFromString %s', mimetype);
+        var xmldoc = new Document(new DOMImplementation());
+        return XMLParser.parseDocument(xmlstring, xmldoc, mimetype);
+    }
+});*/
+
+XMLParser.parseDocument = function(xmlstring, xmldoc, mimetype){
+    //console.log('XMLParser.parseDocument');
+    var tmpdoc = new Document(new DOMImplementation()),
+        parent,
+        importedNode,
+        tmpNode;
+
+    if(mimetype && mimetype == 'text/xml'){
+        //console.log('mimetype: text/xml');
+        tmpdoc.baseURI = 'http://envjs.com/xml';
+        xmlstring = '<html><head></head><body>'+
+            '<envjs_1234567890 xmlns="envjs_1234567890">'
+                +xmlstring+
+            '</envjs_1234567890>'+
+        '</body></html>';
+        Envjs.parseHtmlDocument(xmlstring, tmpdoc, false, null, null);
+        parent = tmpdoc.getElementsByTagName('envjs_1234567890')[0];
+    }else{
+        Envjs.parseHtmlDocument(xmlstring, tmpdoc, false, null, null);
+        parent = tmpdoc.documentElement;
+    }
+
+    while(xmldoc.firstChild != null){
+        xmldoc.removeChild( xmldoc.firstChild );
+    }
+    while(parent.firstChild != null){
+        tmpNode  = parent.removeChild( parent.firstChild );
+        importedNode = xmldoc.importNode( tmpNode, true);
+        xmldoc.appendChild( importedNode );
+    }
+    return xmldoc;
+};
+
+var __fragmentCache__ = {length:0},
+    __cachable__ = 255;
+
+HTMLParser.parseDocument = function(htmlstring, htmldoc){
+    //console.log('HTMLParser.parseDocument %s', htmldoc.async);
+    htmldoc.parsing = true;
+    Envjs.parseHtmlDocument(htmlstring, htmldoc, htmldoc.async, null, null);
+    //Envjs.wait();
+    //console.log('Finished HTMLParser.parseDocument %s', htmldoc.async);
+    return htmldoc;
+};
+HTMLParser.parseFragment = function(htmlstring, element){
+    //console.log('HTMLParser.parseFragment')
+    // fragment is allowed to be an element as well
+    var tmpdoc,
+        parent,
+        importedNode,
+        tmpNode,
+        length,
+        i,
+        docstring;
+    //console.log('parsing fragment: %s', htmlstring);
+    //console.log('__fragmentCache__.length %s', __fragmentCache__.length)
+    if( htmlstring.length > __cachable__ && htmlstring in __fragmentCache__){
+        tmpdoc = __fragmentCache__[htmlstring];
+    }else{
+        //console.log('parsing html fragment \n%s', htmlstring);
+        tmpdoc = new HTMLDocument(new DOMImplementation());
+
+
+        // Need some indicator that this document isn't THE document
+        // to fire off img.src change events and other items.
+        // Otherwise, what happens is the tmpdoc fires and img.src
+        // event, then when it's all imported to the original document
+        // it happens again.
+
+        tmpdoc.fragment = true;
+
+        //preserves leading white space
+        docstring = '<html><head></head><body>'+
+            '<envjs_1234567890 xmlns="envjs_1234567890">'
+                +htmlstring+
+            '</envjs_1234567890>'+
+        '</body></html>';
+        Envjs.parseHtmlDocument(docstring,tmpdoc, false, null,null);
+        if(htmlstring.length > __cachable__ ){
+            tmpdoc.normalizeDocument();
+            __fragmentCache__[htmlstring] = tmpdoc;
+            __fragmentCache__.length += htmlstring.length;
+            tmpdoc.cached = true;
+        }else{
+            tmpdoc.cached = false;
+        }
+    }
+
+    //parent is envjs_1234567890 element
+    parent = tmpdoc.body.childNodes[0];
+    while(element.firstChild != null){
+        //zap the elements children so we can import
+        element.removeChild( element.firstChild );
+    }
+
+    if(tmpdoc.cached){
+        length = parent.childNodes.length;
+        for(i=0;i<length;i++){
+            importedNode = element.importNode( parent.childNodes[i], true );
+            element.appendChild( importedNode );
+        }
+    }else{
+        while(parent.firstChild != null){
+            tmpNode  = parent.removeChild( parent.firstChild );
+            importedNode = element.importNode( tmpNode, true);
+            element.appendChild( importedNode );
+        }
+    }
+
+    // console.log('finished fragment: %s', element.outerHTML);
+    return element;
+};
+
+var __clearFragmentCache__ = function(){
+    __fragmentCache__ = {};
+}
+
+
+/**
+ * @name Document
+ * @w3c:domlevel 2 
+ * @uri http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html
+ */
+__extend__(Document.prototype, {
+    loadXML : function(xmlString) {
+        //console.log('Parser::Document.loadXML');
+        // create Document
+        if(this === document){
+            //$debug("Setting internal window.document");
+            document = this;
+        }
+        // populate Document
+        try {
+            // make sure this document object is empty before we try to load ...
+            this.attributes      = new NamedNodeMap(this, this);
+            this._namespaces     = new NamespaceNodeMap(this, this);
+            this._readonly = false;
+
+            XMLParser.parseDocument(xmlString, this);
+            
+            Envjs.wait(-1);
+        } catch (e) {
+            //$error(e);
+        }
+        return this;
+    }
+});
+
+
+__extend__(HTMLDocument.prototype, {
+
+    open : function() {
+        //console.log('opening doc for write.');
+        if (! this._writebuffer) {
+            this._writebuffer = [];
+        }
+    },
+    close : function() {
+		var text;
+        //console.log('closing doc.');
+        if (this._writebuffer) {
+			text = this._writebuffer.join('');
+            //HTMLParser.parseDocument(this._writebuffer.join(''), this);
+			Envjs.exchangeHTMLDocument(this, text, this.location);
+            this._writebuffer = null;
+            //console.log('finished writing doc.');
+        }
+    },
+
+    /**
+     * http://dev.w3.org/html5/spec/Overview.html#document.write
+     */
+    write: function(htmlstring) {
+        //console.log('writing doc.');
+        this.open();
+        this._writebuffer.push(htmlstring);
+    },
+
+    /**
+     * http://dev.w3.org/html5/spec/Overview.html#dom-document-writeln
+     */
+    writeln: function(htmlstring) {
+        this.open();
+        this._writebuffer.push(htmlstring + '\n');
+    }
+});
+
+/**
+ * elementPopped is called by the parser in two cases
+ *
+ * - an 'tag' is * complete (all children process and end tag, real or
+ *   implied is * processed)
+ * - a replaceElement happens (this happens by making placeholder
+ *   nodes and then the real one is swapped in.
+ *
+ */
+var __elementPopped__ = function(ns, name, node){
+    //console.log('popped html element %s %s %s', ns, name, node);
+    var doc = node.ownerDocument,
+        okay,
+        event;
+    switch(doc.parsing){
+        case false:
+            //innerHTML so dont do loading patterns for parsing
+            //console.log('element popped (implies innerHTML) not in parsing mode %s', node.nodeName);
+            break;
+        case true:
+            switch(doc+''){
+                case '[object XMLDocument]':
+                    break;
+                case '[object HTMLDocument]':
+                    switch(node.namespaceURI){
+                        case "http://n.validator.nu/placeholder/":
+                            //console.log('got holder script during parsing %s', node.textContent);
+                            break;
+                        case null:
+                        case "":
+                        case "http://www.w3.org/1999/xhtml":
+                            switch(name.toLowerCase()){
+                                case 'script':
+		                            //console.log('got actual script during parsing %s', node.textContent);
+                                    try{
+                                        okay = Envjs.loadLocalScript(node, null);
+                                        //console.log('loaded script? %s %s', node.src, okay);
+                                        // only fire event if we actually had something to load
+                                        if (node.src && node.src.length > 0){
+                                            event = doc.createEvent('HTMLEvents');
+                                            event.initEvent( okay ? "load" : "error", false, false );
+                                            node.dispatchEvent( event, false );
+                                        }
+                                    }catch(e){
+                                        console.log('error loading html element %s %s %s %e', ns, name, node, e.toString());
+                                    }
+                                    break;
+                                case 'frame':
+                                case 'iframe':
+									//console.log('popped frame');
+                                    node.contentWindow = { };
+                                    node.contentDocument = new HTMLDocument(new DOMImplementation(), node.contentWindow);
+                                    node.contentWindow.document = node.contentDocument;
+                                    try{
+                                        Window;
+                                    }catch(e){
+                                        node.contentDocument.addEventListener('DOMContentLoaded', function(){
+                                            event = node.contentDocument.createEvent('HTMLEvents');
+                                            event.initEvent("load", false, false);
+                                            node.dispatchEvent( event, false );
+                                        });
+                                    }
+                                    try{
+                                        if (node.src && node.src.length > 0){
+                                            //console.log("getting content document for (i)frame from %s", node.src);
+                                            Envjs.loadFrame(node, Envjs.uri(node.src, node.ownerDocument.location+''));
+                                            event = node.contentDocument.createEvent('HTMLEvents');
+                                            event.initEvent("load", false, false);
+                                            node.dispatchEvent( event, false );
+                                        }else{
+                                            //I dont like this being here:
+                                            //TODO: better  mix-in strategy so the try/catch isnt required
+                                            try{
+                                                if(Window){
+                                                    Envjs.loadFrame(node);
+                                                    //console.log('src/html/document.js: triggering frame load');
+                                                    event = node.contentDocument.createEvent('HTMLEvents');
+                                                    event.initEvent("load", false, false);
+                                                    node.dispatchEvent( event, false );
+                                                }
+                                            }catch(e){}
+                                        }
+                                    }catch(e){
+                                        console.log('error loading html element %s %e', node, e.toString());
+                                    }
+                                    /*try{
+                                        if (node.src && node.src.length > 0){
+                                            //console.log("getting content document for (i)frame from %s", node.src);
+                                            Envjs.loadFrame(node, Envjs.uri(node.src));
+                                            event = node.ownerDocument.createEvent('HTMLEvents');
+                                            event.initEvent("load", false, false);
+                                            node.dispatchEvent( event, false );
+                                        }else{
+                                            //console.log('src/parser/htmldocument: triggering frame load (no src)');
+                                        }
+                                    }catch(e){
+                                        console.log('error loading html element %s %s %s %e', ns, name, node, e.toString());
+                                    }*/
+                                    break;
+                                case 'link':
+                                    if (node.href) {
+                                        __loadLink__(node, node.href);
+                                    }
+                                    break;
+                                case 'option':
+                                    node._updateoptions();
+                                    break;
+                                case 'img':
+                                    if (node.src){
+                                        __loadImage__(node, node.src);
+                                    }
+                                    break;
+                                case 'html':
+                                    //console.log('html popped');
+                                    doc.parsing = false;
+                                    //DOMContentLoaded event
+                                    try{
+										if ( Envjs.killTimersAfterLoad === true ) {
+											Envjs.clear();
+										}
+										if ( Envjs.fireLoad === false ) {
+											return;
+										}
+                                        if(doc.createEvent){
+                                            event = doc.createEvent('Events');
+                                            event.initEvent("DOMContentLoaded", false, false);
+                                            doc.dispatchEvent( event, false );
+                                        }
+                                    }catch(e){
+                                        console.log('%s', e);
+                                    }
+                                    try{
+                                        if(doc.createEvent){
+                                            event = doc.createEvent('HTMLEvents');
+                                            event.initEvent("load", false, false);
+                                            doc.dispatchEvent( event, false );
+                                        }
+                                    }catch(e){
+                                        console.log('%s', e);
+                                    }
+
+                                    try{
+                                        if(doc.parentWindow){
+                                            event = doc.createEvent('HTMLEvents');
+                                            event.initEvent("load", false, false);
+                                            doc.parentWindow.dispatchEvent( event, false );
+                                        }
+                                    }catch(e){
+                                        console.log('%s', e);
+                                    }
+                                    try{
+                                        if(doc === window.document){
+                                            //console.log('triggering window.load')
+                                            event = doc.createEvent('HTMLEvents');
+                                            event.initEvent("load", false, false);
+                                            try{
+                                                window.dispatchEvent( event, false );
+                                            }catch(e){
+                                                console.log('%s', e);
+                                            }
+                                        }
+                                    }catch(e){
+                                        //console.log('%s', e);
+                                        //swallow
+                                    }
+                                default:
+                                    if(node.getAttribute('onload')){
+                                        //console.log('%s onload', node);
+                                        node.onload();
+                                    }
+                                    break;
+                            }//switch on name
+                        default:
+                            break;
+                    }//switch on ns
+                    break;
+                default:
+                    console.log('element popped: %s %s', ns, name, node.ownerDocument+'');
+            }//switch on doc type
+        default:
+            break;
+    }//switch on parsing
+};
+
+__extend__(HTMLElement.prototype,{
+    set innerHTML(html){
+        HTMLParser.parseFragment(html, this);
+    }
+});
+
+/**
+ * @author john resig & the envjs team
+ * @uri http://www.envjs.com/
+ * @copyright 2008-2010
+ * @license MIT
+ */
+//CLOSURE_END
+}());
+/*
+ * Envjs xhr.1.2.35 
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ * 
+ * Parts of the implementation originally written by Yehuda Katz.
+ * 
+ * This file simply provides the global definitions we need to 
+ * be able to correctly implement to core browser (XML)HTTPRequest 
+ * interfaces.
+ */
+/*var Location,
+    XMLHttpRequest;
+*/
+/*
+ * Envjs xhr.1.2.35 
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ */
+
+//CLOSURE_START
+(function(){
+
+
+
+
+
+/**
+ * @author john resig
+ */
+// Helper method for extending one object with another.
+function __extend__(a,b) {
+    for ( var i in b ) {
+        var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
+        if ( g || s ) {
+            if ( g ) { a.__defineGetter__(i, g); }
+            if ( s ) { a.__defineSetter__(i, s); }
+        } else {
+            a[i] = b[i];
+        }
+    } return a;
+}
+
+/**
+ * @author john resig
+ */
+//from jQuery
+function __setArray__( target, array ) {
+    // Resetting the length to 0, then using the native Array push
+    // is a super-fast way to populate an object with array-like properties
+    target.length = 0;
+    Array.prototype.push.apply( target, array );
+}
+
+/**
+ * @author ariel flesler
+ *    http://flesler.blogspot.com/2008/11/fast-trim-function-for-javascript.html
+ * @param {Object} str
+ */
+function __trim__( str ){
+    return (str || "").replace( /^\s+|\s+$/g, "" );
+}
+
+
+/**
+ * @todo: document
+ */
+__extend__(Document.prototype,{
+    load: function(url){
+        if(this.documentURI == 'about:html'){
+            this.location.assign(url);
+        }else if(this.documentURI == url){
+            this.location.reload(false);
+        }else{
+            this.location.replace(url);
+        }
+    },
+    get location(){
+        return this.ownerWindow.location;
+    },
+    set location(url){
+        //very important or you will go into an infinite
+        //loop when creating a xml document
+        this.ownerWindow.location = url;
+    }
+});
+
+/**
+ * Location
+ *
+ * Mozilla MDC:
+ * https://developer.mozilla.org/En/DOM/Window.location
+ * https://developer.mozilla.org/en/DOM/document.location
+ *
+ * HTML5: 6.10.4 The Location interface
+ * http://dev.w3.org/html5/spec/Overview.html#location
+ *
+ * HTML5: 2.5.3 Interfaces for URL manipulation
+ * http://dev.w3.org/html5/spec/Overview.html#url-decomposition-idl-attributes
+ * All of section 2.5 is worth reading, but 2.5.3 contains very
+ * detailed information on how getters/setter should work
+ *
+ * NOT IMPLEMENTED:
+ *  HTML5: Section 6.10.4.1 Security -- prevents scripts from another domain
+ *   from accessing most of the 'Location'
+ *  Not sure if anyone implements this in HTML4
+ */
+
+Location = function(url, doc, history) {
+    //console.log('Location url %s', url);
+    var $url = url,
+        $document = doc ? doc : null,
+        $history = history ? history : null;
+
+    var parts = Envjs.urlsplit($url);
+
+    return {
+        get hash() {
+            return parts.fragment ? '#' + parts.fragment : parts.fragment;
+        },
+        set hash(s) {
+            if (s[0] === '#') {
+                parts.fragment = s.substr(1);
+            } else {
+                parts.fragment = s;
+            }
+            $url = Envjs.urlunsplit(parts);
+            if ($history) {
+                $history.add($url, 'hash');
+            }
+        },
+
+        get host() {
+            return parts.netloc;
+        },
+        set host(s) {
+            if (!s || s === '') {
+                return;
+            }
+
+            parts.netloc = s;
+            $url = Envjs.urlunsplit(parts);
+
+            // this regenerates hostname & port
+            parts = Envjs.urlsplit($url);
+
+            if ($history) {
+                $history.add( $url, 'host');
+            }
+            this.assign($url);
+        },
+
+        get hostname() {
+            return parts.hostname;
+        },
+        set hostname(s) {
+            if (!s || s === '') {
+                return;
+            }
+
+            parts.netloc = s;
+            if (parts.port != '') {
+                parts.netloc += ':' + parts.port;
+            }
+            parts.hostname = s;
+            $url = Envjs.urlunsplit(parts);
+            if ($history) {
+                $history.add( $url, 'hostname');
+            }
+            this.assign($url);
+        },
+
+        get href() {
+            return $url;
+        },
+        set href(url) {
+            $url = url;
+            if ($history) {
+                $history.add($url, 'href');
+            }
+            this.assign($url);
+        },
+
+        get pathname() {
+            return parts.path;
+        },
+        set pathname(s) {
+            if (s[0] === '/') {
+                parts.path = s;
+            } else {
+                parts.path = '/' + s;
+            }
+            $url = Envjs.urlunsplit(parts);
+
+            if ($history) {
+                $history.add($url, 'pathname');
+            }
+            this.assign($url);
+        },
+
+        get port() {
+            // make sure it's a string
+            return '' + parts.port;
+        },
+        set port(p) {
+            // make a string
+            var s = '' + p;
+            parts.port = s;
+            parts.netloc = parts.hostname + ':' + parts.port;
+            $url = Envjs.urlunsplit(parts);
+            if ($history) {
+                $history.add( $url, 'port');
+            }
+            this.assign($url);
+        },
+
+        get protocol() {
+            return parts.scheme + ':';
+        },
+        set protocol(s) {
+            var i = s.indexOf(':');
+            if (i != -1) {
+                s = s.substr(0,i);
+            }
+            parts.scheme = s;
+            $url = Envjs.urlunsplit(parts);
+            if ($history) {
+                $history.add($url, 'protocol');
+            }
+            this.assign($url);
+        },
+
+        get search() {
+            return (parts.query) ? '?' + parts.query : parts.query;
+        },
+        set search(s) {
+            if (s[0] == '?') {
+                s = s.substr(1);
+            }
+            parts.query = s;
+            $url = Envjs.urlunsplit(parts);
+            if ($history) {
+                $history.add($url, 'search');
+            }
+            this.assign($url);
+        },
+
+        toString: function() {
+            return $url;
+        },
+
+        assign: function(url, /*non-standard*/ method, data) {
+            var _this = this,
+                xhr,
+                event;
+			method = method||"GET";
+			data = data||null;
+            //console.log('assigning %s',url);
+
+            //we can only assign if this Location is associated with a document
+            if ($document) {
+                //console.log('fetching %s (async? %s)', url, $document.async);
+                xhr = new XMLHttpRequest();
+				
+		        xhr.setRequestHeader('Referer', $document.location);
+				//console.log("REFERER: %s", $document.location);
+                // TODO: make async flag a Envjs paramter
+                xhr.open(method, url, false);//$document.async);
+
+                // TODO: is there a better way to test if a node is an HTMLDocument?
+                if ($document.toString() === '[object HTMLDocument]') {
+                    //tell the xhr to not parse the document as XML
+                    //console.log('loading html document');
+                    xhr.onreadystatechange = function() {
+                        //console.log('readyState %s', xhr.readyState);
+                        if (xhr.readyState === 4) {
+							switch(xhr.status){
+							case 301:
+							case 302:
+							case 303:
+							case 305:
+							case 307:
+								//console.log('status is not good for assignment %s', xhr.status);
+								break;
+                       		default:
+								//console.log('status is good for assignment %s', xhr.status);
+	                        	if (xhr.readyState === 4) {// update closure upvars
+					            	$url = xhr.url;
+						            parts = Envjs.urlsplit($url);
+	                            	//console.log('new document baseURI %s', xhr.url);
+	                            	Envjs.exchangeHTMLDocument($document, xhr.responseText, xhr.url);
+	                        	}
+							}
+                        }
+                    };
+					try{
+                    	xhr.send(data, false);//dont parse html
+					}catch(e){
+						console.log('failed to load content %s', e);
+						Envjs.exchangeHTMLDocument($document, "\
+							<html><head><title>Error Loading</title></head><body>"+e+"</body></html>\
+						", xhr.url);
+					}
+                } else {
+                    //Treat as an XMLDocument
+                    xhr.onreadystatechange = function() {
+                        if (xhr.readyState === 4) {
+							console.log('exchanging xml content %s', e);
+                            $document = xhr.responseXML;
+                            $document.baseURI = xhr.url;
+                            if ($document.createEvent) {
+                                event = $document.createEvent('Event');
+                                event.initEvent('DOMContentLoaded');
+                                $document.dispatchEvent( event, false );
+                            }
+                        }
+                    };
+                    xhr.send();
+                }
+
+            };
+
+        },
+        reload: function(forceget) {
+            //for now we have no caching so just proxy to assign
+            //console.log('reloading %s',$url);
+            this.assign($url);
+        },
+        replace: function(url, /*non-standard*/ method, data) {
+            this.assign(url, method, data);
+        }
+    };
+};
+
+
+/**
+ *
+ * @class XMLHttpRequest
+ * @author Originally implemented by Yehuda Katz
+ *
+ */
+
+// this implementation can be used without requiring a DOMParser
+// assuming you dont try to use it to get xml/html documents
+var domparser;
+
+XMLHttpRequest = function(){
+    this.headers = {};
+    this.responseHeaders = {};
+    this.aborted = false;//non-standard
+};
+
+// defined by the standard: http://www.w3.org/TR/XMLHttpRequest/#xmlhttprequest
+// but not provided by Firefox.  Safari and others do define it.
+XMLHttpRequest.UNSENT = 0;
+XMLHttpRequest.OPEN = 1;
+XMLHttpRequest.HEADERS_RECEIVED = 2;
+XMLHttpRequest.LOADING = 3;
+XMLHttpRequest.DONE = 4;
+
+XMLHttpRequest.prototype = {
+    open: function(method, url, async, user, password){
+        //console.log('openning xhr %s %s %s', method, url, async);
+        this.readyState = 1;
+        this.async = (async === false)?false:true;
+        this.method = method || "GET";
+        this.url = Envjs.uri(url);
+        this.onreadystatechange();
+    },
+    setRequestHeader: function(header, value){
+        this.headers[header] = value;
+    },
+    send: function(data, parsedoc/*non-standard*/, redirect_count){
+        var _this = this;
+		//console.log('sending request for url %s', this.url);
+        parsedoc = (parsedoc === undefined)?true:!!parsedoc;
+        redirect_count = (redirect_count === undefined) ? 0 : redirect_count;
+        function makeRequest(){
+            var cookie = Envjs.getCookies(_this.url),
+				redirecting = false;
+            if(cookie){
+                _this.setRequestHeader('COOKIE', cookie);
+            }
+			if(window&&window.navigator&&window.navigator.userAgent)
+	        	_this.setRequestHeader('User-Agent', window.navigator.userAgent);
+            Envjs.connection(_this, function(){
+                if (!_this.aborted){
+                    var doc = null,
+                        domparser,
+                        cookie;
+                    
+                    try{
+                        cookie = _this.getResponseHeader('SET-COOKIE');
+                        if(cookie){
+                            Envjs.setCookie(_this.url, cookie);
+                        }
+                    }catch(e){
+                        console.warn("Failed to set cookie");
+                    }
+                    //console.log('status : %s', _this.status);
+					switch(_this.status){
+						case 301:
+						case 302:
+						case 303:
+						case 305:
+						case 307:
+						if(_this.getResponseHeader('Location') && redirect_count < 20){
+							//follow redirect and copy headers
+							redirecting = true;
+							//console.log('following %s redirect %s from %s url %s', 
+							//	redirect_count, _this.status, _this.url, _this.getResponseHeader('Location'));
+	                        _this.url = Envjs.uri(_this.getResponseHeader('Location'));
+	                        //remove current cookie headers to allow the redirect to determine
+	                        //the currect cookie based on the new location
+	                        if('Cookie' in _this.headers ){
+	                            delete _this.headers.Cookie;
+	                        }
+	                        if('Cookie2' in _this.headers ){
+	                            delete _this.headers.Cookie2;
+	                        }
+							redirect_count++;
+							if (_this.async){
+					            //TODO: see TODO notes below
+					            Envjs.runAsync(makeRequest);
+					        }else{
+					            makeRequest();
+					        }
+							return;
+						}break;
+						default:
+						// try to parse the document if we havent explicitly set a
+                        // flag saying not to and if we can assure the text at least
+                        // starts with valid xml
+                        if ( parsedoc && 
+                            _this.getResponseHeader('Content-Type').indexOf('xml') > -1 &&
+                            _this.responseText.match(/^\s*</) ) {
+                            domparser = domparser||new DOMParser();
+                            try {
+                                //console.log("parsing response text into xml document");
+                                doc = domparser.parseFromString(_this.responseText+"", 'text/xml');
+                            } catch(e) {
+                                //Envjs.error('response XML does not appear to be well formed xml', e);
+                                console.warn('parseerror \n%s', e);
+                                doc = document.implementation.createDocument('','error',null);
+                                doc.appendChild(doc.createTextNode(e+''));
+                            }
+                        }else{
+                            //Envjs.warn('response XML does not appear to be xml');
+                        }
+
+                        _this.__defineGetter__("responseXML", function(){
+                            return doc;
+                        });
+							
+					}
+                }
+            }, data);
+
+            if (!_this.aborted  && !redirecting){
+				//console.log('did not abort so call onreadystatechange');
+                _this.onreadystatechange();
+            }
+        }
+
+        if (this.async){
+            //TODO: what we really need to do here is rejoin the
+            //      current thread and call onreadystatechange via
+            //      setTimeout so the callback is essentially applied
+            //      at the end of the current callstack
+            //console.log('requesting async: %s', this.url);
+            Envjs.runAsync(makeRequest);
+        }else{
+            //console.log('requesting sync: %s', this.url);
+            makeRequest();
+        }
+    },
+    abort: function(){
+        this.aborted = true;
+    },
+    onreadystatechange: function(){
+        //Instance specific
+    },
+    getResponseHeader: function(header){
+        //$debug('GETTING RESPONSE HEADER '+header);
+        var rHeader, returnedHeaders;
+        if (this.readyState < 3){
+            throw new Error("INVALID_STATE_ERR");
+        } else {
+            returnedHeaders = [];
+            for (rHeader in this.responseHeaders) {
+                if (rHeader.match(new RegExp(header, "i"))) {
+                    returnedHeaders.push(this.responseHeaders[rHeader]);
+                }
+            }
+
+            if (returnedHeaders.length){
+                //$debug('GOT RESPONSE HEADER '+returnedHeaders.join(", "));
+                return returnedHeaders.join(", ");
+            }
+        }
+        return null;
+    },
+    getAllResponseHeaders: function(){
+        var header, returnedHeaders = [];
+        if (this.readyState < 3){
+            throw new Error("INVALID_STATE_ERR");
+        } else {
+            for (header in this.responseHeaders) {
+                returnedHeaders.push( header + ": " + this.responseHeaders[header] );
+            }
+        }
+        return returnedHeaders.join("\r\n");
+    },
+    async: true,
+    readyState: 0,
+    responseText: "",
+    status: 0,
+    statusText: ""
+};
+
+/**
+ * @author john resig & the envjs team
+ * @uri http://www.envjs.com/
+ * @copyright 2008-2010
+ * @license MIT
+ */
+//CLOSURE_END
+}());
+
+/**
+ * @todo: document
+ */
+/*var Window,
+    Screen,
+    History,
+    Navigator;
+*/
+
+/*
+ * Envjs window.1.2.35 
+ * Pure JavaScript Browser Environment
+ * By John Resig <http://ejohn.org/> and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ */
+
+//CLOSURE_START
+(function(){
+
+
+
+
+
+/**
+ * @author john resig
+ */
+// Helper method for extending one object with another.
+function __extend__(a,b) {
+    for ( var i in b ) {
+        var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
+        if ( g || s ) {
+            if ( g ) { a.__defineGetter__(i, g); }
+            if ( s ) { a.__defineSetter__(i, s); }
+        } else {
+            a[i] = b[i];
+        }
+    } return a;
+}
+
+/**
+ * @todo: document
+ */
+
+__extend__(HTMLFrameElement.prototype,{
+
+    /*get contentDocument(){
+        return this.contentWindow?
+            this.contentWindow.document:
+            null;
+    },*/	
+    set src(value){
+        var event;
+        this.setAttribute('src', value);
+		//only load if we are already appended to the dom
+        if (this.parentNode && value && value.length > 0){
+            console.log('loading frame via set src %s', value);
+            Envjs.loadFrame(this, Envjs.uri(value, this.ownerDocument?this.ownerDocument.location+'':null));
+
+			//DUPLICATED IN src/platform/core/event.js (Envjs.exchangeHTMLDocument)
+            /*console.log('event frame load %s', value);
+            event = this.ownerDocument.createEvent('HTMLEvents');
+            event.initEvent("load", false, false);
+            this.dispatchEvent( event, false );*/
+        }
+    }
+
+});
+HTMLIFrameElement.prototype.contentDocument = HTMLFrameElement.prototype.contentDocument;
+HTMLIFrameElement.prototype.src = HTMLFrameElement.prototype.src;
+
+
+/*
+ *       history.js
+ *
+ */
+
+History = function(owner) {
+    var $current = 0,
+        $history = [null],
+        $owner = owner;
+
+    return {
+        go : function(target) {
+            if (typeof target === "number") {
+                target = $current + target;
+                if (target > -1 && target < $history.length){
+                    if ($history[target].type === "hash") {
+                        if ($owner.location) {
+                            $owner.location.hash = $history[target].value;
+                        }
+                    } else {
+                        if ($owner.location) {
+                            $owner.location = $history[target].value;
+                        }
+                    }
+                    $current = target;
+                }
+            } else {
+                //TODO: walk through the history and find the 'best match'?
+            }
+        },
+
+        get length() {
+            return $history.length;
+        },
+
+        back : function(count) {
+            if (count) {
+                this.go(-count);
+            } else {
+                this.go(-1);
+            }
+        },
+
+        get current() {
+            return this.item($current);
+        },
+
+        get previous() {
+            return this.item($current-1);
+        },
+
+        forward : function(count) {
+            if (count) {
+                this.go(count);
+            } else {
+                this.go(1);
+            }
+        },
+
+        item: function(idx) {
+            if (idx >= 0 && idx < $history.length) {
+                return $history[idx];
+            } else {
+                return null;
+            }
+        },
+
+        add: function(newLocation, type) {
+            //not a standard interface, we expose it to simplify
+            //history state modifications
+            if (newLocation !== $history[$current]) {
+                $history.slice(0, $current);
+                $history.push({
+                    type: type || 'href',
+                    value: newLocation
+                });
+            }
+        }
+    }; /* closes 'return {' */
+};
+
+
+/*
+ *      navigator.js
+ *  Browser Navigator
+ */
+Navigator = function(){
+	var $userAgent;
+    return {
+        get appCodeName(){
+            return Envjs.appCodeName;
+        },
+        get appName(){
+            return Envjs.appName;
+        },
+        get appVersion(){
+            return Envjs.version +" ("+
+                this.platform +"; "+
+                "U; "+//?
+                Envjs.os_name+" "+Envjs.os_arch+" "+Envjs.os_version+"; "+
+                (Envjs.lang?Envjs.lang:"en-US")+"; "+
+                "rv:"+Envjs.revision+
+                ")";
+        },
+        get cookieEnabled(){
+            return true;
+        },
+        get mimeTypes(){
+            return [];
+        },
+        get platform(){
+            return Envjs.platform;
+        },
+        get plugins(){
+            return [];
+        },
+        get userAgent(){
+            return $userAgent||(this.appCodeName + "/" + this.appVersion + " Resig/20070309 PilotFish/1.2.35");
+        },
+		set userAgent(agent){
+			$userAgent = agent;
+		},
+        javaEnabled : function(){
+            return Envjs.javaEnabled;
+        }
+    };
+};
+
+
+/**
+ * Screen
+ * @param {Object} __window__
+ */
+
+Screen = function(__window__){
+
+    var $availHeight  = 600,
+        $availWidth   = 800,
+        $colorDepth   = 16,
+        $pixelDepth   = 24,
+        $height       = 600,
+        $width        = 800,
+        $top          = 0,
+        $left         = 0,
+        $availTop     = 0,
+        $availLeft    = 0;
+
+    __extend__( __window__, {
+        moveBy : function(dx,dy){
+            //TODO - modify $locals to reflect change
+        },
+        moveTo : function(x,y) {
+            //TODO - modify $locals to reflect change
+        },
+        /*print : function(){
+            //TODO - good global to modify to ensure print is not misused
+        };*/
+        resizeBy : function(dw, dh){
+            __window__resizeTo($width + dw, $height + dh);
+        },
+        resizeTo : function(width, height){
+            $width = (width <= $availWidth) ? width : $availWidth;
+            $height = (height <= $availHeight) ? height : $availHeight;
+        },
+        scroll : function(x,y){
+            //TODO - modify $locals to reflect change
+        },
+        scrollBy : function(dx, dy){
+            //TODO - modify $locals to reflect change
+        },
+        scrollTo : function(x,y){
+            //TODO - modify $locals to reflect change
+        }
+    });
+
+    return {
+        get top(){
+            return $top;
+        },
+        get left(){
+            return $left;
+        },
+        get availTop(){
+            return $availTop;
+        },
+        get availLeft(){
+            return $availLeft;
+        },
+        get availHeight(){
+            return $availHeight;
+        },
+        get availWidth(){
+            return $availWidth;
+        },
+        get colorDepth(){
+            return $colorDepth;
+        },
+        get pixelDepth(){
+            return $pixelDepth;
+        },
+        get height(){
+            return $height;
+        },
+        get width(){
+            return $width;
+        }
+    };
+};
+
+/*
+ * Copyright (c) 2010 Nick Galbreath
+ * http://code.google.com/p/stringencoders/source/browse/#svn/trunk/javascript
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* base64 encode/decode compatible with window.btoa/atob
+ *
+ * window.atob/btoa is a Firefox extension to convert binary data (the "b")
+ * to base64 (ascii, the "a").
+ *
+ * It is also found in Safari and Chrome.  It is not available in IE.
+ *
+ * if (!window.btoa) window.btoa = base64.encode
+ * if (!window.atob) window.atob = base64.decode
+ *
+ * The original spec's for atob/btoa are a bit lacking
+ * https://developer.mozilla.org/en/DOM/window.atob
+ * https://developer.mozilla.org/en/DOM/window.btoa
+ *
+ * window.btoa and base64.encode takes a string where charCodeAt is [0,255]
+ * If any character is not [0,255], then an DOMException(5) is thrown.
+ *
+ * window.atob and base64.decode take a base64-encoded string
+ * If the input length is not a multiple of 4, or contains invalid characters
+ *   then an DOMException(5) is thrown.
+ */
+var base64 = {};
+base64.PADCHAR = '=';
+base64.ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+
+base64.makeDOMException = function() {
+    // sadly in FF,Safari,Chrome you can't make a DOMException
+    var e, tmp;
+
+    try {
+        return new DOMException(DOMException.INVALID_CHARACTER_ERR);
+    } catch (tmp) {
+        // not available, just passback a duck-typed equiv
+        // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error
+        // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error/prototype
+        var ex = new Error("DOM Exception 5");
+
+        // ex.number and ex.description is IE-specific.
+        ex.code = ex.number = 5;
+        ex.name = ex.description = "INVALID_CHARACTER_ERR";
+
+        // Safari/Chrome output format
+        ex.toString = function() { return 'Error: ' + ex.name + ': ' + ex.message; };
+        return ex;
+    }
+};
+
+base64.getbyte64 = function(s,i) {
+    // This is oddly fast, except on Chrome/V8.
+    //  Minimal or no improvement in performance by using a
+    //   object with properties mapping chars to value (eg. 'A': 0)
+    var idx = base64.ALPHA.indexOf(s.charAt(i));
+    if (idx === -1) {
+        throw base64.makeDOMException();
+    }
+    return idx;
+};
+
+base64.decode = function(s) {
+    // convert to string
+    s = '' + s;
+    var getbyte64 = base64.getbyte64;
+    var pads, i, b10;
+    var imax = s.length;
+    if (imax === 0) {
+        return s;
+    }
+
+    if (imax % 4 !== 0) {
+        throw base64.makeDOMException();
+    }
+
+    pads = 0;
+    if (s.charAt(imax - 1) === base64.PADCHAR) {
+        pads = 1;
+        if (s.charAt(imax - 2) === base64.PADCHAR) {
+            pads = 2;
+        }
+        // either way, we want to ignore this last block
+        imax -= 4;
+    }
+
+    var x = [];
+    for (i = 0; i < imax; i += 4) {
+        b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) |
+            (getbyte64(s,i+2) << 6) | getbyte64(s,i+3);
+        x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff, b10 & 0xff));
+    }
+
+    switch (pads) {
+    case 1:
+        b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) | (getbyte64(s,i+2) << 6);
+        x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff));
+        break;
+    case 2:
+        b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12);
+        x.push(String.fromCharCode(b10 >> 16));
+        break;
+    }
+    return x.join('');
+};
+
+base64.getbyte = function(s,i) {
+    var x = s.charCodeAt(i);
+    if (x > 255) {
+        throw base64.makeDOMException();
+    }
+    return x;
+};
+
+base64.encode = function(s) {
+    if (arguments.length !== 1) {
+        throw new SyntaxError("Not enough arguments");
+    }
+    var padchar = base64.PADCHAR;
+    var alpha   = base64.ALPHA;
+    var getbyte = base64.getbyte;
+
+    var i, b10;
+    var x = [];
+
+    // convert to string
+    s = '' + s;
+
+    var imax = s.length - s.length % 3;
+
+    if (s.length === 0) {
+        return s;
+    }
+    for (i = 0; i < imax; i += 3) {
+        b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8) | getbyte(s,i+2);
+        x.push(alpha.charAt(b10 >> 18));
+        x.push(alpha.charAt((b10 >> 12) & 0x3F));
+        x.push(alpha.charAt((b10 >> 6) & 0x3f));
+        x.push(alpha.charAt(b10 & 0x3f));
+    }
+    switch (s.length - imax) {
+    case 1:
+        b10 = getbyte(s,i) << 16;
+        x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) +
+               padchar + padchar);
+        break;
+    case 2:
+        b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8);
+        x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) +
+               alpha.charAt((b10 >> 6) & 0x3f) + padchar);
+        break;
+    }
+    return x.join('');
+};
+//These descriptions of window properties are taken loosely David Flanagan's
+//'JavaScript - The Definitive Guide' (O'Reilly)
+
+var __top__ = function(_scope){
+    var _parent = _scope.parent;
+    while (_scope && _parent && _scope !== _parent) {
+        if (_parent === _parent.parent) {
+            break;
+        }
+        _parent = _parent.parent;
+        //console.log('scope %s _parent %s', scope, _parent);
+    }
+    return _parent || null;
+};
+
+/**
+ * Window
+ * @param {Object} scope
+ * @param {Object} parent
+ * @param {Object} opener
+ */
+Window = function(scope, parent, opener){
+
+    // the window property is identical to the self property and to this obj
+    //var proxy = new Envjs.proxy(scope, parent);
+    //scope.__proxy__ = proxy;
+    scope.__defineGetter__('window', function(){
+        return scope;
+    });
+
+    var $uuid = new Date().getTime()+'-'+Math.floor(Math.random()*1000000000000000);
+    Envjs.windows($uuid, scope);
+    //console.log('opening window %s', $uuid);
+
+    // every window has one-and-only-one .document property which is always
+    // an [object HTMLDocument].  also, only window.document objects are
+    // html documents, all other documents created by the window.document are
+    // [object XMLDocument]
+    var $htmlImplementation =  new DOMImplementation();
+    $htmlImplementation.namespaceAware = true;
+    $htmlImplementation.errorChecking = false;
+
+    // read only reference to the Document object
+    var $document = new HTMLDocument($htmlImplementation, scope);
+
+    // A read-only reference to the Window object that contains this window
+    // or frame.  If the window is a top-level window, parent refers to
+    // the window itself.  If this window is a frame, this property refers
+    // to the window or frame that contains it.
+    var $parent = parent;
+
+    /**> $cookies - see cookie.js <*/
+    // read only boolean specifies whether the window has been closed
+    var $closed = false;
+
+    // a read/write string that specifies the default message that
+    // appears in the status line
+    var $defaultStatus = "Done";
+
+    // IE only, refers to the most recent event object - this maybe be
+    // removed after review
+    var $event = null;
+
+    // a read-only reference to the History object
+    var $history = new History();
+
+    // a read-only reference to the Location object.  the location object does
+    // expose read/write properties
+    var $location = new Location('about:blank', $document, $history);
+
+    // The name of window/frame. Set directly, when using open(), or in frameset.
+    // May be used when specifying the target attribute of links
+    var $name = null;
+
+    // a read-only reference to the Navigator object
+    var $navigator = new Navigator();
+
+    // a read/write reference to the Window object that contained the script
+    // that called open() to open this browser window.  This property is valid
+    // only for top-level window objects.
+    var $opener = opener?opener:null;
+
+    // read-only properties that specify the height and width, in pixels
+    var $innerHeight = 600, $innerWidth = 800;
+
+    // Read-only properties that specify the total height and width, in pixels,
+    // of the browser window. These dimensions include the height and width of
+    // the menu bar, toolbars, scrollbars, window borders and so on.  These
+    // properties are not supported by IE and IE offers no alternative
+    // properties;
+    var $outerHeight = $innerHeight,
+        $outerWidth = $innerWidth;
+
+    // Read-only properties that specify the number of pixels that the current
+    // document has been scrolled to the right and down.  These are not
+    // supported by IE.
+    var $pageXOffset = 0, $pageYOffset = 0;
+
+    // a read-only reference to the Screen object that specifies information
+    // about the screen: the number of available pixels and the number of
+    // available colors.
+    var $screen = new Screen(scope);
+
+    // read only properties that specify the coordinates of the upper-left
+    // corner of the screen.
+    var $screenX = 1,
+        $screenY = 1;
+    var $screenLeft = $screenX,
+        $screenTop = $screenY;
+
+    // a read/write string that specifies the current status line.
+    var $status = '';
+
+    __extend__(scope, EventTarget.prototype);
+
+    return __extend__( scope, {
+        get closed(){
+            return $closed;
+        },
+        get defaultStatus(){
+            return $defaultStatus;
+        },
+        set defaultStatus(defaultStatus){
+            $defaultStatus = defaultStatus;
+        },
+        get document(){
+            return $document;
+        },
+        set document(doc){
+            $document = doc;
+        },
+        /*
+        deprecated ie specific property probably not good to support
+        get event(){
+            return $event;
+        },
+        */
+        get frames(){
+        return new HTMLCollection($document.getElementsByTagName('frame'));
+        },
+        get length(){
+            // should be frames.length,
+            return this.frames.length;
+        },
+        get history(){
+            return $history;
+        },
+        get innerHeight(){
+            return $innerHeight;
+        },
+        get innerWidth(){
+            return $innerWidth;
+        },
+        get clientHeight(){
+            return $innerHeight;
+        },
+        get clientWidth(){
+            return $innerWidth;
+        },
+        get location(){
+            return $location;
+        },
+        set location(url){
+			//very important or you will go into an infinite
+        	//loop when creating a xml document
+			//console.log('setting window location %s', url);
+        	if(url) {
+            	$location.assign(Envjs.uri(url, $location+''));
+			}
+        },
+        get name(){
+            return $name;
+        },
+        set name(newName){
+            $name = newName;
+        },
+        get navigator(){
+            return $navigator;
+        },
+        get opener(){
+            return $opener;
+        },
+        get outerHeight(){
+            return $outerHeight;
+        },
+        get outerWidth(){
+            return $outerWidth;
+        },
+        get pageXOffest(){
+            return $pageXOffset;
+        },
+        get pageYOffset(){
+            return $pageYOffset;
+        },
+        get parent(){
+            return $parent;
+        },
+        get screen(){
+            return $screen;
+        },
+        get screenLeft(){
+            return $screenLeft;
+        },
+        get screenTop(){
+            return $screenTop;
+        },
+        get screenX(){
+            return $screenX;
+        },
+        get screenY(){
+            return $screenY;
+        },
+        get self(){
+            return scope;
+        },
+        get status(){
+            return $status;
+        },
+        set status(status){
+            $status = status;
+        },
+        // a read-only reference to the top-level window that contains this window.
+        // If this window is a top-level window it is simply a reference to itself.
+        // If this window is a frame, the top property refers to the top-level
+        // window that contains the frame.
+        get top(){
+            return __top__(scope);
+        },
+        get window(){
+            return this;
+        },
+        toString : function(){
+            return '[Window]';
+        },
+
+        /**
+         * getComputedStyle
+         *
+         * Firefox 3.6:
+         *  - Requires both elements to be present else an
+         *    exception is thrown.
+         *  - Returns a 'ComputedCSSStyleDeclaration' object.
+         *    while a raw element.style returns a 'CSSStyleDeclaration' object.
+         *  - Bogus input also throws exception
+         *
+         * Safari 4:
+         *  - Requires one argument (second can be MIA)
+         *  - Returns a CSSStyleDeclaration object
+         *  - if bad imput, returns null
+         *
+         * getComputedStyle should really be an "add on" from the css
+         * modules.  Unfortunately, 'window' comes way after the 'css'
+         * so css can't add it.
+         */
+        getComputedStyle: function(element, pseudoElement) {
+            return element.style;
+        },
+
+        open: function(url, name, features, replace){
+            if (features) {
+                console.log("'features argument not yet implemented");
+            }
+            var _window = Envjs.proxy({}),
+                open;
+            if(replace && name){
+                for(open in Envjs.windows()){
+                    if(open.name === name) {
+                        _window = open;
+                    }
+                }
+            }
+            new Window(_window, _window, this);
+            if(name) {
+                _window.name = name;
+            }
+            _window.document.async = false;
+            _window.document.location.assign(Envjs.uri(url));
+            return _window;
+        },
+        close: function(){
+            //console.log('closing window %s', __windows__[$uuid]);
+			var frames = $document.getElementsByTagName('frame'),
+				iframes = $document.getElementsByTagName('iframe'),
+				i;
+			for(i=0;i<frames.length;i++){
+				Envjs.unloadFrame(frame[i]);
+			}	
+			for(i=0;i<iframes.length;i++){
+				Envjs.unloadFrame(frame[i]);
+			}
+            try{
+				Envjs.windows($uuid, null);
+            }catch(e){
+                console.log('%s',e);
+            }
+			return null;
+        },
+        alert : function(message){
+            Envjs.alert(message);
+        },
+        confirm : function(question){
+            Envjs.confirm(question);
+        },
+        prompt : function(message, defaultMsg){
+            Envjs.prompt(message, defaultMsg);
+        },
+        btoa: function(binary){
+            return base64.encode(binary);
+        },
+        atob: function(ascii){
+            return base64.decode(ascii);
+        },
+		//these should be undefined on instantiation
+        //onload: function(){},
+        //onunload: function(){},
+		focus: function(){},
+		blur: function(){},
+        get guid(){
+            return $uuid;
+        }
+    });
+
+};
+
+
+//finally pre-supply the window with the window-like environment
+//console.log('Default Window');
+new Window(__this__, __this__);
+/**
+ * @author john resig & the envjs team
+ * @uri http://www.envjs.com/
+ * @copyright 2008-2010
+ * @license MIT
+ */
+//CLOSURE_END
+}());
diff --git a/browserid/static/dialog/steal/rhino/file.js b/browserid/static/dialog/steal/rhino/file.js
new file mode 100644
index 0000000000000000000000000000000000000000..0f8baaea9eb127fa90e0abcbb15dda08e92ed6df
--- /dev/null
+++ b/browserid/static/dialog/steal/rhino/file.js
@@ -0,0 +1,328 @@
+;
+(function( steal ) {
+
+	var extend = steal.extend;
+
+	if (!steal.File ) {
+		steal.File = function( path ) {
+			if ( this.constructor != steal.File ) {
+				return new steal.File(path)
+			}
+			this.path = path;
+		}
+	}
+	var copy = function( jFile1, jFile2 ) {
+		var fin = new java.io.FileInputStream(jFile1);
+		var fout = new java.io.FileOutputStream(jFile2);
+
+		// Transfer bytes from in to out
+		var data = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 1024);
+		var len = 0;
+		while ((len = fin.read(data)) > 0 ) {
+			fout.write(data, 0, len);
+		}
+		fin.close();
+		fout.close();
+	}
+	var addDir = function( dirObj, out, replacePath ) {
+		var files = dirObj.listFiles();
+		var tmpBuf = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 1024);
+
+		for ( var i = 0; i < files.length; i++ ) {
+			if ( files[i].isDirectory() ) {
+				addDir(files[i], out, replacePath);
+				continue;
+			}
+			var inarr = new java.io.FileInputStream(files[i].getAbsolutePath());
+			var zipPath = files[i].getPath().replace(replacePath, "").replace("\\", "/")
+			if (/\.git|\.zip/.test(zipPath) ) continue;
+			print(zipPath)
+			out.putNextEntry(new java.util.zip.ZipEntry(zipPath));
+			var len;
+			while ((len = inarr.read(tmpBuf)) > 0 ) {
+				out.write(tmpBuf, 0, len);
+			}
+			out.closeEntry();
+			inarr.close();
+		}
+	}
+	extend(steal.File.prototype, {
+		/**
+		 * Removes hash and params
+		 * @return {String}
+		 */
+		clean: function() {
+			return this.path.match(/([^\?#]*)/)[1];
+		},
+		/**
+		 * Returns everything before the last /
+		 */
+		dir: function() {
+			var last = this.clean().lastIndexOf('/'),
+				dir = (last != -1) ? this.clean().substring(0, last) : '',
+				parts = dir != '' && dir.match(/^(https?:\/|file:\/)$/);
+			return parts && parts[1] ? this.clean() : dir;
+		},
+		/**
+		 * Returns the domain for the current path.
+		 * Returns null if the domain is a file.
+		 */
+		domain: function() {
+			if ( this.path.indexOf('file:') == 0 ) return null;
+			var http = this.path.match(/^(?:https?:\/\/)([^\/]*)/);
+			return http ? http[1] : null;
+		},
+		protocol: function() {
+			return this.path.match(/^(https?:|file:)/)[1]
+		},
+		/**
+		 * Joins url onto path
+		 * @param {Object} url
+		 */
+		join: function( url ) {
+			return new steal.File(url).joinFrom(this.path);
+		},
+		/**
+		 * Returns the path of this file referenced form another url.
+		 * @codestart
+		 * new steal.File('a/b.c').joinFrom('/d/e')//-> /d/e/a/b.c
+		 * @codeend
+		 * @param {Object} url
+		 * @param {Object} expand
+		 * @return {String} 
+		 */
+		joinFrom: function( url, expand ) {
+			if ( this.isDomainAbsolute() ) {
+				var u = new File(url);
+				if ( this.domain() && this.domain() == u.domain() ) return this.afterDomain();
+				else if ( this.domain() == u.domain() ) { // we are from a file
+					return this.toReferenceFromSameDomain(url);
+				} else return this.path;
+			} else if ( url == steal.pageDir && !expand ) {
+				return this.path;
+			} else if ( this.isLocalAbsolute() ) {
+				var u = new File(url);
+				if (!u.domain() ) return this.path;
+				return u.protocol() + "//" + u.domain() + this.path;
+			}
+			else {
+
+				if ( url == '' ) return this.path.replace(/\/$/, '');
+				var urls = url.split('/'),
+					paths = this.path.split('/'),
+					path = paths[0];
+				if ( url.match(/\/$/) ) urls.pop();
+				while ( path == '..' && paths.length > 0 ) {
+					paths.shift();
+					urls.pop();
+					path = paths[0];
+				}
+				return urls.concat(paths).join('/');
+			}
+		},
+		/**
+		 * Returns true if the file is relative
+		 */
+		relative: function() {
+			return this.path.match(/^(https?:|file:|\/)/) == null;
+		},
+		/**
+		 * Returns the part of the path that is after the domain part
+		 */
+		after_domain: function() {
+			return this.path.match(/(?:https?:\/\/[^\/]*)(.*)/)[1];
+		},
+		/**
+		 * 
+		 * @param {Object} url
+		 */
+		toReferenceFromSameDomain: function( url ) {
+			var parts = this.path.split('/'),
+				other_parts = url.split('/'),
+				result = '';
+			while ( parts.length > 0 && other_parts.length > 0 && parts[0] == other_parts[0] ) {
+				parts.shift();
+				other_parts.shift();
+			}
+			for ( var i = 0; i < other_parts.length; i++ ) result += '../';
+			return result + parts.join('/');
+		},
+		/**
+		 * Is the file on the same domain as our page.
+		 */
+		is_cross_domain: function() {
+			if ( this.isLocalAbsolute() ) return false;
+			return this.domain() != new steal.File(location.href).domain();
+		},
+		isLocalAbsolute: function() {
+			return this.path.indexOf('/') === 0
+		},
+		isDomainAbsolute: function() {
+			return this.path.match(/^(https?:|file:)/) != null
+		},
+		/**
+		 * For a given path, a given working directory, and file location, update the path so 
+		 * it points to the right location.
+		 */
+
+
+		mkdir: function() {
+			print(this.path)
+			var out = new java.io.File(this.path)
+			out.mkdir();
+		},
+		mkdirs: function() {
+			var out = new java.io.File(this.path)
+			out.mkdirs();
+		},
+		exists: function() {
+			var exists = (new java.io.File(this.path)).exists();
+			return exists;
+		},
+		copyTo: function( dest, ignore ) {
+			var me = new java.io.File(this.path)
+			var you = new java.io.File(dest);
+			if ( me.isDirectory() ) {
+				var children = me.list();
+				for ( var i = 0; i < children.length; i++ ) {
+					var newMe = new java.io.File(me, children[i]);
+					var newYou = new java.io.File(you, children[i]);
+					if ( ignore && ignore.indexOf("" + newYou.getName()) != -1 ) {
+						continue;
+					}
+					if ( newMe.isDirectory() ) {
+						newYou.mkdir();
+						new steal.File(newMe.path).copyTo(newYou.path, ignore)
+					} else {
+						copy(newMe, newYou)
+					}
+				}
+				return;
+			}
+			copy(me, you)
+		},
+		save: function( src, encoding ) {
+			var fout = new java.io.FileOutputStream(new java.io.File(this.path));
+
+			var out = new java.io.OutputStreamWriter(fout, "UTF-8");
+			var s = new java.lang.String(src || "");
+
+			var text = new java.lang.String((s).getBytes(), encoding || "UTF-8");
+			out.write(text, 0, text.length());
+			out.flush();
+			out.close();
+		},
+		download_from: function( address ) {
+			var input =
+			new java.io.BufferedInputStream(
+			new java.net.URL(address).openStream());
+
+			bout = new java.io.BufferedOutputStream(
+			new java.io.FileOutputStream(this.path), 1024);
+			var data = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 1024);
+			var num_read = 0;
+			while ((num_read = input.read(data, 0, 1024)) >= 0 ) {
+				bout.write(data, 0, num_read);
+			}
+			bout.close();
+		},
+		basename: function() {
+			return this.path.match(/\/?([^\/]*)\/?$/)[1];
+		},
+		remove: function() {
+			var file = new java.io.File(this.path);
+			file["delete"]();
+		},
+		removeDir: function() {
+			var me = new java.io.File(this.path)
+			if ( me.exists() ) {
+				var files = me.listFiles();
+				for ( var i = 0; i < files.length; i++ ) {
+					if ( files[i].isDirectory() ) {
+						new steal.File(files[i]).removeDir();
+					} else {
+						files[i]["delete"]();
+					}
+				}
+			}
+			me["delete"]()
+		},
+		zipDir: function( name, replacePath ) {
+			var dirObj = new java.io.File(this.path);
+			var out = new java.util.zip.ZipOutputStream(new java.io.FileOutputStream(name));
+			addDir(dirObj, out, replacePath);
+			out.close();
+		},
+		contents: function( func, current ) {
+			
+			var me = new java.io.File(this.path),
+				listOfFiles = me.listFiles();
+				
+			if ( listOfFiles == null ) {
+				//print("there is nothing in " + this.path)
+				return;
+			}
+			for ( var i = 0; i < listOfFiles.length; i++ ) {
+				func(listOfFiles[i].getName(), listOfFiles[i].isFile() ? "file" : "directory", current)
+			}
+			return listOfFiles;
+		},
+		/**
+		 * Returns the path to the root jmvc folder
+		 */
+		pathToRoot: function( isFile ) {
+			var root = steal.File.getRoot(),
+				rootFolders = root.split(/\/|\\/),
+				targetDir = rootFolders[rootFolders.length-1]
+				i = 0,
+				adjustedPath = (targetDir? this.path.replace(new RegExp(".*"+targetDir+"\/?"),""): 
+					this.path),
+				myFolders = adjustedPath.split(/\/|\\/);
+
+			//for each .. in loc folders, replace with steal folder
+			if ( myFolders[i] == ".." ) {
+				while ( myFolders[i] == ".." ) {
+					myFolders[i] = rootFolders.pop();
+					i++;
+				}
+			} else {
+				for ( i = 0; i < myFolders.length - 1; i++ ) {
+					myFolders[i] = ".."
+				}
+			}
+			myFolders.pop();
+
+			if (!isFile ) {
+				myFolders.push('..')
+			}
+			return myFolders.join("/")
+		}
+	});
+
+	/**
+	 * If there's a CMD system variable (like "documentjs/document.bat"), 
+	 * assumes the root is the folder one below the scripts folder.
+	 * 
+	 * Otherwise, assumes the current directory IS the root jmvc folder (framework)
+	 * 
+	 */
+	steal.File.getRoot = function() {
+		var cwd = steal.File.cwd(),
+			cmd = ""+java.lang.System.getProperty("cmd"),
+			root = cwd,
+			relativeRoot;
+		
+		if(cmd) {
+			relativeRoot = cmd.replace(/\/?[^\/]*\/[^\/]*$/, "")
+			root = cwd+'/'+relativeRoot;
+		} 
+		return root;
+	}
+	steal.File.cwdURL = function() {
+		return new java.io.File("").toURL().toString();
+	}
+	steal.File.cwd = function() {
+		return String(new java.io.File('').getAbsoluteFile().toString());
+	}
+
+})(steal);
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/rhino/js.jar b/browserid/static/dialog/steal/rhino/js.jar
new file mode 100644
index 0000000000000000000000000000000000000000..2369f99a9edc78dbd027b839cf9e7a7e77ac3436
Binary files /dev/null and b/browserid/static/dialog/steal/rhino/js.jar differ
diff --git a/browserid/static/dialog/steal/rhino/loader b/browserid/static/dialog/steal/rhino/loader
new file mode 100644
index 0000000000000000000000000000000000000000..2b3210751acde8f80a8adb1c6c78d69f39ed7d0d
--- /dev/null
+++ b/browserid/static/dialog/steal/rhino/loader
@@ -0,0 +1,16 @@
+#!/bin/sh
+# This script is the common JS loader
+
+ARGS=[
+for arg
+do
+  ARGS=$ARGS"'$arg'",
+done
+ARGS=$ARGS]
+
+#if [ $LOADPATH == "" ]
+#then
+#  LOADPATH=$BASE$1
+#fi
+
+java -Xmx170m -Xss1024k -cp $CP -Dbasepath=$BASE -Dcmd=$CMD org.mozilla.javascript.tools.shell.Main -opt -1 -e _args="$ARGS" -e 'load('"'"$LOADPATH"'"')'
diff --git a/browserid/static/dialog/steal/rhino/loader.bat b/browserid/static/dialog/steal/rhino/loader.bat
new file mode 100644
index 0000000000000000000000000000000000000000..a2ccf002e295001cebcb3b6b091f7682d91feb3e
--- /dev/null
+++ b/browserid/static/dialog/steal/rhino/loader.bat
@@ -0,0 +1,35 @@
+@echo off
+
+SETLOCAL ENABLEDELAYEDEXPANSION
+
+if not "%BASE%" == "" ( set BASE=%BASE:\=/% )
+if not "%CMD%" == "" ( set CMD=%CMD:\=/% )
+
+:: trim spaces
+for /f "tokens=1*" %%A in ("%BASE%") do SET BASE=%%A
+for /f "tokens=1*" %%A in ("%CMD%") do SET CMD=%%A
+
+:: handle args
+SET ARGS=[
+for /f "tokens=1,2,3,4,5,6 delims= " %%a in ("%*") do SET ARGS=!ARGS!'%%a','%%b','%%c','%%d','%%e','%%f'
+for %%a in (",''=") do ( call set ARGS=%%ARGS:%%~a%% )
+for /f "tokens=1*" %%A in ("%ARGS%") do SET ARGS=%%A
+SET ARGS=%ARGS%]
+set ARGS=%ARGS:\=/%
+
+:: figure out startup path
+if "%LOADPATH%" == "" ( set LOADPATH=%BASE%%1 )
+
+:: if no LOADPATH (TODO this won't work as is because loadpath is never empty)
+if "%LOADPATH%"=="" (
+	java -cp js.jar org.mozilla.javascript.tools.shell.Main
+	GOTO END
+)
+
+:: need to use forward slashes for paths
+set LOADPATH=%LOADPATH:\=/%
+
+:: invoke Rhino
+java -Xmx170m -Xss1024k -cp %CP% -Dbasepath="%BASE%" -Dcmd="%CMD%" org.mozilla.javascript.tools.shell.Main -opt -1 -e _args=%ARGS% -e load('%LOADPATH%')
+
+:END
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/rhino/loader.js b/browserid/static/dialog/steal/rhino/loader.js
new file mode 100644
index 0000000000000000000000000000000000000000..6490b0cf1dc37c6879aa645e26427b8ad0acd29d
--- /dev/null
+++ b/browserid/static/dialog/steal/rhino/loader.js
@@ -0,0 +1,14 @@
+rhinoLoader = function( func, fireLoad ) {
+	rhinoLoader.callback = func;
+	load('steal/rhino/env.js');
+	Envjs('steal/rhino/empty.html', {
+		scriptTypes: {
+			"text/javascript": true,
+			"text/envjs": true
+		},
+		fireLoad: fireLoad,
+		logLevel: 2,
+		dontPrintUserAgent: true,
+		killTimersAfterLoad: true
+	});
+}
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/rhino/prompt.js b/browserid/static/dialog/steal/rhino/prompt.js
new file mode 100644
index 0000000000000000000000000000000000000000..92f2041fcc85315930846064588de0e06fdbee52
--- /dev/null
+++ b/browserid/static/dialog/steal/rhino/prompt.js
@@ -0,0 +1,48 @@
+steal(function( steal ) {
+	steal.prompt = function( question ) {
+		java.lang.System.out.print(question);
+		var br = new java.io.BufferedReader(new java.io.InputStreamReader(java.lang.System["in"]));
+		var response;
+		try {
+			response = br.readLine();
+		} catch (e) {
+			System.out.println("IO error trying to read");
+		}
+		return response;
+	}
+	/**
+	 * 
+	 * @param {String} question
+	 * @param {Boolean} true or false
+	 */
+	steal.prompt.yesno = function( question ) {
+		var response = "";
+		while (!response.match(/^\s*[yn]\s*$/i) ) {
+			response = steal.prompt(question)
+		}
+		return response.match(/[yn]/i)[0].toLowerCase() == "y";
+	}
+
+	/**
+	 * Accepts an array of possible arguments and creates global variables for each that is found in args
+	 * ie: steal.handleArgs(_args, ["path"])
+	 * Args are passed in via command line scripts like this:
+	 * js run.js path=/one/two docsLocation=docs
+	 * @param {Object} possibleArgs
+	 */
+	steal.handleArgs = function( args, possibleArgs ) {
+		var i, arg, j, possibleArg, matchedArg, results = {};
+		for ( i = 0; i < args.length; i++ ) {
+			arg = args[i];
+			for ( j = 0; j < possibleArgs.length; j++ ) {
+				possibleArg = possibleArgs[j];
+				reg = new RegExp("^" + possibleArg + "\=([^\\s]+)");
+				matchedArg = arg.match(reg);
+				if ( matchedArg && matchedArg[1] ) {
+					results[possibleArg] = matchedArg[1];
+				}
+			}
+		}
+		return results;
+	}
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/rhino/steal.js b/browserid/static/dialog/steal/rhino/steal.js
new file mode 100644
index 0000000000000000000000000000000000000000..63965bdb8c8c3f87a8a47779b0428a493024eab5
--- /dev/null
+++ b/browserid/static/dialog/steal/rhino/steal.js
@@ -0,0 +1,135 @@
+//a steal for the filesystem
+(function() {
+	var oldWindow = function() {
+		return (function() {
+			return this
+		}).call(null, 0);
+	},
+		oldSteal = oldWindow().steal;
+	var steal = (oldWindow().steal = function() {
+		for ( var i = 0; i < arguments.length; i++ ) {
+			var inc = arguments[i];
+			if ( typeof inc == 'string' ) {
+				load(inc.substr(2) + ".js")
+			} else {
+				inc(steal)
+			}
+		}
+		return steal;
+	});
+	steal.plugins = function() {
+		for ( var i = 0; i < arguments.length; i++ ) {
+			var inc = arguments[i];
+			if ( typeof inc == 'string' ) {
+				load(inc + "/" + inc.match(/\w+$/)[0] + ".js")
+			} else {
+				inc(steal)
+			}
+		}
+		return steal;
+	}
+	steal.extend = function( d, s ) {
+		for ( var p in s ) d[p] = s[p];
+		return d;
+	};
+
+	steal.isArray = function( arr ) {
+		return Object.prototype.toString.call(arr) === "[object Array]"
+	}
+	steal.then = steal;
+	steal.inArray = function( item, arr ) {
+		var len = arr.length;
+		for ( var i = 0; i < len; i++ ) {
+			if ( arr[i] == item ) {
+				return i;
+			}
+		}
+		return -1;
+	};
+	steal.cleanId = function( id ) {
+		return id.replace(/[\/\.]/g, "_");
+	};
+	steal.win = oldWindow;
+	if ( oldSteal ) {
+		steal._steal = oldSteal;
+	}
+	/**
+	 * Converts args or a string into options
+	 * @param {Object} args
+	 * @param {Object} options something like 
+	 * {
+	 * name : {
+	 * 	shortcut : "-n",
+	 * 	args: ["first","second"]
+	 * },
+	 * other : 1
+	 * }
+	 */
+	steal.opts = function( args, options ) {
+		if ( typeof args == 'string' ) {
+			args = args.split(' ')
+		}
+		if (!steal.isArray(args) ) {
+			return args
+		}
+
+		var opts = {};
+		//normalizes options
+		(function() {
+			var name, val, helper
+			for ( name in options ) {
+				val = options[name];
+				if ( steal.isArray(val) || typeof val == 'number' ) {
+					options[name] = {
+						args: val
+					};
+				}
+				options[name].name = name;
+				//move helper
+				helper = options[name].helper || name.substr(0, 1);
+
+				options[helper] = options[name]
+			}
+		})();
+		var latest, def;
+		for ( var i = 0; i < args.length; i++ ) {
+			if ( args[i].indexOf('-') == 0 && (def = options[args[i].substr(1)]) ) {
+				latest = def.name;
+				opts[latest] = true;
+				//opts[latest] = []
+			} else {
+				if ( opts[latest] === true ) {
+					opts[latest] = args[i]
+				} else {
+					if (!steal.isArray(opts[latest]) ) {
+						opts[latest] = [opts[latest]]
+					}
+					opts[latest].push(args[i])
+				}
+
+			}
+		}
+
+		return opts;
+	}
+	steal.clear = function() {
+		var win = steal.win();
+		for ( var n in win ) {
+			if ( n != "_S" ) {
+				//this[n] = null;
+				delete win[n];
+			}
+		}
+		return steal;
+	}
+	// a way to turn off printing (mostly for testing purposes)
+	steal.print = function(){
+
+		if(typeof STEALPRINT == "undefined" || STEALPRINT !== false){
+			print.apply(null, arguments)
+		}
+	}
+})()
+
+
+load('steal/rhino/file.js')
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/rhino/test.js b/browserid/static/dialog/steal/rhino/test.js
new file mode 100644
index 0000000000000000000000000000000000000000..fe7e9343c9ff370131d1388f68e7523c21bba55d
--- /dev/null
+++ b/browserid/static/dialog/steal/rhino/test.js
@@ -0,0 +1,16 @@
+load('steal/rhino/steal.js')
+steal('//steal/test/test', function( s ) {
+
+	//test options
+	var res = s.opts("-n abc def -other foo", {
+		name: {
+			shortcut: "-n",
+			args: ["first", "second"]
+		},
+		other: 1
+	})
+
+	s.test.ok(res.name)
+	s.test.ok(res.name[0] == "abc")
+	s.test.ok(res.name[1] == "def")
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/rhino/utils.js b/browserid/static/dialog/steal/rhino/utils.js
new file mode 100644
index 0000000000000000000000000000000000000000..1a13c975bea1db7ac25558471963424f8ca12dd6
--- /dev/null
+++ b/browserid/static/dialog/steal/rhino/utils.js
@@ -0,0 +1,35 @@
+/**
+ * Rhino utilities
+ */
+(function(){
+	//convert readFile and load
+	var oldLoad = load,
+		oldReadFile = readFile,
+		basePath = java.lang.System.getProperty("basepath");
+	
+	var pathFromRoot = function(path){
+		if (!/^\/\//.test(path) && !/^\w\:\\/.test(path) && !/^http/.test(path) && basePath) {
+			path = basePath + "../" + path
+		}
+		return path;
+	}
+		
+	var oldRunCommand = runCommand;
+	/**
+	 * @param {Object} cmd something like java bla/here/something.jar -userExtensions something/here.js
+	 * @param {Object} transformPath if true, this will take relative paths and add the basePath to it, it will 
+	 * also fix the slashes for your OS
+	 */
+	runCommand = function(shell, shellCmd, cmd){
+		var fileRegex = /([^\s]|\/)+\.\w+/g // anything with a slash, no space, and a period
+		cmd = cmd.replace(fileRegex, pathFromRoot);
+		oldRunCommand(shell, shellCmd, cmd);
+	}
+		
+	load = function( path ) {
+		oldLoad(pathFromRoot(path))
+	}
+	readFile = function( path ) {
+		return oldReadFile(pathFromRoot(path))
+	}
+})()
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/steal.js b/browserid/static/dialog/steal/steal.js
new file mode 100644
index 0000000000000000000000000000000000000000..984687d8fb93d3d20c4aa94f894b46397c6756dc
--- /dev/null
+++ b/browserid/static/dialog/steal/steal.js
@@ -0,0 +1,1360 @@
+/*
+ * JavaScriptMVC - steal.js
+ * (c) 2010 Jupiter JavaScript Consulting
+ * 
+ * steal provides dependency management
+ * steal('path/to/file').then(function(){
+ *   //do stuff with file
+ * })
+ */
+
+/*jslint evil: true */
+/*global steal: true, window: false */
+//put everything in function to keep space clean
+(function() {
+
+	if ( typeof steal != 'undefined' && steal.nodeType ) {
+		throw ("steal is defined an element's id!");
+	}
+
+	// HELPERS (if you are trying to understand steal, skip this part)
+	// keep a reference to the old steal
+	var oldsteal = window.steal,
+		// returns the document head (creates one if necessary)
+		head = function() {
+			var d = document,
+				de = d.documentElement,
+				heads = d.getElementsByTagName("head");
+			if ( heads.length > 0 ) {
+				return heads[0];
+			}
+			var head = d.createElement('head');
+			de.insertBefore(head, de.firstChild);
+			return head;
+		},
+		// creates a script tag
+		scriptTag = function() {
+			var start = document.createElement('script');
+			start.type = 'text/javascript';
+			return start;
+		},
+		extend = function( d, s ) {
+			for ( var p in s ) {
+				d[p] = s[p];
+			}
+			return d;
+		},
+		getLastPart = function( p ) {
+			return p.match(/[^\/]+$/)[0];
+		},
+		browser = {
+			msie: !! (window.attachEvent && !window.opera),
+			opera: !! window.opera,
+			safari: navigator.userAgent.indexOf('AppleWebKit/') > -1,
+			firefox: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
+			mobilesafari: !! navigator.userAgent.match(/Apple.*Mobile.*Safari/),
+			rhino: navigator.userAgent.match(/Rhino/) && true
+		},
+		factory = function() {
+			return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
+		},
+		// writes a steal to the page in a way that steal.end gets called after the script gets run
+		insert = function( options ) {
+			// source we need to know how to get to steal, then load 
+			// relative to path to steal
+			options = extend({
+				id: options.src && steal.cleanId(options.src)
+			}, options);
+
+			var text = "",
+				scriptTag = '<script ',
+				bodyText;
+			if ( options.src ) {
+				var src_file = steal.File(options.src);
+				if (!src_file.isLocalAbsolute() && !src_file.protocol() ) {
+					options.src = steal.root.join(options.src);
+				}
+			}
+
+
+			if ( options.type && options.process ) {
+				text = steal.request(options.src);
+				if (!text ) {
+					throw "steal.js there is nothing at " + options.src;
+				}
+				bodyText = options.process(text);
+				options.type = 'text/javascript';
+				delete options.process;
+				delete options.src;
+
+			} else if ( options.type && options.type != 'text/javascript' && !browser.rhino ) {
+				text = steal.request(options.src);
+				if (!text ) {
+					throw "steal.js there is nothing at " + options.src;
+				}
+				options.text = text;
+				delete options.src;
+			}
+
+			for ( var attr in options ) {
+				scriptTag += attr + "='" + options[attr] + "' ";
+			}
+			if ( steal.support.load && !steal.browser.rhino && !bodyText ) {
+				scriptTag += steal.loadErrorTimer(options);
+			}
+			scriptTag += '>' + (bodyText || '') + '</script>';
+			if ( steal.support.load ) {
+				scriptTag += '<script type="text/javascript"' + '>steal.end()</script>';
+			}
+			else {
+				scriptTag += '<script type="text/javascript" src="' + steal.root.join('steal/end.js') + '"></script>';
+			}
+			document.write((options.src || bodyText ? scriptTag : ''));
+		};
+
+	/**
+	 * @class steal
+	 * @parent stealjs
+	 * <p>Steal makes JavaScript dependency management and resource loading easy.</p>
+	 * <p>This page details the steal script (<code>steal/steal.js</code>), 
+	 * and steal function which are used to load files into your page.  
+	 * For documentation of other Steal projects, read [stealjs StealJS].</p>
+	 * <h3>Quick Overview</h3>
+	 * 
+	 * <p>To start using steal, add the steal script to your page, and tell it the first
+	 * file to load:</p>
+	 * </p>
+	 * @codestart html
+	 *&lt;script type='text/javascript'
+	 *        src='public/steal/steal.js?<u><b>myapp/myapp.js</b></u>'>&lt;/script>
+	 * @codeend
+	 * 
+	 * <p>In the file (<code>public/myapp/myapp.js</code>), 
+	 * 'steal' all other files that you need like:</p>
+	 * @codestart
+	 * steal("anotherFile")           //loads myapp/anotherFiles.js
+	 *    .css('style')               //      myapp/style.css
+	 *    .plugins('jquery/view',     //      jquery/view/view.js
+	 *             'steal/less')      //      steal/less/less.js
+	 *    .then(function(){           //called when all prior files have completed
+	 *       steal.less('myapp')      //loads myapp/myapp.less
+	 *    })
+	 *    .views('//myapp/show.ejs')  //loads myapp/show.ejs
+	 * @codeend
+	 * <p>Finally compress your page's JavaScript and CSS with:</p>
+	 * @codestart
+	 * > js steal/buildjs path/to/mypage.html
+	 * @codeend
+	 * <h2>Use</h2>
+	 * Use of steal.js is broken into 5 parts:
+	 * <ul>
+	 * <li>Loading steal.js </li> 
+	 *  <li>Loading your 'application' file.</li>
+	 *    <li>"Stealing" scripts</li>
+	 *    <li>Building (Concatenating+Compressing) the app</li>
+	 *    <li>Switching to the production build</li>
+	 * </ul>
+	 * 
+	 * 
+	 * <h3>Loading <code>steal.js</code></h3>
+	 * <p>First, you need to [download download JavaScriptMVC] (or steal standalone) and unzip it into a
+	 *    public folder on your server.  For this example, lets assume you have the steal script in
+	 *    <code>public/steal/steal.js</code>.   
+	 * </p>
+	 * <p>Next, you need to load the <code>steal.js</code> script in your html page.  We suggest 
+	 *    [http://developer.yahoo.com/performance/rules.html#js_bottom bottom loading] your scripts.
+	 *    For example, if your page is in <code>pages/myapp.html</code>, you can get steal like:
+	 * </p>
+	 * @codestart html
+	 * &lt;script type='text/javascript'
+	 *     src='../public/steal/steal.js'>
+	 * &lt;/script>
+	 * @codeend
+	 * <h3>Loading your 'application' file</h3>
+	 * <p>The first file your application loads
+	 * is referred to as an "application" file.  It loads all the files and resources
+	 * that your application needs.  For this example, we'll put our application file in:
+	 * <code>public/myapp/myapp.js</code>
+	 * </p>
+	 * <p>You have to tell steal where to find it by configuring [steal.static.options].
+	 * There are a lot of ways to configure steal to load your app file, but we've made it really easy:</p>
+	 * @codestart html
+	 * &lt;script type='text/javascript'
+	 *     src='../public/steal/steal.js?<u><b>myapp/myapp.js</b></u>'>
+	 * &lt;/script>
+	 * @codeend
+	 * This sets ...
+	 * @codestart
+	 * steal.options.startFile = 'myapp/myapp.js'
+	 * @codeend
+	 * 
+	 * ... and results in steal loading 
+	 * <code>public/myapp/myapp.js</code>.</p>
+	 * 
+	 * <div class='whisper'>
+	 *    TIP: If startFile doesn't end with <code>.js</code> (ex: myapp), steal assumes
+	 *    you are using JavaScriptMVC's folder pattern and will load:
+	 *    <code>myapp/myapp.js</code> just to save you 9 characters.
+	 * </div>
+	 * <h3>Stealing Scripts</h3>
+	 * In your files, use the steal function and its helpers
+	 *  to load dependencies then describe your functionality.
+	 * Typically, most of the 'stealing' is done in your application file.  Loading 
+	 * jQuery and jQuery.UI from google, a local helpers.js 
+	 * and then adding tabs might look something like this:
+	 * @codestart
+	 * steal( 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js',
+	 *        'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.0/jquery-ui.js',
+	 *        'helpers')
+	 * .then( function(){
+	 *   $('#tabs').tabs();
+	 * });
+	 * @codeend
+	 * 
+	 * There's a few things to notice:
+	 * 
+	 *   - the steal function can take multiple arguments.  Each argument 
+	 *    can be a string, object, or function.  Learn more about what can be passed to 
+	 *    steal in the [steal.prototype.init] documentation. 
+	 *   - steal can load cross domain</li>
+	 *   - steal loads relative to the current file</li>
+	 *   - steal adds .js if not present</li>
+	 *   - steal is chainable (most function return steal)
+     * 
+	 * ### Building the app
+	 * 
+	 * Building the app means combining and compressing your apps JavaScript and CSS into a single file.
+	 * A lot more details can be found on building in the 
+	 * [steal.build steal.build documentation].  But, if you used JavaScriptMVC's app or plugin
+	 * generator, you can build
+	 * your app's JS and CSS with:
+	 * 
+	 * 
+	 * @codestart no-highlight
+	 * js myapp\scripts\compress.js
+	 * @codeend
+	 * 
+	 * Or if you are using steal without JavaScriptMVC:
+	 * 
+	 * @codestart no-highlight
+	 * js steal/buildjs pages/myapp.html -to public/myapp
+	 * @codeend
+	 * 
+	 * This creates <code>public/myapp/production.js</code> and <code>public/myapp/production.css</code>.
+	 * 
+	 * ### Switching to the production build
+	 * 
+	 * To use the production files, load steal.production.js instead of steal.js in your html file:
+	 * 
+	 * @codestart html
+	 * &lt;script type='text/javascript'
+	 *         src='../public/steal/<u><b>steal.production.js</b></u>?myapp/myapp.js'>
+	 * &lt;/script>
+	 * @codeend
+	 * 
+	 * ## Steal helpers
+	 * 
+	 * There are a number of steal helper functions that can be used to load files in a particular location
+	 * or of a type other than JavaScript:
+	 * 
+	 *  * [steal.static.coffee] - loads  
+	 *     [http://jashkenas.github.com/coffee-script/ CoffeeScript] scripts.
+	 *  * [steal.static.controllers] - loads controllers relative to the current path.
+	 *  * [steal.static.css] - loads a css file.
+	 *  * [steal.static.less] - loads [http://lesscss.org/ Less] style sheets.
+	 *  * [steal.static.models] - loads models relative to the current path.
+	 *  * [steal.static.plugins] - loads JavaScript files relative to steal's root folder.
+	 *  * [steal.static.resources] - loads a script in a relative resources folder.
+	 *  * [steal.static.views] - loads a client side template to be compiled into the production build.
+	 * 
+	 * ## Script Load Order
+	 * 
+	 * The load order for your scripts follows a consistent last-in first-out order across all browsers. 
+	 * This is the same way the following document.write would work in msie, Firefox, or Safari:
+	 * @codestart
+	 * document.write('&lt;script type="text/javascript" src="some_script.js"></script>')
+	 * @codeend
+	 * An example helps illustrate this.<br/>
+	 * <img src='http://wiki.javascriptmvc.com/images/last_in_first_out.png'/>
+	 * <table class="options">
+	 * <tr class="top">
+	 * <th>Load Order</th>
+	 * <th class="right">File</th>
+	 * </tr>
+	 * <tbody>
+	 * <tr>
+	 * <td>1</td>
+	 * <td class="right">1.js</td>
+	 * </tr>
+	 * <tr>
+	 * <td>2</td>
+	 * <td class="right">3.js</td>
+	 * </tr>
+	 * <tr>
+	 * <td>3</td>
+	 * <td class="right">4.js</td>
+	 * </tr>
+	 * <tr>
+	 * <td>4</td>
+	 * <td class="right">2.js</td>
+	 * </tr>
+	 * <tr>
+	 * <td>5</td>
+	 * <td class="right">5.js</td>
+	 * </tr>
+	 * <tr class="bottom">
+	 * <td>6</td>
+	 * <td class="right">6.js</td>
+	 * </tr>
+	 *</tbody></table>
+	 * @constructor 
+	 * Loads files or runs functions after all previous files and functions have been loaded.
+	 * @param {String|Object|Function+} resource Each argument represents a resource or function.
+	 * Arguments can be a String, Object, or Function.
+	 * <table class='options'>
+	 *  <tr>
+	 *  <th>Type</th><th>Description</th>
+	 *  </tr>
+	 *  <tr><td>String</td>
+	 * <td>A path to a JavaScript file.  The path can optionally end in '.js'.<br/>  
+	 * Paths are typically assumed to be relative to the current JavaScript file. But paths, that start
+	 * with: 
+	 * <ul>
+	 * <li><code>http(s)://</code> are absolutely referenced.</li>
+	 * <li><code>/</code> are referenced from the current domain.</li>
+	 * <li><code>//</code> are referenced from the ROOT folder.</li>
+	 * 
+	 * </td></tr>
+	 *  <tr><td>Object</td>
+	 *  <td>An Object with the following properties:
+	 *  <ul>
+	 *  <li>path {String} - relative path to a JavaScript file.  </li>
+	 *  <li>type {optional:String} - Script type (defaults to text/javascript)</li>
+	 *  <li>skipInsert {optional:Boolean} - Include not added as script tag</li>
+	 *  <li>compress {optional:String} - "false" if you don't want to compress script</li>
+	 *  <li>package {optional:String} - Script package name (defaults to production.js)</li> 
+	 *  </ul>
+	 *  </td></tr>
+	 *  <tr><td>Function</td><td>A function to run after all the prior steals have finished loading</td></tr>
+	 * </table>
+	 * @return {steal} returns itself for chaining.
+	 */
+	steal = function() {
+		for ( var i = 0; i < arguments.length; i++ ) {
+			steal.add(new steal.fn.init(arguments[i]));
+		}
+		return steal;
+	};
+
+	(function() {
+		var eventSupported = function( eventName, tag ) {
+			var el = document.createElement(tag);
+			eventName = "on" + eventName;
+
+			var isSupported = (eventName in el);
+			if (!isSupported ) {
+				el.setAttribute(eventName, "return;");
+				isSupported = typeof el[eventName] === "function";
+			}
+			el = null;
+			return isSupported;
+		};
+		steal.support = {
+			load: eventSupported("load", "script"),
+			readystatechange: eventSupported("readystatechange", "script"),
+			error: eventSupported("readystatechange", "script")
+		};
+	})();
+
+
+	steal.fn = steal.prototype = {
+		// sets up a steal instance and records the current path, etc
+		init: function( options ) {
+			if ( typeof options == 'function' ) {
+				var path = steal.getCurrent();
+				this.path = path;
+				this.func = function() {
+					steal.curDir(path);
+					options(steal.send || window.jQuery || steal); //should return what was steald before 'then'
+				};
+				this.options = options;
+				return;
+			}
+			if ( typeof options == 'string' ) {
+				if (/\.js$/i.test(options) ) {
+					options = {
+						path: options
+					};
+				} else {
+					options = {
+						path: options + '.js'
+					};
+				}
+			}
+			extend(this, options);
+
+			this.options = options; //TODO: needed?
+			this.originalPath = this.path;
+
+			//get actual path
+			var pathFile = steal.File(this.path);
+
+			this.path = pathFile.normalize();
+			if ( this.originalPath.match(/^\/\//) ) {
+				this.absolute = steal.root.join(this.originalPath.substr(2));
+			}
+			else {
+				this.absolute = pathFile.relative() ? pathFile.joinFrom(steal.getAbsolutePath(), true) : this.path;
+			}
+
+			this.dir = steal.File(this.path).dir();
+		},
+		/**
+		 * Adds a script tag to the dom, loading and running the steal's JavaScript file.
+		 * @hide
+		 */
+		run: function() {
+			//set next to current so other includes will be added to it
+			steal.cur(this);
+			//only load if actually pulled, this helps us mark only once
+			this.dependencies = [];
+			var isProduction = (steal.options.env == "production"),
+				options = extend({
+					type: "text/javascript",
+					compress: "true",
+					"package": "production.js"
+				}, extend({
+					src: this.path
+				}, this.options));
+
+			if ( this.func ) {
+				//console.log("run FUNCTION")
+				//run function and continue to next steald
+				this.func();
+				steal.end();
+			} else if (!isProduction || this.force ) { //force is for packaging
+				//console.log("run INSERT",this.path)
+				if ( this.type ) {
+					insert(options);
+				} else {
+					steal.curDir(this.path);
+					insert(this.skipInsert ? undefined : options);
+				}
+			} else {
+				//console.log("run VIRTUAL ",this.path)
+				if (!this.type ) {
+					steal.curDir(this.path);
+				}
+			}
+
+		},
+		/**
+		 * Loads the steal code immediately.  This is typically used after DOM has loaded.
+		 * @hide
+		 */
+		runNow: function() {
+			steal.curDir(this.path);
+
+			return browser.rhino ? load(this.path) : steal.insertHead(steal.root.join(this.path));
+		}
+
+	};
+	steal.fn.init.prototype = steal.fn;
+	//where the root steal folder is
+	steal.root = null;
+	//where the page is
+	steal.pageDir = null;
+	//provide extend to others
+	steal.extend = extend;
+	//save a reference to the browser
+	steal.browser = browser;
+
+
+	/**
+	 * @class
+	 * Used for getting information out of a path
+	 * @constructor
+	 * Takes a path
+	 * @param {String} path 
+	 */
+	steal.File = function( path ) {
+		if ( this.constructor != steal.File ) {
+			return new steal.File(path);
+		}
+		this.path = path;
+	};
+	var File = steal.File;
+	extend(File.prototype,
+	/* @prototype */
+	{
+		/**
+		 * Removes hash and params
+		 * @return {String}
+		 */
+		clean: function() {
+			return this.path.match(/([^\?#]*)/)[1];
+		},
+		/**
+		 * Returns everything before the last /
+		 */
+		dir: function() {
+			var last = this.clean().lastIndexOf('/'),
+				dir = (last != -1) ? this.clean().substring(0, last) : '',
+				parts = dir !== '' && dir.match(/^(https?:\/|file:\/)$/);
+			return parts && parts[1] ? this.clean() : dir;
+		},
+		/**
+		 * Returns the domain for the current path.
+		 * Returns null if the domain is a file.
+		 */
+		domain: function() {
+			if ( this.path.indexOf('file:') === 0 ) {
+				return null;
+			}
+			var http = this.path.match(/^(?:https?:\/\/)([^\/]*)/);
+			return http ? http[1] : null;
+		},
+		/**
+		 * Joins a url onto a path.  One way of understanding this is that your File object represents your current location, and calling join() is analogous to "cd" on a command line.
+		 * @codestart
+		 * new steal.File("d/e").join("../a/b/c"); // Yields the path "d/a/b/c"
+		 * @codeend
+		 * @param {String} url
+		 */
+		join: function( url ) {
+			return File(url).joinFrom(this.path);
+		},
+		/**
+		 * Returns the path of this file referenced from another url or path.
+		 * @codestart
+		 * new steal.File('a/b.c').joinFrom('/d/e')//-> /d/e/a/b.c
+		 * @codeend
+		 * @param {String} url
+		 * @param {Boolean} expand if the path should be expanded
+		 * @return {String} 
+		 */
+		joinFrom: function( url, expand ) {
+			var u = File(url);
+			if ( this.protocol() ) { //if we are absolutely referenced
+				//try to shorten the path as much as possible:
+				if ( this.domain() && this.domain() == u.domain() ) {
+					return this.afterDomain();
+				}
+				else if ( this.domain() == u.domain() ) { // we are from a file
+					return this.toReferenceFromSameDomain(url);
+				} else {
+					return this.path;
+				}
+
+			} else if ( url == steal.pageDir && !expand ) {
+
+				return this.path;
+
+			} else if ( this.isLocalAbsolute() ) { // we are a path like /page.js
+				if (!u.domain() ) {
+					return this.path;
+				}
+
+				return u.protocol() + "//" + u.domain() + this.path;
+
+			}
+			else { //we have 2 relative paths, remove folders with every ../
+				if ( url === '' ) {
+					return this.path.replace(/\/$/, '');
+				}
+				var urls = url.split('/'),
+					paths = this.path.split('/'),
+					path = paths[0];
+				
+				//if we are joining from a folder like cookbook/, remove the last empty part
+				if ( url.match(/\/$/) ) {
+					urls.pop();
+				}
+				// for each .. remove one folder
+				while ( path == '..' && paths.length > 0 ) {
+					// if we've emptied out, folders, just break
+					// leaving any additional ../s
+					if(! urls.pop() ){ 
+						break;
+					}
+					paths.shift();
+					
+					path = paths[0];
+				}
+				return urls.concat(paths).join('/');
+			}
+		},
+		/**
+		 * Joins the file to the current working directory.
+		 */
+		joinCurrent: function() {
+			return this.joinFrom(steal.curDir());
+		},
+		/**
+		 * Returns true if the file is relative
+		 */
+		relative: function() {
+			return this.path.match(/^(https?:|file:|\/)/) === null;
+		},
+		/**
+		 * Returns the part of the path that is after the domain part
+		 */
+		afterDomain: function() {
+			return this.path.match(/https?:\/\/[^\/]*(.*)/)[1];
+		},
+		/**
+		 * Returns the relative path between two paths with common folders.
+		 * @codestart
+		 * new steal.File('a/b/c/x/y').toReferenceFromSameDomain('a/b/c/d/e')//-> ../../x/y
+		 * @codeend
+		 * @param {Object} url
+		 * @return {String} 
+		 */
+		toReferenceFromSameDomain: function( url ) {
+			var parts = this.path.split('/'),
+				other_parts = url.split('/'),
+				result = '';
+			while ( parts.length > 0 && other_parts.length > 0 && parts[0] == other_parts[0] ) {
+				parts.shift();
+				other_parts.shift();
+			}
+			for ( var i = 0; i < other_parts.length; i++ ) {
+				result += '../';
+			}
+			return result + parts.join('/');
+		},
+		/**
+		 * Is the file on the same domain as our page.
+		 */
+		isCrossDomain: function() {
+			return this.isLocalAbsolute() ? false : this.domain() != File(window.location.href).domain();
+		},
+		isLocalAbsolute: function() {
+			return this.path.indexOf('/') === 0;
+		},
+		protocol: function() {
+			var match = this.path.match(/^(https?:|file:)/);
+			return match && match[0];
+		},
+		/**
+		 * For a given path, a given working directory, and file location, update the path so 
+		 * it points to a location relative to steal's root.
+		 */
+		normalize: function() {
+
+			var current = steal.curDir(),
+				//if you are cross domain from the page, and providing a path that doesn't have an domain
+				path = this.path;
+
+			if (/^\/\//.test(this.path) ) { //if path is rooted from steal's root 
+				path = this.path.substr(2);
+
+			} else if ( this.relative() || (steal.isCurrentCrossDomain() && //if current file is on another domain and
+			!this.protocol()) ) { //this file doesn't have a protocol
+				path = this.joinFrom(current);
+
+			}
+			return path;
+		}
+	});
+	/**
+	 *  @add steal
+	 */
+	// break
+	/* @static */
+	//break
+	/**
+	 * @attribute pageDir
+	 * @hide
+	 * The current page's folder's path.
+	 */
+	steal.pageDir = File(window.location.href).dir();
+
+	//find steal
+	/**
+	 * @attribute options
+	 * Options that deal with steal
+	 * <table class='options'>
+	 * <tr>
+	 *     <th>Option</th><th>Default</th><th>Description</th>
+	 * </tr>
+	 * <tr><td>env</td><td>development</td><td>Which environment is currently running</td></tr>
+	 * <tr><td>encoding</td><td>utf-8</td><td>What encoding to use for script loading</td></tr>
+	 * <tr><td>cacheInclude</td><td>true</td><td>true if you want to let browser determine if it should cache script; false will always load script</td></tr>
+	 * 
+	 * <tr><td>done</td><td>null</td><td>If a function is present, calls function when all steals have been loaded</td></tr>
+	 * <tr><td>documentLocation</td><td>null</td><td>If present, ajax request will reference this instead of the current window location.  
+	 * Set this in run_unit, to force unit tests to use a real server for ajax requests. </td></tr>
+	 * <tr><td>logLevel</td><td>0</td><td>0 - Log everything<br/>1 - Log Warnings<br/>2 - Log Nothing</td></tr>
+	 * <tr><td>startFile</td><td>null</td><td>This is the first file to load.  It is typically determined from the first script option parameter 
+	 * in the inclue script. </td></tr>
+	 * </table>
+	 * <ul>
+	 *    <li><code>steal.options.startFile</code> - the first file steal loads.  This file
+	 *    loads all other scripts needed by your application.</li>
+	 *    <li><code>steal.options.env</code> - the environment (development or production)
+	 *     that determines if steal loads your all your script files or a single
+	 *     compressed file.
+	 *    </li>
+	 * </ul>
+	 * <p><code>steal.options</code> can be configured by:</p>
+	 * <ul>
+	 *    <li>The steal.js script tag in your page (most common pattern).</li>
+	 *    <li>An existing steal object in the window object</li>
+	 *    <li><code>window.location.hash</code></li>
+	 * </ul>
+	 * <p>
+	 *    The steal.js script tag is by far the most common approach. 
+	 *    For the other methods,
+	 *    check out [steal.static.options] documentation.
+	 *    To load <code>myapp/myapp.js</code> in development mode, your 
+	 *    script tag would look like:
+	 * </p>
+	 * 
+	 * @codestart
+	 * &lt;script type='text/javascript'
+	 *     src='path/to/steal.js?<u><b>myapp/myapp.js</b></u>,<u><b>development</b></u>'>
+	 * &lt;/script>
+	 * @codeend
+	 * <div class='whisper'>
+	 * Typically you want this script tag right before the closing body tag (<code>&lt;/body></code>) of your page.
+	 * </div>
+	 * <p>Note that the path to <code>myapp/myapp.js</code> 
+	 * is relative to the 'steal' folder's parent folder.  This
+	 * is typically called the JavaScriptMVC root folder or just root folder if you're cool.</p>
+	 * <p>And since JavaScriptMVC likes folder structures like:</p>
+	 * @codestart text
+	 * \myapp
+	 *    \myapp.js
+	 * \steal
+	 *    \steal.js
+	 * @codeend
+	 * <p>If your path doesn't end with <code>.js</code>, JavaScriptMVC assumes you are loading an 
+	 * application and will add <code>/myapp.js</code> on for you.  This means that this does the same thing too:</p>
+	 * @codestart
+	 * &lt;script type='text/javascript'
+	 *        src='path/to/steal.js?<u><b>myapp</b></u>'>&lt;/script>
+	 * @codeend
+	 * <div class='whisper'>Steal, and everything else in JavaScriptMVC, provide these little shortcuts
+	 * when you are doing things 'right'.  In this case, you save 9 characters 
+	 * (<code>/myapp.js</code>) by organizing your app the way, JavaScriptMVC expects.</div>
+	 * </div>
+	 */
+	steal.options = {
+		loadProduction: true,
+		env: 'development',
+		production: null,
+		encoding: "utf-8",
+		cacheInclude: true,
+		logLevel: 0
+	};
+
+	// variables used while including
+	var first = true,
+		//If we haven't steald a file yet
+		first_wave_done = false,
+		//a list of all steald paths
+		cwd = '',
+		//  the current steal
+		cur = null,
+		//where we are currently including
+		steals = [],
+		//    
+		current_steals = [],
+		//steals that are pending to be steald
+		total = []; //
+	extend(steal, {
+		/**
+		 * Sets options from script
+		 * @hide
+		 */
+		setScriptOptions: function() {
+			var scripts = document.getElementsByTagName("script"),
+				scriptOptions, commaSplit, stealReg = /steal\.(production\.)?js/;
+
+			//find the steal script and setup initial paths.
+			for ( var i = 0; i < scripts.length; i++ ) {
+				var src = scripts[i].src;
+				if ( src && stealReg.test(src) ) { //if script has steal.js
+					var mvc_root = File(File(src).joinFrom(steal.pageDir)).dir(),
+						loc = /\.\.$/.test(mvc_root) ? mvc_root + '/..' : mvc_root.replace(/steal$/, '');
+
+					if (/.+\/$/.test(loc) ) {
+						loc = loc.replace(/\/$/, '');
+					}
+
+					if (/steal\.production\.js/.test(src) ) {
+						steal.options.env = "production";
+					}
+					steal.root = File(loc);
+					if ( src.indexOf('?') != -1 ) {
+						scriptOptions = src.split('?')[1];
+					}
+				}
+
+			}
+
+			//if there is stuff after ?
+			if ( scriptOptions ) {
+				// if it looks like steal[xyz]=bar, add those to the options
+				if ( scriptOptions.indexOf('=') > -1 ) {
+					scriptOptions.replace(/steal\[([^\]]+)\]=([^&]+)/g, function( whoe, prop, val ) {
+						steal.options[prop] = val;
+					});
+				} else {
+					//set with comma style
+					commaSplit = scriptOptions.split(",");
+					if ( commaSplit[0] && commaSplit[0].lastIndexOf('.js') > 0 ) {
+						steal.options.startFile = commaSplit[0];
+					} else if ( commaSplit[0] ) {
+						steal.options.app = commaSplit[0];
+					}
+					if ( commaSplit[1] && steal.options.env != "production" ) {
+						steal.options.env = commaSplit[1];
+					}
+				}
+
+			}
+
+		},
+		setOldIncludeOptions: function() {
+			extend(steal.options, oldsteal);
+		},
+		setHashOptions: function() {
+			window.location.hash.replace(/steal\[(\w+)\]=(\w+)/g, function( whoe, prop, val ) {
+				steal.options[prop] = val;
+			});
+		},
+		/**
+		 * Starts including files, sets options.
+		 * @hide
+		 */
+		init: function() {
+			this.setScriptOptions();
+			//force into development mode to prevent errors
+			if ( steal.browser.rhino ) {
+				steal.options.env = 'development';
+			}
+			this.setOldIncludeOptions();
+			this.setHashOptions();
+			//clean up any options
+			if ( steal.options.app ) {
+				steal.options.startFile = steal.options.app + "/" + steal.options.app.match(/[^\/]+$/)[0] + ".js";
+			}
+			if ( steal.options.ignoreControllers ) {
+				steal.controllers = function() {
+					return steal;
+				};
+				steal.controller = function() {
+					return steal;
+				};
+			}
+			//calculate production location;
+			if (!steal.options.production && steal.options.startFile ) {
+				steal.options.production = "//" + File(steal.options.startFile).dir() + '/production';
+			}
+			if ( steal.options.production ) {
+				steal.options.production = steal.options.production + (steal.options.production.indexOf('.js') == -1 ? '.js' : '');
+			}
+			//we only load things with force = true
+			if ( steal.options.env == 'production' && steal.options.loadProduction ) {
+				if ( steal.options.production ) {
+					first = false; //makes it so we call close after
+					//steal(steal.options.startFile);
+					steal({
+						path: steal.options.production,
+						force: true
+					});
+				}
+
+			} else {
+
+				var current_path = steal.getCurrent();
+				steal({
+					path: 'steal/dev/dev.js',
+					ignore: true
+				});
+				steal.curDir(current_path);
+
+
+
+
+				//if you have a startFile load it
+				if ( steal.options.startFile ) {
+					first = false; //makes it so we call close after
+					//steal(steal.options.startFile);
+					steal._start = new steal.fn.init(steal.options.startFile);
+					steal.add(steal._start);
+				}
+
+			}
+
+
+
+			if ( steal.options.startFile ) {
+				steal.start();
+			}
+		},
+		/**
+		 * Gets or sets the current directory your relative steals will reference.
+		 * @param {String} [path] the new current directory path
+		 * @return {String|steal} the path of the current directory or steal for chaining.
+		 */
+		curDir: function( path ) {
+			if ( path !== undefined ) {
+				cwd = path;
+				return steal;
+			} else {
+				var dir = File(cwd).dir();
+				//make sure it has a /
+				return dir ? dir + (dir.lastIndexOf('/') === dir.length - 1 ? '' : '/') : dir;
+			}
+
+		},
+		cur: function( steal ) {
+			if ( steal !== undefined ) {
+				return (cur = steal);
+			} else {
+				return cur;
+			}
+		},
+		//is the current folder cross domain from our folder?
+		isCurrentCrossDomain: function() {
+			return File(steal.getAbsolutePath()).isCrossDomain();
+		},
+		getCurrent: function() {
+			return cwd;
+		},
+		getAbsolutePath: function() {
+			var dir = this.curDir(),
+				fwd = File(this.curDir());
+			return fwd.relative() ? fwd.joinFrom(steal.root.path, true) : dir;
+		},
+		// Adds a steal to the pending list of steals.
+		add: function( newInclude ) {
+			//If steal is a function, add to list, and unshift
+			if ( typeof newInclude.func == 'function' ) {
+				//console.log("add","FUNCTION")
+				current_steals.unshift(newInclude); //add to the front
+				return;
+			}
+			var cur = steal.cur(), 
+				existing = steal.exists(newInclude);
+
+			
+			//if we have already performed loads, insert new steals in head
+			//now we should check if it has already been steald or added earlier in this file
+			if ( !existing ) {
+				if ( cur ) {
+					cur.dependencies.push(newInclude);
+				}
+				if ( first_wave_done ) {
+					return newInclude.runNow();
+				}
+				//but the file could still be in the list of steals but we need it earlier, so remove it and add it here
+				var path = newInclude.absolute || newInclude.path;
+				for ( var i = 0; i < steals.length; i++ ) {
+					if ( steals[i].absolute == path ) {
+						steals.splice(i, 1);
+						break;
+					}
+				}
+				//console.log("add FILE",newInclude.path)
+				current_steals.unshift(newInclude);
+			}else{
+				cur.dependencies.push(existing);
+			}
+		},
+		//this should probably be kept as a hash.
+		//returns the steal if the steal already exists
+		exists: function( inc ) {
+			var path = inc.absolute || inc.path,
+				i;
+			for ( i = 0; i < total.length; i++ ) {
+				if ( total[i].absolute == path ) {
+					return total[i];
+				}
+			}
+			for ( i = 0; i < current_steals.length; i++ ) {
+				if ( current_steals[i].absolute == path ) {
+					return current_steals[i];
+				}
+			}
+			return;
+		},
+		done: function() {
+			if ( typeof steal.options.done == "function" ) {
+				steal.options.done(total);
+			}
+		},
+		// Called after every file is loaded.  Gets the next file and steals it.
+		end: function( src ) {
+			//prevents warning of bad includes
+			clearTimeout(steal.timer);
+			// add steals that were just added to the end of the list
+			steals = steals.concat(current_steals);
+			if (!steals.length ) {
+				return;
+			}
+
+			// take the last one
+			var next = steals.pop();
+
+			// if there are no more
+			if (!next ) {
+				first_wave_done = true;
+				steal.done();
+			} else {
+				//add to the total list of things that have been steald, and clear current steals
+				total.push(next);
+				current_steals = [];
+				next.run();
+
+			}
+
+		},
+
+		/**
+		 * Starts loading files.  This is useful when steal is being used without providing an initial file or app to load.
+		 * You can steal files, but then call steal.start() to start actually loading them.
+		 * 
+		 * <h3>Example:</h3>
+		 * @codestart html
+		 * &lt;script src='steal/steal.js'>&lt;/script>
+		 * &lt;script type='text/javascript'>
+		 *    steal.plugins('controller')
+		 *    steal.start();
+		 * &lt;/script>
+		 * @codeend
+		 * The above code loads steal, then uses steal to load the plugin controller.
+		 */
+		start: function() {
+			steal.end();
+		},
+		/**
+		 * Loads css files from the given relative path.
+		 * @codestart
+		 * steal.css('mystyles') //loads mystyles.css
+		 * @codeend
+		 * Styles loaded in this way will be compressed into a single style.
+		 * @param {String+} relative URL(s) to stylesheets
+		 * @return {steal} steal for chaining
+		 */
+		css: function() {
+			//if production, 
+			if ( steal.options.env == 'production' ) {
+				if ( steal.loadedProductionCSS ) {
+					return steal;
+				} else {
+					var productionCssPath = steal.File(steal.options.production.replace(".js", ".css")).normalize();
+					productionCssPath = steal.root.join(productionCssPath);
+					steal.createLink(productionCssPath);
+					steal.loadedProductionCSS = true;
+					return steal;
+				}
+			}
+			var current;
+			for ( var i = 0; i < arguments.length; i++ ) {
+				current = File(arguments[i] + ".css").joinCurrent();
+				steal.createLink(steal.root.join(current));
+			}
+			return this;
+		},
+		/**
+		 * Creates a css link and appends it to head.
+		 * @hide
+		 * @param {Object} location
+		 * @return {HTMLLinkElement}
+		 */
+		createLink: function( location, options ) {
+			options = options || {};
+			var link = document.createElement('link');
+			link.rel = options.rel || "stylesheet";
+			link.href = location;
+			link.type = options.type || 'text/css';
+			head().appendChild(link);
+			return link;
+		},
+		/**
+		 * @hide
+		 * Synchronously requests a file.  This is here to read a file for other types.	 * 
+		 * @param {String} path path of file you want to load
+		 * @param {optional:String} content_type optional content type
+		 * @return {String} text of file
+		 */
+		request: function( path, content_type ) {
+			var contentType = (content_type || "application/x-www-form-urlencoded; charset=" + steal.options.encoding),
+				request = factory();
+			request.open("GET", path, false);
+			request.setRequestHeader('Content-type', contentType);
+			if ( request.overrideMimeType ) {
+				request.overrideMimeType(contentType);
+			}
+
+			try {
+				request.send(null);
+			}
+			catch (e) {
+				return null;
+			}
+			if ( request.status === 500 || request.status === 404 || request.status === 2 || (request.status === 0 && request.responseText === '') ) {
+				return null;
+			}
+			return request.responseText;
+		},
+		/**
+		 * Inserts a script tag in head with the encoding.
+		 * @hide
+		 * @param {Object} src
+		 * @param {Object} encode
+		 */
+		insertHead: function( src, encode, type, text, id ) {
+			encode = encode || "UTF-8";
+			var script = scriptTag();
+			if ( src ) {
+				script.src = src;
+			}
+			if ( id ) {
+				script.id = id;
+			}
+			script.charset = encode;
+			script.type = type || "text/javascript";
+			if ( text ) {
+				script.text = text;
+			}
+			head().appendChild(script);
+		},
+		write: function( src, encode ) {
+			encode = encode || "UTF-8";
+			document.write('<script type="text/javascript" src="' + src + '" encode="+encode+"></script>');
+		},
+		resetApp: function( f ) {
+			return function( name ) {
+				var current_path = steal.getCurrent();
+				steal.curDir("");
+				if ( name.path ) {
+					name.path = f(name.path);
+				} else {
+					name = f(name);
+				}
+				steal(name);
+				steal.curDir(current_path);
+				return steal;
+			};
+		},
+		callOnArgs: function( f ) {
+			return function() {
+				for ( var i = 0; i < arguments.length; i++ ) {
+					f(arguments[i]);
+				}
+				return steal;
+			};
+
+		},
+		// Returns a function that applies a function to a list of arguments.  Then steals those
+		// arguments.
+		applier: function( f ) {
+			return function() {
+				var args = [];
+				for ( var i = 0; i < arguments.length; i++ ) {
+					if ( typeof arguments[i] == "function" ) {
+						args[i] = arguments[i];
+					} else {
+						args[i] = f(arguments[i]);
+					}
+
+				}
+				steal.apply(null, args);
+				return steal;
+			};
+		},
+		then: steal,
+		total: total
+	});
+	var stealPlugin = steal.resetApp(function( p ) {
+		return p + '/' + getLastPart(p);
+	});
+	steal.packs = function() {
+		for ( var i = 0; i < arguments.length; i++ ) {
+			if ( typeof arguments[i] == "function" ) {
+				steal(arguments[i]);
+			} else {
+				steal({
+					force: true,
+					path: "//packages/" + arguments[i] + ".js"
+				});
+			}
+		}
+		return this;
+	};
+
+	extend(steal, {
+
+		/**
+		 * @function plugins
+		 * Loads a list of plugins given a path relative to steal's ROOT folder.
+		 * 
+		 * Steal.plugins is used to load relative to ROOT no matter where the current file is 
+		 * located.  For example, if you want to load the 'foo/bar' plugin that is located like:
+		 * 
+		 * @codestart
+		 * steal\
+		 * foo\
+		 *    bar\
+		 *       bar.js
+		 * @codeend
+		 * 
+		 * You can load it like:
+		 * 
+		 * @codestart
+		 * steal.plugins('foo/bar');
+		 * @codeend
+		 * 
+		 * It should be noted that plugins always looks for a JS file that shares the name of the
+		 * plugin's folder (bar.js is in bar).
+		 * 
+		 * @param {String} plugin_location location of a plugin, ex: jquery/dom/history.
+		 * @return {steal} a new steal object
+		 * 
+		 */
+		plugins: steal.callOnArgs(stealPlugin),
+
+
+		/**
+		 * @function controllers
+		 * Loads controllers from the current file's <b>controllers</b> directory.
+		 * <br>
+		 * <code>steal.controllers</code> adds the suffix <code>_controller.js</code> to each name passed in.
+		 * <br>
+		 * <br>
+		 * Example:
+		 * <br>
+		 * If you want to load controllers/recipe_controller.js and controllers/ingredient_controller.js,
+		 * write:
+		 * @codestart 
+		 *  steal.controllers('recipe',
+		 *                    'ingredient')
+		 * @codeend
+		 * @param {String+} controller the name of of the {NAME}_controller.js file to load. You can pass multiple controller names.
+		 * @return {steal} the steal function for chaining.    
+		 */
+		controllers: steal.applier(function( i ) {
+			if ( i.match(/^\/\//) ) {
+				i = steal.root.join(i.substr(2));
+				return i;
+			}
+			return 'controllers/' + i + '_controller';
+		}),
+
+		/**
+		 * @function models
+		 * Loads models  from the current file's <b>models</b> directory.
+		 * <br>
+		 * <br>
+		 * Example:
+		 * <br>
+		 * If you want to include models/recipe.js and models/ingredient.js,
+		 * write:
+		 * @codestart 
+		 *  steal.models('recipe',
+		 *               'ingredient')
+		 * @codeend
+		 * @param {String+} model The name of the model file you want to load.  You can pass multiple model names.
+		 * @return {steal} the steal function for chaining.
+		 */
+		models: steal.applier(function( i ) {
+			if ( i.match(/^\/\//) ) {
+				i = steal.root.join(i.substr(2));
+				return i;
+			}
+			return 'models/' + i;
+		}),
+
+		/**
+		 * @function resources
+		 * Loads resources from the current file's <b>resources</b> directory.
+		 * <br>
+		 * <br>
+		 * Example:
+		 * <br>
+		 * If you want to load resources/i18n.js, write:
+		 * @codestart 
+		 *  steal.resources('i18n')
+		 * @codeend
+		 * @param {String+} resource The name of the resource file you want to load.  You can pass multiple model names.
+		 * @return {steal} the steal function for chaining.
+		 */
+		resources: steal.applier(function( i ) {
+			if ( i.match(/^\/\//) ) {
+				i = steal.root.join(i.substr(2));
+				return i;
+			}
+			return 'resources/' + i;
+		}),
+
+		/**
+		 * @function views
+		 * Loads views to be added to the production build.  Paths must be given from steal's ROOT folder.
+		 * <br>
+		 * <br>
+		 * Example:
+		 * <br>
+		 * The following loads, coookbook/views/recipe/show.ejs and coookbook/views/recipe/list.ejs:
+		 * @codestart 
+		 *  steal.views('//coookbook/views/recipe/show.ejs',
+		 *              '//coookbook/views/recipe/list.ejs')
+		 * @codeend
+		 * @param {String} path The view's path rooted from steal's root folder.
+		 * @return {steal} the steal function for chaining.   
+		 */
+		views: function() {
+			// Only includes views for compression and docs (when running in rhino)
+			if ( browser.rhino || steal.options.env == "production" ) {
+				for ( var i = 0; i < arguments.length; i++ ) {
+					steal.view(arguments[i]);
+				}
+			}
+			return steal;
+		},
+
+		timerCount: 0,
+		view: function( path ) {
+			var type = path.match(/\.\w+$/gi)[0].replace(".", "");
+			if( path.indexOf("//") !== 0 ){
+				path = "views/"+path;
+			}
+			steal({
+				path: path,
+				type: "text/" + type,
+				compress: "false"
+			});
+			return steal;
+		},
+		timers: {},
+		//tracks the last script
+		ct: function( id ) { //for clear timer
+			clearTimeout(steal.timers[id]);
+			delete steal.timers[id];
+		},
+		loadErrorTimer: function( options ) {
+			var count = ++steal.timerCount;
+			steal.timers[count] = setTimeout(function() {
+				throw "steal.js Could not load " + options.src + ".  Are you sure you have the right path?";
+			}, 5000);
+			return "onLoad='steal.ct(" + count + ")' ";
+		},
+		cleanId: function( id ) {
+			return id.replace(/[\/\.]/g, "_");
+		}
+	});
+	//for integration with other build types
+	if (!steal.build ) {
+		steal.build = {
+			types: {}
+		};
+	}
+
+	steal.loadedProductionCSS = false;
+
+	steal.init();
+})();
diff --git a/browserid/static/dialog/steal/steal.production.js b/browserid/static/dialog/steal/steal.production.js
new file mode 100644
index 0000000000000000000000000000000000000000..b0c1daed3e2572aded56199a9c0cb017dbd38dc6
--- /dev/null
+++ b/browserid/static/dialog/steal/steal.production.js
@@ -0,0 +1,23 @@
+(function(){if(typeof steal!="undefined"&&steal.nodeType)throw"steal is defined an element's id!";var s=window.steal,n=function(){var a=document,b=a.documentElement,c=a.getElementsByTagName("head");if(c.length>0)return c[0];a=a.createElement("head");b.insertBefore(a,b.firstChild);return a},t=function(){var a=document.createElement("script");a.type="text/javascript";return a},h=function(a,b){for(var c in b)a[c]=b[c];return a},u=function(a){return a.match(/[^\/]+$/)[0]},l={msie:!!(window.attachEvent&&
+!window.opera),opera:!!window.opera,safari:navigator.userAgent.indexOf("AppleWebKit/")>-1,firefox:navigator.userAgent.indexOf("Gecko")>-1&&navigator.userAgent.indexOf("KHTML")==-1,mobilesafari:!!navigator.userAgent.match(/Apple.*Mobile.*Safari/),rhino:navigator.userAgent.match(/Rhino/)&&true},v=function(){return window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest},o=function(a){a=h({id:a.src&&steal.cleanId(a.src)},a);var b="",c="<script ",d;if(a.src){b=steal.File(a.src);
+if(!b.isLocalAbsolute()&&!b.protocol())a.src=steal.root.join(a.src)}if(a.type&&a.process){b=steal.request(a.src);if(!b)throw"steal.js there is nothing at "+a.src;d=a.process(b);a.type="text/javascript";delete a.process;delete a.src}else if(a.type&&a.type!="text/javascript"&&!l.rhino){b=steal.request(a.src);if(!b)throw"steal.js there is nothing at "+a.src;a.text=b;delete a.src}for(var g in a)c+=g+"='"+a[g]+"' ";if(steal.support.load&&!steal.browser.rhino&&!d)c+=steal.loadErrorTimer(a);c+=">"+(d||"")+
+"<\/script>";c+=steal.support.load?'<script type="text/javascript">steal.end()<\/script>':'<script type="text/javascript" src="'+steal.root.join("steal/end.js")+'"><\/script>';document.write(a.src||d?c:"")};steal=function(){for(var a=0;a<arguments.length;a++)steal.add(new steal.fn.init(arguments[a]));return steal};(function(){var a=function(b,c){c=document.createElement(c);b="on"+b;var d=b in c;if(!d){c.setAttribute(b,"return;");d=typeof c[b]==="function"}return d};steal.support={load:a("load","script"),
+readystatechange:a("readystatechange","script"),error:a("readystatechange","script")}})();steal.fn=steal.prototype={init:function(a){if(typeof a=="function"){var b=steal.getCurrent();this.path=b;this.func=function(){steal.curDir(b);a(steal.send||window.jQuery||steal)};this.options=a}else{if(typeof a=="string")a=/\.js$/i.test(a)?{path:a}:{path:a+".js"};h(this,a);this.options=a;this.originalPath=this.path;var c=steal.File(this.path);this.path=c.normalize();this.absolute=this.originalPath.match(/^\/\//)?
+steal.root.join(this.originalPath.substr(2)):c.relative()?c.joinFrom(steal.getAbsolutePath(),true):this.path;this.dir=steal.File(this.path).dir()}},run:function(){steal.cur(this);this.dependencies=[];var a=steal.options.env=="production",b=h({type:"text/javascript",compress:"true","package":"production.js"},h({src:this.path},this.options));if(this.func){this.func();steal.end()}else if(!a||this.force)if(this.type)o(b);else{steal.curDir(this.path);o(this.skipInsert?undefined:b)}else this.type||steal.curDir(this.path)},
+runNow:function(){steal.curDir(this.path);return l.rhino?load(this.path):steal.insertHead(steal.root.join(this.path))}};steal.fn.init.prototype=steal.fn;steal.root=null;steal.pageDir=null;steal.extend=h;steal.browser=l;steal.File=function(a){if(this.constructor!=steal.File)return new steal.File(a);this.path=a};var f=steal.File;h(f.prototype,{clean:function(){return this.path.match(/([^\?#]*)/)[1]},dir:function(){var a=this.clean().lastIndexOf("/");a=a!=-1?this.clean().substring(0,a):"";var b=a!==
+""&&a.match(/^(https?:\/|file:\/)$/);return b&&b[1]?this.clean():a},domain:function(){if(this.path.indexOf("file:")===0)return null;var a=this.path.match(/^(?:https?:\/\/)([^\/]*)/);return a?a[1]:null},join:function(a){return f(a).joinFrom(this.path)},joinFrom:function(a,b){var c=f(a);if(this.protocol())return this.domain()&&this.domain()==c.domain()?this.afterDomain():this.domain()==c.domain()?this.toReferenceFromSameDomain(a):this.path;else if(a==steal.pageDir&&!b)return this.path;else if(this.isLocalAbsolute()){if(!c.domain())return this.path;
+return c.protocol()+"//"+c.domain()+this.path}else{if(a==="")return this.path.replace(/\/$/,"");b=a.split("/");c=this.path.split("/");var d=c[0];for(a.match(/\/$/)&&b.pop();d==".."&&c.length>0;){if(!b.pop())break;c.shift();d=c[0]}return b.concat(c).join("/")}},joinCurrent:function(){return this.joinFrom(steal.curDir())},relative:function(){return this.path.match(/^(https?:|file:|\/)/)===null},afterDomain:function(){return this.path.match(/https?:\/\/[^\/]*(.*)/)[1]},toReferenceFromSameDomain:function(a){var b=
+this.path.split("/");a=a.split("/");for(var c="";b.length>0&&a.length>0&&b[0]==a[0];){b.shift();a.shift()}for(var d=0;d<a.length;d++)c+="../";return c+b.join("/")},isCrossDomain:function(){return this.isLocalAbsolute()?false:this.domain()!=f(window.location.href).domain()},isLocalAbsolute:function(){return this.path.indexOf("/")===0},protocol:function(){var a=this.path.match(/^(https?:|file:)/);return a&&a[0]},normalize:function(){var a=steal.curDir(),b=this.path;if(/^\/\//.test(this.path))b=this.path.substr(2);
+else if(this.relative()||steal.isCurrentCrossDomain()&&!this.protocol())b=this.joinFrom(a);return b}});steal.pageDir=f(window.location.href).dir();steal.options={loadProduction:true,env:"development",production:null,encoding:"utf-8",cacheInclude:true,logLevel:0};var p=true,q=false,m="",r=null,i=[],j=[],k=[];h(steal,{setScriptOptions:function(){for(var a=document.getElementsByTagName("script"),b,c=/steal\.(production\.)?js/,d=0;d<a.length;d++){var g=a[d].src;if(g&&c.test(g)){var e=f(f(g).joinFrom(steal.pageDir)).dir();
+e=/\.\.$/.test(e)?e+"/..":e.replace(/steal$/,"");if(/.+\/$/.test(e))e=e.replace(/\/$/,"");if(/steal\.production\.js/.test(g))steal.options.env="production";steal.root=f(e);if(g.indexOf("?")!=-1)b=g.split("?")[1]}}if(b)if(b.indexOf("=")>-1)b.replace(/steal\[([^\]]+)\]=([^&]+)/g,function(y,w,x){steal.options[w]=x});else{a=b.split(",");if(a[0]&&a[0].lastIndexOf(".js")>0)steal.options.startFile=a[0];else if(a[0])steal.options.app=a[0];if(a[1]&&steal.options.env!="production")steal.options.env=a[1]}},
+setOldIncludeOptions:function(){h(steal.options,s)},setHashOptions:function(){window.location.hash.replace(/steal\[(\w+)\]=(\w+)/g,function(a,b,c){steal.options[b]=c})},init:function(){this.setScriptOptions();if(steal.browser.rhino)steal.options.env="development";this.setOldIncludeOptions();this.setHashOptions();if(steal.options.app)steal.options.startFile=steal.options.app+"/"+steal.options.app.match(/[^\/]+$/)[0]+".js";if(steal.options.ignoreControllers){steal.controllers=function(){return steal};
+steal.controller=function(){return steal}}if(!steal.options.production&&steal.options.startFile)steal.options.production="//"+f(steal.options.startFile).dir()+"/production";if(steal.options.production)steal.options.production+=steal.options.production.indexOf(".js")==-1?".js":"";if(steal.options.env=="production"&&steal.options.loadProduction){if(steal.options.production){p=false;steal({path:steal.options.production,force:true})}}else{var a=steal.getCurrent();steal({path:"steal/dev/dev.js",ignore:true});
+steal.curDir(a);if(steal.options.startFile){p=false;steal._start=new steal.fn.init(steal.options.startFile);steal.add(steal._start)}}steal.options.startFile&&steal.start()},curDir:function(a){if(a!==undefined){m=a;return steal}else return(a=f(m).dir())?a+(a.lastIndexOf("/")===a.length-1?"":"/"):a},cur:function(a){return a!==undefined?(r=a):r},isCurrentCrossDomain:function(){return f(steal.getAbsolutePath()).isCrossDomain()},getCurrent:function(){return m},getAbsolutePath:function(){var a=this.curDir(),
+b=f(this.curDir());return b.relative()?b.joinFrom(steal.root.path,true):a},add:function(a){if(typeof a.func=="function")j.unshift(a);else{var b=steal.cur(),c=steal.exists(a);if(c)b.dependencies.push(c);else{b&&b.dependencies.push(a);if(q)return a.runNow();b=a.absolute||a.path;for(c=0;c<i.length;c++)if(i[c].absolute==b){i.splice(c,1);break}j.unshift(a)}}},exists:function(a){a=a.absolute||a.path;var b;for(b=0;b<k.length;b++)if(k[b].absolute==a)return k[b];for(b=0;b<j.length;b++)if(j[b].absolute==a)return j[b]},
+done:function(){typeof steal.options.done=="function"&&steal.options.done(k)},end:function(){clearTimeout(steal.timer);i=i.concat(j);if(i.length){var a=i.pop();if(a){k.push(a);j=[];a.run()}else{q=true;steal.done()}}},start:function(){steal.end()},css:function(){if(steal.options.env=="production"){if(!steal.loadedProductionCSS){var a=steal.File(steal.options.production.replace(".js",".css")).normalize();a=steal.root.join(a);steal.createLink(a);steal.loadedProductionCSS=true}return steal}for(var b=
+0;b<arguments.length;b++){a=f(arguments[b]+".css").joinCurrent();steal.createLink(steal.root.join(a))}return this},createLink:function(a,b){b=b||{};var c=document.createElement("link");c.rel=b.rel||"stylesheet";c.href=a;c.type=b.type||"text/css";n().appendChild(c);return c},request:function(a,b){b=b||"application/x-www-form-urlencoded; charset="+steal.options.encoding;var c=v();c.open("GET",a,false);c.setRequestHeader("Content-type",b);c.overrideMimeType&&c.overrideMimeType(b);try{c.send(null)}catch(d){return null}if(c.status===
+500||c.status===404||c.status===2||c.status===0&&c.responseText==="")return null;return c.responseText},insertHead:function(a,b,c,d,g){b=b||"UTF-8";var e=t();if(a)e.src=a;if(g)e.id=g;e.charset=b;e.type=c||"text/javascript";if(d)e.text=d;n().appendChild(e)},write:function(a){document.write('<script type="text/javascript" src="'+a+'" encode="+encode+"><\/script>')},resetApp:function(a){return function(b){var c=steal.getCurrent();steal.curDir("");if(b.path)b.path=a(b.path);else b=a(b);steal(b);steal.curDir(c);
+return steal}},callOnArgs:function(a){return function(){for(var b=0;b<arguments.length;b++)a(arguments[b]);return steal}},applier:function(a){return function(){for(var b=[],c=0;c<arguments.length;c++)b[c]=typeof arguments[c]=="function"?arguments[c]:a(arguments[c]);steal.apply(null,b);return steal}},then:steal,total:k});steal.plugin=steal.resetApp(function(a){return a+"/"+u(a)});steal.packs=function(){for(var a=0;a<arguments.length;a++)typeof arguments[a]=="function"?steal(arguments[a]):steal({force:true,
+path:"//packages/"+arguments[a]+".js"});return this};h(steal,{plugins:steal.callOnArgs(steal.plugin),controllers:steal.applier(function(a){if(a.match(/^\/\//))return a=steal.root.join(a.substr(2));return"controllers/"+a+"_controller"}),models:steal.applier(function(a){if(a.match(/^\/\//))return a=steal.root.join(a.substr(2));return"models/"+a}),resources:steal.applier(function(a){if(a.match(/^\/\//))return a=steal.root.join(a.substr(2));return"resources/"+a}),views:function(){if(l.rhino||steal.options.env==
+"production")for(var a=0;a<arguments.length;a++)steal.view(arguments[a]);return steal},timerCount:0,view:function(a){var b=a.match(/\.\w+$/gi)[0].replace(".","");if(a.indexOf("//")!==0)a="views/"+a;steal({path:a,type:"text/"+b,compress:"false"});return steal},timers:{},ct:function(a){clearTimeout(steal.timers[a]);delete steal.timers[a]},loadErrorTimer:function(a){var b=++steal.timerCount;steal.timers[b]=setTimeout(function(){throw"steal.js Could not load "+a.src+".  Are you sure you have the right path?";
+},5E3);return"onLoad='steal.ct("+b+")' "},cleanId:function(a){return a.replace(/[\/\.]/g,"_")}});if(!steal.build)steal.build={types:{}};steal.loadedProductionCSS=false;steal.init()})();
diff --git a/browserid/static/dialog/steal/test/absoluteurl.html b/browserid/static/dialog/steal/test/absoluteurl.html
new file mode 100644
index 0000000000000000000000000000000000000000..70187af6cef70e380e312efd81a2f95520ef0bec
--- /dev/null
+++ b/browserid/static/dialog/steal/test/absoluteurl.html
@@ -0,0 +1,7 @@
+<html>
+    <head>
+		<script type='text/javascript' src='../steal.js?steal[app]=steal/test/absoluteurl'></script>
+    </head>
+    <body>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/test/absoluteurl/absoluteurl.js b/browserid/static/dialog/steal/test/absoluteurl/absoluteurl.js
new file mode 100644
index 0000000000000000000000000000000000000000..f7b37cac868afca9bb01b97243e2ea8790255627
--- /dev/null
+++ b/browserid/static/dialog/steal/test/absoluteurl/absoluteurl.js
@@ -0,0 +1 @@
+steal("//steal/test/absoluteurl/alert")
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/test/absoluteurl/alert.js b/browserid/static/dialog/steal/test/absoluteurl/alert.js
new file mode 100644
index 0000000000000000000000000000000000000000..8e56b213358b460cac2a0ece6ed4f1e5a5443398
--- /dev/null
+++ b/browserid/static/dialog/steal/test/absoluteurl/alert.js
@@ -0,0 +1 @@
+alert('hi')
diff --git a/browserid/static/dialog/steal/test/another/two.js b/browserid/static/dialog/steal/test/another/two.js
new file mode 100644
index 0000000000000000000000000000000000000000..4f6bd54c2de6eb1693b3bf328a9f4655aadfea76
--- /dev/null
+++ b/browserid/static/dialog/steal/test/another/two.js
@@ -0,0 +1,2 @@
+order(2);
+steal('../three')
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/test/one/four.js b/browserid/static/dialog/steal/test/one/four.js
new file mode 100644
index 0000000000000000000000000000000000000000..4e91196dbfc495a4bc037a13eaea9d81e37c9474
--- /dev/null
+++ b/browserid/static/dialog/steal/test/one/four.js
@@ -0,0 +1 @@
+order(4);
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/test/one/one.js b/browserid/static/dialog/steal/test/one/one.js
new file mode 100644
index 0000000000000000000000000000000000000000..9927ff562be6aa738c3f0c3b92753b8b4d6daea2
--- /dev/null
+++ b/browserid/static/dialog/steal/test/one/one.js
@@ -0,0 +1,6 @@
+order(1);
+steal('../another/two','four','wrong');
+//something here
+another = function(somevariablename){
+    return somevariablename *2;
+};
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/test/qunit.html b/browserid/static/dialog/steal/test/qunit.html
new file mode 100644
index 0000000000000000000000000000000000000000..ef8a24924e635aa274fb74350d007b55bdcf6b73
--- /dev/null
+++ b/browserid/static/dialog/steal/test/qunit.html
@@ -0,0 +1,22 @@
+<html>
+    <head>
+        <link rel="stylesheet" type="text/css" href="../../funcunit/qunit/qunit.css" />
+        <title>QUnit Test</title>
+        <style>
+            body  {
+                margin: 0px; padding: 0px;
+            }
+        </style>
+		<script type='text/javascript' src='../../steal/steal.js?steal[app]=steal/test/qunit'></script>
+    </head>
+    <body>
+
+        <h1 id="qunit-header">Steal Test Suite</h1>
+    	<h2 id="qunit-banner"></h2>
+    	<div id="qunit-testrunner-toolbar"></div>
+    	<h2 id="qunit-userAgent"></h2>
+		<div id="test-content"></div>
+        <ol id="qunit-tests"></ol>
+		<div id="qunit-test-area"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/test/qunit/one.css b/browserid/static/dialog/steal/test/qunit/one.css
new file mode 100644
index 0000000000000000000000000000000000000000..1871d637786a7ad524a8a91704b2fcbdd86bf937
--- /dev/null
+++ b/browserid/static/dialog/steal/test/qunit/one.css
@@ -0,0 +1,4 @@
+#makeBlue {
+	color : blue;
+	width: 100px;
+}
diff --git a/browserid/static/dialog/steal/test/qunit/qunit.js b/browserid/static/dialog/steal/test/qunit/qunit.js
new file mode 100644
index 0000000000000000000000000000000000000000..1c5903e87ada9421969cb6400f4147e9ce8ab8e4
--- /dev/null
+++ b/browserid/static/dialog/steal/test/qunit/qunit.js
@@ -0,0 +1,4 @@
+steal
+  .plugins("funcunit/qunit")
+  .css('one','../two')
+  .then("steal_test")
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/test/qunit/steal_test.js b/browserid/static/dialog/steal/test/qunit/steal_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..ffce4bda99af160cb7c323131fd2beab9a93ed5a
--- /dev/null
+++ b/browserid/static/dialog/steal/test/qunit/steal_test.js
@@ -0,0 +1,207 @@
+module("steal")
+
+test("domain", function() {
+	equals(null, new steal.File("file://C:/Development").domain(), "problems from file")
+	equals('something.com', new steal.File('http://something.com/asfdkl;a').domain(), "something.com is the correct http domain.")
+	equals('127.0.0.1:3006', new steal.File('https://127.0.0.1:3006/asdf').domain(), "something.com is the correct https domain.")
+})
+
+test("joinFrom", function() {
+	var result;
+	equals(
+	steal.File('a/b.c').joinFrom('/d/e'), "/d/e/a/b.c", "/d/e/a/b.c is correctly joined.");
+
+	result = new steal.File('a/b.c').joinFrom('d/e');
+	equals(result, "d/e/a/b.c", "d/e/a/b.c is correctly joined.");
+
+	result = new steal.File('a/b.c').joinFrom('d/e/');
+	equals(result, "d/e/a/b.c", "d/e/a/b.c is correctly joined.");
+
+	result = new steal.File('a/b.c').joinFrom('http://abc.com');
+	equals(result, "http://abc.com/a/b.c", "http://abc.com/a/b.c is correctly joined.");
+
+	result = new steal.File('/a/b.c').joinFrom('http://abc.com');
+	equals(result, "http://abc.com/a/b.c", "http://abc.com/a/b.c is correctly joined.");
+
+	result = new steal.File('a/b.c').joinFrom('http://abc.com/');
+	equals(result, "http://abc.com/a/b.c", "http://abc.com/a/b.c is correctly joined.");
+
+	result = new steal.File('/a/b.c').joinFrom('http://abc.com/');
+	equals(result, "http://abc.com/a/b.c", "http://abc.com/a/b.c is correctly joined.");
+
+	result = new steal.File('a/b.c').joinFrom('../d/e');
+	equals(result, "../d/e/a/b.c", "../d/e/a/b.c is correctly joined.");
+
+	result = new steal.File('a/b.c').joinFrom('');
+	equals(result, "a/b.c", "a/b.c is correctly joined.");
+
+	result = new steal.File('/a/b.c').joinFrom('');
+	equals(result, "/a/b.c", "/a/b.c is correctly joined.");
+	
+	
+	result = new steal.File('../../up.js').joinFrom('cookbook/')
+	equals(result, "../up.js", "up.js is correctly joined.")
+})
+
+test("dir", function() {
+	equals("/a/b/c", new steal.File("/a/b/c/cookbook.html").dir(), "/a/b/c dir is correct.")
+	equals("a/b/c", new steal.File("a/b/c/cookbook.html").dir(), "a/b/c dir is correct.")
+	equals("../a/b/c", new steal.File("../a/b/c/cookbook.html").dir(), "../a/b/c dir is correct.")
+	equals("http://127.0.0.1:3007", new steal.File("http://127.0.0.1:3007/cookbook.html").dir(), "http://127.0.0.1:3007 dir is correct.")
+})
+
+test("File.clean", function() {
+	result = new steal.File('http://abc.com#action').clean();
+	equals(result, "http://abc.com", "http://abc.com#action is correctly cleaned.");
+
+	result = new steal.File('http://abc.com#action&q=param').clean();
+	equals(result, "http://abc.com", "http://abc.com#action&q=param is correctly cleaned.");
+
+	result = new steal.File('http://abc.com/#action&q=param').clean();
+	equals(result, "http://abc.com/", "http://abc.com/#action&q=param is correctly cleaned.");
+
+	result = new steal.File('a/b/#action&q=param').clean();
+	equals(result, "a/b/", "a/b/#action&q=param is correctly cleaned.");
+
+	result = new steal.File('a/b#action&q=param').clean();
+	equals(result, "a/b", "a/b#action&q=param is correctly cleaned.");
+})
+
+test("File.protocol", function() {
+	result = new steal.File('http://abc.com').protocol();
+	equals(result, "http:", "http://abc.com protocol should be http:.");
+
+	result = new steal.File('https://abc.com').protocol();
+	equals(result, "https:", "https://abc.com protocol should be https:.");
+
+	result = new steal.File('file://a/b/c').protocol();
+	equals(result, "file:", "file://a/b/c protocol should be file:.");
+
+	result = new steal.File('file:///a/b/c').protocol();
+	equals(result, "file:", "file:///a/b/c protocol should be file:.");
+})
+
+test("File.join", function() {
+	result = new steal.File("http://abc.com").join("/a/b/c");
+	equals(result, "http://abc.com/a/b/c", "http://abc.com/a/b/c was joined successfuly.");
+
+	result = new steal.File("http://abc.com/").join("/a/b/c");
+	equals(result, "http://abc.com/a/b/c", "http://abc.com/a/b/c was joined successfuly.");
+
+	result = new steal.File("http://abc.com/").join("a/b/c");
+	equals(result, "http://abc.com/a/b/c", "http://abc.com/a/b/c was joined successfuly.");
+
+	result = new steal.File("http://abc.com").join("a/b/c");
+	equals(result, "http://abc.com/a/b/c", "http://abc.com/a/b/c was joined successfuly.");
+
+	result = new steal.File("a/b/c").join("d/e");
+	equals(result, "a/b/c/d/e", "a/b/c/d/e was joined successfuly.");
+
+	result = new steal.File("a/b/c/").join("d/e");
+	equals(result, "a/b/c/d/e", "a/b/c/d/e was joined successfuly.");
+
+	result = new steal.File("a/b/c/").join("/d/e");
+	equals(result, "/d/e", "/d/e was joined successfuly.");
+
+	result = new steal.File("a/b/c").join("/d/e");
+	equals(result, "/d/e", "/d/e was joined successfuly.");
+})
+
+test("File.joinCurrent", function() {
+	steal.curDir("http://abc.com");
+	result = new steal.File("d/e").joinCurrent();
+	equals(result, "http://abc.com/d/e", "http://abc.com/d/e was joined successfuly.");
+
+	steal.curDir("/a/b/");
+	result = new steal.File("c/d").joinCurrent();
+	equals(result, "/a/b/c/d", "/a/b/c/d was joined successfuly.");
+})
+
+test("File.relative", function() {
+	result = new steal.File("a/b/c").relative();
+	ok(result, "a/b/c is relative.")
+
+	result = new steal.File("/a/b/c").relative();
+	ok(!result, "/a/b/c is NOT relative.")
+})
+
+test("File.isLocalAbsolute", function() {
+	result = new steal.File("/a/b/c").isLocalAbsolute();
+	ok(result, "/a/b/c is absolute.")
+
+	result = new steal.File("a/b/c").isLocalAbsolute();
+	ok(!result, "a/b/c is NOT absolute.")
+})
+
+test("File.isDomainAbsolute()", function() {
+	var result = new steal.File("http://abc.com/d/e").protocol();
+	ok(result, "http://abc.com/d/e domain is absolute.")
+
+	result = new steal.File("http://abc.com/d/e/").protocol();
+	ok(result, "http://abc.com/d/e/ domain is absolute.")
+
+	result = new steal.File("https://abc.com/d/e").protocol();
+	ok(result, "https://abc.com/d/e domain is absolute.")
+
+	result = new steal.File("https://abc.com/d/e/").protocol();
+	ok(result, "https://abc.com/d/e/ domain is absolute.")
+
+	result = new steal.File("file://a/b/c/d/e").protocol();
+	ok(result, "file://a/b/c/d/e domain is absolute.")
+
+	result = new steal.File("file://a/b/c/d/e/").protocol();
+	ok(result, "file://a/b/c/d/e/ domain is absolute.")
+
+	result = new steal.File("file:///a/b/c/d/e").protocol();
+	ok(result, "file:///a/b/c/d/e domain is absolute.");
+
+	result = new steal.File("/a/b/c/d/e").protocol();
+	ok(!result, "/a/b/c/d/e domain is absolute.");
+})
+
+test("File.afterDomain", function() {
+	result = new steal.File("http://abc.com/d/e").afterDomain();
+	equals(result, "/d/e", "/d/e is the correct after domain result.");
+})
+
+test("File.toReferenceFromSameDomain()", function() {
+	result = new steal.File("http://abc.com/d/e").toReferenceFromSameDomain("http://abc.com/d/e/f/g/h");
+	equals(result, "../../../", "../../../ is the correct reference from same domain result.");
+
+	result = new steal.File("http://abc.com/d/e/x/y").toReferenceFromSameDomain("http://abc.com/d/e/f/g/h");
+	equals(result, "../../../x/y", "../../../x/y is the correct reference from same domain result.");
+
+	result = new steal.File("a/b/c/x/y").toReferenceFromSameDomain("a/b/c/d/e");
+	equals(result, "../../x/y", "../../x/y is the correct reference from same domain result.");
+
+	result = new steal.File("a/b/c/d/e").toReferenceFromSameDomain("a/b/c/d/e");
+	equals(result, "", "'' is the correct reference from same domain result.");
+})
+
+test("File.normalize", function() {
+	steal.curDir("/a/b/");
+	result = new steal.File("c/d").normalize();
+	equals(result, "/a/b/c/d", "/a/b/c/d was normalized successfuly.");
+
+	steal.curDir("/a/b/c");
+	result = new steal.File("//d/e").normalize();
+	equals(result, "d/e", "d/e was normalized successfuly.");
+
+	steal.curDir("/a/b/c");
+	result = new steal.File("/d/e").normalize();
+	equals(result, "/d/e", "/d/e was normalized successfuly.");
+
+	steal.curDir("http://abc.com");
+	result = new steal.File("d/e").normalize();
+	equals(result, "http://abc.com/d/e", "http://abc.com/d/e was normalized successfuly.");
+
+	steal.curDir("http://abc.com");
+	result = new steal.File("/d/e").normalize();
+	equals(result, "http://abc.com/d/e", "http://abc.com/d/e was normalized successfuly.");
+});
+
+test("css", function(){
+	document.getElementById("qunit-test-area").innerHTML = ("<div id='makeBlue'>Blue</div><div id='makeGreen'>Green</div>");
+	equals(document.getElementById("makeBlue").clientWidth, 100, "relative in loaded");
+	equals(document.getElementById("makeGreen").clientWidth, 50, "relative up loaded")
+})
diff --git a/browserid/static/dialog/steal/test/run.js b/browserid/static/dialog/steal/test/run.js
new file mode 100644
index 0000000000000000000000000000000000000000..e7401c8282a8beea21956cceef83cde3003a9cef
--- /dev/null
+++ b/browserid/static/dialog/steal/test/run.js
@@ -0,0 +1,13 @@
+// loads all of steal's command line tests
+
+load('steal/build/test/run.js');
+
+load('steal/build/styles/test/styles_test.js');
+
+load('steal/get/test/get_test.js');
+
+load('steal/clean/test/clean_test.js');
+
+load('steal/generate/test/run.js');
+
+// TODO test get!
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/test/steal.html b/browserid/static/dialog/steal/test/steal.html
new file mode 100644
index 0000000000000000000000000000000000000000..be938925e523a92a4beec0b59e83594b74cd1239
--- /dev/null
+++ b/browserid/static/dialog/steal/test/steal.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+	<head>
+		<title>steal</title>
+        <style type='text/css'>
+            body {font-family: verdana}
+            .error {border: solid 1px red;}
+            .error_text { color: red; font-size: 10px;}
+            td {padding: 3px;}
+        </style>
+	</head>
+	<body>
+		<script type='text/javascript'>
+			var order_num = 0;
+			order = function(o){
+				var p  = document.createElement('p');
+				if (typeof o == 'number') {
+					p.style.backgroundColor = o == order_num ? '#ddffdd' : '#ffdddd'
+					p.innerHTML = '' + o + '=' + (order_num++) + ': ' + steal.getCurrent() + ', ' + steal.current.path;
+				}else{
+					p.innerHTML = o
+				}
+				document.body.appendChild(p)
+			}
+			window.onload = function(){
+				var p  = document.createElement('p');
+				p.style.backgroundColor =  '#ffdddd'
+				p.innerHTML = 'load'
+				document.body.appendChild(p)
+			}
+		</script>
+		<script type='text/javascript' 
+                src='../steal.js?steal[app]=steal/test/one&steal[env]=development'>   
+        </script>	
+	</body>
+</html>
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/test/test.js b/browserid/static/dialog/steal/test/test.js
new file mode 100644
index 0000000000000000000000000000000000000000..1f3721bb0159f56c9dfefbae122aa332ae335e05
--- /dev/null
+++ b/browserid/static/dialog/steal/test/test.js
@@ -0,0 +1,112 @@
+// this is test helpers for steal
+steal(function(steal){
+	
+var assertions = [],
+	module = "";
+steal.test =  {
+	//clears every property fromt he window, returns steal (might return old stuff)
+	clear: function() {
+		var win = this.getWindow();
+		for(var n in win){
+			if(n != "_S" && n != "STEALPRINT"){
+				//this[n] = null;
+				delete win[n];
+			}
+		}
+		this.testNamespace();
+		return steal;
+	},
+	getWindow: function() {
+		return (function(){return this}).call(null,0)
+	},
+	wait: function( name ) {
+		var checkExists = function(name){
+	        var parts = name.split(".");
+	        var cur = this;
+	        for(var i =0; i < parts.length; i++){
+	            if(! cur[parts[i]] ){
+	                return false;
+	            }else
+	                cur = cur[parts[i]];
+	        }
+	        return true;
+	    }
+	    while(!checkExists(name)){
+	        java.lang.Thread.currentThread().sleep(300);
+	    }
+	},
+	sleep: function( duration ){
+        java.lang.Thread.currentThread().sleep(duration);		
+	},
+	print: function() {
+		var win =this.getWindow();
+		for(var n in win) print(n);
+	},
+	deleteDir: function( dir ) {
+		if (dir.isDirectory()) {
+	        var children = dir.list();
+	        for (var i=0; i<children.length; i++) {
+	            var success = deleteDir(new java.io.File(dir, children[i]));
+	            if (!success) return false;
+	            
+	        }
+	    }
+	
+	    // The directory is now empty so delete it
+	    return dir['delete']();
+	},
+	remove: function() {
+		for(var i=0; i < arguments.length; i++){
+			this.deleteDir(new java.io.File(arguments[i]) )
+		}
+	},
+	testNamespace: function() {
+		var win = this.getWindow();
+		for(var n in win) {
+			if(n !== "_S" && n !== "STEALPRINT")
+				throw "Namespace Pollution "+n;
+		}
+	},
+	equals: function( a, b, message ) {
+		if(a !== b)
+			throw ""+a+"!="+b+":"+message
+		else{
+			assertions.push(message)
+		}
+	},
+	ok: function( v, message ) {
+		if(!v){
+			throw "not "+v+" "+message
+		}
+		else{
+			assertions.push(message)
+		}
+	},
+	open: function( src , fireLoad ) {
+		load("steal/rhino/env.js");
+		if(typeof Envjs == 'undefined'){
+			print("I DON'T GET IT")
+		}
+		Envjs(src, {
+			scriptTypes : {
+				"text/javascript" : true,
+				"text/envjs" : true,
+				"": true
+			}, 
+			fireLoad: fireLoad !== undefined ? fireLoad : true, 
+			logLevel: 2,
+			dontPrintUserAgent: true
+		});
+	},
+	test : function(name, test){
+		assertions = []
+		test(steal.test);
+		print("  -- "+name+" "+assertions.length)
+	},
+	module : function(name ){
+		module = name;
+		print("==========  "+name+"  =========")
+	}
+}
+	
+})
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/test/three.js b/browserid/static/dialog/steal/test/three.js
new file mode 100644
index 0000000000000000000000000000000000000000..057013fe1d4a3300b08f5cc41cbc27fd28d52cbc
--- /dev/null
+++ b/browserid/static/dialog/steal/test/three.js
@@ -0,0 +1,3 @@
+steal(function() {
+	order(3)
+});
\ No newline at end of file
diff --git a/browserid/static/dialog/steal/test/two.css b/browserid/static/dialog/steal/test/two.css
new file mode 100644
index 0000000000000000000000000000000000000000..17868348da2fe4ad6ed44f525902798af22a4029
--- /dev/null
+++ b/browserid/static/dialog/steal/test/two.css
@@ -0,0 +1,4 @@
+#makeGreen {
+	color : green;
+	width: 50px;
+}
diff --git a/browserid/static/dialog/steal/update b/browserid/static/dialog/steal/update
new file mode 100644
index 0000000000000000000000000000000000000000..7b5c328c90864dfc6bcc7e3ee327d34fe7cfc4ec
--- /dev/null
+++ b/browserid/static/dialog/steal/update
@@ -0,0 +1,5 @@
+load('steal/rhino/steal.js')
+
+steal('//steal/get/get', function(s){
+	s.get('http://github.com/jupiterjs/steal/', {name: 'steal'});
+})