diff --git a/js/ndnProtocol.xpi b/js/ndnProtocol.xpi
index ecf43f8..dcff5bf 100644
--- a/js/ndnProtocol.xpi
+++ b/js/ndnProtocol.xpi
Binary files differ
diff --git a/js/ndnProtocol/modules/make-ndn-js.jsm.sh b/js/ndnProtocol/modules/make-ndn-js.jsm.sh
index 87e4772..43f4125 100755
--- a/js/ndnProtocol/modules/make-ndn-js.jsm.sh
+++ b/js/ndnProtocol/modules/make-ndn-js.jsm.sh
@@ -1,38 +1,2 @@
 #!/bin/sh
-cat ndn-js-header.txt \
-  ../../Closure.js \
-  ../../NDN.js \
-  ../../XpcomTransport.js \
-  ../../util/CCNProtocolDTags.js \
-  ../../util/CCNTime.js \
-  ../../Name.js \
-  ../../ContentObject.js \
-  ../../encoding/DateFormat.js \
-  ../../Interest.js \
-  ../../Key.js \
-  ../../PublisherID.js \
-  ../../PublisherPublicKeyDigest.js \
-  ../../FaceInstance.js \
-  ../../ForwardingEntry.js \
-  ../../encoding/BinaryXMLEncoder.js \
-  ../../encoding/BinaryXMLDecoder.js \
-  ../../encoding/BinaryXMLStructureDecoder.js \
-  ../../encoding/DataUtils.js \
-  ../../encoding/MimeTypes.js \
-  ../../encoding/EncodingUtils.js \
-  ../../security/KeyManager.js \
-  ../../securityLib/sha1.js \
-  ../../securityLib/sha256.js \
-  ../../securityLib/sha512.js \
-  ../../securityLib/md5.js \
-  ../../securityLib/ripemd160.js \
-  ../../securityLib/base64.js \
-  ../../securityLib/rsa.js \
-  ../../securityLib/rsa2.js \
-  ../../securityLib/rsapem-1.1.js \
-  ../../securityLib/rsasign-1.2.js \
-  ../../securityLib/asn1hex-1.1.js \
-  ../../securityLib/x509-1.1.js \
-  ../../securityLib/jsbn.js \
-  ../../securityLib/jsbn2.js \
-  > ndn-js.jsm
+cat ndn-js-header.txt ../../tools/build/ndn-js.js ../../XpcomTransport.js ../../encoding/MimeTypes.js > ndn-js.jsm
diff --git a/js/ndnProtocol/modules/ndn-js-header.txt b/js/ndnProtocol/modules/ndn-js-header.txt
index 2517732..e30c261 100644
--- a/js/ndnProtocol/modules/ndn-js-header.txt
+++ b/js/ndnProtocol/modules/ndn-js-header.txt
@@ -1,6 +1,7 @@
 /* This file is created by running make-ndn-js.jsm.sh in this directory.
  * It concatenates ndn-js-header.txt with all the ndn-js source files to
  *   make ndn-js.jsm .
+ * The file ../../tools/build/ndn-js.js must already be built.
  * author: Jeff Thompson
  * See COPYING for copyright and distribution information.
  */
diff --git a/js/ndnProtocol/modules/ndn-js.jsm b/js/ndnProtocol/modules/ndn-js.jsm
index 73ca64a..01b91b3 100644
--- a/js/ndnProtocol/modules/ndn-js.jsm
+++ b/js/ndnProtocol/modules/ndn-js.jsm
@@ -11,9 +11,6 @@
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/NetUtil.jsm");
 
-// LOG is used by some of the NDN code.
-var LOG = 0;
-
 // jsbn.js needs the navigator object which isn't defined in XPCOM, so make a local hack.
 var navigator = {
     appName: "Netscape"
@@ -26,141 +23,254 @@
     }
 };
 
-/* 
- * @author: Jeff Thompson
- * See COPYING for copyright and distribution information.
- * Provide the callback closure for the async communication methods in the NDN class.
- * This is a port of Closure.py from PyCCN, written by: 
- * Derek Kulinski <takeda@takeda.tk>
- * Jeff Burke <jburke@ucla.edu>
- */
-
-/*
- * Create a subclass of Closure and pass an object to async calls.
- */
-var Closure = function Closure() {
-	// I don't think storing NDN's closure is needed
-	// and it creates a reference loop, as of now both
-	// of those variables are never set -- Derek
-	//
-	// Use instance variables to return data to callback
-	this.ndn_data = null;  // this holds the ndn_closure
-    this.ndn_data_dirty = false;
-};
-
-// Upcall result
-Closure.RESULT_ERR               = -1; // upcall detected an error
-Closure.RESULT_OK                =  0; // normal upcall return
-Closure.RESULT_REEXPRESS         =  1; // reexpress the same interest again
-Closure.RESULT_INTEREST_CONSUMED =  2; // upcall claims to consume interest
-Closure.RESULT_VERIFY            =  3; // force an unverified result to be verified
-Closure.RESULT_FETCHKEY          =  4; // get the key in the key locator and re-call the interest
-                                       //   with the key available in the local storage
-
-// Upcall kind
-Closure.UPCALL_FINAL              = 0; // handler is about to be deregistered
-Closure.UPCALL_INTEREST           = 1; // incoming interest
-Closure.UPCALL_CONSUMED_INTEREST  = 2; // incoming interest, someone has answered
-Closure.UPCALL_CONTENT            = 3; // incoming verified content
-Closure.UPCALL_INTEREST_TIMED_OUT = 4; // interest timed out
-Closure.UPCALL_CONTENT_UNVERIFIED = 5; // content that has not been verified
-Closure.UPCALL_CONTENT_BAD        = 6; // verification failed
-
-/*
- * Override this in your subclass.
- * If you're getting strange errors in upcall()
- * check your code whether you're returning a value.
- */
-Closure.prototype.upcall = function(kind, upcallInfo) {
-	//dump('upcall ' + this + " " + kind + " " + upcallInfo + "\n");
-	return Closure.RESULT_OK;
-};
-
-var UpcallInfo = function UpcallInfo(ndn, interest, matchedComps, contentObject) {
-	this.ndn = ndn;  // NDN object (not used)
-	this.interest = interest;  // Interest object
-	this.matchedComps = matchedComps;  // int
-	this.contentObject = contentObject;  // Content object
-};
-
-UpcallInfo.prototype.toString = function() {
-	var ret = "ndn = " + this.ndn;
-	ret += "\nInterest = " + this.interest;
-	ret += "\nmatchedComps = " + this.matchedComps;
-	ret += "\nContentObject: " + this.contentObject;
-	return ret;
-}
-/*
- * @author: Meki Cherkaoui, Jeff Thompson, Wentao Shang
- * See COPYING for copyright and distribution information.
- * This class represents the top-level object for communicating with an NDN host.
- */
-
-var LOG = 0;
-
-/**
- * settings is an associative array with the following defaults:
- * {
- *   host: 'localhost',
- *   port: 9696,
- *   getTransport: function() { return new WebSocketTransport(); }
- * }
- */
-var NDN = function NDN(settings) {
-    settings = (settings || {});
-	this.host = (settings.host || "localhost");
-	this.port = (settings.port || 9696);
-    var getTransport = (settings.getTransport || function() { return new WebSocketTransport(); });
-    this.transport = getTransport();    
-};
-
-
-/* Java Socket Bridge and XPCOM transport */
-
-NDN.prototype.createRoute = function(host,port){
-	this.host=host;
-	this.port=port;
-}
-
-/** Encode name as an Interest. If template is not null, use its attributes.
- *  Send the interest to host:port, read the entire response and call
- *  closure.upcall(Closure.UPCALL_CONTENT (or Closure.UPCALL_CONTENT_UNVERIFIED),
- *                 new UpcallInfo(this, interest, 0, contentObject)).                 
- */
-NDN.prototype.expressInterest = function(
-        // Name
-        name,
-        // Closure
-        closure,
-        // Interest
-        template) {
-	if (this.host == null || this.port == null) {
-		dump('ERROR host OR port NOT SET\n');
-        return;
-    }
-    
-	var interest = new Interest(name);
-    if (template != null) {
-		interest.minSuffixComponents = template.minSuffixComponents;
-		interest.maxSuffixComponents = template.maxSuffixComponents;
-		interest.publisherPublicKeyDigest = template.publisherPublicKeyDigest;
-		interest.exclude = template.exclude;
-		interest.childSelector = template.childSelector;
-		interest.answerOriginKind = template.answerOriginKind;
-		interest.scope = template.scope;
-		interest.interestLifetime = template.interestLifetime;
-    }
-    else
-        interest.interestLifetime = 4200;
-    
-    this.transport.expressInterest(this, interest, closure);
-};
-
-
-NDN.prototype.registerPrefix = function(name, closure, flag) {
-    return this.transport.registerPrefix(this, name, closure, flag);
-}
-/* 
+var Closure=function(){this.ndn_data=null;this.ndn_data_dirty=!1;this.timerID=-1};Closure.RESULT_ERR=-1;Closure.RESULT_OK=0;Closure.RESULT_REEXPRESS=1;Closure.RESULT_INTEREST_CONSUMED=2;Closure.RESULT_VERIFY=3;Closure.RESULT_FETCHKEY=4;Closure.UPCALL_FINAL=0;Closure.UPCALL_INTEREST=1;Closure.UPCALL_CONSUMED_INTEREST=2;Closure.UPCALL_CONTENT=3;Closure.UPCALL_INTEREST_TIMED_OUT=4;Closure.UPCALL_CONTENT_UNVERIFIED=5;Closure.UPCALL_CONTENT_BAD=6;Closure.prototype.upcall=function(){return Closure.RESULT_OK};
+var UpcallInfo=function(a,b,c,d){this.ndn=a;this.interest=b;this.matchedComps=c;this.contentObject=d};UpcallInfo.prototype.toString=function(){var a="ndn = "+this.ndn,a=a+("\nInterest = "+this.interest),a=a+("\nmatchedComps = "+this.matchedComps);return a+="\nContentObject: "+this.contentObject};
+var LOG=0,NDN=function NDN(b){b=b||{};this.host=b.host||"localhost";this.port=b.port||9696;this.transport=(b.getTransport||function(){return new WebSocketTransport})();this.readyStatus=NDN.UNOPEN;this.onopen=b.onopen||function(){3<LOG&&console.log("NDN connection established.")};this.onclose=b.onclose||function(){3<LOG&&console.log("NDN connection closed.")}};NDN.UNOPEN=0;NDN.OPENED=1;NDN.CLOSED=2;NDN.prototype.createRoute=function(a,b){this.host=a;this.port=b};
+NDN.prototype.expressInterest=function(a,b,c){null==this.host||null==this.port?dump("ERROR host OR port NOT SET\n"):(a=new Interest(a),null!=c?(a.minSuffixComponents=c.minSuffixComponents,a.maxSuffixComponents=c.maxSuffixComponents,a.publisherPublicKeyDigest=c.publisherPublicKeyDigest,a.exclude=c.exclude,a.childSelector=c.childSelector,a.answerOriginKind=c.answerOriginKind,a.scope=c.scope,a.interestLifetime=c.interestLifetime):a.interestLifetime=4200,this.transport.expressInterest(this,a,b))};
+NDN.prototype.registerPrefix=function(a,b,c){return this.transport.registerPrefix(this,a,b,c)};var WebSocketTransport=function(){this.ccndid=this.ws=null;this.maxBufferSize=1E4;this.buffer=new Uint8Array(this.maxBufferSize);this.bufferOffset=0;this.structureDecoder=new BinaryXMLStructureDecoder},ccndIdFetcher="/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY";
+WebSocketTransport.prototype.connectWebSocket=function(a){null!=this.ws&&delete this.ws;this.ws=new WebSocket("ws://"+a.host+":"+a.port);0<LOG&&console.log("ws connection created.");this.ws.binaryType="arraybuffer";var b=this;this.ws.onmessage=function(c){c=c.data;if(null==c||void 0==c||""==c)console.log("INVALID ANSWER");else if(c instanceof ArrayBuffer){c=new Uint8Array(c);3<LOG&&console.log("BINARY RESPONSE IS "+DataUtils.toHex(c));try{if(c.length+b.bufferOffset>=b.buffer.byteLength){3<LOG&&console.log("NDN.ws.onmessage: buffer overflow. Accumulate received length: "+
+b.bufferOffset+". Current packet length: "+c.length+".");delete b.structureDecoder;delete b.buffer;b.structureDecoder=new BinaryXMLStructureDecoder;b.buffer=new Uint8Array(b.maxBufferSize);b.bufferOffset=0;return}b.buffer.set(c,b.bufferOffset);b.bufferOffset+=c.length;if(!b.structureDecoder.findElementEnd(b.buffer.subarray(0,b.bufferOffset))){3<LOG&&console.log("Incomplete packet received. Length "+c.length+". Wait for more input.");return}3<LOG&&console.log("Complete packet received. Length "+c.length+
+". Start decoding.")}catch(d){console.log("NDN.ws.onmessage exception: "+d);return}c=new BinaryXMLDecoder(b.buffer);if(c.peekStartElement(CCNProtocolDTags.Interest)){3<LOG&&console.log("Interest packet received.");var e=new Interest;e.from_ccnb(c);3<LOG&&console.log(e);var f=escape(e.name.getName());3<LOG&&console.log(f);f=getEntryForRegisteredPrefix(f);null!=f&&f.closure.upcall(Closure.UPCALL_INTEREST,new UpcallInfo(a,e,0,null))}else c.peekStartElement(CCNProtocolDTags.ContentObject)?(3<LOG&&console.log("ContentObject packet received."),
+e=new ContentObject,e.from_ccnb(c),3<LOG&&console.log(e),f=e.name.getName(),3<LOG&&console.log(f),null==b.ccndid&&null!=f.match(ccndIdFetcher)?!e.signedInfo||!e.signedInfo.publisher||!e.signedInfo.publisher.publisherPublicKeyDigest?(console.log("Cannot contact router, close NDN now."),a.readyStatus=NDN.CLOSED,a.onclose()):(b.ccndid=e.signedInfo.publisher.publisherPublicKeyDigest,3<LOG&&console.log(b.ccndid),a.readyStatus=NDN.OPENED,a.onopen()):(f=getEntryForExpressedInterest(f),null!=f&&(clearTimeout(f.closure.timerID),
+index=PITTable.indexOf(f),PITTable.splice(index,1),f.closure.upcall(Closure.UPCALL_CONTENT,new UpcallInfo(a,null,0,e))))):console.log("Incoming packet is not Interest or ContentObject. Discard now.");delete c;delete b.structureDecoder;delete b.buffer;b.structureDecoder=new BinaryXMLStructureDecoder;b.buffer=new Uint8Array(b.maxBufferSize);b.bufferOffset=0}};this.ws.onopen=function(a){3<LOG&&console.log(a);3<LOG&&console.log("ws.onopen: WebSocket connection opened.");3<LOG&&console.log("ws.onopen: ReadyState: "+
+this.readyState);a=new Interest(new Name(ccndIdFetcher));a.InterestLifetime=4200;var a=encodeToBinaryInterest(a),d=new Uint8Array(a.length);d.set(a);b.ws.send(d.buffer)};this.ws.onerror=function(a){console.log("ws.onerror: ReadyState: "+this.readyState);console.log(a);console.log("ws.onerror: WebSocket error: "+a.data)};this.ws.onclose=function(){console.log("ws.onclose: WebSocket connection closed.");b.ws=null;a.readyStatus=NDN.CLOSED;a.onclose()}};
+var PITTable=[],PITEntry=function(a,b){this.interest=a;this.closure=b};function getEntryForExpressedInterest(a){for(var b=0;b<PITTable.length;b++)if(null!=a.match(PITTable[b].interest))return PITTable[b];return null}
+WebSocketTransport.prototype.expressInterest=function(a,b,c){if(null!=this.ws){var d=encodeToBinaryInterest(b),e=new Uint8Array(d.length);e.set(d);var f=new PITEntry(b.name.getName(),c);PITTable.push(f);this.ws.send(e.buffer);3<LOG&&console.log("ws.send() returned.");c.timerID=setTimeout(function(){3<LOG&&console.log("Interest time out.");index=PITTable.indexOf(f);PITTable.splice(index,1);c.upcall(Closure.UPCALL_INTEREST_TIMED_OUT,new UpcallInfo(a,b,0,null))},b.interestLifetime)}else console.log("WebSocket connection is not established.")};
+var CSTable=[],CSEntry=function(a,b){this.name=a;this.closure=b};function getEntryForRegisteredPrefix(a){for(var b=0;b<CSTable.length;b++)if(null!=CSTable[b].name.match(a))return CSTable[b];return null}
+WebSocketTransport.prototype.registerPrefix=function(a,b,c){if(null!=this.ws){if(null==this.ccndid)return console.log("ccnd node ID unkonwn. Cannot register prefix."),-1;var a=new ForwardingEntry("selfreg",b,null,null,3,2147483647),a=encodeForwardingEntry(a),d=new SignedInfo;d.setFields();a=new ContentObject(new Name,d,a,new Signature);a.sign();a=encodeToBinaryContentObject(a);a=new Name(["ccnx",this.ccndid,"selfreg",a]);a=new Interest(a);a.scope=1;d=encodeToBinaryInterest(a);a=new Uint8Array(d.length);
+a.set(d);3<LOG&&console.log("Send Interest registration packet.");b=new CSEntry(b.getName(),c);CSTable.push(b);this.ws.send(a.buffer);return 0}console.log("WebSocket connection is not established.");return-1};
+var CCNProtocolDTags={Any:13,Name:14,Component:15,Certificate:16,Collection:17,CompleteName:18,Content:19,SignedInfo:20,ContentDigest:21,ContentHash:22,Count:24,Header:25,Interest:26,Key:27,KeyLocator:28,KeyName:29,Length:30,Link:31,LinkAuthenticator:32,NameComponentCount:33,RootDigest:36,Signature:37,Start:38,Timestamp:39,Type:40,Nonce:41,Scope:42,Exclude:43,Bloom:44,BloomSeed:45,AnswerOriginKind:47,InterestLifetime:48,Witness:53,SignatureBits:54,DigestAlgorithm:55,BlockSize:56,FreshnessSeconds:58,
+FinalBlockID:59,PublisherPublicKeyDigest:60,PublisherCertificateDigest:61,PublisherIssuerKeyDigest:62,PublisherIssuerCertificateDigest:63,ContentObject:64,WrappedKey:65,WrappingKeyIdentifier:66,WrapAlgorithm:67,KeyAlgorithm:68,Label:69,EncryptedKey:70,EncryptedNonceKey:71,WrappingKeyName:72,Action:73,FaceID:74,IPProto:75,Host:76,Port:77,MulticastInterface:78,ForwardingFlags:79,FaceInstance:80,ForwardingEntry:81,MulticastTTL:82,MinSuffixComponents:83,MaxSuffixComponents:84,ChildSelector:85,RepositoryInfo:86,
+Version:87,RepositoryVersion:88,GlobalPrefix:89,LocalName:90,Policy:91,Namespace:92,GlobalPrefixName:93,PolicyVersion:94,KeyValueSet:95,KeyValuePair:96,IntegerValue:97,DecimalValue:98,StringValue:99,BinaryValue:100,NameValue:101,Entry:102,ACL:103,ParameterizedName:104,Prefix:105,Suffix:106,Root:107,ProfileName:108,Parameters:109,InfoString:110,StatusResponse:112,StatusCode:113,StatusText:114,SyncNode:115,SyncNodeKind:116,SyncNodeElement:117,SyncVersion:118,SyncNodeElements:119,SyncContentHash:120,
+SyncLeafCount:121,SyncTreeDepth:122,SyncByteCount:123,ConfigSlice:124,ConfigSliceList:125,ConfigSliceOp:126,CCNProtocolDataUnit:17702112,CCNPROTOCOL_DATA_UNIT:"CCNProtocolDataUnit"},CCNProtocolDTagsStrings=[null,null,null,null,null,null,null,null,null,null,null,null,null,"Any","Name","Component","Certificate","Collection","CompleteName","Content","SignedInfo","ContentDigest","ContentHash",null,"Count","Header","Interest","Key","KeyLocator","KeyName","Length","Link","LinkAuthenticator","NameComponentCount",
+null,null,"RootDigest","Signature","Start","Timestamp","Type","Nonce","Scope","Exclude","Bloom","BloomSeed",null,"AnswerOriginKind","InterestLifetime",null,null,null,null,"Witness","SignatureBits","DigestAlgorithm","BlockSize",null,"FreshnessSeconds","FinalBlockID","PublisherPublicKeyDigest","PublisherCertificateDigest","PublisherIssuerKeyDigest","PublisherIssuerCertificateDigest","ContentObject","WrappedKey","WrappingKeyIdentifier","WrapAlgorithm","KeyAlgorithm","Label","EncryptedKey","EncryptedNonceKey",
+"WrappingKeyName","Action","FaceID","IPProto","Host","Port","MulticastInterface","ForwardingFlags","FaceInstance","ForwardingEntry","MulticastTTL","MinSuffixComponents","MaxSuffixComponents","ChildSelector","RepositoryInfo","Version","RepositoryVersion","GlobalPrefix","LocalName","Policy","Namespace","GlobalPrefixName","PolicyVersion","KeyValueSet","KeyValuePair","IntegerValue","DecimalValue","StringValue","BinaryValue","NameValue","Entry","ACL","ParameterizedName","Prefix","Suffix","Root","ProfileName",
+"Parameters","InfoString",null,"StatusResponse","StatusCode","StatusText","SyncNode","SyncNodeKind","SyncNodeElement","SyncVersion","SyncNodeElements","SyncContentHash","SyncLeafCount","SyncTreeDepth","SyncByteCount","ConfigSlice","ConfigSliceList","ConfigSliceOp"],CCNTime=function(a){this.NANOS_MAX=999877929;"number"==typeof a?this.msec=a:1<LOG&&console.log("UNRECOGNIZED TYPE FOR TIME")};CCNTime.prototype.getJavascriptDate=function(){var a=new Date;a.setTime(this.msec);return a};
+var Name=function Name(b){if("string"==typeof b)3<LOG&&console.log("Content Name String "+b),this.components=Name.createNameArray(b);else if("object"===typeof b){4<LOG&&console.log("Content Name Array "+b);this.components=[];for(var c=0;c<b.length;++c)this.add(b[c])}else null==b?this.components=[]:1<LOG&&console.log("NO CONTENT NAME GIVEN")};Name.prototype.getName=function(){return this.to_uri()};
+Name.createNameArray=function(a){a=a.trim();if(0>=a.length)return[];var b=a.indexOf(":");if(0<=b){var c=a.indexOf("/");if(0>c||b<c)a=a.substr(b+1,a.length-b-1).trim()}if("/"==a[0])if(2<=a.length&&"/"==a[1]){b=a.indexOf("/",2);if(0>b)return[];a=a.substr(b+1,a.length-b-1).trim()}else a=a.substr(1,a.length-1).trim();a=a.split("/");for(b=0;b<a.length;++b){c=unescape(a[b].trim());if(null==c.match(/[^.]/))if(2>=c.length){a.splice(b,1);--b;continue}else a[b]=c.substr(3,c.length-3);else a[b]=c;a[b]=DataUtils.toNumbersFromString(a[b])}return a};
+Name.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());for(this.components=[];a.peekStartElement(CCNProtocolDTags.Component);)this.add(a.readBinaryElement(CCNProtocolDTags.Component));a.readEndElement()};Name.prototype.to_ccnb=function(a){if(null==this.components)throw Error("CANNOT ENCODE EMPTY CONTENT NAME");a.writeStartElement(this.getElementLabel());for(var b=this.components.length,c=0;c<b;c++)a.writeElement(CCNProtocolDTags.Component,this.components[c]);a.writeEndElement()};
+Name.prototype.getElementLabel=function(){return CCNProtocolDTags.Name};
+Name.prototype.add=function(a){var b;if("string"==typeof a)b=DataUtils.stringToUtf8Array(a);else if("object"==typeof a&&a instanceof Uint8Array)b=new Uint8Array(a);else if("object"==typeof a&&a instanceof ArrayBuffer)b=new Uint8Array(new ArrayBuffer(a.byteLength)),b.set(new Uint8Array(a));else if("object"==typeof a)b=new Uint8Array(a);else throw Error("Cannot add Name element at index "+this.components.length+": Invalid type");return this.components.push(b)};
+Name.prototype.to_uri=function(){for(var a="",b=0;b<this.components.length;++b)a+="/"+Name.toEscapedString(this.components[b]);return a};Name.prototype.getPrefix=function(a){return new Name(this.components.slice(0,a))};Name.prototype.getComponent=function(a){var b=new ArrayBuffer(this.components[a].length);(new Uint8Array(b)).set(this.components[a]);return b};
+Name.prototype.indexOfFileName=function(){for(var a=this.components.length-1;0<=a;--a){var b=this.components[a];if(!(0>=b.length)&&!(0==b[0]||192==b[0]||193==b[0]||245<=b[0]&&255>=b[0]))return a}return-1};
+Name.prototype.getContentDigestValue=function(){for(var a=Name.ContentDigestPrefix.length+32+Name.ContentDigestSuffix.length,b=this.components.length-1;0<=b;--b)if(this.components[b].length==a&&DataUtils.arraysEqual(this.components[b].subarray(0,Name.ContentDigestPrefix.length),Name.ContentDigestPrefix)&&DataUtils.arraysEqual(this.components[b].subarray(this.components[b].length-Name.ContentDigestSuffix.length,this.components[b].length),Name.ContentDigestSuffix))return this.components[b].subarray(Name.ContentDigestPrefix.length,
+Name.ContentDigestPrefix.length+32);return null};Name.ContentDigestPrefix=new Uint8Array([193,46,77,46,71,193,1,170,2,133]);Name.ContentDigestSuffix=new Uint8Array([0]);Name.toEscapedString=function(a){for(var b="",c=!1,d=0;d<a.length;++d)if(46!=a[d]){c=!0;break}if(c)for(d=0;d<a.length;++d)c=a[d],b=48<=c&&57>=c||65<=c&&90>=c||97<=c&&122>=c||43==c||45==c||46==c||95==c?b+String.fromCharCode(c):b+("%"+(16>c?"0":"")+c.toString(16).toUpperCase());else{b="...";for(d=0;d<a.length;++d)b+="."}return b};
+var ContentObject=function(a,b,c,d){this.name="string"===typeof a?new Name(a):a;this.signedInfo=b;this.content=c;this.signature=d;this.rawSignatureData=this.endContent=this.startSignedInfo=this.endSIG=this.startSIG=null};
+ContentObject.prototype.sign=function(){var a=this.encodeObject(this.name),b=this.encodeObject(this.signedInfo),c=this.encodeContent(),d=new ArrayBuffer(a.length+b.length+c.length),d=new Uint8Array(d);d.set(a,0);d.set(b,a.length);d.set(c,a.length+b.length);4<LOG&&console.log("Signature Data is (binary) "+d);4<LOG&&console.log("Signature Data is (RawString)");4<LOG&&console.log(DataUtils.toString(d));a=new RSAKey;a.readPrivateKeyFromPEMString(globalKeyManager.privateKey);a=a.signByteArrayWithSHA256(d);
+4<LOG&&console.log("SIGNATURE SAVED IS");4<LOG&&console.log(a);4<LOG&&console.log(DataUtils.toNumbers(a.trim()));this.signature.signature=DataUtils.toNumbers(a.trim())};ContentObject.prototype.encodeObject=function(a){var b=new BinaryXMLEncoder;a.to_ccnb(b);return b.getReducedOstream()};ContentObject.prototype.encodeContent=function(){var a=new BinaryXMLEncoder;a.writeElement(CCNProtocolDTags.Content,this.content);return a.getReducedOstream()};
+ContentObject.prototype.saveRawData=function(a){this.rawSignatureData=a.subarray(this.startSIG,this.endSIG)};
+ContentObject.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());a.peekStartElement(CCNProtocolDTags.Signature)&&(this.signature=new Signature,this.signature.from_ccnb(a));this.startSIG=a.offset;this.name=new Name;this.name.from_ccnb(a);a.peekStartElement(CCNProtocolDTags.SignedInfo)&&(this.signedInfo=new SignedInfo,this.signedInfo.from_ccnb(a));this.content=a.readBinaryElement(CCNProtocolDTags.Content);this.endSIG=a.offset;a.readEndElement();this.saveRawData(a.istream)};
+ContentObject.prototype.to_ccnb=function(a){a.writeStartElement(this.getElementLabel());null!=this.signature&&this.signature.to_ccnb(a);this.startSIG=a.offset;null!=this.name&&this.name.to_ccnb(a);null!=this.signedInfo&&this.signedInfo.to_ccnb(a);a.writeElement(CCNProtocolDTags.Content,this.content);this.endSIG=a.offset;a.writeEndElement();this.saveRawData(a.ostream)};ContentObject.prototype.getElementLabel=function(){return CCNProtocolDTags.ContentObject};
+var Signature=function(a,b,c){this.Witness=a;this.signature=b;this.digestAlgorithm=c};
+Signature.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());4<LOG&&console.log("STARTED DECODING SIGNATURE ");a.peekStartElement(CCNProtocolDTags.DigestAlgorithm)&&(4<LOG&&console.log("DIGIEST ALGORITHM FOUND"),this.digestAlgorithm=a.readUTF8Element(CCNProtocolDTags.DigestAlgorithm));a.peekStartElement(CCNProtocolDTags.Witness)&&(4<LOG&&console.log("WITNESS FOUND FOUND"),this.Witness=a.readBinaryElement(CCNProtocolDTags.Witness));this.signature=a.readBinaryElement(CCNProtocolDTags.SignatureBits);
+4<LOG&&console.log("READ SIGNATURE ");a.readEndElement()};
+Signature.prototype.to_ccnb=function(a){if(!this.validate())throw Error("Cannot encode: field values missing.");a.writeStartElement(this.getElementLabel());null!=this.digestAlgorithm&&!this.digestAlgorithm.equals(CCNDigestHelper.DEFAULT_DIGEST_ALGORITHM)&&a.writeElement(CCNProtocolDTags.DigestAlgorithm,OIDLookup.getDigestOID(this.DigestAlgorithm));null!=this.Witness&&a.writeElement(CCNProtocolDTags.Witness,this.Witness);a.writeElement(CCNProtocolDTags.SignatureBits,this.signature);a.writeEndElement()};
+Signature.prototype.getElementLabel=function(){return CCNProtocolDTags.Signature};Signature.prototype.validate=function(){return null!=this.signature};
+var ContentType={DATA:0,ENCR:1,GONE:2,KEY:3,LINK:4,NACK:5},ContentTypeValue={"0":787648,1:1101969,2:1631044,3:2639423,4:2917194,5:3408010},ContentTypeValueReverse={787648:0,1101969:1,1631044:2,2639423:3,2917194:4,3408010:5},SignedInfo=function(a,b,c,d,e,f){this.publisher=a;this.timestamp=b;this.type=c;this.locator=d;this.freshnessSeconds=e;this.finalBlockID=f};
+SignedInfo.prototype.setFields=function(){var a=globalKeyManager.publicKey;4<LOG&&console.log("PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ");4<LOG&&console.log(a);var a=DataUtils.toNumbers(globalKeyManager.publicKey),b=hex_sha256_from_bytes(a);this.publisher=new PublisherPublicKeyDigest(DataUtils.toNumbers(b));b=(new Date).getTime();this.timestamp=new CCNTime(b);4<LOG&&console.log("TIME msec is");4<LOG&&console.log(this.timestamp.msec);this.type=0;4<LOG&&console.log("PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ");
+4<LOG&&console.log(a);this.locator=new KeyLocator(a,KeyLocatorType.KEY)};
+SignedInfo.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());a.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)&&(3<LOG&&console.log("DECODING PUBLISHER KEY"),this.publisher=new PublisherPublicKeyDigest,this.publisher.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.Timestamp)&&(this.timestamp=a.readDateTime(CCNProtocolDTags.Timestamp),4<LOG&&console.log("TIMESTAMP FOUND IS  "+this.timestamp));if(a.peekStartElement(CCNProtocolDTags.Type)){if(binType=a.readBinaryElement(CCNProtocolDTags.Type),
+4<LOG&&console.log("Binary Type of of Signed Info is "+binType),this.type=binType,null==this.type)throw Error("Cannot parse signedInfo type: bytes.");}else this.type=ContentType.DATA;a.peekStartElement(CCNProtocolDTags.FreshnessSeconds)&&(this.freshnessSeconds=a.readIntegerElement(CCNProtocolDTags.FreshnessSeconds),4<LOG&&console.log("FRESHNESS IN SECONDS IS "+this.freshnessSeconds));a.peekStartElement(CCNProtocolDTags.FinalBlockID)&&(this.finalBlockID=a.readBinaryElement(CCNProtocolDTags.FinalBlockID));
+a.peekStartElement(CCNProtocolDTags.KeyLocator)&&(this.locator=new KeyLocator,this.locator.from_ccnb(a));a.readEndElement()};
+SignedInfo.prototype.to_ccnb=function(a){if(!this.validate())throw Error("Cannot encode : field values missing.");a.writeStartElement(this.getElementLabel());null!=this.publisher&&(3<LOG&&console.log("ENCODING PUBLISHER KEY"+this.publisher.publisherPublicKeyDigest),this.publisher.to_ccnb(a));null!=this.timestamp&&a.writeDateTime(CCNProtocolDTags.Timestamp,this.timestamp);null!=this.type&&0!=this.type&&a.writeElement(CCNProtocolDTags.type,this.type);null!=this.freshnessSeconds&&a.writeElement(CCNProtocolDTags.FreshnessSeconds,
+this.freshnessSeconds);null!=this.finalBlockID&&a.writeElement(CCNProtocolDTags.FinalBlockID,this.finalBlockID);null!=this.locator&&this.locator.to_ccnb(a);a.writeEndElement()};SignedInfo.prototype.valueToType=function(){return null};SignedInfo.prototype.getElementLabel=function(){return CCNProtocolDTags.SignedInfo};SignedInfo.prototype.validate=function(){return null==this.publisher||null==this.timestamp||null==this.locator?!1:!0};
+var DateFormat=function(){var a=/d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,b=/\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,c=/[^-+\dA-Z]/g,d=function(a,b){a=String(a);for(b=b||2;a.length<b;)a="0"+a;return a};return function(e,f,g){var h=dateFormat;1==arguments.length&&("[object String]"==Object.prototype.toString.call(e)&&!/\d/.test(e))&&(f=e,e=void 0);e=e?new Date(e):new Date;if(isNaN(e))throw SyntaxError("invalid date");
+f=String(h.masks[f]||f||h.masks["default"]);"UTC:"==f.slice(0,4)&&(f=f.slice(4),g=!0);var j=g?"getUTC":"get",l=e[j+"Date"](),n=e[j+"Day"](),m=e[j+"Month"](),p=e[j+"FullYear"](),k=e[j+"Hours"](),q=e[j+"Minutes"](),s=e[j+"Seconds"](),j=e[j+"Milliseconds"](),r=g?0:e.getTimezoneOffset(),t={d:l,dd:d(l),ddd:h.i18n.dayNames[n],dddd:h.i18n.dayNames[n+7],m:m+1,mm:d(m+1),mmm:h.i18n.monthNames[m],mmmm:h.i18n.monthNames[m+12],yy:String(p).slice(2),yyyy:p,h:k%12||12,hh:d(k%12||12),H:k,HH:d(k),M:q,MM:d(q),s:s,
+ss:d(s),l:d(j,3),L:d(99<j?Math.round(j/10):j),t:12>k?"a":"p",tt:12>k?"am":"pm",T:12>k?"A":"P",TT:12>k?"AM":"PM",Z:g?"UTC":(String(e).match(b)||[""]).pop().replace(c,""),o:(0<r?"-":"+")+d(100*Math.floor(Math.abs(r)/60)+Math.abs(r)%60,4),S:["th","st","nd","rd"][3<l%10?0:(10!=l%100-l%10)*l%10]};return f.replace(a,function(a){return a in t?t[a]:a.slice(1,a.length-1)})}}();
+DateFormat.masks={"default":"ddd mmm dd yyyy HH:MM:ss",shortDate:"m/d/yy",mediumDate:"mmm d, yyyy",longDate:"mmmm d, yyyy",fullDate:"dddd, mmmm d, yyyy",shortTime:"h:MM TT",mediumTime:"h:MM:ss TT",longTime:"h:MM:ss TT Z",isoDate:"yyyy-mm-dd",isoTime:"HH:MM:ss",isoDateTime:"yyyy-mm-dd'T'HH:MM:ss",isoUtcDateTime:"UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"};DateFormat.i18n={dayNames:"Sun Mon Tue Wed Thu Fri Sat Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),monthNames:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec January February March April May June July August September October November December".split(" ")};
+Date.prototype.format=function(a,b){return dateFormat(this,a,b)};var Interest=function(a,b,c,d,e,f,g,h,j,l,n){this.name=a;this.faceInstance=b;this.maxSuffixComponents=d;this.minSuffixComponents=c;this.publisherPublicKeyDigest=e;this.exclude=f;this.childSelector=g;this.answerOriginKind=h;this.scope=j;this.interestLifetime=l;this.nonce=n};Interest.RECURSIVE_POSTFIX="*";Interest.CHILD_SELECTOR_LEFT=0;Interest.CHILD_SELECTOR_RIGHT=1;Interest.ANSWER_CONTENT_STORE=1;Interest.ANSWER_GENERATED=2;
+Interest.ANSWER_STALE=4;Interest.MARK_STALE=16;Interest.DEFAULT_ANSWER_ORIGIN_KIND=Interest.ANSWER_CONTENT_STORE|Interest.ANSWER_GENERATED;
+Interest.prototype.from_ccnb=function(a){a.readStartElement(CCNProtocolDTags.Interest);this.name=new Name;this.name.from_ccnb(a);a.peekStartElement(CCNProtocolDTags.MinSuffixComponents)&&(this.minSuffixComponents=a.readIntegerElement(CCNProtocolDTags.MinSuffixComponents));a.peekStartElement(CCNProtocolDTags.MaxSuffixComponents)&&(this.maxSuffixComponents=a.readIntegerElement(CCNProtocolDTags.MaxSuffixComponents));a.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)&&(this.publisherPublicKeyDigest=
+new PublisherPublicKeyDigest,this.publisherPublicKeyDigest.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.Exclude)&&(this.exclude=new Exclude,this.exclude.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.ChildSelector)&&(this.childSelector=a.readIntegerElement(CCNProtocolDTags.ChildSelector));a.peekStartElement(CCNProtocolDTags.AnswerOriginKind)&&(this.answerOriginKind=a.readIntegerElement(CCNProtocolDTags.AnswerOriginKind));a.peekStartElement(CCNProtocolDTags.Scope)&&(this.scope=a.readIntegerElement(CCNProtocolDTags.Scope));
+a.peekStartElement(CCNProtocolDTags.InterestLifetime)&&(this.interestLifetime=DataUtils.bigEndianToUnsignedInt(a.readBinaryElement(CCNProtocolDTags.InterestLifetime))/4096);a.peekStartElement(CCNProtocolDTags.Nonce)&&(this.nonce=a.readBinaryElement(CCNProtocolDTags.Nonce));a.readEndElement()};
+Interest.prototype.to_ccnb=function(a){a.writeStartElement(CCNProtocolDTags.Interest);this.name.to_ccnb(a);null!=this.minSuffixComponents&&a.writeElement(CCNProtocolDTags.MinSuffixComponents,this.minSuffixComponents);null!=this.maxSuffixComponents&&a.writeElement(CCNProtocolDTags.MaxSuffixComponents,this.maxSuffixComponents);null!=this.publisherPublicKeyDigest&&this.publisherPublicKeyDigest.to_ccnb(a);null!=this.exclude&&this.exclude.to_ccnb(a);null!=this.childSelector&&a.writeElement(CCNProtocolDTags.ChildSelector,
+this.childSelector);this.DEFAULT_ANSWER_ORIGIN_KIND!=this.answerOriginKind&&null!=this.answerOriginKind&&a.writeElement(CCNProtocolDTags.AnswerOriginKind,this.answerOriginKind);null!=this.scope&&a.writeElement(CCNProtocolDTags.Scope,this.scope);null!=this.interestLifetime&&a.writeElement(CCNProtocolDTags.InterestLifetime,DataUtils.nonNegativeIntToBigEndian(4096*this.interestLifetime));null!=this.nonce&&a.writeElement(CCNProtocolDTags.Nonce,this.nonce);a.writeEndElement()};
+Interest.prototype.matches_name=function(a){var b=this.name.components,a=a.components;if(b.length>a.length)return!1;for(var c=0;c<b.length;++c)if(!DataUtils.arraysEqual(b[c],a[c]))return!1;return!0};var Exclude=function(a){this.OPTIMUM_FILTER_SIZE=100;this.values=a};Exclude.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());a.readEndElement()};
+Exclude.prototype.to_ccnb=function(a){if(!validate())throw new ContentEncodingException("Cannot encode "+this.getClass().getName()+": field values missing.");empty()||(a.writeStartElement(getElementLabel()),a.writeEndElement())};Exclude.prototype.getElementLabel=function(){return CCNProtocolDTags.Exclude};var ExcludeAny=function(){};ExcludeAny.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());a.readEndElement()};
+ExcludeAny.prototype.to_ccnb=function(a){a.writeStartElement(this.getElementLabel());a.writeEndElement()};ExcludeAny.prototype.getElementLabel=function(){return CCNProtocolDTags.Any};var ExcludeComponent=function(a){this.body=a};ExcludeComponent.prototype.from_ccnb=function(a){this.body=a.readBinaryElement(this.getElementLabel())};ExcludeComponent.prototype.to_ccnb=function(a){a.writeElement(this.getElementLabel(),this.body)};ExcludeComponent.prototype.getElementLabel=function(){return CCNProtocolDTags.Component};
+var Key=function(){},KeyLocatorType={NAME:1,KEY:2,CERTIFICATE:3},KeyLocator=function(a,b){this.type=b;b==KeyLocatorType.NAME?this.keyName=a:b==KeyLocatorType.KEY?(4<LOG&&console.log("SET KEY"),this.publicKey=a):b==KeyLocatorType.CERTIFICATE&&(this.certificate=a)};
+KeyLocator.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());if(a.peekStartElement(CCNProtocolDTags.Key)){try{this.publicKey=encodedKey=a.readBinaryElement(CCNProtocolDTags.Key),this.type=2,4<LOG&&console.log("PUBLIC KEY FOUND: "+this.publicKey)}catch(b){throw Error("Cannot parse key: ",b);}if(null==this.publicKey)throw Error("Cannot parse key: ");}else if(a.peekStartElement(CCNProtocolDTags.Certificate)){try{this.certificate=encodedCert=a.readBinaryElement(CCNProtocolDTags.Certificate),
+this.type=3,4<LOG&&console.log("CERTIFICATE FOUND: "+this.certificate)}catch(c){throw Error("Cannot decode certificate: "+c);}if(null==this.certificate)throw Error("Cannot parse certificate! ");}else this.type=1,this.keyName=new KeyName,this.keyName.from_ccnb(a);a.readEndElement()};
+KeyLocator.prototype.to_ccnb=function(a){4<LOG&&console.log("type is is "+this.type);if(!this.validate())throw new ContentEncodingException("Cannot encode "+this.getClass().getName()+": field values missing.");a.writeStartElement(this.getElementLabel());if(this.type==KeyLocatorType.KEY)5<LOG&&console.log("About to encode a public key"+this.publicKey),a.writeElement(CCNProtocolDTags.Key,this.publicKey);else if(this.type==KeyLocatorType.CERTIFICATE)try{a.writeElement(CCNProtocolDTags.Certificate,this.certificate)}catch(b){throw Error("CertificateEncodingException attempting to write key locator: "+
+b);}else this.type==KeyLocatorType.NAME&&this.keyName.to_ccnb(a);a.writeEndElement()};KeyLocator.prototype.getElementLabel=function(){return CCNProtocolDTags.KeyLocator};KeyLocator.prototype.validate=function(){return null!=this.keyName||null!=this.publicKey||null!=this.certificate};var KeyName=function(){this.contentName=this.contentName;this.publisherID=this.publisherID};
+KeyName.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());this.contentName=new Name;this.contentName.from_ccnb(a);4<LOG&&console.log("KEY NAME FOUND: ");PublisherID.peek(a)&&(this.publisherID=new PublisherID,this.publisherID.from_ccnb(a));a.readEndElement()};
+KeyName.prototype.to_ccnb=function(a){if(!this.validate())throw Error("Cannot encode : field values missing.");a.writeStartElement(this.getElementLabel());this.contentName.to_ccnb(a);null!=this.publisherID&&this.publisherID.to_ccnb(a);a.writeEndElement()};KeyName.prototype.getElementLabel=function(){return CCNProtocolDTags.KeyName};KeyName.prototype.validate=function(){return null!=this.contentName};
+var PublisherType=function(a){this.KEY=CCNProtocolDTags.PublisherPublicKeyDigest;this.CERTIFICATE=CCNProtocolDTags.PublisherCertificateDigest;this.ISSUER_KEY=CCNProtocolDTags.PublisherIssuerKeyDigest;this.ISSUER_CERTIFICATE=CCNProtocolDTags.PublisherIssuerCertificateDigest;this.Tag=a},isTypeTagVal=function(a){return a==CCNProtocolDTags.PublisherPublicKeyDigest||a==CCNProtocolDTags.PublisherCertificateDigest||a==CCNProtocolDTags.PublisherIssuerKeyDigest||a==CCNProtocolDTags.PublisherIssuerCertificateDigest?
+!0:!1},PublisherID=function(){this.PUBLISHER_ID_DIGEST_ALGORITHM="SHA-256";this.PUBLISHER_ID_LEN=32;this.publisherType=this.publisherID=null};
+PublisherID.prototype.from_ccnb=function(a){var b=a.peekStartElementAsLong();if(null==b)throw Error("Cannot parse publisher ID.");this.publisherType=new PublisherType(b);if(!isTypeTagVal(b))throw Error("Invalid publisher ID, got unexpected type: "+b);this.publisherID=a.readBinaryElement(b);if(null==this.publisherID)throw new ContentDecodingException(Error("Cannot parse publisher ID of type : "+b+"."));};
+PublisherID.prototype.to_ccnb=function(a){if(!this.validate())throw Error("Cannot encode "+this.getClass().getName()+": field values missing.");a.writeElement(this.getElementLabel(),this.publisherID)};PublisherID.peek=function(a){nextTag=a.peekStartElementAsLong();return null==nextTag?!1:isTypeTagVal(nextTag)};PublisherID.prototype.getElementLabel=function(){return this.publisherType.Tag};PublisherID.prototype.validate=function(){return null!=id()&&null!=type()};
+var PublisherPublicKeyDigest=function(a){this.PUBLISHER_ID_LEN=64;this.publisherPublicKeyDigest=a};
+PublisherPublicKeyDigest.prototype.from_ccnb=function(a){this.publisherPublicKeyDigest=a.readBinaryElement(this.getElementLabel());4<LOG&&console.log("Publisher public key digest is "+this.publisherPublicKeyDigest);if(null==this.publisherPublicKeyDigest)throw Error("Cannot parse publisher key digest.");this.publisherPublicKeyDigest.length!=this.PUBLISHER_ID_LEN&&0<LOG&&console.log("LENGTH OF PUBLISHER ID IS WRONG! Expected "+this.PUBLISHER_ID_LEN+", got "+this.publisherPublicKeyDigest.length)};
+PublisherPublicKeyDigest.prototype.to_ccnb=function(a){if(!this.validate())throw Error("Cannot encode : field values missing.");3<LOG&&console.log("PUBLISHER KEY DIGEST IS"+this.publisherPublicKeyDigest);a.writeElement(this.getElementLabel(),this.publisherPublicKeyDigest)};PublisherPublicKeyDigest.prototype.getElementLabel=function(){return CCNProtocolDTags.PublisherPublicKeyDigest};PublisherPublicKeyDigest.prototype.validate=function(){return null!=this.publisherPublicKeyDigest};
+var NetworkProtocol={TCP:6,UDP:17},FaceInstance=function(a,b,c,d,e,f,g,h,j){this.action=a;this.publisherPublicKeyDigest=b;this.faceID=c;this.ipProto=d;this.host=e;this.Port=f;this.multicastInterface=g;this.multicastTTL=h;this.freshnessSeconds=j};
+FaceInstance.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());a.peekStartElement(CCNProtocolDTags.Action)&&(this.action=a.readUTF8Element(CCNProtocolDTags.Action));a.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)&&(this.publisherPublicKeyDigest=new PublisherPublicKeyDigest,this.publisherPublicKeyDigest.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.FaceID)&&(this.faceID=a.readIntegerElement(CCNProtocolDTags.FaceID));if(a.peekStartElement(CCNProtocolDTags.IPProto)){var b=
+a.readIntegerElement(CCNProtocolDTags.IPProto);this.ipProto=null;if(NetworkProtocol.TCP==b)this.ipProto=NetworkProtocol.TCP;else if(NetworkProtocol.UDP==b)this.ipProto=NetworkProtocol.UDP;else throw Error("FaceInstance.decoder.  Invalid "+CCNProtocolDTags.tagToString(CCNProtocolDTags.IPProto)+" field: "+b);}a.peekStartElement(CCNProtocolDTags.Host)&&(this.host=a.readUTF8Element(CCNProtocolDTags.Host));a.peekStartElement(CCNProtocolDTags.Port)&&(this.Port=a.readIntegerElement(CCNProtocolDTags.Port));
+a.peekStartElement(CCNProtocolDTags.MulticastInterface)&&(this.multicastInterface=a.readUTF8Element(CCNProtocolDTags.MulticastInterface));a.peekStartElement(CCNProtocolDTags.MulticastTTL)&&(this.multicastTTL=a.readIntegerElement(CCNProtocolDTags.MulticastTTL));a.peekStartElement(CCNProtocolDTags.FreshnessSeconds)&&(this.freshnessSeconds=a.readIntegerElement(CCNProtocolDTags.FreshnessSeconds));a.readEndElement()};
+FaceInstance.prototype.to_ccnb=function(a){a.writeStartElement(this.getElementLabel());null!=this.action&&0!=this.action.length&&a.writeElement(CCNProtocolDTags.Action,this.action);null!=this.publisherPublicKeyDigest&&this.publisherPublicKeyDigest.to_ccnb(a);null!=this.faceID&&a.writeElement(CCNProtocolDTags.FaceID,this.faceID);null!=this.ipProto&&a.writeElement(CCNProtocolDTags.IPProto,this.ipProto);null!=this.host&&0!=this.host.length&&a.writeElement(CCNProtocolDTags.Host,this.host);null!=this.Port&&
+a.writeElement(CCNProtocolDTags.Port,this.Port);null!=this.multicastInterface&&0!=this.multicastInterface.length&&a.writeElement(CCNProtocolDTags.MulticastInterface,this.multicastInterface);null!=this.multicastTTL&&a.writeElement(CCNProtocolDTags.MulticastTTL,this.multicastTTL);null!=this.freshnessSeconds&&a.writeElement(CCNProtocolDTags.FreshnessSeconds,this.freshnessSeconds);a.writeEndElement()};FaceInstance.prototype.getElementLabel=function(){return CCNProtocolDTags.FaceInstance};
+var ForwardingEntry=function(a,b,c,d,e,f){this.action=a;this.prefixName=b;this.ccndID=c;this.faceID=d;this.flags=e;this.lifetime=f};
+ForwardingEntry.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());a.peekStartElement(CCNProtocolDTags.Action)&&(this.action=a.readUTF8Element(CCNProtocolDTags.Action));a.peekStartElement(CCNProtocolDTags.Name)&&(this.prefixName=new Name,this.prefixName.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)&&(this.CcndId=new PublisherPublicKeyDigest,this.CcndId.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.FaceID)&&(this.faceID=a.readIntegerElement(CCNProtocolDTags.FaceID));
+a.peekStartElement(CCNProtocolDTags.ForwardingFlags)&&(this.flags=a.readIntegerElement(CCNProtocolDTags.ForwardingFlags));a.peekStartElement(CCNProtocolDTags.FreshnessSeconds)&&(this.lifetime=a.readIntegerElement(CCNProtocolDTags.FreshnessSeconds));a.readEndElement()};
+ForwardingEntry.prototype.to_ccnb=function(a){a.writeStartElement(this.getElementLabel());null!=this.action&&0!=this.action.length&&a.writeElement(CCNProtocolDTags.Action,this.action);null!=this.prefixName&&this.prefixName.to_ccnb(a);null!=this.CcndId&&this.CcndId.to_ccnb(a);null!=this.faceID&&a.writeElement(CCNProtocolDTags.FaceID,this.faceID);null!=this.flags&&a.writeElement(CCNProtocolDTags.ForwardingFlags,this.flags);null!=this.lifetime&&a.writeElement(CCNProtocolDTags.FreshnessSeconds,this.lifetime);
+a.writeEndElement()};ForwardingEntry.prototype.getElementLabel=function(){return CCNProtocolDTags.ForwardingEntry};
+var XML_EXT=0,XML_TAG=1,XML_DTAG=2,XML_ATTR=3,XML_DATTR=4,XML_BLOB=5,XML_UDATA=6,XML_CLOSE=0,XML_SUBTYPE_PROCESSING_INSTRUCTIONS=16,XML_TT_BITS=3,XML_TT_MASK=(1<<XML_TT_BITS)-1,XML_TT_VAL_BITS=XML_TT_BITS+1,XML_TT_VAL_MASK=(1<<XML_TT_VAL_BITS)-1,XML_REG_VAL_BITS=7,XML_REG_VAL_MASK=(1<<XML_REG_VAL_BITS)-1,XML_TT_NO_MORE=1<<XML_REG_VAL_BITS,BYTE_MASK=255,LONG_BYTES=8,LONG_BITS=64,bits_11=2047,bits_18=262143,bits_32=4294967295,BinaryXMLEncoder=function(){this.ostream=new Uint8Array(1E4);this.offset=
+0;this.CODEC_NAME="Binary"};BinaryXMLEncoder.prototype.writeUString=function(a){this.encodeUString(a,XML_UDATA)};BinaryXMLEncoder.prototype.writeBlob=function(a){3<LOG&&console.log(a);this.encodeBlob(a,a.length)};BinaryXMLEncoder.prototype.writeStartElement=function(a,b){null==a?this.encodeUString(a,XML_TAG):this.encodeTypeAndVal(XML_DTAG,a);null!=b&&this.writeAttributes(b)};BinaryXMLEncoder.prototype.writeEndElement=function(){this.ostream[this.offset]=XML_CLOSE;this.offset+=1};
+BinaryXMLEncoder.prototype.writeAttributes=function(a){if(null!=a)for(var b=0;b<a.length;b++){var c=a[b].k,d=a[b].v,e=stringToTag(c);null==e?this.encodeUString(c,XML_ATTR):this.encodeTypeAndVal(XML_DATTR,e);this.encodeUString(d)}};stringToTag=function(a){return 0<=a&&a<CCNProtocolDTagsStrings.length?CCNProtocolDTagsStrings[a]:a==CCNProtocolDTags.CCNProtocolDataUnit?CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT:null};
+tagToString=function(a){for(var b=0;b<CCNProtocolDTagsStrings.length;++b)if(null!=CCNProtocolDTagsStrings[b]&&CCNProtocolDTagsStrings[b]==a)return b;return CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT==a?CCNProtocolDTags.CCNProtocolDataUnit:null};
+BinaryXMLEncoder.prototype.writeElement=function(a,b,c){this.writeStartElement(a,c);"number"===typeof b?(4<LOG&&console.log("GOING TO WRITE THE NUMBER .charCodeAt(0) "+b.toString().charCodeAt(0)),4<LOG&&console.log("GOING TO WRITE THE NUMBER "+b.toString()),4<LOG&&console.log("type of number is "+typeof b.toString()),this.writeUString(b.toString())):"string"===typeof b?(4<LOG&&console.log("GOING TO WRITE THE STRING  "+b),4<LOG&&console.log("type of STRING is "+typeof b),this.writeUString(b)):(4<LOG&&
+console.log("GOING TO WRITE A BLOB  "+b),this.writeBlob(b));this.writeEndElement()};var TypeAndVal=function(a,b){this.type=a;this.val=b};
+BinaryXMLEncoder.prototype.encodeTypeAndVal=function(a,b){4<LOG&&console.log("Encoding type "+a+" and value "+b);4<LOG&&console.log("OFFSET IS "+this.offset);if(a>XML_UDATA||0>a||0>b)throw Error("Tag and value must be positive, and tag valid.");var c=this.numEncodingBytes(b);if(this.offset+c>this.ostream.length)throw Error("Buffer space of "+(this.ostream.length-this.offset)+" bytes insufficient to hold "+c+" of encoded type and value.");this.ostream[this.offset+c-1]=BYTE_MASK&(XML_TT_MASK&a|(XML_TT_VAL_MASK&
+b)<<XML_TT_BITS)|XML_TT_NO_MORE;for(var b=b>>>XML_TT_VAL_BITS,d=this.offset+c-2;0!=b&&d>=this.offset;)this.ostream[d]=BYTE_MASK&b&XML_REG_VAL_MASK,b>>>=XML_REG_VAL_BITS,--d;if(0!=b)throw Error("This should not happen: miscalculated encoding");this.offset+=c;return c};
+BinaryXMLEncoder.prototype.encodeUString=function(a,b){if(null!=a&&!(b==XML_TAG||b==XML_ATTR&&0==a.length)){3<LOG&&console.log("The string to write is ");3<LOG&&console.log(a);var c=DataUtils.stringToUtf8Array(a);this.encodeTypeAndVal(b,b==XML_TAG||b==XML_ATTR?c.length-1:c.length);3<LOG&&console.log("THE string to write is ");3<LOG&&console.log(c);this.writeString(c,this.offset);this.offset+=c.length}};
+BinaryXMLEncoder.prototype.encodeBlob=function(a,b){null!=a&&(4<LOG&&console.log("LENGTH OF XML_BLOB IS "+b),this.encodeTypeAndVal(XML_BLOB,b),this.writeBlobArray(a,this.offset),this.offset+=b)};var ENCODING_LIMIT_1_BYTE=(1<<XML_TT_VAL_BITS)-1,ENCODING_LIMIT_2_BYTES=(1<<XML_TT_VAL_BITS+XML_REG_VAL_BITS)-1,ENCODING_LIMIT_3_BYTES=(1<<XML_TT_VAL_BITS+2*XML_REG_VAL_BITS)-1;
+BinaryXMLEncoder.prototype.numEncodingBytes=function(a){if(a<=ENCODING_LIMIT_1_BYTE)return 1;if(a<=ENCODING_LIMIT_2_BYTES)return 2;if(a<=ENCODING_LIMIT_3_BYTES)return 3;for(var b=1,a=a>>>XML_TT_VAL_BITS;0!=a;)b++,a>>>=XML_REG_VAL_BITS;return b};
+BinaryXMLEncoder.prototype.writeDateTime=function(a,b){4<LOG&&console.log("ENCODING DATE with LONG VALUE");4<LOG&&console.log(b.msec);var c=Math.round(4096*(b.msec/1E3)).toString(16),c=DataUtils.toNumbers("0".concat(c,"0"));4<LOG&&console.log("ENCODING DATE with BINARY VALUE");4<LOG&&console.log(c);4<LOG&&console.log("ENCODING DATE with BINARY VALUE(HEX)");4<LOG&&console.log(DataUtils.toHex(c));this.writeElement(a,c)};
+BinaryXMLEncoder.prototype.writeString=function(a){if("string"===typeof a){4<LOG&&console.log("GOING TO WRITE A STRING");4<LOG&&console.log(a);for(i=0;i<a.length;i++)4<LOG&&console.log("input.charCodeAt(i)="+a.charCodeAt(i)),this.ostream[this.offset+i]=a.charCodeAt(i)}else 4<LOG&&console.log("GOING TO WRITE A STRING IN BINARY FORM"),4<LOG&&console.log(a),this.writeBlobArray(a)};BinaryXMLEncoder.prototype.writeBlobArray=function(a){4<LOG&&console.log("GOING TO WRITE A BLOB");this.ostream.set(a,this.offset)};
+BinaryXMLEncoder.prototype.getReducedOstream=function(){return this.ostream.subarray(0,this.offset)};XML_EXT=0;XML_TAG=1;XML_DTAG=2;XML_ATTR=3;XML_DATTR=4;XML_BLOB=5;XML_UDATA=6;XML_CLOSE=0;XML_SUBTYPE_PROCESSING_INSTRUCTIONS=16;XML_TT_BITS=3;XML_TT_MASK=(1<<XML_TT_BITS)-1;XML_TT_VAL_BITS=XML_TT_BITS+1;XML_TT_VAL_MASK=(1<<XML_TT_VAL_BITS)-1;XML_REG_VAL_BITS=7;XML_REG_VAL_MASK=(1<<XML_REG_VAL_BITS)-1;XML_TT_NO_MORE=1<<XML_REG_VAL_BITS;BYTE_MASK=255;LONG_BYTES=8;LONG_BITS=64;bits_11=2047;bits_18=262143;
+bits_32=4294967295;tagToString=function(a){return 0<=a&&a<CCNProtocolDTagsStrings.length?CCNProtocolDTagsStrings[a]:a==CCNProtocolDTags.CCNProtocolDataUnit?CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT:null};stringToTag=function(a){for(var b=0;b<CCNProtocolDTagsStrings.length;++b)if(null!=CCNProtocolDTagsStrings[b]&&CCNProtocolDTagsStrings[b]==a)return b;return CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT==a?CCNProtocolDTags.CCNProtocolDataUnit:null};
+var BinaryXMLDecoder=function(a){this.istream=a;this.offset=0};
+BinaryXMLDecoder.prototype.readAttributes=function(a){if(null!=a)try{for(var b=this.peekTypeAndVal();null!=b&&(XML_ATTR==b.type()||XML_DATTR==b.type());){var c=this.decodeTypeAndVal(),d=null;if(XML_ATTR==c.type())d=this.decodeUString(c.val()+1);else if(XML_DATTR==c.type()&&(d=tagToString(c.val()),null==d))throw new ContentDecodingException(Error("Unknown DATTR value"+c.val()));var e=this.decodeUString();a.put(d,e);b=this.peekTypeAndVal()}}catch(f){throw new ContentDecodingException(Error("readStartElement",f));
+}};BinaryXMLDecoder.prototype.initializeDecoding=function(){};BinaryXMLDecoder.prototype.readStartDocument=function(){};BinaryXMLDecoder.prototype.readEndDocument=function(){};
+BinaryXMLDecoder.prototype.readStartElement=function(a,b){tv=this.decodeTypeAndVal();if(null==tv)throw new ContentDecodingException(Error("Expected start element: "+a+" got something not a tag."));var c=null;tv.type()==XML_TAG?(c="string"==typeof tv.val()?parseInt(tv.val())+1:tv.val()+1,c=this.decodeUString(c)):tv.type()==XML_DTAG&&(c=tv.val());if(null==c||c!=a)throw console.log("expecting "+a+" but got "+c),new ContentDecodingException(Error("Expected start element: "+a+" got: "+c+"("+tv.val()+")"));
+null!=b&&readAttributes(b)};
+BinaryXMLDecoder.prototype.readAttributes=function(a){if(null!=a)try{for(var b=this.peekTypeAndVal();null!=b&&(XML_ATTR==b.type()||XML_DATTR==b.type());){var c=this.decodeTypeAndVal(),d=null;if(XML_ATTR==c.type()){var e;e="string"==typeof tv.val()?parseInt(tv.val())+1:tv.val()+1;d=this.decodeUString(e)}else if(XML_DATTR==c.type()&&(d=tagToString(c.val()),null==d))throw new ContentDecodingException(Error("Unknown DATTR value"+c.val()));var f=this.decodeUString();a.push([d,f]);b=this.peekTypeAndVal()}}catch(g){throw new ContentDecodingException(Error("readStartElement",
+g));}};BinaryXMLDecoder.prototype.peekStartElementAsString=function(){var a=null,b=this.offset;try{var c=this.decodeTypeAndVal();if(null!=c)if(c.type()==XML_TAG){var d;d="string"==typeof c.val()?parseInt(c.val())+1:c.val()+1;a=this.decodeUString(d)}else c.type()==XML_DTAG&&(a=tagToString(c.val()))}catch(e){}finally{try{this.offset=b}catch(f){throw Log.logStackTrace(Log.FAC_ENCODING,Level.WARNING,f),new ContentDecodingException(Error("Cannot reset stream! "+f.getMessage(),f));}}return a};
+BinaryXMLDecoder.prototype.peekStartElement=function(a){if("string"==typeof a){var b=this.peekStartElementAsString();return null!=b&&b==a?!0:!1}if("number"==typeof a)return b=this.peekStartElementAsLong(),null!=b&&b==a?!0:!1;throw new ContentDecodingException(Error("SHOULD BE STRING OR NUMBER"));};
+BinaryXMLDecoder.prototype.peekStartElementAsLong=function(){var a=null,b=this.offset;try{var c=this.decodeTypeAndVal();if(null!=c)if(c.type()==XML_TAG){if(c.val()+1>DEBUG_MAX_LEN)throw new ContentDecodingException(Error("Decoding error: length "+c.val()+1+" longer than expected maximum length!"));var d;d="string"==typeof c.val()?parseInt(c.val())+1:c.val()+1;var e=this.decodeUString(d),a=stringToTag(e)}else c.type()==XML_DTAG&&(a=c.val())}catch(f){}finally{try{this.offset=b}catch(g){throw Log.logStackTrace(Log.FAC_ENCODING,
+Level.WARNING,g),Error("Cannot reset stream! "+g.getMessage(),g);}}return a};BinaryXMLDecoder.prototype.readBinaryElement=function(a,b){var c=null;this.readStartElement(a,b);return c=this.readBlob()};
+BinaryXMLDecoder.prototype.readEndElement=function(){4<LOG&&console.log("this.offset is "+this.offset);var a=this.istream[this.offset];this.offset++;4<LOG&&console.log("XML_CLOSE IS "+XML_CLOSE);4<LOG&&console.log("next is "+a);if(a!=XML_CLOSE)throw console.log("Expected end element, got: "+a),new ContentDecodingException(Error("Expected end element, got: "+a));};BinaryXMLDecoder.prototype.readUString=function(){var a=this.decodeUString();this.readEndElement();return a};
+BinaryXMLDecoder.prototype.readBlob=function(){var a=this.decodeBlob();this.readEndElement();return a};BinaryXMLDecoder.prototype.readDateTime=function(a){var a=this.readBinaryElement(a),a=DataUtils.toHex(a),a=parseInt(a,16),b=1E3*(a/4096);3<LOG&&console.log("DECODED DATE WITH VALUE");3<LOG&&console.log(b);b=new CCNTime(b);if(null==b)throw new ContentDecodingException(Error("Cannot parse timestamp: "+DataUtils.printHexBytes(a)));return b};
+BinaryXMLDecoder.prototype.decodeTypeAndVal=function(){var a=-1,b=0,c=!0;do{var d=this.istream[this.offset];if(0>d||0==d&&0==b)return null;(c=0==(d&XML_TT_NO_MORE))?(b<<=XML_REG_VAL_BITS,b|=d&XML_REG_VAL_MASK):(a=d&XML_TT_MASK,b<<=XML_TT_VAL_BITS,b|=d>>>XML_TT_BITS&XML_TT_VAL_MASK);this.offset++}while(c);3<LOG&&console.log("TYPE is "+a+" VAL is "+b);return new TypeAndVal(a,b)};BinaryXMLDecoder.peekTypeAndVal=function(){var a=null,b=this.offset;try{a=this.decodeTypeAndVal()}finally{this.offset=b}return a};
+BinaryXMLDecoder.prototype.decodeBlob=function(a){if(null==a)return a=this.decodeTypeAndVal(),a="string"==typeof a.val()?parseInt(a.val()):a.val(),this.decodeBlob(a);var b=this.istream.subarray(this.offset,this.offset+a);this.offset+=a;return b};var count=0;
+BinaryXMLDecoder.prototype.decodeUString=function(a){if(null==a){var a=this.offset,b=this.decodeTypeAndVal();3<LOG&&console.log("TV is "+b);3<LOG&&console.log(b);3<LOG&&console.log("Type of TV is "+typeof b);return null==b||XML_UDATA!=b.type()?(this.offset=a,""):this.decodeUString(b.val())}a=this.decodeBlob(a);return DataUtils.toString(a)};TypeAndVal=function(a,b){this.t=a;this.v=b};TypeAndVal.prototype.type=function(){return this.t};TypeAndVal.prototype.val=function(){return this.v};
+BinaryXMLDecoder.prototype.readIntegerElement=function(a){4<LOG&&console.log("READING INTEGER "+a);4<LOG&&console.log("TYPE OF "+typeof a);a=this.readUTF8Element(a);return parseInt(a)};BinaryXMLDecoder.prototype.readUTF8Element=function(a,b){this.readStartElement(a,b);return this.readUString()};BinaryXMLDecoder.prototype.seek=function(a){this.offset=a};function ContentDecodingException(a){this.message=a.message;for(var b in a)this[b]=a[b]}ContentDecodingException.prototype=Error();
+ContentDecodingException.prototype.name="ContentDecodingException";var BinaryXMLStructureDecoder=function(){this.gotElementEnd=!1;this.level=this.offset=0;this.state=BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE;this.headerLength=0;this.useHeaderBuffer=!1;this.headerBuffer=new Uint8Array(5);this.nBytesToRead=0};BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE=0;BinaryXMLStructureDecoder.READ_BYTES=1;
+BinaryXMLStructureDecoder.prototype.findElementEnd=function(a){if(this.gotElementEnd)return!0;for(var b=new BinaryXMLDecoder(a);;){if(this.offset>=a.length)return!1;switch(this.state){case BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE:if(0==this.headerLength&&a[this.offset]==XML_CLOSE){++this.offset;--this.level;if(0==this.level)return!0;if(0>this.level)throw Error("BinaryXMLStructureDecoder: Unexepected close tag at offset "+(this.offset-1));this.startHeader();break}for(var c=this.headerLength;;){if(this.offset>=
+a.length){this.useHeaderBuffer=!0;var d=this.headerLength-c;this.setHeaderBuffer(a.subarray(this.offset-d,d),c);return!1}d=a[this.offset++];++this.headerLength;if(d&XML_TT_NO_MORE)break}this.useHeaderBuffer?(d=this.headerLength-c,this.setHeaderBuffer(a.subarray(this.offset-d,d),c),c=(new BinaryXMLDecoder(this.headerBuffer)).decodeTypeAndVal()):(b.seek(this.offset-this.headerLength),c=b.decodeTypeAndVal());if(null==c)throw Error("BinaryXMLStructureDecoder: Can't read header starting at offset "+(this.offset-
+this.headerLength));d=c.t;if(d==XML_DATTR)this.startHeader();else if(d==XML_DTAG||d==XML_EXT)++this.level,this.startHeader();else if(d==XML_TAG||d==XML_ATTR)d==XML_TAG&&++this.level,this.nBytesToRead=c.v+1,this.state=BinaryXMLStructureDecoder.READ_BYTES;else if(d==XML_BLOB||d==XML_UDATA)this.nBytesToRead=c.v,this.state=BinaryXMLStructureDecoder.READ_BYTES;else throw Error("BinaryXMLStructureDecoder: Unrecognized header type "+d);break;case BinaryXMLStructureDecoder.READ_BYTES:c=a.length-this.offset;
+if(c<this.nBytesToRead)return this.offset+=c,this.nBytesToRead-=c,!1;this.offset+=this.nBytesToRead;this.startHeader();break;default:throw Error("BinaryXMLStructureDecoder: Unrecognized state "+this.state);}}};BinaryXMLStructureDecoder.prototype.startHeader=function(){this.headerLength=0;this.useHeaderBuffer=!1;this.state=BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE};BinaryXMLStructureDecoder.prototype.seek=function(a){this.offset=a};
+BinaryXMLStructureDecoder.prototype.setHeaderBuffer=function(a,b){var c=a.length+b;c>this.headerBuffer.length&&(c=new Uint8Array(c+5),c.set(this.headerBuffer),this.headerBuffer=c);this.headerBuffer.set(a,b)};var DataUtils=function(){};DataUtils.keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+DataUtils.stringtoBase64=function(a){var a=escape(a),b="",c,d,e="",f,g,h="",j=0;do c=a.charCodeAt(j++),d=a.charCodeAt(j++),e=a.charCodeAt(j++),f=c>>2,c=(c&3)<<4|d>>4,g=(d&15)<<2|e>>6,h=e&63,isNaN(d)?g=h=64:isNaN(e)&&(h=64),b=b+DataUtils.keyStr.charAt(f)+DataUtils.keyStr.charAt(c)+DataUtils.keyStr.charAt(g)+DataUtils.keyStr.charAt(h);while(j<a.length);return b};
+DataUtils.base64toString=function(a){var b="",c,d,e="",f,g="",h=0;/[^A-Za-z0-9\+\/\=]/g.exec(a)&&alert("There were invalid base64 characters in the input text.\nValid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\nExpect errors in decoding.");a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");do c=DataUtils.keyStr.indexOf(a.charAt(h++)),d=DataUtils.keyStr.indexOf(a.charAt(h++)),f=DataUtils.keyStr.indexOf(a.charAt(h++)),g=DataUtils.keyStr.indexOf(a.charAt(h++)),c=c<<2|d>>4,d=(d&15)<<4|f>>2,e=(f&3)<<6|g,
+b+=String.fromCharCode(c),64!=f&&(b+=String.fromCharCode(d)),64!=g&&(b+=String.fromCharCode(e));while(h<a.length);return unescape(b)};DataUtils.toHex=function(a){4<LOG&&console.log("ABOUT TO CONVERT "+a);for(var b="",c=0;c<a.length;c++)b+=(16>a[c]?"0":"")+a[c].toString(16);4<LOG&&console.log("Converted to: "+b);return b};DataUtils.stringToHex=function(a){for(var b="",c=0;c<a.length;++c)var d=a.charCodeAt(c),b=b+((16>d?"0":"")+d.toString(16));return b};
+DataUtils.toString=function(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(a[c]);return b};DataUtils.toNumbers=function(a){if("string"==typeof a){var b=new Uint8Array(Math.floor(a.length/2)),c=0;a.replace(/(..)/g,function(a){b[c++]=parseInt(a,16)});return b}};DataUtils.hexToRawString=function(a){if("string"==typeof a){var b="";a.replace(/(..)/g,function(a){b+=String.fromCharCode(parseInt(a,16))});return b}};
+DataUtils.toNumbersFromString=function(a){for(var b=new Uint8Array(a.length),c=0;c<a.length;c++)b[c]=a.charCodeAt(c);return b};DataUtils.stringToUtf8Array=function(a){return DataUtils.toNumbersFromString(str2rstr_utf8(a))};DataUtils.concatArrays=function(a){for(var b=0,c=0;c<a.length;++c)b+=a[c].length;for(var b=new Uint8Array(b),d=0,c=0;c<a.length;++c)b.set(a[c],d),d+=a[c].length;return b};
+DataUtils.decodeUtf8=function(a){for(var b="",c=0,d=0,e=0;c<a.length;)if(d=a.charCodeAt(c),128>d)b+=String.fromCharCode(d),c++;else if(191<d&&224>d)e=a.charCodeAt(c+1),b+=String.fromCharCode((d&31)<<6|e&63),c+=2;else var e=a.charCodeAt(c+1),f=a.charCodeAt(c+2),b=b+String.fromCharCode((d&15)<<12|(e&63)<<6|f&63),c=c+3;return b};DataUtils.arraysEqual=function(a,b){if(a.length!=b.length)return!1;for(var c=0;c<a.length;++c)if(a[c]!=b[c])return!1;return!0};
+DataUtils.bigEndianToUnsignedInt=function(a){for(var b=0,c=0;c<a.length;++c)b<<=8,b+=a[c];return b};DataUtils.nonNegativeIntToBigEndian=function(a){a=Math.round(a);if(0>=a)return new Uint8Array(0);for(var b=new Uint8Array(8),c=0;0!=a;)++c,b[8-c]=a&255,a>>=8;return b.subarray(8-c,8)};function encodeToHexInterest(a){return DataUtils.toHex(encodeToBinaryInterest(a))}function encodeToBinaryInterest(a){var b=new BinaryXMLEncoder;a.to_ccnb(b);return b.getReducedOstream()}
+function encodeToHexContentObject(a){return DataUtils.toHex(encodeToBinaryContentObject(a))}function encodeToBinaryContentObject(a){var b=new BinaryXMLEncoder;a.to_ccnb(b);return b.getReducedOstream()}function encodeForwardingEntry(a){var b=new BinaryXMLEncoder;a.to_ccnb(b);return b.getReducedOstream()}function decodeHexFaceInstance(a){a=DataUtils.toNumbers(a);decoder=new BinaryXMLDecoder(a);3<LOG&&console.log("DECODING HEX FACE INSTANCE  \n"+a);a=new FaceInstance;a.from_ccnb(decoder);return a}
+function decodeHexInterest(a){a=DataUtils.toNumbers(a);decoder=new BinaryXMLDecoder(a);3<LOG&&console.log("DECODING HEX INTERST  \n"+a);a=new Interest;a.from_ccnb(decoder);return a}function decodeHexContentObject(a){a=DataUtils.toNumbers(a);decoder=new BinaryXMLDecoder(a);3<LOG&&console.log("DECODED HEX CONTENT OBJECT \n"+a);co=new ContentObject;co.from_ccnb(decoder);return co}
+function decodeHexForwardingEntry(a){a=DataUtils.toNumbers(a);decoder=new BinaryXMLDecoder(a);3<LOG&&console.log("DECODED HEX FORWARDING ENTRY \n"+a);forwardingEntry=new ForwardingEntry;forwardingEntry.from_ccnb(decoder);return forwardingEntry}
+function contentObjectToHtml(a){var b="";if(-1==a)b+="NO CONTENT FOUND";else if(-2==a)b+="CONTENT NAME IS EMPTY";else{null!=a.name&&null!=a.name.components&&(b+="NAME: "+a.name.to_uri(),b+="<br /><br />");null!=a.content&&(b+="CONTENT(ASCII): "+DataUtils.toString(a.content),b+="<br />",b+="<br />");null!=a.content&&(b+="CONTENT(hex): "+DataUtils.toHex(a.content),b+="<br />",b+="<br />");null!=a.signature&&null!=a.signature.signature&&(b+="SIGNATURE(hex): "+DataUtils.toHex(a.signature.signature),b+=
+"<br />",b+="<br />");null!=a.signedInfo&&(null!=a.signedInfo.publisher&&null!=a.signedInfo.publisher.publisherPublicKeyDigest)&&(b+="Publisher Public Key Digest(hex): "+DataUtils.toHex(a.signedInfo.publisher.publisherPublicKeyDigest),b+="<br />",b+="<br />");if(null!=a.signedInfo&&null!=a.signedInfo.timestamp){var c=new Date;c.setTime(a.signedInfo.timestamp.msec);b+="TimeStamp: "+c;b+="<br />";b+="TimeStamp(number): "+a.signedInfo.timestamp.msec;b+="<br />"}null!=a.signedInfo&&null!=a.signedInfo.finalBlockID&&
+(b+="FinalBlockID: "+DataUtils.toHex(a.signedInfo.finalBlockID),b+="<br />");if(null!=a.signedInfo&&null!=a.signedInfo.locator&&null!=a.signedInfo.locator.certificate){var c=DataUtils.toString(a.signedInfo.locator.certificate),d=rstr2b64(c),e=DataUtils.toHex(a.signedInfo.locator.certificate).toLowerCase(),f=DataUtils.toString(a.signedInfo.locator.certificate),c=DataUtils.toHex(a.signature.signature).toLowerCase(),g=DataUtils.toString(a.rawSignatureData),b=b+("DER Certificate: "+d),b=b+"<br />",b=
+b+"<br />";2<LOG&&console.log(" ContentName + SignedInfo + Content = "+g);2<LOG&&console.log("HEX OF ContentName + SignedInfo + Content = ");2<LOG&&console.log(DataUtils.stringtoBase64(g));2<LOG&&console.log(" PublicKey = "+d);2<LOG&&console.log(" PublicKeyHex = "+e);2<LOG&&console.log(" PublicKeyString = "+f);2<LOG&&console.log(" Signature is");2<LOG&&console.log(c);e=new X509;e.readCertPEM(d);c=e.subjectPublicKeyRSA.verifyByteArray(a.rawSignatureData,c);2<LOG&&console.log("result is "+c);d=e.subjectPublicKeyRSA.n;
+e=e.subjectPublicKeyRSA.e;2<LOG&&console.log("PUBLIC KEY n after is ");2<LOG&&console.log(d);2<LOG&&console.log("EXPONENT e after is ");2<LOG&&console.log(e);b=c?b+"SIGNATURE VALID":b+"SIGNATURE INVALID";b+="<br />";b+="<br />"}null!=a.signedInfo&&(null!=a.signedInfo.locator&&null!=a.signedInfo.locator.publicKey)&&(d=rstr2b64(DataUtils.toString(a.signedInfo.locator.publicKey)),e=DataUtils.toHex(a.signedInfo.locator.publicKey).toLowerCase(),f=DataUtils.toString(a.signedInfo.locator.publicKey),c=DataUtils.toHex(a.signature.signature).toLowerCase(),
+g=DataUtils.toString(a.rawSignatureData),b+="DER Certificate: "+d,b+="<br />",b+="<br />",2<LOG&&console.log(" ContentName + SignedInfo + Content = "+g),2<LOG&&console.log(" PublicKey = "+d),2<LOG&&console.log(" PublicKeyHex = "+e),2<LOG&&console.log(" PublicKeyString = "+f),2<LOG&&console.log(" Signature "+c),2<LOG&&console.log(" Signature NOW IS"),2<LOG&&console.log(a.signature.signature),d=e.slice(56,314),b+="PUBLISHER KEY(hex): "+d,b+="<br />",b+="<br />",2<LOG&&console.log("PUBLIC KEY IN HEX is "),
+2<LOG&&console.log(d),f=e.slice(318,324),2<LOG&&console.log("kp size is "+d.length),b+="exponent: "+f,b+="<br />",b+="<br />",2<LOG&&console.log("EXPONENT is "),2<LOG&&console.log(f),e=new RSAKey,e.setPublic(d,f),c=e.verifyByteArray(a.rawSignatureData,c),2<LOG&&console.log("PUBLIC KEY n after is "),2<LOG&&console.log(e.n),2<LOG&&console.log("EXPONENT e after is "),2<LOG&&console.log(e.e),b=c?b+"SIGNATURE VALID":b+"SIGNATURE INVALID",b+="<br />",b+="<br />")}return b}
+var KeyManager=function(){this.certificate="MIIBmzCCAQQCCQC32FyQa61S7jANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwdheGVsY2R2MB4XDTEyMDQyODIzNDQzN1oXDTEyMDUyODIzNDQzN1owEjEQMA4GA1UEAxMHYXhlbGNkdjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4X0wp9goqxuECxdULcr2IHr9Ih4Iaypg0Wy39URIup8/CLzQmdsh3RYqd55hqonu5VTTpH3iMLx6xZDVJAZ8OJi7pvXcQ2C4Re2kjL2c8SanI0RfDhlS1zJadfr1VhRPmpivcYawJ4aFuOLAi+qHFxtN7lhcGCgpW1OV60oXd58CAwEAATANBgkqhkiG9w0BAQUFAAOBgQDLOrA1fXzSrpftUB5Ro6DigX1Bjkf7F5Bkd69hSVp+jYeJFBBlsILQAfSxUZPQtD+2Yc3iCmSYNyxqu9PcufDRJlnvB7PG29+L3y9lR37tetzUV9eTscJ7rdp8Wt6AzpW32IJ/54yKNfP7S6ZIoIG+LP6EIxq6s8K1MXRt8uBJKw==";
+this.publicKey="30819F300D06092A864886F70D010101050003818D0030818902818100E17D30A7D828AB1B840B17542DCAF6207AFD221E086B2A60D16CB7F54448BA9F3F08BCD099DB21DD162A779E61AA89EEE554D3A47DE230BC7AC590D524067C3898BBA6F5DC4360B845EDA48CBD9CF126A723445F0E1952D7325A75FAF556144F9A98AF7186B0278685B8E2C08BEA87171B4DEE585C1828295B5395EB4A17779F0203010001";this.privateKey="MIICXQIBAAKBgQDhfTCn2CirG4QLF1QtyvYgev0iHghrKmDRbLf1REi6nz8IvNCZ2yHdFip3nmGqie7lVNOkfeIwvHrFkNUkBnw4mLum9dxDYLhF7aSMvZzxJqcjRF8OGVLXMlp1+vVWFE+amK9xhrAnhoW44sCL6ocXG03uWFwYKClbU5XrShd3nwIDAQABAoGAGkv6T6jC3WmhFZYL6CdCWvlc6gysmKrhjarrLTxgavtFY6R5g2ft5BXAsCCVbUkWxkIFSKqxpVNl0gKZCNGEzPDN6mHJOQI/h0rlxNIHAuGfoAbCzALnqmyZivhJAPGijAyKuU9tczsst5+Kpn+bn7ehzHQuj7iwJonS5WbojqECQQD851K8TpW2GrRizNgG4dx6orZxAaon/Jnl8lS7soXhllQty7qG+oDfzznmdMsiznCqEABzHUUKOVGE9RWPN3aRAkEA5D/w9N55d0ibnChFJlc8cUAoaqH+w+U3oQP2Lb6AZHJpLptN4y4b/uf5d4wYU5/i/gC7SSBH3wFhh9bjRLUDLwJAVOx8vN0Kqt7myfKNbCo19jxjVSlA8TKCn1Oznl/BU1I+rC4oUaEW25DjmX6IpAR8kq7S59ThVSCQPjxqY/A08QJBAIRaF2zGPITQk3r/VumemCvLWiRK/yG0noc9dtibqHOWbCtcXtOm/xDWjq+lis2i3ssOvYrvrv0/HcDY+Dv1An0CQQCLJtMsfSg4kvG/FRY5UMhtMuwo8ovYcMXt4Xv/LWaMhndD67b2UGawQCRqr5ghRTABWdDD/HuuMBjrkPsX0861"};
+KeyManager.prototype.verify=function(a,b){var c=this.certificate,d=new X509;d.readCertPEM(c);return d.subjectPublicKeyRSA.verifyString(a,b)};KeyManager.prototype.sign=function(a){var b=this.privateKey,c=new RSAKey;c.readPrivateKeyFromPEMString(b);return c.signString(a,"sha256")};var globalKeyManager=new KeyManager,hexcase=0,b64pad="";function hex_sha256_from_bytes(a){return rstr2hex(binb2rstr(binb_sha256(byteArray2binb(a),8*a.length)))}
+function hex_sha256(a){return rstr2hex(rstr_sha256(str2rstr_utf8(a)))}function b64_sha256(a){return rstr2b64(rstr_sha256(str2rstr_utf8(a)))}function any_sha256(a,b){return rstr2any(rstr_sha256(str2rstr_utf8(a)),b)}function hex_hmac_sha256(a,b){return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(a),str2rstr_utf8(b)))}function b64_hmac_sha256(a,b){return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(a),str2rstr_utf8(b)))}
+function any_hmac_sha256(a,b,c){return rstr2any(rstr_hmac_sha256(str2rstr_utf8(a),str2rstr_utf8(b)),c)}function sha256_vm_test(){return"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"==hex_sha256("abc").toLowerCase()}function rstr_sha256(a){return binb2rstr(binb_sha256(rstr2binb(a),8*a.length))}
+function rstr_hmac_sha256(a,b){var c=rstr2binb(a);16<c.length&&(c=binb_sha256(c,8*a.length));for(var d=Array(16),e=Array(16),f=0;16>f;f++)d[f]=c[f]^909522486,e[f]=c[f]^1549556828;c=binb_sha256(d.concat(rstr2binb(b)),512+8*b.length);return binb2rstr(binb_sha256(e.concat(c),768))}function rstr2hex(a){try{hexcase}catch(b){hexcase=0}for(var c=hexcase?"0123456789ABCDEF":"0123456789abcdef",d="",e,f=0;f<a.length;f++)e=a.charCodeAt(f),d+=c.charAt(e>>>4&15)+c.charAt(e&15);return d}
+function rstr2b64(a){try{b64pad}catch(b){b64pad=""}for(var c="",d=a.length,e=0;e<d;e+=3)for(var f=a.charCodeAt(e)<<16|(e+1<d?a.charCodeAt(e+1)<<8:0)|(e+2<d?a.charCodeAt(e+2):0),g=0;4>g;g++)c=8*e+6*g>8*a.length?c+b64pad:c+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(f>>>6*(3-g)&63);return c}
+function rstr2any(a,b){var c=b.length,d=[],e,f,g,h,j=Array(Math.ceil(a.length/2));for(e=0;e<j.length;e++)j[e]=a.charCodeAt(2*e)<<8|a.charCodeAt(2*e+1);for(;0<j.length;){h=[];for(e=g=0;e<j.length;e++)if(g=(g<<16)+j[e],f=Math.floor(g/c),g-=f*c,0<h.length||0<f)h[h.length]=f;d[d.length]=g;j=h}c="";for(e=d.length-1;0<=e;e--)c+=b.charAt(d[e]);d=Math.ceil(8*a.length/(Math.log(b.length)/Math.log(2)));for(e=c.length;e<d;e++)c=b[0]+c;return c}
+function str2rstr_utf8(a){for(var b="",c=-1,d,e;++c<a.length;)d=a.charCodeAt(c),e=c+1<a.length?a.charCodeAt(c+1):0,55296<=d&&(56319>=d&&56320<=e&&57343>=e)&&(d=65536+((d&1023)<<10)+(e&1023),c++),127>=d?b+=String.fromCharCode(d):2047>=d?b+=String.fromCharCode(192|d>>>6&31,128|d&63):65535>=d?b+=String.fromCharCode(224|d>>>12&15,128|d>>>6&63,128|d&63):2097151>=d&&(b+=String.fromCharCode(240|d>>>18&7,128|d>>>12&63,128|d>>>6&63,128|d&63));return b}
+function str2rstr_utf16le(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(a.charCodeAt(c)&255,a.charCodeAt(c)>>>8&255);return b}function str2rstr_utf16be(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(a.charCodeAt(c)>>>8&255,a.charCodeAt(c)&255);return b}function rstr2binb(a){for(var b=Array(a.length>>2),c=0;c<8*a.length;c+=8)b[c>>5]|=(a.charCodeAt(c/8)&255)<<24-c%32;return b}
+function byteArray2binb(a){for(var b=Array(a.length>>2),c=0;c<8*a.length;c+=8)b[c>>5]|=(a[c/8]&255)<<24-c%32;return b}function binb2rstr(a){for(var b="",c=0;c<32*a.length;c+=8)b+=String.fromCharCode(a[c>>5]>>>24-c%32&255);return b}function sha256_S(a,b){return a>>>b|a<<32-b}function sha256_R(a,b){return a>>>b}function sha256_Ch(a,b,c){return a&b^~a&c}function sha256_Maj(a,b,c){return a&b^a&c^b&c}function sha256_Sigma0256(a){return sha256_S(a,2)^sha256_S(a,13)^sha256_S(a,22)}
+function sha256_Sigma1256(a){return sha256_S(a,6)^sha256_S(a,11)^sha256_S(a,25)}function sha256_Gamma0256(a){return sha256_S(a,7)^sha256_S(a,18)^sha256_R(a,3)}function sha256_Gamma1256(a){return sha256_S(a,17)^sha256_S(a,19)^sha256_R(a,10)}function sha256_Sigma0512(a){return sha256_S(a,28)^sha256_S(a,34)^sha256_S(a,39)}function sha256_Sigma1512(a){return sha256_S(a,14)^sha256_S(a,18)^sha256_S(a,41)}function sha256_Gamma0512(a){return sha256_S(a,1)^sha256_S(a,8)^sha256_R(a,7)}
+function sha256_Gamma1512(a){return sha256_S(a,19)^sha256_S(a,61)^sha256_R(a,6)}
+var sha256_K=[1116352408,1899447441,-1245643825,-373957723,961987163,1508970993,-1841331548,-1424204075,-670586216,310598401,607225278,1426881987,1925078388,-2132889090,-1680079193,-1046744716,-459576895,-272742522,264347078,604807628,770255983,1249150122,1555081692,1996064986,-1740746414,-1473132947,-1341970488,-1084653625,-958395405,-710438585,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,-2117940946,-1838011259,-1564481375,-1474664885,-1035236496,-949202525,
+-778901479,-694614492,-200395387,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,-2067236844,-1933114872,-1866530822,-1538233109,-1090935817,-965641998];function binb_sha256(a,b){var c=[1779033703,-1150833019,1013904242,-1521486534,1359893119,-1694144372,528734635,1541459225],d=Array(64);a[b>>5]|=128<<24-b%32;a[(b+64>>9<<4)+15]=b;for(var e=0;e<a.length;e+=16)processBlock_sha256(a,e,c,d);return c}
+function processBlock_sha256(a,b,c,d){var e,f,g,h,j,l,n,m,p,k,q;e=c[0];f=c[1];g=c[2];h=c[3];j=c[4];l=c[5];n=c[6];m=c[7];for(p=0;64>p;p++)d[p]=16>p?a[p+b]:safe_add(safe_add(safe_add(sha256_Gamma1256(d[p-2]),d[p-7]),sha256_Gamma0256(d[p-15])),d[p-16]),k=safe_add(safe_add(safe_add(safe_add(m,sha256_Sigma1256(j)),sha256_Ch(j,l,n)),sha256_K[p]),d[p]),q=safe_add(sha256_Sigma0256(e),sha256_Maj(e,f,g)),m=n,n=l,l=j,j=safe_add(h,k),h=g,g=f,f=e,e=safe_add(k,q);c[0]=safe_add(e,c[0]);c[1]=safe_add(f,c[1]);c[2]=
+safe_add(g,c[2]);c[3]=safe_add(h,c[3]);c[4]=safe_add(j,c[4]);c[5]=safe_add(l,c[5]);c[6]=safe_add(n,c[6]);c[7]=safe_add(m,c[7])}function safe_add(a,b){var c=(a&65535)+(b&65535);return(a>>16)+(b>>16)+(c>>16)<<16|c&65535}var Sha256=function(){this.W=Array(64);this.hash=[1779033703,-1150833019,1013904242,-1521486534,1359893119,-1694144372,528734635,1541459225];this.nTotalBytes=0;this.buffer=new Uint8Array(64);this.nBufferBytes=0};
+Sha256.prototype.update=function(a){this.nTotalBytes+=a.length;if(0<this.nBufferBytes){var b=this.buffer.length-this.nBufferBytes;if(a.length<b){this.buffer.set(a,this.nBufferBytes);this.nBufferBytes+=a.length;return}this.buffer.set(a.subarray(0,b),this.nBufferBytes);processBlock_sha256(byteArray2binb(this.buffer),0,this.hash,this.W);this.nBufferBytes=0;a=a.subarray(b,a.length);if(0==a.length)return}b=a.length>>6;if(0<b){for(var b=64*b,c=byteArray2binb(a.subarray(0,b)),d=0;d<c.length;d+=16)processBlock_sha256(c,
+d,this.hash,this.W);a=a.subarray(b,a.length)}0<a.length&&(this.buffer.set(a),this.nBufferBytes=a.length)};Sha256.prototype.finalize=function(){var a=byteArray2binb(this.buffer.subarray(0,this.nBufferBytes)),b=8*this.nBufferBytes;a[b>>5]|=128<<24-b%32;a[(b+64>>9<<4)+15]=8*this.nTotalBytes;for(b=0;b<a.length;b+=16)processBlock_sha256(a,b,this.hash,this.W);return Sha256.binb2Uint8Array(this.hash)};
+Sha256.binb2Uint8Array=function(a){for(var b=new Uint8Array(4*a.length),c=0,d=0;d<32*a.length;d+=8)b[c++]=a[d>>5]>>>24-d%32&255;return b};var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",b64pad="=";
+function hex2b64(a){var b,c,d="";for(b=0;b+3<=a.length;b+=3)c=parseInt(a.substring(b,b+3),16),d+=b64map.charAt(c>>6)+b64map.charAt(c&63);b+1==a.length?(c=parseInt(a.substring(b,b+1),16),d+=b64map.charAt(c<<2)):b+2==a.length&&(c=parseInt(a.substring(b,b+2),16),d+=b64map.charAt(c>>2)+b64map.charAt((c&3)<<4));for(;0<(d.length&3);)d+=b64pad;return d}
+function b64tohex(a){var b="",c,d=0,e;for(c=0;c<a.length&&a.charAt(c)!=b64pad;++c)v=b64map.indexOf(a.charAt(c)),0>v||(0==d?(b+=int2char(v>>2),e=v&3,d=1):1==d?(b+=int2char(e<<2|v>>4),e=v&15,d=2):2==d?(b+=int2char(e),b+=int2char(v>>2),e=v&3,d=3):(b+=int2char(e<<2|v>>4),b+=int2char(v&15),d=0));1==d&&(b+=int2char(e<<2));return b}function b64toBA(a){var a=b64tohex(a),b,c=[];for(b=0;2*b<a.length;++b)c[b]=parseInt(a.substring(2*b,2*b+2),16);return c}function parseBigInt(a,b){return new BigInteger(a,b)}
+function linebrk(a,b){for(var c="",d=0;d+b<a.length;)c+=a.substring(d,d+b)+"\n",d+=b;return c+a.substring(d,a.length)}function byte2Hex(a){return 16>a?"0"+a.toString(16):a.toString(16)}
+function pkcs1pad2(a,b){if(b<a.length+11)return alert("Message too long for RSA"),null;for(var c=[],d=a.length-1;0<=d&&0<b;){var e=a.charCodeAt(d--);128>e?c[--b]=e:127<e&&2048>e?(c[--b]=e&63|128,c[--b]=e>>6|192):(c[--b]=e&63|128,c[--b]=e>>6&63|128,c[--b]=e>>12|224)}c[--b]=0;d=new SecureRandom;for(e=[];2<b;){for(e[0]=0;0==e[0];)d.nextBytes(e);c[--b]=e[0]}c[--b]=2;c[--b]=0;return new BigInteger(c)}function RSAKey(){this.n=null;this.e=0;this.coeff=this.dmq1=this.dmp1=this.q=this.p=this.d=null}
+function RSASetPublic(a,b){null!=a&&null!=b&&0<a.length&&0<b.length?(this.n=parseBigInt(a,16),this.e=parseInt(b,16)):alert("Invalid RSA public key")}function RSADoPublic(a){return a.modPowInt(this.e,this.n)}function RSAEncrypt(a){a=pkcs1pad2(a,this.n.bitLength()+7>>3);if(null==a)return null;a=this.doPublic(a);if(null==a)return null;a=a.toString(16);return 0==(a.length&1)?a:"0"+a}RSAKey.prototype.doPublic=RSADoPublic;RSAKey.prototype.setPublic=RSASetPublic;RSAKey.prototype.encrypt=RSAEncrypt;
+function pkcs1unpad2(a,b){for(var c=a.toByteArray(),d=0;d<c.length&&0==c[d];)++d;if(c.length-d!=b-1||2!=c[d])return null;for(++d;0!=c[d];)if(++d>=c.length)return null;for(var e="";++d<c.length;){var f=c[d]&255;128>f?e+=String.fromCharCode(f):191<f&&224>f?(e+=String.fromCharCode((f&31)<<6|c[d+1]&63),++d):(e+=String.fromCharCode((f&15)<<12|(c[d+1]&63)<<6|c[d+2]&63),d+=2)}return e}
+function RSASetPrivate(a,b,c){null!=a&&null!=b&&0<a.length&&0<b.length?(this.n=parseBigInt(a,16),this.e=parseInt(b,16),this.d=parseBigInt(c,16)):alert("Invalid RSA private key")}
+function RSASetPrivateEx(a,b,c,d,e,f,g,h){null!=a&&null!=b&&0<a.length&&0<b.length?(this.n=parseBigInt(a,16),this.e=parseInt(b,16),this.d=parseBigInt(c,16),this.p=parseBigInt(d,16),this.q=parseBigInt(e,16),this.dmp1=parseBigInt(f,16),this.dmq1=parseBigInt(g,16),this.coeff=parseBigInt(h,16)):alert("Invalid RSA private key")}
+function RSAGenerate(a,b){var c=new SecureRandom,d=a>>1;this.e=parseInt(b,16);for(var e=new BigInteger(b,16);;){for(;!(this.p=new BigInteger(a-d,1,c),0==this.p.subtract(BigInteger.ONE).gcd(e).compareTo(BigInteger.ONE)&&this.p.isProbablePrime(10)););for(;!(this.q=new BigInteger(d,1,c),0==this.q.subtract(BigInteger.ONE).gcd(e).compareTo(BigInteger.ONE)&&this.q.isProbablePrime(10)););if(0>=this.p.compareTo(this.q)){var f=this.p;this.p=this.q;this.q=f}var f=this.p.subtract(BigInteger.ONE),g=this.q.subtract(BigInteger.ONE),
+h=f.multiply(g);if(0==h.gcd(e).compareTo(BigInteger.ONE)){this.n=this.p.multiply(this.q);this.d=e.modInverse(h);this.dmp1=this.d.mod(f);this.dmq1=this.d.mod(g);this.coeff=this.q.modInverse(this.p);break}}}function RSADoPrivate(a){if(null==this.p||null==this.q)return a.modPow(this.d,this.n);for(var b=a.mod(this.p).modPow(this.dmp1,this.p),a=a.mod(this.q).modPow(this.dmq1,this.q);0>b.compareTo(a);)b=b.add(this.p);return b.subtract(a).multiply(this.coeff).mod(this.p).multiply(this.q).add(a)}
+function RSADecrypt(a){a=parseBigInt(a,16);a=this.doPrivate(a);return null==a?null: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;function _rsapem_pemToBase64(a){a=a.replace("-----BEGIN RSA PRIVATE KEY-----","");a=a.replace("-----END RSA PRIVATE KEY-----","");return a=a.replace(/[ \n]+/g,"")}
+function _rsapem_getPosArrayOfChildrenFromHex(a){var b=[],c=ASN1HEX.getStartPosOfV_AtObj(a,0),d=ASN1HEX.getPosOfNextSibling_AtObj(a,c),e=ASN1HEX.getPosOfNextSibling_AtObj(a,d),f=ASN1HEX.getPosOfNextSibling_AtObj(a,e),g=ASN1HEX.getPosOfNextSibling_AtObj(a,f),h=ASN1HEX.getPosOfNextSibling_AtObj(a,g),j=ASN1HEX.getPosOfNextSibling_AtObj(a,h),l=ASN1HEX.getPosOfNextSibling_AtObj(a,j),a=ASN1HEX.getPosOfNextSibling_AtObj(a,l);b.push(c,d,e,f,g,h,j,l,a);return b}
+function _rsapem_getHexValueArrayOfChildrenFromHex(a){var b=_rsapem_getPosArrayOfChildrenFromHex(a),c=ASN1HEX.getHexOfV_AtObj(a,b[0]),d=ASN1HEX.getHexOfV_AtObj(a,b[1]),e=ASN1HEX.getHexOfV_AtObj(a,b[2]),f=ASN1HEX.getHexOfV_AtObj(a,b[3]),g=ASN1HEX.getHexOfV_AtObj(a,b[4]),h=ASN1HEX.getHexOfV_AtObj(a,b[5]),j=ASN1HEX.getHexOfV_AtObj(a,b[6]),l=ASN1HEX.getHexOfV_AtObj(a,b[7]),a=ASN1HEX.getHexOfV_AtObj(a,b[8]),b=[];b.push(c,d,e,f,g,h,j,l,a);return b}
+function _rsapem_readPrivateKeyFromPEMString(a){a=_rsapem_pemToBase64(a);a=b64tohex(a);a=_rsapem_getHexValueArrayOfChildrenFromHex(a);this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8])}RSAKey.prototype.readPrivateKeyFromPEMString=_rsapem_readPrivateKeyFromPEMString;var _RSASIGN_DIHEAD=[];_RSASIGN_DIHEAD.sha1="3021300906052b0e03021a05000414";_RSASIGN_DIHEAD.sha256="3031300d060960864801650304020105000420";_RSASIGN_DIHEAD.sha384="3041300d060960864801650304020205000430";
+_RSASIGN_DIHEAD.sha512="3051300d060960864801650304020305000440";_RSASIGN_DIHEAD.md2="3020300c06082a864886f70d020205000410";_RSASIGN_DIHEAD.md5="3020300c06082a864886f70d020505000410";_RSASIGN_DIHEAD.ripemd160="3021300906052b2403020105000414";var _RSASIGN_HASHHEXFUNC=[];_RSASIGN_HASHHEXFUNC.sha1=function(a){return hex_sha1(a)};_RSASIGN_HASHHEXFUNC.sha256=function(a){return hex_sha256(a)};_RSASIGN_HASHHEXFUNC.sha512=function(a){return hex_sha512(a)};_RSASIGN_HASHHEXFUNC.md5=function(a){return hex_md5(a)};
+_RSASIGN_HASHHEXFUNC.ripemd160=function(a){return hex_rmd160(a)};var _RSASIGN_HASHBYTEFUNC=[];_RSASIGN_HASHBYTEFUNC.sha256=function(a){return hex_sha256_from_bytes(a)};var _RE_HEXDECONLY=RegExp("");_RE_HEXDECONLY.compile("[^0-9a-f]","gi");function _rsasign_getHexPaddedDigestInfoForString(a,b,c){for(var b=b/4,a=(0,_RSASIGN_HASHHEXFUNC[c])(a),c="00"+_RSASIGN_DIHEAD[c]+a,a="",b=b-4-c.length,d=0;d<b;d+=2)a+="ff";return sPaddedMessageHex="0001"+a+c}
+function _rsasign_getHexPaddedDigestInfoForStringHEX(a,b,c){for(var b=b/4,a=(0,_RSASIGN_HASHHEXFUNC[c])(a),c="00"+_RSASIGN_DIHEAD[c]+a,a="",b=b-4-c.length,d=0;d<b;d+=2)a+="ff";return sPaddedMessageHex="0001"+a+c}function _rsasign_getHexPaddedDigestInfoForByteArray(a,b,c){for(var b=b/4,a=(0,_RSASIGN_HASHBYTEFUNC[c])(a),c="00"+_RSASIGN_DIHEAD[c]+a,a="",b=b-4-c.length,d=0;d<b;d+=2)a+="ff";return sPaddedMessageHex="0001"+a+c}
+function _zeroPaddingOfSignature(a,b){for(var c="",d=b/4-a.length,e=0;e<d;e++)c+="0";return c+a}function _rsasign_signString(a,b){var c=_rsasign_getHexPaddedDigestInfoForString(a,this.n.bitLength(),b),c=parseBigInt(c,16),c=this.doPrivate(c).toString(16);return _zeroPaddingOfSignature(c,this.n.bitLength())}
+function _rsasign_signStringHEX(a,b){var c=_rsasign_getHexPaddedDigestInfoForString(a,this.n.bitLength(),b),c=parseBigInt(c,16),c=this.doPrivate(c).toString(16);return _zeroPaddingOfSignature(c,this.n.bitLength())}function _rsasign_signByteArray(a,b,c){a=_rsasign_getHexPaddedDigestInfoForByteArray(a,c.n.bitLength(),b);a=parseBigInt(a,16);a=c.doPrivate(a).toString(16);return _zeroPaddingOfSignature(a,c.n.bitLength())}
+function _rsasign_signByteArrayWithSHA256(a){return _rsasign_signByteArray(a,"sha256",this)}function _rsasign_signStringWithSHA1(a){return _rsasign_signString(a,"sha1")}function _rsasign_signStringWithSHA256(a){return _rsasign_signString(a,"sha256")}function _rsasign_getDecryptSignatureBI(a,b,c){var d=new RSAKey;d.setPublic(b,c);return d.doPublic(a)}function _rsasign_getHexDigestInfoFromSig(a,b,c){return _rsasign_getDecryptSignatureBI(a,b,c).toString(16).replace(/^1f+00/,"")}
+function _rsasign_getAlgNameAndHashFromHexDisgestInfo(a){for(var b in _RSASIGN_DIHEAD){var c=_RSASIGN_DIHEAD[b],d=c.length;if(a.substring(0,d)==c)return[b,a.substring(d)]}return[]}function _rsasign_verifySignatureWithArgs(a,b,c,d){b=_rsasign_getHexDigestInfoFromSig(b,c,d);c=_rsasign_getAlgNameAndHashFromHexDisgestInfo(b);if(0==c.length)return!1;b=c[1];a=(0,_RSASIGN_HASHHEXFUNC[c[0]])(a);return b==a}
+function _rsasign_verifyHexSignatureForMessage(a,b){var c=parseBigInt(a,16);return _rsasign_verifySignatureWithArgs(b,c,this.n.toString(16),this.e.toString(16))}
+function _rsasign_verifyString(a,b){b=b.replace(_RE_HEXDECONLY,"");3<LOG&&console.log("n is "+this.n);3<LOG&&console.log("e is "+this.e);if(b.length!=this.n.bitLength()/4)return 0;var b=b.replace(/[ \n]+/g,""),c=parseBigInt(b,16),c=this.doPublic(c).toString(16).replace(/^1f+00/,""),d=_rsasign_getAlgNameAndHashFromHexDisgestInfo(c);if(0==d.length)return!1;c=d[1];d=(0,_RSASIGN_HASHHEXFUNC[d[0]])(a);return c==d}
+function _rsasign_verifyByteArray(a,b){b=b.replace(_RE_HEXDECONLY,"");3<LOG&&console.log("n is "+this.n);3<LOG&&console.log("e is "+this.e);if(b.length!=this.n.bitLength()/4)return 0;var b=b.replace(/[ \n]+/g,""),c=parseBigInt(b,16),c=this.doPublic(c).toString(16).replace(/^1f+00/,""),d=_rsasign_getAlgNameAndHashFromHexDisgestInfo(c);if(0==d.length)return!1;c=d[1];d=(0,_RSASIGN_HASHBYTEFUNC[d[0]])(a);return c==d}RSAKey.prototype.signString=_rsasign_signString;RSAKey.prototype.signByteArray=_rsasign_signByteArray;
+RSAKey.prototype.signByteArrayWithSHA256=_rsasign_signByteArrayWithSHA256;RSAKey.prototype.signStringWithSHA1=_rsasign_signStringWithSHA1;RSAKey.prototype.signStringWithSHA256=_rsasign_signStringWithSHA256;RSAKey.prototype.sign=_rsasign_signString;RSAKey.prototype.signWithSHA1=_rsasign_signStringWithSHA1;RSAKey.prototype.signWithSHA256=_rsasign_signStringWithSHA256;RSAKey.prototype.verifyByteArray=_rsasign_verifyByteArray;RSAKey.prototype.verifyString=_rsasign_verifyString;
+RSAKey.prototype.verifyHexSignatureForMessage=_rsasign_verifyHexSignatureForMessage;RSAKey.prototype.verify=_rsasign_verifyString;RSAKey.prototype.verifyHexSignatureForByteArrayMessage=_rsasign_verifyHexSignatureForMessage;function _asnhex_getByteLengthOfL_AtObj(a,b){if("8"!=a.substring(b+2,b+3))return 1;var c=parseInt(a.substring(b+3,b+4));return 0==c?-1:0<c&&10>c?c+1:-2}function _asnhex_getHexOfL_AtObj(a,b){var c=_asnhex_getByteLengthOfL_AtObj(a,b);return 1>c?"":a.substring(b+2,b+2+2*c)}
+function _asnhex_getIntOfL_AtObj(a,b){var c=_asnhex_getHexOfL_AtObj(a,b);return""==c?-1:(8>parseInt(c.substring(0,1))?parseBigInt(c,16):parseBigInt(c.substring(2),16)).intValue()}function _asnhex_getStartPosOfV_AtObj(a,b){var c=_asnhex_getByteLengthOfL_AtObj(a,b);return 0>c?c:b+2*(c+1)}function _asnhex_getHexOfV_AtObj(a,b){var c=_asnhex_getStartPosOfV_AtObj(a,b),d=_asnhex_getIntOfL_AtObj(a,b);return a.substring(c,c+2*d)}
+function _asnhex_getHexOfTLV_AtObj(a,b){var c=a.substr(b,2),d=_asnhex_getHexOfL_AtObj(a,b),e=_asnhex_getHexOfV_AtObj(a,b);return c+d+e}function _asnhex_getPosOfNextSibling_AtObj(a,b){var c=_asnhex_getStartPosOfV_AtObj(a,b),d=_asnhex_getIntOfL_AtObj(a,b);return c+2*d}
+function _asnhex_getPosArrayOfChildren_AtObj(a,b){var c=[],d=_asnhex_getStartPosOfV_AtObj(a,b);c.push(d);for(var e=_asnhex_getIntOfL_AtObj(a,b),f=d,g=0;;){f=_asnhex_getPosOfNextSibling_AtObj(a,f);if(null==f||f-d>=2*e)break;if(200<=g)break;c.push(f);g++}return c}function _asnhex_getNthChildIndex_AtObj(a,b,c){return _asnhex_getPosArrayOfChildren_AtObj(a,b)[c]}
+function _asnhex_getDecendantIndexByNthList(a,b,c){if(0==c.length)return b;var d=c.shift(),b=_asnhex_getPosArrayOfChildren_AtObj(a,b);return _asnhex_getDecendantIndexByNthList(a,b[d],c)}function _asnhex_getDecendantHexTLVByNthList(a,b,c){b=_asnhex_getDecendantIndexByNthList(a,b,c);return _asnhex_getHexOfTLV_AtObj(a,b)}function _asnhex_getDecendantHexVByNthList(a,b,c){b=_asnhex_getDecendantIndexByNthList(a,b,c);return _asnhex_getHexOfV_AtObj(a,b)}function ASN1HEX(){return ASN1HEX}
+ASN1HEX.getByteLengthOfL_AtObj=_asnhex_getByteLengthOfL_AtObj;ASN1HEX.getHexOfL_AtObj=_asnhex_getHexOfL_AtObj;ASN1HEX.getIntOfL_AtObj=_asnhex_getIntOfL_AtObj;ASN1HEX.getStartPosOfV_AtObj=_asnhex_getStartPosOfV_AtObj;ASN1HEX.getHexOfV_AtObj=_asnhex_getHexOfV_AtObj;ASN1HEX.getHexOfTLV_AtObj=_asnhex_getHexOfTLV_AtObj;ASN1HEX.getPosOfNextSibling_AtObj=_asnhex_getPosOfNextSibling_AtObj;ASN1HEX.getPosArrayOfChildren_AtObj=_asnhex_getPosArrayOfChildren_AtObj;ASN1HEX.getNthChildIndex_AtObj=_asnhex_getNthChildIndex_AtObj;
+ASN1HEX.getDecendantIndexByNthList=_asnhex_getDecendantIndexByNthList;ASN1HEX.getDecendantHexVByNthList=_asnhex_getDecendantHexVByNthList;ASN1HEX.getDecendantHexTLVByNthList=_asnhex_getDecendantHexTLVByNthList;var dbits,canary=0xdeadbeefcafe,j_lm=15715070==(canary&16777215);function BigInteger(a,b,c){null!=a&&("number"==typeof a?this.fromNumber(a,b,c):null==b&&"string"!=typeof a?this.fromString(a,256):this.fromString(a,b))}function nbi(){return new BigInteger(null)}
+function am1(a,b,c,d,e,f){for(;0<=--f;){var g=b*this[a++]+c[d]+e,e=Math.floor(g/67108864);c[d++]=g&67108863}return e}function am2(a,b,c,d,e,f){for(var g=b&32767,b=b>>15;0<=--f;){var h=this[a]&32767,j=this[a++]>>15,l=b*h+j*g,h=g*h+((l&32767)<<15)+c[d]+(e&1073741823),e=(h>>>30)+(l>>>15)+b*j+(e>>>30);c[d++]=h&1073741823}return e}
+function am3(a,b,c,d,e,f){for(var g=b&16383,b=b>>14;0<=--f;){var h=this[a]&16383,j=this[a++]>>14,l=b*h+j*g,h=g*h+((l&16383)<<14)+c[d]+e,e=(h>>28)+(l>>14)+b*j;c[d++]=h&268435455}return e}j_lm&&"Microsoft Internet Explorer"==navigator.appName?(BigInteger.prototype.am=am2,dbits=30):j_lm&&"Netscape"!=navigator.appName?(BigInteger.prototype.am=am1,dbits=26):(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",BI_RC=[],rr,vv;rr=48;for(vv=0;9>=vv;++vv)BI_RC[rr++]=vv;rr=97;for(vv=10;36>vv;++vv)BI_RC[rr++]=vv;rr=65;for(vv=10;36>vv;++vv)BI_RC[rr++]=vv;function int2char(a){return BI_RM.charAt(a)}function intAt(a,b){var c=BI_RC[a.charCodeAt(b)];return null==c?-1:c}
+function bnpCopyTo(a){for(var b=this.t-1;0<=b;--b)a[b]=this[b];a.t=this.t;a.s=this.s}function bnpFromInt(a){this.t=1;this.s=0>a?-1:0;0<a?this[0]=a:-1>a?this[0]=a+DV:this.t=0}function nbv(a){var b=nbi();b.fromInt(a);return b}
+function bnpFromString(a,b){var c;if(16==b)c=4;else if(8==b)c=3;else if(256==b)c=8;else if(2==b)c=1;else if(32==b)c=5;else if(4==b)c=2;else{this.fromRadix(a,b);return}this.s=this.t=0;for(var d=a.length,e=!1,f=0;0<=--d;){var g=8==c?a[d]&255:intAt(a,d);0>g?"-"==a.charAt(d)&&(e=!0):(e=!1,0==f?this[this.t++]=g:f+c>this.DB?(this[this.t-1]|=(g&(1<<this.DB-f)-1)<<f,this[this.t++]=g>>this.DB-f):this[this.t-1]|=g<<f,f+=c,f>=this.DB&&(f-=this.DB))}8==c&&0!=(a[0]&128)&&(this.s=-1,0<f&&(this[this.t-1]|=(1<<this.DB-
+f)-1<<f));this.clamp();e&&BigInteger.ZERO.subTo(this,this)}function bnpClamp(){for(var a=this.s&this.DM;0<this.t&&this[this.t-1]==a;)--this.t}
+function bnToString(a){if(0>this.s)return"-"+this.negate().toString(a);if(16==a)a=4;else if(8==a)a=3;else if(2==a)a=1;else if(32==a)a=5;else if(4==a)a=2;else return this.toRadix(a);var b=(1<<a)-1,c,d=!1,e="",f=this.t,g=this.DB-f*this.DB%a;if(0<f--){if(g<this.DB&&0<(c=this[f]>>g))d=!0,e=int2char(c);for(;0<=f;)g<a?(c=(this[f]&(1<<g)-1)<<a-g,c|=this[--f]>>(g+=this.DB-a)):(c=this[f]>>(g-=a)&b,0>=g&&(g+=this.DB,--f)),0<c&&(d=!0),d&&(e+=int2char(c))}return d?e:"0"}
+function bnNegate(){var a=nbi();BigInteger.ZERO.subTo(this,a);return a}function bnAbs(){return 0>this.s?this.negate():this}function bnCompareTo(a){var b=this.s-a.s;if(0!=b)return b;var c=this.t,b=c-a.t;if(0!=b)return b;for(;0<=--c;)if(0!=(b=this[c]-a[c]))return b;return 0}function nbits(a){var b=1,c;if(0!=(c=a>>>16))a=c,b+=16;if(0!=(c=a>>8))a=c,b+=8;if(0!=(c=a>>4))a=c,b+=4;if(0!=(c=a>>2))a=c,b+=2;0!=a>>1&&(b+=1);return b}
+function bnBitLength(){return 0>=this.t?0:this.DB*(this.t-1)+nbits(this[this.t-1]^this.s&this.DM)}function bnpDLShiftTo(a,b){var c;for(c=this.t-1;0<=c;--c)b[c+a]=this[c];for(c=a-1;0<=c;--c)b[c]=0;b.t=this.t+a;b.s=this.s}function bnpDRShiftTo(a,b){for(var c=a;c<this.t;++c)b[c-a]=this[c];b.t=Math.max(this.t-a,0);b.s=this.s}
+function bnpLShiftTo(a,b){var c=a%this.DB,d=this.DB-c,e=(1<<d)-1,f=Math.floor(a/this.DB),g=this.s<<c&this.DM,h;for(h=this.t-1;0<=h;--h)b[h+f+1]=this[h]>>d|g,g=(this[h]&e)<<c;for(h=f-1;0<=h;--h)b[h]=0;b[f]=g;b.t=this.t+f+1;b.s=this.s;b.clamp()}
+function bnpRShiftTo(a,b){b.s=this.s;var c=Math.floor(a/this.DB);if(c>=this.t)b.t=0;else{var d=a%this.DB,e=this.DB-d,f=(1<<d)-1;b[0]=this[c]>>d;for(var g=c+1;g<this.t;++g)b[g-c-1]|=(this[g]&f)<<e,b[g-c]=this[g]>>d;0<d&&(b[this.t-c-1]|=(this.s&f)<<e);b.t=this.t-c;b.clamp()}}
+function bnpSubTo(a,b){for(var c=0,d=0,e=Math.min(a.t,this.t);c<e;)d+=this[c]-a[c],b[c++]=d&this.DM,d>>=this.DB;if(a.t<this.t){for(d-=a.s;c<this.t;)d+=this[c],b[c++]=d&this.DM,d>>=this.DB;d+=this.s}else{for(d+=this.s;c<a.t;)d-=a[c],b[c++]=d&this.DM,d>>=this.DB;d-=a.s}b.s=0>d?-1:0;-1>d?b[c++]=this.DV+d:0<d&&(b[c++]=d);b.t=c;b.clamp()}
+function bnpMultiplyTo(a,b){var c=this.abs(),d=a.abs(),e=c.t;for(b.t=e+d.t;0<=--e;)b[e]=0;for(e=0;e<d.t;++e)b[e+c.t]=c.am(0,d[e],b,e,0,c.t);b.s=0;b.clamp();this.s!=a.s&&BigInteger.ZERO.subTo(b,b)}function bnpSquareTo(a){for(var b=this.abs(),c=a.t=2*b.t;0<=--c;)a[c]=0;for(c=0;c<b.t-1;++c){var d=b.am(c,b[c],a,2*c,0,1);if((a[c+b.t]+=b.am(c+1,2*b[c],a,2*c+1,d,b.t-c-1))>=b.DV)a[c+b.t]-=b.DV,a[c+b.t+1]=1}0<a.t&&(a[a.t-1]+=b.am(c,b[c],a,2*c,0,1));a.s=0;a.clamp()}
+function bnpDivRemTo(a,b,c){var d=a.abs();if(!(0>=d.t)){var e=this.abs();if(e.t<d.t)null!=b&&b.fromInt(0),null!=c&&this.copyTo(c);else{null==c&&(c=nbi());var f=nbi(),g=this.s,a=a.s,h=this.DB-nbits(d[d.t-1]);0<h?(d.lShiftTo(h,f),e.lShiftTo(h,c)):(d.copyTo(f),e.copyTo(c));d=f.t;e=f[d-1];if(0!=e){var j=e*(1<<this.F1)+(1<d?f[d-2]>>this.F2:0),l=this.FV/j,j=(1<<this.F1)/j,n=1<<this.F2,m=c.t,p=m-d,k=null==b?nbi():b;f.dlShiftTo(p,k);0<=c.compareTo(k)&&(c[c.t++]=1,c.subTo(k,c));BigInteger.ONE.dlShiftTo(d,
+k);for(k.subTo(f,f);f.t<d;)f[f.t++]=0;for(;0<=--p;){var q=c[--m]==e?this.DM:Math.floor(c[m]*l+(c[m-1]+n)*j);if((c[m]+=f.am(0,q,c,p,0,d))<q){f.dlShiftTo(p,k);for(c.subTo(k,c);c[m]<--q;)c.subTo(k,c)}}null!=b&&(c.drShiftTo(d,b),g!=a&&BigInteger.ZERO.subTo(b,b));c.t=d;c.clamp();0<h&&c.rShiftTo(h,c);0>g&&BigInteger.ZERO.subTo(c,c)}}}}function bnMod(a){var b=nbi();this.abs().divRemTo(a,null,b);0>this.s&&0<b.compareTo(BigInteger.ZERO)&&a.subTo(b,b);return b}function Classic(a){this.m=a}
+function cConvert(a){return 0>a.s||0<=a.compareTo(this.m)?a.mod(this.m):a}function cRevert(a){return a}function cReduce(a){a.divRemTo(this.m,null,a)}function cMulTo(a,b,c){a.multiplyTo(b,c);this.reduce(c)}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(1>this.t)return 0;var a=this[0];if(0==(a&1))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 0<b?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);0>a.s&&0<b.compareTo(BigInteger.ZERO)&&this.m.subTo(b,b);return b}function montRevert(a){var b=nbi();a.copyTo(b);this.reduce(b);return b}
+function montReduce(a){for(;a.t<=this.mt2;)a[a.t++]=0;for(var b=0;b<this.m.t;++b){var c=a[b]&32767,d=c*this.mpl+((c*this.mph+(a[b]>>15)*this.mpl&this.um)<<15)&a.DM,c=b+this.m.t;for(a[c]+=this.m.am(0,d,a,b,0,this.m.t);a[c]>=a.DV;)a[c]-=a.DV,a[++c]++}a.clamp();a.drShiftTo(this.m.t,a);0<=a.compareTo(this.m)&&a.subTo(this.m,a)}function montSqrTo(a,b){a.squareTo(b);this.reduce(b)}function montMulTo(a,b,c){a.multiplyTo(b,c);this.reduce(c)}Montgomery.prototype.convert=montConvert;
+Montgomery.prototype.revert=montRevert;Montgomery.prototype.reduce=montReduce;Montgomery.prototype.mulTo=montMulTo;Montgomery.prototype.sqrTo=montSqrTo;function bnpIsEven(){return 0==(0<this.t?this[0]&1:this.s)}function bnpExp(a,b){if(4294967295<a||1>a)return BigInteger.ONE;var c=nbi(),d=nbi(),e=b.convert(this),f=nbits(a)-1;for(e.copyTo(c);0<=--f;)if(b.sqrTo(c,d),0<(a&1<<f))b.mulTo(d,e,c);else var g=c,c=d,d=g;return b.revert(c)}
+function bnModPowInt(a,b){var c;c=256>a||b.isEven()?new Classic(b):new Montgomery(b);return this.exp(a,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(0>this.s){if(1==this.t)return this[0]-this.DV;if(0==this.t)return-1}else{if(1==this.t)return this[0];if(0==this.t)return 0}return(this[1]&(1<<32-this.DB)-1)<<this.DB|this[0]}function bnByteValue(){return 0==this.t?this.s:this[0]<<24>>24}function bnShortValue(){return 0==this.t?this.s:this[0]<<16>>16}function bnpChunkSize(a){return Math.floor(Math.LN2*this.DB/Math.log(a))}
+function bnSigNum(){return 0>this.s?-1:0>=this.t||1==this.t&&0>=this[0]?0:1}function bnpToRadix(a){null==a&&(a=10);if(0==this.signum()||2>a||36<a)return"0";var b=this.chunkSize(a),b=Math.pow(a,b),c=nbv(b),d=nbi(),e=nbi(),f="";for(this.divRemTo(c,d,e);0<d.signum();)f=(b+e.intValue()).toString(a).substr(1)+f,d.divRemTo(c,d,e);return e.intValue().toString(a)+f}
+function bnpFromRadix(a,b){this.fromInt(0);null==b&&(b=10);for(var c=this.chunkSize(b),d=Math.pow(b,c),e=!1,f=0,g=0,h=0;h<a.length;++h){var j=intAt(a,h);0>j?"-"==a.charAt(h)&&0==this.signum()&&(e=!0):(g=b*g+j,++f>=c&&(this.dMultiply(d),this.dAddOffset(g,0),g=f=0))}0<f&&(this.dMultiply(Math.pow(b,f)),this.dAddOffset(g,0));e&&BigInteger.ZERO.subTo(this,this)}
+function bnpFromNumber(a,b,c){if("number"==typeof b)if(2>a)this.fromInt(1);else{this.fromNumber(a,c);this.testBit(a-1)||this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);for(this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(b);)this.dAddOffset(2,0),this.bitLength()>a&&this.subTo(BigInteger.ONE.shiftLeft(a-1),this)}else{var c=[],d=a&7;c.length=(a>>3)+1;b.nextBytes(c);c[0]=0<d?c[0]&(1<<d)-1:0;this.fromString(c,256)}}
+function bnToByteArray(){var a=this.t,b=[];b[0]=this.s;var c=this.DB-a*this.DB%8,d,e=0;if(0<a--){if(c<this.DB&&(d=this[a]>>c)!=(this.s&this.DM)>>c)b[e++]=d|this.s<<this.DB-c;for(;0<=a;)if(8>c?(d=(this[a]&(1<<c)-1)<<8-c,d|=this[--a]>>(c+=this.DB-8)):(d=this[a]>>(c-=8)&255,0>=c&&(c+=this.DB,--a)),0!=(d&128)&&(d|=-256),0==e&&(this.s&128)!=(d&128)&&++e,0<e||d!=this.s)b[e++]=d}return b}function bnEquals(a){return 0==this.compareTo(a)}function bnMin(a){return 0>this.compareTo(a)?this:a}
+function bnMax(a){return 0<this.compareTo(a)?this:a}function bnpBitwiseTo(a,b,c){var d,e,f=Math.min(a.t,this.t);for(d=0;d<f;++d)c[d]=b(this[d],a[d]);if(a.t<this.t){e=a.s&this.DM;for(d=f;d<this.t;++d)c[d]=b(this[d],e);c.t=this.t}else{e=this.s&this.DM;for(d=f;d<a.t;++d)c[d]=b(e,a[d]);c.t=a.t}c.s=b(this.s,a.s);c.clamp()}function op_and(a,b){return a&b}function bnAnd(a){var b=nbi();this.bitwiseTo(a,op_and,b);return b}function op_or(a,b){return a|b}
+function bnOr(a){var b=nbi();this.bitwiseTo(a,op_or,b);return b}function op_xor(a,b){return a^b}function bnXor(a){var b=nbi();this.bitwiseTo(a,op_xor,b);return b}function op_andnot(a,b){return a&~b}function bnAndNot(a){var b=nbi();this.bitwiseTo(a,op_andnot,b);return b}function bnNot(){for(var a=nbi(),b=0;b<this.t;++b)a[b]=this.DM&~this[b];a.t=this.t;a.s=~this.s;return a}function bnShiftLeft(a){var b=nbi();0>a?this.rShiftTo(-a,b):this.lShiftTo(a,b);return b}
+function bnShiftRight(a){var b=nbi();0>a?this.lShiftTo(-a,b):this.rShiftTo(a,b);return b}function lbit(a){if(0==a)return-1;var b=0;0==(a&65535)&&(a>>=16,b+=16);0==(a&255)&&(a>>=8,b+=8);0==(a&15)&&(a>>=4,b+=4);0==(a&3)&&(a>>=2,b+=2);0==(a&1)&&++b;return b}function bnGetLowestSetBit(){for(var a=0;a<this.t;++a)if(0!=this[a])return a*this.DB+lbit(this[a]);return 0>this.s?this.t*this.DB:-1}function cbit(a){for(var b=0;0!=a;)a&=a-1,++b;return b}
+function bnBitCount(){for(var a=0,b=this.s&this.DM,c=0;c<this.t;++c)a+=cbit(this[c]^b);return a}function bnTestBit(a){var b=Math.floor(a/this.DB);return b>=this.t?0!=this.s:0!=(this[b]&1<<a%this.DB)}function bnpChangeBit(a,b){var c=BigInteger.ONE.shiftLeft(a);this.bitwiseTo(c,b,c);return c}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(a,b){for(var c=0,d=0,e=Math.min(a.t,this.t);c<e;)d+=this[c]+a[c],b[c++]=d&this.DM,d>>=this.DB;if(a.t<this.t){for(d+=a.s;c<this.t;)d+=this[c],b[c++]=d&this.DM,d>>=this.DB;d+=this.s}else{for(d+=this.s;c<a.t;)d+=a[c],b[c++]=d&this.DM,d>>=this.DB;d+=a.s}b.s=0>d?-1:0;0<d?b[c++]=d:-1>d&&(b[c++]=this.DV+d);b.t=c;b.clamp()}function bnAdd(a){var b=nbi();this.addTo(a,b);return b}function bnSubtract(a){var b=nbi();this.subTo(a,b);return b}
+function bnMultiply(a){var b=nbi();this.multiplyTo(a,b);return b}function bnDivide(a){var b=nbi();this.divRemTo(a,b,null);return b}function bnRemainder(a){var b=nbi();this.divRemTo(a,null,b);return b}function bnDivideAndRemainder(a){var b=nbi(),c=nbi();this.divRemTo(a,b,c);return[b,c]}function bnpDMultiply(a){this[this.t]=this.am(0,a-1,this,0,0,this.t);++this.t;this.clamp()}
+function bnpDAddOffset(a,b){if(0!=a){for(;this.t<=b;)this[this.t++]=0;for(this[b]+=a;this[b]>=this.DV;)this[b]-=this.DV,++b>=this.t&&(this[this.t++]=0),++this[b]}}function NullExp(){}function nNop(a){return a}function nMulTo(a,b,c){a.multiplyTo(b,c)}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(a,b,c){var d=Math.min(this.t+a.t,b);c.s=0;for(c.t=d;0<d;)c[--d]=0;var e;for(e=c.t-this.t;d<e;++d)c[d+this.t]=this.am(0,a[d],c,d,0,this.t);for(e=Math.min(a.t,b);d<e;++d)this.am(0,a[d],c,d,0,b-d);c.clamp()}function bnpMultiplyUpperTo(a,b,c){--b;var d=c.t=this.t+a.t-b;for(c.s=0;0<=--d;)c[d]=0;for(d=Math.max(b-this.t,0);d<a.t;++d)c[this.t+d-b]=this.am(b-d,a[d],c,0,0,this.t+d-b);c.clamp();c.drShiftTo(1,c)}
+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(0>a.s||a.t>2*this.m.t)return a.mod(this.m);if(0>a.compareTo(this.m))return a;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);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);for(this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);0>a.compareTo(this.r2);)a.dAddOffset(1,this.m.t+1);for(a.subTo(this.r2,a);0<=a.compareTo(this.m);)a.subTo(this.m,a)}function barrettSqrTo(a,b){a.squareTo(b);this.reduce(b)}function barrettMulTo(a,b,c){a.multiplyTo(b,c);this.reduce(c)}Barrett.prototype.convert=barrettConvert;
+Barrett.prototype.revert=barrettRevert;Barrett.prototype.reduce=barrettReduce;Barrett.prototype.mulTo=barrettMulTo;Barrett.prototype.sqrTo=barrettSqrTo;
+function bnModPow(a,b){var c=a.bitLength(),d,e=nbv(1),f;if(0>=c)return e;d=18>c?1:48>c?3:144>c?4:768>c?5:6;f=8>c?new Classic(b):b.isEven()?new Barrett(b):new Montgomery(b);var g=[],h=3,j=d-1,l=(1<<d)-1;g[1]=f.convert(this);if(1<d){c=nbi();for(f.sqrTo(g[1],c);h<=l;)g[h]=nbi(),f.mulTo(c,g[h-2],g[h]),h+=2}for(var n=a.t-1,m,p=!0,k=nbi(),c=nbits(a[n])-1;0<=n;){c>=j?m=a[n]>>c-j&l:(m=(a[n]&(1<<c+1)-1)<<j-c,0<n&&(m|=a[n-1]>>this.DB+c-j));for(h=d;0==(m&1);)m>>=1,--h;if(0>(c-=h))c+=this.DB,--n;if(p)g[m].copyTo(e),
+p=!1;else{for(;1<h;)f.sqrTo(e,k),f.sqrTo(k,e),h-=2;0<h?f.sqrTo(e,k):(h=e,e=k,k=h);f.mulTo(k,g[m],e)}for(;0<=n&&0==(a[n]&1<<c);)f.sqrTo(e,k),h=e,e=k,k=h,0>--c&&(c=this.DB-1,--n)}return f.revert(e)}
+function bnGCD(a){var b=0>this.s?this.negate():this.clone(),a=0>a.s?a.negate():a.clone();if(0>b.compareTo(a))var c=b,b=a,a=c;var c=b.getLowestSetBit(),d=a.getLowestSetBit();if(0>d)return b;c<d&&(d=c);0<d&&(b.rShiftTo(d,b),a.rShiftTo(d,a));for(;0<b.signum();)0<(c=b.getLowestSetBit())&&b.rShiftTo(c,b),0<(c=a.getLowestSetBit())&&a.rShiftTo(c,a),0<=b.compareTo(a)?(b.subTo(a,b),b.rShiftTo(1,b)):(a.subTo(b,a),a.rShiftTo(1,a));0<d&&a.lShiftTo(d,a);return a}
+function bnpModInt(a){if(0>=a)return 0;var b=this.DV%a,c=0>this.s?a-1:0;if(0<this.t)if(0==b)c=this[0]%a;else for(var d=this.t-1;0<=d;--d)c=(b*c+this[d])%a;return c}
+function bnModInverse(a){var b=a.isEven();if(this.isEven()&&b||0==a.signum())return BigInteger.ZERO;for(var c=a.clone(),d=this.clone(),e=nbv(1),f=nbv(0),g=nbv(0),h=nbv(1);0!=c.signum();){for(;c.isEven();){c.rShiftTo(1,c);if(b){if(!e.isEven()||!f.isEven())e.addTo(this,e),f.subTo(a,f);e.rShiftTo(1,e)}else f.isEven()||f.subTo(a,f);f.rShiftTo(1,f)}for(;d.isEven();){d.rShiftTo(1,d);if(b){if(!g.isEven()||!h.isEven())g.addTo(this,g),h.subTo(a,h);g.rShiftTo(1,g)}else h.isEven()||h.subTo(a,h);h.rShiftTo(1,
+h)}0<=c.compareTo(d)?(c.subTo(d,c),b&&e.subTo(g,e),f.subTo(h,f)):(d.subTo(c,d),b&&g.subTo(e,g),h.subTo(f,h))}if(0!=d.compareTo(BigInteger.ONE))return BigInteger.ZERO;if(0<=h.compareTo(a))return h.subtract(a);if(0>h.signum())h.addTo(a,h);else return h;return 0>h.signum()?h.add(a):h}
+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],lplim=67108864/lowprimes[lowprimes.length-1];
+function bnIsProbablePrime(a){var b,c=this.abs();if(1==c.t&&c[0]<=lowprimes[lowprimes.length-1]){for(b=0;b<lowprimes.length;++b)if(c[0]==lowprimes[b])return!0;return!1}if(c.isEven())return!1;for(b=1;b<lowprimes.length;){for(var d=lowprimes[b],e=b+1;e<lowprimes.length&&d<lplim;)d*=lowprimes[e++];for(d=c.modInt(d);b<e;)if(0==d%lowprimes[b++])return!1}return c.millerRabin(a)}
+function bnpMillerRabin(a){var b=this.subtract(BigInteger.ONE),c=b.getLowestSetBit();if(0>=c)return!1;var d=b.shiftRight(c),a=a+1>>1;a>lowprimes.length&&(a=lowprimes.length);for(var e=nbi(),f=0;f<a;++f){e.fromInt(lowprimes[f]);var g=e.modPow(d,this);if(0!=g.compareTo(BigInteger.ONE)&&0!=g.compareTo(b)){for(var h=1;h++<c&&0!=g.compareTo(b);)if(g=g.modPowInt(2,this),0==g.compareTo(BigInteger.ONE))return!1;if(0!=g.compareTo(b))return!1}}return!0}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;
+/** 
  * @author: Jeff Thompson
  * See COPYING for copyright and distribution information.
  * Implement getAsync and putAsync used by NDN using nsISocketTransportService.
@@ -270,3653 +380,6 @@
 }
 
 /*
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class contains all CCNx tags
- */
-
-
-var CCNProtocolDTags = {
-
-	/**
-	 * Note if you add one of these, add it to the reverse string map as well.
-	 * Emphasize getting the work done at compile time over trying to make something
-	 * flexible and developer error-proof.
-	 */
-
-	 Any : 13,
-	 Name : 14,
-	 Component : 15,
-	 Certificate : 16,
-	 Collection : 17,
-	 CompleteName : 18,
-	 Content : 19,
-	 SignedInfo : 20,
-	 ContentDigest : 21,
-	 ContentHash : 22,
-	 Count : 24,
-	 Header : 25,
-	 Interest : 26,	/* 20090915 */
-	 Key : 27,
-	 KeyLocator : 28,
-	 KeyName : 29,
-	 Length : 30,
-	 Link : 31,
-	 LinkAuthenticator : 32,
-	 NameComponentCount : 33,	/* DeprecatedInInterest */
-	 RootDigest : 36,
-	 Signature : 37,
-	 Start : 38,
-	 Timestamp : 39,
-	 Type : 40,
-	 Nonce : 41,
-	 Scope : 42,
-	 Exclude : 43,
-	 Bloom : 44,
-	 BloomSeed : 45,
-	 AnswerOriginKind : 47,
-	 InterestLifetime : 48,
-	 Witness : 53,
-	 SignatureBits : 54,
-	 DigestAlgorithm : 55,
-	 BlockSize : 56,
-	 FreshnessSeconds : 58,
-	 FinalBlockID : 59,
-	 PublisherPublicKeyDigest : 60,
-	 PublisherCertificateDigest : 61,
-	 PublisherIssuerKeyDigest : 62,
-	 PublisherIssuerCertificateDigest : 63,
-	 ContentObject : 64,	/* 20090915 */
-	 WrappedKey : 65,
-	 WrappingKeyIdentifier : 66,
-	 WrapAlgorithm : 67,
-	 KeyAlgorithm : 68,
-	 Label : 69,
-	 EncryptedKey : 70,
-	 EncryptedNonceKey : 71,
-	 WrappingKeyName : 72,
-	 Action : 73,
-	 FaceID : 74,
-	 IPProto : 75,
-	 Host : 76,
-	 Port : 77,
-	 MulticastInterface : 78,
-	 ForwardingFlags : 79,
-	 FaceInstance : 80,
-	 ForwardingEntry : 81,
-	 MulticastTTL : 82,
-	 MinSuffixComponents : 83,
-	 MaxSuffixComponents : 84,
-	 ChildSelector : 85,
-	 RepositoryInfo : 86,
-	 Version : 87,
-	 RepositoryVersion : 88,
-	 GlobalPrefix : 89,
-	 LocalName : 90,
-	 Policy : 91,
-	 Namespace : 92,
-	 GlobalPrefixName : 93,
-	 PolicyVersion : 94,
-	 KeyValueSet : 95,
-	 KeyValuePair : 96,
-	 IntegerValue : 97,
-	 DecimalValue : 98,
-	 StringValue : 99,
-	 BinaryValue : 100,
-	 NameValue : 101,
-	 Entry : 102,
-	 ACL : 103,
-	 ParameterizedName : 104,
-	 Prefix : 105,
-	 Suffix : 106,
-	 Root : 107,
-	 ProfileName : 108,
-	 Parameters : 109,
-	 InfoString : 110,
-	// 111 unallocated
-	 StatusResponse : 112,
-	 StatusCode : 113,
-	 StatusText : 114,
-
-	// Sync protocol
-	 SyncNode : 115,
-	 SyncNodeKind : 116,
-	 SyncNodeElement : 117,
-	 SyncVersion : 118,
-	 SyncNodeElements : 119,
-	 SyncContentHash : 120,
-	 SyncLeafCount : 121,
-	 SyncTreeDepth : 122,
-	 SyncByteCount : 123,
-	 ConfigSlice : 124,
-	 ConfigSliceList : 125,
-	 ConfigSliceOp : 126,
-
-	// Remember to keep in sync with schema/tagnames.csvsdict
-	 CCNProtocolDataUnit : 17702112,
-	 CCNPROTOCOL_DATA_UNIT : "CCNProtocolDataUnit"
-};
-
-var CCNProtocolDTagsStrings = [
-	null, null, null, null, null, null, null, null, null, null, null,
-	null, null,
-	"Any", "Name", "Component", "Certificate", "Collection", "CompleteName",
-	"Content", "SignedInfo", "ContentDigest", "ContentHash", null, "Count", "Header",
-	"Interest", "Key", "KeyLocator", "KeyName", "Length", "Link", "LinkAuthenticator",
-	"NameComponentCount", null, null, "RootDigest", "Signature", "Start", "Timestamp", "Type",
-	"Nonce", "Scope", "Exclude", "Bloom", "BloomSeed", null, "AnswerOriginKind",
-	"InterestLifetime", null, null, null, null, "Witness", "SignatureBits", "DigestAlgorithm", "BlockSize",
-	null, "FreshnessSeconds", "FinalBlockID", "PublisherPublicKeyDigest", "PublisherCertificateDigest",
-	"PublisherIssuerKeyDigest", "PublisherIssuerCertificateDigest", "ContentObject",
-	"WrappedKey", "WrappingKeyIdentifier", "WrapAlgorithm", "KeyAlgorithm", "Label",
-	"EncryptedKey", "EncryptedNonceKey", "WrappingKeyName", "Action", "FaceID", "IPProto",
-	"Host", "Port", "MulticastInterface", "ForwardingFlags", "FaceInstance",
-	"ForwardingEntry", "MulticastTTL", "MinSuffixComponents", "MaxSuffixComponents", "ChildSelector",
-	"RepositoryInfo", "Version", "RepositoryVersion", "GlobalPrefix", "LocalName",
-	"Policy", "Namespace", "GlobalPrefixName", "PolicyVersion", "KeyValueSet", "KeyValuePair",
-	"IntegerValue", "DecimalValue", "StringValue", "BinaryValue", "NameValue", "Entry",
-	"ACL", "ParameterizedName", "Prefix", "Suffix", "Root", "ProfileName", "Parameters",
-	"InfoString", null,
-    "StatusResponse", "StatusCode", "StatusText", "SyncNode", "SyncNodeKind", "SyncNodeElement",
-    "SyncVersion", "SyncNodeElements", "SyncContentHash", "SyncLeafCount", "SyncTreeDepth", "SyncByteCount",
-    "ConfigSlice", "ConfigSliceList", "ConfigSliceOp" ];
-
-
-//TESTING
-//console.log(exports.CCNProtocolDTagsStrings[17]);
-
-/*
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class represents CCNTime Objects
- */
-
-var CCNTime = function CCNTime(
-                               
-		input) {
-
-
-
-
-	this.NANOS_MAX = 999877929;
-	
-	/*if(typeof input =='object'){
-		this.longDate = DataUtils.byteArrayToUnsignedLong(input);
-		this.binaryDate = input;
-	}*/
-	if(typeof input =='number'){
-		this.msec = input;
-		//this.binaryDate = DataUtils.unsignedLongToByteArray(input);
-
-	}
-	else{
-		if(LOG>1) console.log('UNRECOGNIZED TYPE FOR TIME');
-	}
-};
-
-
-CCNTime.prototype.getJavascriptDate = function(){
-	var d = new Date();
-	d.setTime( this.msec );
-	return d
-};
-
-	/**
-	 * Create a CCNTime
-	 * @param timestamp source timestamp to initialize from, some precision will be lost
-	 */
-
-
-	/**
-	 * Create a CCNTime from its binary encoding
-	 * @param binaryTime12 the binary representation of a CCNTime
-	 */
-/*CCNTime.prototype.setDateBinary = function(
-	//byte [] 
-		binaryTime12) {
-
-
-	if ((null == binaryTime12) || (binaryTime12.length == 0)) {
-		throw new IllegalArgumentException("Invalid binary time!");
-	}
-	
-
-	value = 0;
-	for(i = 0; i < binaryTime12.length; i++) {
-		value = value << 8;
-		b = (binaryTime12[i]) & 0xFF;
-		value |= b;
-	}
-
-	//this.date = new Date(value);
-
-};
-
-//byte[]
-CCNTime.prototype.toBinaryTime = function() {
-
-	return this.msec; //unsignedLongToByteArray(this.date.getTime());
-
-}*/
-/*
-unsignedLongToByteArray= function( value) {
-	if( 0 == value )
-		return [0];
-
-	if( 0 <= value && value <= 0x00FF ) {
-		//byte [] 
-		bb = new Array[1];
-		bb[0] = (value & 0x00FF);
-		return bb;
-	}
-
-	
-	//byte [] 
-	out = null;
-	//int
-	offset = -1;
-	for(var i = 7; i >=0; --i) {
-		//byte
-		b = ((value >> (i * 8)) & 0xFF);
-		if( out == null && b != 0 ) {
-			out = new Array(i+1);//byte[i+1];
-			offset = i;
-		}
-		if( out != null )
-			out[ offset - i ] = b;
-	}
-	return out;
-}*/
-	
-/*
- * @author: Meki Cheraoui, Jeff Thompson
- * See COPYING for copyright and distribution information.
- * This class represents a Name as an array of components where each is a byte array.
- */
- 
-/*
- * Create a new Name from _components.
- * If _components is a string, parse it as a URI.  Otherwise it is an array of components
- * where each is a string, byte array, ArrayBuffer or Uint8Array. 
- * Convert and store as an array of Uint8Array.
- * If a component is a string, encode as utf8.
- */
-var Name = function Name(_components){
-	if( typeof _components == 'string') {		
-		if(LOG>3)console.log('Content Name String '+_components);
-		this.components = Name.createNameArray(_components);
-	}
-	else if(typeof _components === 'object'){		
-		if(LOG>4)console.log('Content Name Array '+_components);
-		this.components = [];
-        for (var i = 0; i < _components.length; ++i)
-            this.add(_components[i]);
-	}
-	else if(_components==null)
-		this.components =[];
-	else
-		if(LOG>1)console.log("NO CONTENT NAME GIVEN");
-};
-
-Name.prototype.getName = function() {
-    return this.to_uri();
-};
-
-/* Parse name as a URI and return an array of Uint8Array components.
- *
- */
-Name.createNameArray = function(name) {
-    name = name.trim();
-    if (name.length <= 0)
-        return [];
-
-    var iColon = name.indexOf(':');
-    if (iColon >= 0) {
-        // Make sure the colon came before a '/'.
-        var iFirstSlash = name.indexOf('/');
-        if (iFirstSlash < 0 || iColon < iFirstSlash)
-            // Omit the leading protocol such as ndn:
-            name = name.substr(iColon + 1, name.length - iColon - 1).trim();
-    }
-    
-  	if (name[0] == '/') {
-        if (name.length >= 2 && name[1] == '/') {
-            // Strip the authority following "//".
-            var iAfterAuthority = name.indexOf('/', 2);
-            if (iAfterAuthority < 0)
-                // Unusual case: there was only an authority.
-                return [];
-            else
-                name = name.substr(iAfterAuthority + 1, name.length - iAfterAuthority - 1).trim();
-        }
-        else
-            name = name.substr(1, name.length - 1).trim();
-    }
-
-	var array = name.split('/');
-    
-    // Unescape the components.
-    for (var i = 0; i < array.length; ++i) {
-        var component = unescape(array[i].trim());
-        
-        if (component.match(/[^.]/) == null) {
-            // Special case for component of only periods.  
-            if (component.length <= 2) {
-                // Zero, one or two periods is illegal.  Ignore this componenent to be
-                //   consistent with the C implmentation.
-                // This also gets rid of a trailing '/'.
-                array.splice(i, 1);
-                --i;  
-                continue;
-            }
-            else
-                // Remove 3 periods.
-                array[i] = component.substr(3, component.length - 3);
-        }
-        else
-            array[i] = component;
-        
-        // Change the component to Uint8Array now.
-        array[i] = DataUtils.toNumbersFromString(array[i]);
-    }
-
-	return array;
-}
-
-
-Name.prototype.from_ccnb = function(/*XMLDecoder*/ decoder)  {
-		decoder.readStartElement(this.getElementLabel());
-
-		
-		this.components = new Array(); //new ArrayList<byte []>();
-
-		while (decoder.peekStartElement(CCNProtocolDTags.Component)) {
-			this.add(decoder.readBinaryElement(CCNProtocolDTags.Component));
-		}
-		
-		decoder.readEndElement();
-};
-
-Name.prototype.to_ccnb = function(/*XMLEncoder*/ encoder)  {
-		
-		if( this.components ==null ) 
-			throw new Error("CANNOT ENCODE EMPTY CONTENT NAME");
-
-		encoder.writeStartElement(this.getElementLabel());
-		var count = this.components.length;
-		for (var i=0; i < count; i++) {
-			encoder.writeElement(CCNProtocolDTags.Component, this.components[i]);
-		}
-		encoder.writeEndElement();
-};
-
-Name.prototype.getElementLabel = function(){
-	return CCNProtocolDTags.Name;
-};
-
-/*
- * component is a string, byte array, ArrayBuffer or Uint8Array.
- * Convert to Uint8Array and add to this Name.
- * If a component is a string, encode as utf8.
- * Return the converted value.
- */
-Name.prototype.add = function(component){
-    var result;
-    if(typeof component == 'string')
-        result = DataUtils.stringToUtf8Array(component);
-	else if(typeof component == 'object' && component instanceof Uint8Array)
-        result = new Uint8Array(component);
-	else if(typeof component == 'object' && component instanceof ArrayBuffer) {
-        // Make a copy.  Don't use ArrayBuffer.slice since it isn't always supported.
-        result = new Uint8Array(new ArrayBuffer(component.byteLength));
-        result.set(new Uint8Array(component));
-    }
-	else if(typeof component == 'object')
-        // Assume component is a byte array.  We can't check instanceof Array because
-        //   this doesn't work in JavaScript if the array comes from a different module.
-        result = new Uint8Array(component);
-	else 
-		throw new Error("Cannot add Name element at index " + this.components.length + 
-            ": Invalid type");
-    
-	return this.components.push(result);
-};
-
-// Return the escaped name string according to "CCNx URI Scheme".
-Name.prototype.to_uri = function() {	
-	var result = "";
-	
-	for(var i = 0; i < this.components.length; ++i)
-		result += "/"+ Name.toEscapedString(this.components[i]);
-	
-	return result;	
-};
-
-/*
- * Return a new Name with the first nComponents components of this Name.
- */
-Name.prototype.getPrefix = function(nComponents) {
-    return new Name(this.components.slice(0, nComponents));
-}
-
-/*
- * Return a new ArrayBuffer of the component at i.
- */
-Name.prototype.getComponent = function(i) {
-    var result = new ArrayBuffer(this.components[i].length);
-    new Uint8Array(result).set(this.components[i]);
-    return result;
-}
-
-/*
- * The "file name" in a name is the last component that isn't blank and doesn't start with one of the
- *   special marker octets (for version, etc.).  Return the index in this.components of
- *   the file name, or -1 if not found.
- */
-Name.prototype.indexOfFileName = function() {
-    for (var i = this.components.length - 1; i >= 0; --i) {
-        var component = this.components[i];
-        if (component.length <= 0)
-            continue;
-        
-        if (component[0] == 0 || component[0] == 0xC0 || component[0] == 0xC1 || 
-            (component[0] >= 0xF5 && component[0] <= 0xFF))
-            continue;
-        
-        return i;
-    }
-    
-    return -1;
-}
-
-/*
- * Find the last component in name that has a ContentDigest and return the digest value as Uint8Array, 
- *   or null if not found.
- * A ContentDigest component is Name.ContentDigestPrefix + 32 bytes + Name.ContentDigestSuffix.
- */
-Name.prototype.getContentDigestValue = function() {
-    var digestComponentLength = Name.ContentDigestPrefix.length + 32 + Name.ContentDigestSuffix.length; 
-    for (var i = this.components.length - 1; i >= 0; --i) {
-        // Check for the correct length and equal ContentDigestPrefix and ContentDigestSuffix.
-        if (this.components[i].length == digestComponentLength &&
-            DataUtils.arraysEqual(this.components[i].subarray(0, Name.ContentDigestPrefix.length), 
-                                  Name.ContentDigestPrefix) &&
-            DataUtils.arraysEqual(this.components[i].subarray
-               (this.components[i].length - Name.ContentDigestSuffix.length, this.components[i].length),
-                                  Name.ContentDigestSuffix))
-           return this.components[i].subarray
-               (Name.ContentDigestPrefix.length, Name.ContentDigestPrefix.length + 32);
-    }
-    
-    return null;
-}
-
-// Meta GUID "%C1.M.G%C1" + ContentDigest with a 32 byte BLOB. 
-Name.ContentDigestPrefix = new Uint8Array([0xc1, 0x2e, 0x4d, 0x2e, 0x47, 0xc1, 0x01, 0xaa, 0x02, 0x85]);
-Name.ContentDigestSuffix = new Uint8Array([0x00]);
-
-/**
- * Return component as an escaped string according to "CCNx URI Scheme".
- * We can't use encodeURIComponent because that doesn't encode all the characters we want to.
- */
-Name.toEscapedString = function(component) {
-    var result = "";
-    var gotNonDot = false;
-    for (var i = 0; i < component.length; ++i) {
-        if (component[i] != 0x2e) {
-            gotNonDot = true;
-            break;
-        }
-    }
-    if (!gotNonDot) {
-        // Special case for component of zero or more periods.  Add 3 periods.
-        result = "...";
-        for (var i = 0; i < component.length; ++i)
-            result += ".";
-    }
-    else {
-        for (var i = 0; i < component.length; ++i) {
-            var value = component[i];
-            // Check for 0-9, A-Z, a-z, (+), (-), (.), (_)
-            if (value >= 0x30 && value <= 0x39 || value >= 0x41 && value <= 0x5a ||
-                value >= 0x61 && value <= 0x7a || value == 0x2b || value == 0x2d || 
-                value == 0x2e || value == 0x5f)
-                result += String.fromCharCode(value);
-            else
-                result += "%" + (value < 16 ? "0" : "") + value.toString(16).toUpperCase();
-        }
-    }
-    return result;
-};
-/*
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class represents ContentObject Objects
- */
-var ContentObject = function ContentObject(_name,_signedInfo,_content,_signature){
-	
-	
-	if (typeof _name === 'string'){
-		this.name = new Name(_name);
-	}
-	else{
-		//TODO Check the class of _name
-		this.name = _name;
-	}
-	this.signedInfo = _signedInfo;
-	this.content=_content;
-	this.signature = _signature;
-
-	
-	this.startSIG = null;
-	this.endSIG = null;
-	
-	this.startSignedInfo = null;
-	this.endContent = null;
-	
-	this.rawSignatureData = null;
-};
-
-ContentObject.prototype.sign = function(){
-
-	var n1 = this.encodeObject(this.name);
-	var n2 = this.encodeObject(this.signedInfo);
-	var n3 = this.encodeContent();
-	/*console.log('sign: ');
-	console.log(n1);
-	console.log(n2);
-	console.log(n3);*/
-	
-	//var n = n1.concat(n2,n3);
-	var tempBuf = new ArrayBuffer(n1.length + n2.length + n3.length);
-	var n = new Uint8Array(tempBuf);
-	//console.log(n);
-	n.set(n1, 0);
-	//console.log(n);
-	n.set(n2, n1.length);
-	//console.log(n);
-	n.set(n3, n1.length + n2.length);
-	//console.log(n);
-	
-	if(LOG>4)console.log('Signature Data is (binary) '+n);
-	
-	if(LOG>4)console.log('Signature Data is (RawString)');
-	
-	if(LOG>4)console.log( DataUtils.toString(n) );
-	
-	//var sig = DataUtils.toString(n);
-
-	
-	var rsa = new RSAKey();
-			
-	rsa.readPrivateKeyFromPEMString(globalKeyManager.privateKey);
-	
-	//var hSig = rsa.signString(sig, "sha256");
-
-	var hSig = rsa.signByteArrayWithSHA256(n);
-
-	
-	if(LOG>4)console.log('SIGNATURE SAVED IS');
-	
-	if(LOG>4)console.log(hSig);
-	
-	if(LOG>4)console.log(  DataUtils.toNumbers(hSig.trim()));
-
-	this.signature.signature = DataUtils.toNumbers(hSig.trim());
-	
-
-};
-
-ContentObject.prototype.encodeObject = function encodeObject(obj){
-	var enc = new BinaryXMLEncoder();
- 
-	obj.to_ccnb(enc);
-	
-	var num = enc.getReducedOstream();
-
-	return num;
-
-	
-};
-
-ContentObject.prototype.encodeContent = function encodeContent(obj){
-	var enc = new BinaryXMLEncoder();
-	 
-	enc.writeElement(CCNProtocolDTags.Content, this.content);
-
-	var num = enc.getReducedOstream();
-
-	return num;
-
-	
-};
-
-ContentObject.prototype.saveRawData = function(bytes){
-	
-	var sigBits = bytes.subarray(this.startSIG, this.endSIG);
-
-	this.rawSignatureData = sigBits;
-};
-
-ContentObject.prototype.from_ccnb = function(/*XMLDecoder*/ decoder) {
-
-	// TODO VALIDATE THAT ALL FIELDS EXCEPT SIGNATURE ARE PRESENT
-
-		decoder.readStartElement(this.getElementLabel());
-
-
-		if( decoder.peekStartElement(CCNProtocolDTags.Signature) ){
-			this.signature = new Signature();
-			this.signature.from_ccnb(decoder);
-		}
-		
-		//this.endSIG = decoder.offset;
-
-		this.startSIG = decoder.offset;
-
-		this.name = new Name();
-		this.name.from_ccnb(decoder);
-		
-		//this.startSignedInfo = decoder.offset;
-	
-		
-		if( decoder.peekStartElement(CCNProtocolDTags.SignedInfo) ){
-			this.signedInfo = new SignedInfo();
-			this.signedInfo.from_ccnb(decoder);
-		}
-		
-		this.content = decoder.readBinaryElement(CCNProtocolDTags.Content);
-
-		
-		//this.endContent = decoder.offset;
-		this.endSIG = decoder.offset;
-
-		
-		decoder.readEndElement();
-		
-		this.saveRawData(decoder.istream);
-};
-
-ContentObject.prototype.to_ccnb = function(/*XMLEncoder*/ encoder)  {
-
-	//TODO verify name, SignedInfo and Signature is present
-
-
-	encoder.writeStartElement(this.getElementLabel());
-
-	
-
-
-	if(null!=this.signature) this.signature.to_ccnb(encoder);
-	
-	
-	this.startSIG = encoder.offset;
-	
-
-	if(null!=this.name) this.name.to_ccnb(encoder);
-	
-	//this.endSIG = encoder.offset;
-	//this.startSignedInfo = encoder.offset;
-	
-	
-	if(null!=this.signedInfo) this.signedInfo.to_ccnb(encoder);
-
-	encoder.writeElement(CCNProtocolDTags.Content, this.content);
-
-	
-	this.endSIG = encoder.offset;
-	
-	//this.endContent = encoder.offset;
-	
-
-	encoder.writeEndElement();
-	
-	this.saveRawData(encoder.ostream);
-	
-};
-
-ContentObject.prototype.getElementLabel= function(){return CCNProtocolDTags.ContentObject;};
-
-/**
- * Signature
- */
-var Signature = function Signature(_witness,_signature,_digestAlgorithm) {
-	
-    this.Witness = _witness;//byte [] _witness;
-	this.signature = _signature;//byte [] _signature;
-	this.digestAlgorithm = _digestAlgorithm//String _digestAlgorithm;
-};
-
-Signature.prototype.from_ccnb =function( decoder) {
-		decoder.readStartElement(this.getElementLabel());
-		
-		if(LOG>4)console.log('STARTED DECODING SIGNATURE ');
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.DigestAlgorithm)) {
-			
-			if(LOG>4)console.log('DIGIEST ALGORITHM FOUND');
-			this.digestAlgorithm = decoder.readUTF8Element(CCNProtocolDTags.DigestAlgorithm); 
-		}
-		if (decoder.peekStartElement(CCNProtocolDTags.Witness)) {
-			if(LOG>4)console.log('WITNESS FOUND FOUND');
-			this.Witness = decoder.readBinaryElement(CCNProtocolDTags.Witness); 
-		}
-		
-		//FORCE TO READ A SIGNATURE
-
-			//if(LOG>4)console.log('SIGNATURE FOUND ');
-			this.signature = decoder.readBinaryElement(CCNProtocolDTags.SignatureBits);	
-			if(LOG>4)console.log('READ SIGNATURE ');
-
-		decoder.readEndElement();
-	
-};
-
-
-Signature.prototype.to_ccnb= function( encoder){
-    	
-	if (!this.validate()) {
-		throw new Error("Cannot encode: field values missing.");
-	}
-	
-	encoder.writeStartElement(this.getElementLabel());
-	
-	if ((null != this.digestAlgorithm) && (!this.digestAlgorithm.equals(CCNDigestHelper.DEFAULT_DIGEST_ALGORITHM))) {
-		encoder.writeElement(CCNProtocolDTags.DigestAlgorithm, OIDLookup.getDigestOID(this.DigestAlgorithm));
-	}
-	
-	if (null != this.Witness) {
-		// needs to handle null witness
-		encoder.writeElement(CCNProtocolDTags.Witness, this.Witness);
-	}
-
-	encoder.writeElement(CCNProtocolDTags.SignatureBits, this.signature);
-
-	encoder.writeEndElement();   		
-};
-
-Signature.prototype.getElementLabel = function() { return CCNProtocolDTags.Signature; };
-
-
-Signature.prototype.validate = function() {
-		return null != this.signature;
-};
-
-
-/**
- * SignedInfo
- */
-var ContentType = {DATA:0, ENCR:1, GONE:2, KEY:3, LINK:4, NACK:5};
-var ContentTypeValue = {0:0x0C04C0, 1:0x10D091,2:0x18E344,3:0x28463F,4:0x2C834A,5:0x34008A};
-var ContentTypeValueReverse = {0x0C04C0:0, 0x10D091:1,0x18E344:2,0x28463F:3,0x2C834A:4,0x34008A:5};
-
-var SignedInfo = function SignedInfo(_publisher,_timestamp,_type,_locator,_freshnessSeconds,_finalBlockID){
-
-	//TODO, Check types
-
-    this.publisher = _publisher; //publisherPublicKeyDigest
-    this.timestamp=_timestamp; // CCN Time
-    this.type=_type; // ContentType
-    this.locator =_locator;//KeyLocator
-    this.freshnessSeconds =_freshnessSeconds; // Integer
-    this.finalBlockID=_finalBlockID; //byte array
-
-};
-
-SignedInfo.prototype.setFields = function(){
-	//BASE64 -> RAW STRING
-	
-	//this.locator = new KeyLocator(  DataUtils.toNumbersFromString(stringCertificate)  ,KeyLocatorType.CERTIFICATE );
-	
-	var publicKeyHex = globalKeyManager.publicKey;
-
-	if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
-	if(LOG>4)console.log(publicKeyHex);
-	
-	var publicKeyBytes = DataUtils.toNumbers(globalKeyManager.publicKey) ; 
-
-	
-
-	//var stringCertificate = DataUtils.base64toString(globalKeyManager.certificate);
-	
-	//if(LOG>3)console.log('string Certificate is '+stringCertificate);
-
-	//HEX -> BYTE ARRAY
-	//var publisherkey = DataUtils.toNumbers(hex_sha256(stringCertificate));
-	
-	//if(LOG>3)console.log('publisher key is ');
-	//if(LOG>3)console.log(publisherkey);
-	
-	var publisherKeyDigest = hex_sha256_from_bytes(publicKeyBytes);
-
-	this.publisher = new PublisherPublicKeyDigest(  DataUtils.toNumbers(  publisherKeyDigest )  );
-	
-	//this.publisher = new PublisherPublicKeyDigest(publisherkey);
-
-	var d = new Date();
-	
-	var time = d.getTime();
-	
-
-    this.timestamp = new CCNTime( time );
-    
-    if(LOG>4)console.log('TIME msec is');
-
-    if(LOG>4)console.log(this.timestamp.msec);
-
-    //DATA
-	this.type = 0;//0x0C04C0;//ContentTypeValue[ContentType.DATA];
-	
-	//if(LOG>4)console.log('toNumbersFromString(stringCertificate) '+DataUtils.toNumbersFromString(stringCertificate));
-	
-	if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
-	if(LOG>4)console.log(publicKeyBytes);
-
-	this.locator = new KeyLocator(  publicKeyBytes  ,KeyLocatorType.KEY );
-
-	//this.locator = new KeyLocator(  DataUtils.toNumbersFromString(stringCertificate)  ,KeyLocatorType.CERTIFICATE );
-
-};
-
-SignedInfo.prototype.from_ccnb = function( decoder){
-
-		decoder.readStartElement( this.getElementLabel() );
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
-			if(LOG>3) console.log('DECODING PUBLISHER KEY');
-			this.publisher = new PublisherPublicKeyDigest();
-			this.publisher.from_ccnb(decoder);
-		}
-
-		if (decoder.peekStartElement(CCNProtocolDTags.Timestamp)) {
-			this.timestamp = decoder.readDateTime(CCNProtocolDTags.Timestamp);
-			if(LOG>4)console.log('TIMESTAMP FOUND IS  '+this.timestamp);
-
-		}
-
-		if (decoder.peekStartElement(CCNProtocolDTags.Type)) {
-			binType = decoder.readBinaryElement(CCNProtocolDTags.Type);//byte [] 
-		
-			
-			//TODO Implement type of Key Reading
-			
-			if(LOG>4)console.log('Binary Type of of Signed Info is '+binType);
-
-			this.type = binType;
-			
-			
-			//TODO Implement type of Key Reading
-			
-			
-			if (null == this.type) {
-				throw new Error("Cannot parse signedInfo type: bytes.");
-			}
-			
-		} else {
-			this.type = ContentType.DATA; // default
-		}
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.FreshnessSeconds)) {
-			this.freshnessSeconds = decoder.readIntegerElement(CCNProtocolDTags.FreshnessSeconds);
-			if(LOG>4) console.log('FRESHNESS IN SECONDS IS '+ this.freshnessSeconds);
-		}
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.FinalBlockID)) {
-			this.finalBlockID = decoder.readBinaryElement(CCNProtocolDTags.FinalBlockID);
-		}
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.KeyLocator)) {
-			this.locator = new KeyLocator();
-			this.locator.from_ccnb(decoder);
-		}
-				
-		decoder.readEndElement();
-};
-
-SignedInfo.prototype.to_ccnb = function( encoder)  {
-		if (!this.validate()) {
-			throw new Error("Cannot encode : field values missing.");
-		}
-		encoder.writeStartElement(this.getElementLabel());
-		
-		if (null!=this.publisher) {
-			if(LOG>3) console.log('ENCODING PUBLISHER KEY' + this.publisher.publisherPublicKeyDigest);
-
-			this.publisher.to_ccnb(encoder);
-		}
-
-		if (null!=this.timestamp) {
-			encoder.writeDateTime(CCNProtocolDTags.Timestamp, this.timestamp );
-		}
-		
-		if (null!=this.type && this.type !=0) {
-			
-			encoder.writeElement(CCNProtocolDTags.type, this.type);
-		}
-		
-		if (null!=this.freshnessSeconds) {
-			encoder.writeElement(CCNProtocolDTags.FreshnessSeconds, this.freshnessSeconds);
-		}
-
-		if (null!=this.finalBlockID) {
-			encoder.writeElement(CCNProtocolDTags.FinalBlockID, this.finalBlockID);
-		}
-
-		if (null!=this.locator) {
-			this.locator.to_ccnb(encoder);
-		}
-
-		encoder.writeEndElement();   		
-};
-	
-SignedInfo.prototype.valueToType = function(){
-	//for (Entry<byte [], ContentType> entry : ContentValueTypes.entrySet()) {
-		//if (Arrays.equals(value, entry.getKey()))
-			//return entry.getValue();
-		//}
-	return null;
-	
-};
-
-SignedInfo.prototype.getElementLabel = function() { 
-	return CCNProtocolDTags.SignedInfo;
-};
-
-SignedInfo.prototype.validate = function() {
-		// We don't do partial matches any more, even though encoder/decoder
-		// is still pretty generous.
-		if (null ==this.publisher || null==this.timestamp ||null== this.locator)
-			return false;
-		return true;
-};
-/*
- * Date Format 1.2.3
- * (c) 2007-2009 Steven Levithan <stevenlevithan.com>
- * MIT license
- *
- * Includes enhancements by Scott Trenda <scott.trenda.net>
- * and Kris Kowal <cixar.com/~kris.kowal/>
- *
- * Accepts a date, a mask, or a date and a mask.
- * Returns a formatted version of the given date.
- * The date defaults to the current date/time.
- * The mask defaults to dateFormat.masks.default.
- */
-
-var DateFormat = function () {
-	var	token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
-		timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
-		timezoneClip = /[^-+\dA-Z]/g,
-		pad = function (val, len) {
-			val = String(val);
-			len = len || 2;
-			while (val.length < len) val = "0" + val;
-			return val;
-		};
-
-	// Regexes and supporting functions are cached through closure
-	return function (date, mask, utc) {
-		var dF = dateFormat;
-
-		// You can't provide utc if you skip other args (use the "UTC:" mask prefix)
-		if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) {
-			mask = date;
-			date = undefined;
-		}
-
-		// Passing date through Date applies Date.parse, if necessary
-		date = date ? new Date(date) : new Date;
-		if (isNaN(date)) throw SyntaxError("invalid date");
-
-		mask = String(dF.masks[mask] || mask || dF.masks["default"]);
-
-		// Allow setting the utc argument via the mask
-		if (mask.slice(0, 4) == "UTC:") {
-			mask = mask.slice(4);
-			utc = true;
-		}
-
-		var	_ = utc ? "getUTC" : "get",
-			d = date[_ + "Date"](),
-			D = date[_ + "Day"](),
-			m = date[_ + "Month"](),
-			y = date[_ + "FullYear"](),
-			H = date[_ + "Hours"](),
-			M = date[_ + "Minutes"](),
-			s = date[_ + "Seconds"](),
-			L = date[_ + "Milliseconds"](),
-			o = utc ? 0 : date.getTimezoneOffset(),
-			flags = {
-				d:    d,
-				dd:   pad(d),
-				ddd:  dF.i18n.dayNames[D],
-				dddd: dF.i18n.dayNames[D + 7],
-				m:    m + 1,
-				mm:   pad(m + 1),
-				mmm:  dF.i18n.monthNames[m],
-				mmmm: dF.i18n.monthNames[m + 12],
-				yy:   String(y).slice(2),
-				yyyy: y,
-				h:    H % 12 || 12,
-				hh:   pad(H % 12 || 12),
-				H:    H,
-				HH:   pad(H),
-				M:    M,
-				MM:   pad(M),
-				s:    s,
-				ss:   pad(s),
-				l:    pad(L, 3),
-				L:    pad(L > 99 ? Math.round(L / 10) : L),
-				t:    H < 12 ? "a"  : "p",
-				tt:   H < 12 ? "am" : "pm",
-				T:    H < 12 ? "A"  : "P",
-				TT:   H < 12 ? "AM" : "PM",
-				Z:    utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
-				o:    (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
-				S:    ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
-			};
-
-		return mask.replace(token, function ($0) {
-			return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
-		});
-	};
-}();
-
-// Some common format strings
-DateFormat.masks = {
-	"default":      "ddd mmm dd yyyy HH:MM:ss",
-	shortDate:      "m/d/yy",
-	mediumDate:     "mmm d, yyyy",
-	longDate:       "mmmm d, yyyy",
-	fullDate:       "dddd, mmmm d, yyyy",
-	shortTime:      "h:MM TT",
-	mediumTime:     "h:MM:ss TT",
-	longTime:       "h:MM:ss TT Z",
-	isoDate:        "yyyy-mm-dd",
-	isoTime:        "HH:MM:ss",
-	isoDateTime:    "yyyy-mm-dd'T'HH:MM:ss",
-	isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
-};
-
-// Internationalization strings
-DateFormat.i18n = {
-	dayNames: [
-		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
-		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
-	],
-	monthNames: [
-		"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
-		"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
-	]
-};
-
-// For convenience...
-Date.prototype.format = function (mask, utc) {
-	return dateFormat(this, mask, utc);
-};
- /*
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class represents Interest Objects
- */
-
-var Interest = function Interest(_name,_faceInstance,_minSuffixComponents,_maxSuffixComponents,_publisherPublicKeyDigest, _exclude, _childSelector,_answerOriginKind,_scope,_interestLifetime,_nonce){
-		
-	this.name = _name;
-	this.faceInstance = _faceInstance;
-	this.maxSuffixComponents = _maxSuffixComponents;
-	this.minSuffixComponents = _minSuffixComponents;
-	
-	this.publisherPublicKeyDigest = _publisherPublicKeyDigest;
-	this.exclude = _exclude;
-	this.childSelector = _childSelector;
-	this.answerOriginKind = _answerOriginKind;
-	this.scope = _scope;
-	this.interestLifetime = _interestLifetime;  // number of seconds
-	this.nonce = _nonce;	
-};
-
-Interest.RECURSIVE_POSTFIX = "*";
-
-Interest.CHILD_SELECTOR_LEFT = 0;
-Interest.CHILD_SELECTOR_RIGHT = 1;
-Interest.ANSWER_CONTENT_STORE = 1;
-Interest.ANSWER_GENERATED = 2;
-Interest.ANSWER_STALE = 4;		// Stale answer OK
-Interest.MARK_STALE = 16;		// Must have scope 0.  Michael calls this a "hack"
-
-Interest.DEFAULT_ANSWER_ORIGIN_KIND = Interest.ANSWER_CONTENT_STORE | Interest.ANSWER_GENERATED;
-
-
-Interest.prototype.from_ccnb = function(/*XMLDecoder*/ decoder) {
-
-		decoder.readStartElement(CCNProtocolDTags.Interest);
-
-		this.name = new Name();
-		this.name.from_ccnb(decoder);
-
-		if (decoder.peekStartElement(CCNProtocolDTags.MinSuffixComponents))
-			this.minSuffixComponents = decoder.readIntegerElement(CCNProtocolDTags.MinSuffixComponents);
-
-		if (decoder.peekStartElement(CCNProtocolDTags.MaxSuffixComponents)) 
-			this.maxSuffixComponents = decoder.readIntegerElement(CCNProtocolDTags.MaxSuffixComponents);
-			
-		if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
-			this.publisherPublicKeyDigest = new PublisherPublicKeyDigest();
-			this.publisherPublicKeyDigest.from_ccnb(decoder);
-		}
-
-		if (decoder.peekStartElement(CCNProtocolDTags.Exclude)) {
-			this.exclude = new Exclude();
-			this.exclude.from_ccnb(decoder);
-		}
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.ChildSelector))
-			this.childSelector = decoder.readIntegerElement(CCNProtocolDTags.ChildSelector);
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.AnswerOriginKind))
-			this.answerOriginKind = decoder.readIntegerElement(CCNProtocolDTags.AnswerOriginKind);
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.Scope))
-			this.scope = decoder.readIntegerElement(CCNProtocolDTags.Scope);
-
-		if (decoder.peekStartElement(CCNProtocolDTags.InterestLifetime))
-			this.interestLifetime = DataUtils.bigEndianToUnsignedInt
-                (decoder.readBinaryElement(CCNProtocolDTags.InterestLifetime)) / 4096;
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.Nonce))
-			this.nonce = decoder.readBinaryElement(CCNProtocolDTags.Nonce);
-		
-		decoder.readEndElement();
-};
-
-Interest.prototype.to_ccnb = function(/*XMLEncoder*/ encoder){
-		//Could check if name is present
-		
-		encoder.writeStartElement(CCNProtocolDTags.Interest);
-		
-		this.name.to_ccnb(encoder);
-	
-		if (null != this.minSuffixComponents) 
-			encoder.writeElement(CCNProtocolDTags.MinSuffixComponents, this.minSuffixComponents);	
-
-		if (null != this.maxSuffixComponents) 
-			encoder.writeElement(CCNProtocolDTags.MaxSuffixComponents, this.maxSuffixComponents);
-
-		if (null != this.publisherPublicKeyDigest)
-			this.publisherPublicKeyDigest.to_ccnb(encoder);
-		
-		if (null != this.exclude)
-			this.exclude.to_ccnb(encoder);
-		
-		if (null != this.childSelector) 
-			encoder.writeElement(CCNProtocolDTags.ChildSelector, this.childSelector);
-
-		if (this.DEFAULT_ANSWER_ORIGIN_KIND != this.answerOriginKind && this.answerOriginKind!=null) 
-			encoder.writeElement(CCNProtocolDTags.AnswerOriginKind, this.answerOriginKind);
-		
-		if (null != this.scope) 
-			encoder.writeElement(CCNProtocolDTags.Scope, this.scope);
-		
-		if (null != this.interestLifetime) 
-			encoder.writeElement(CCNProtocolDTags.InterestLifetime, 
-                DataUtils.nonNegativeIntToBigEndian(this.interestLifetime * 4096));
-		
-		if (null != this.nonce)
-			encoder.writeElement(CCNProtocolDTags.Nonce, this.nonce);
-		
-		encoder.writeEndElement();
-
-};
-
-Interest.prototype.matches_name = function(/*Name*/ name){
-	var i_name = this.name.components;
-	var o_name = name.components;
-
-	// The intrest name is longer than the name we are checking it against.
-	if (i_name.length > o_name.length)
-            return false;
-
-	// Check if at least one of given components doesn't match.
-        for (var i = 0; i < i_name.length; ++i) {
-            if (!DataUtils.arraysEqual(i_name[i], o_name[i]))
-                return false;
-        }
-
-	return true;
-}
-
-/**
- * Exclude
- */
-var Exclude = function Exclude(_values){ 
-	
-	this.OPTIMUM_FILTER_SIZE = 100;
-	
-
-	this.values = _values; //array of elements
-	
-}
-
-Exclude.prototype.from_ccnb = function(/*XMLDecoder*/ decoder) {
-
-
-		
-		decoder.readStartElement(this.getElementLabel());
-
-		//TODO APPLY FILTERS/EXCLUDE
-		
-		//TODO 
-		/*var component;
-		var any = false;
-		while ((component = decoder.peekStartElement(CCNProtocolDTags.Component)) || 
-				(any = decoder.peekStartElement(CCNProtocolDTags.Any)) ||
-					decoder.peekStartElement(CCNProtocolDTags.Bloom)) {
-			var ee = component?new ExcludeComponent(): any ? new ExcludeAny() : new BloomFilter();
-			ee.decode(decoder);
-			_values.add(ee);
-		}*/
-
-		decoder.readEndElement();
-
-};
-
-Exclude.prototype.to_ccnb=function(/*XMLEncoder*/ encoder)  {
-		if (!validate()) {
-			throw new ContentEncodingException("Cannot encode " + this.getClass().getName() + ": field values missing.");
-		}
-
-		if (empty())
-			return;
-
-		encoder.writeStartElement(getElementLabel());
-
-		encoder.writeEndElement();
-		
-	};
-
-Exclude.prototype.getElementLabel = function() { return CCNProtocolDTags.Exclude; };
-
-
-/**
- * ExcludeAny
- */
-var ExcludeAny = function ExcludeAny() {
-
-};
-
-ExcludeAny.prototype.from_ccnb = function(decoder) {
-		decoder.readStartElement(this.getElementLabel());
-		decoder.readEndElement();
-};
-
-
-ExcludeAny.prototype.to_ccnb = function( encoder) {
-		encoder.writeStartElement(this.getElementLabel());
-		encoder.writeEndElement();
-};
-
-ExcludeAny.prototype.getElementLabel=function() { return CCNProtocolDTags.Any; };
-
-
-/**
- * ExcludeComponent
- */
-var ExcludeComponent = function ExcludeComponent(_body) {
-
-	//TODO Check BODY is an Array of componenets.
-	
-	this.body = _body
-};
-
-ExcludeComponent.prototype.from_ccnb = function( decoder)  {
-		this.body = decoder.readBinaryElement(this.getElementLabel());
-};
-
-ExcludeComponent.prototype.to_ccnb = function(encoder) {
-		encoder.writeElement(this.getElementLabel(), this.body);
-};
-
-ExcludeComponent.prototype.getElementLabel = function() { return CCNProtocolDTags.Component; };
-/*
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class represents Key Objects
- */
-
-var Key = function Key(){
-    /* TODO: Port from PyCCN:
-	generateRSA()
-	privateToDER()
-	publicToDER()
-	privateToPEM()
-	publicToPEM()
-	fromDER()
-	fromPEM()
-     */
-}
-
-/**
- * KeyLocator
- */
-var KeyLocatorType = {
-	  NAME:1,
-	  KEY:2,
-	  CERTIFICATE:3
-};
-
-var KeyLocator = function KeyLocator(_input,_type){ 
-
-    this.type=_type;
-    
-    if (_type==KeyLocatorType.NAME){
-    	this.keyName = _input;
-    }
-    else if(_type==KeyLocatorType.KEY){
-    	if(LOG>4)console.log('SET KEY');
-    	this.publicKey = _input;
-    }
-    else if(_type==KeyLocatorType.CERTIFICATE){
-    	this.certificate = _input;
-    }
-
-};
-
-KeyLocator.prototype.from_ccnb = function(decoder) {
-
-		decoder.readStartElement(this.getElementLabel());
-
-		if (decoder.peekStartElement(CCNProtocolDTags.Key)) {
-			try {
-				encodedKey = decoder.readBinaryElement(CCNProtocolDTags.Key);
-				// This is a DER-encoded SubjectPublicKeyInfo.
-				
-				//TODO FIX THIS, This should create a Key Object instead of keeping bytes
-
-				this.publicKey =   encodedKey;//CryptoUtil.getPublicKey(encodedKey);
-				this.type = 2;
-				
-
-				if(LOG>4) console.log('PUBLIC KEY FOUND: '+ this.publicKey);
-				//this.publicKey = encodedKey;
-				
-				
-			} catch (e) {
-				throw new Error("Cannot parse key: ", e);
-			} 
-
-			if (null == this.publicKey) {
-				throw new Error("Cannot parse key: ");
-			}
-
-		} else if ( decoder.peekStartElement(CCNProtocolDTags.Certificate)) {
-			try {
-				encodedCert = decoder.readBinaryElement(CCNProtocolDTags.Certificate);
-				
-				/*
-				 * Certificates not yet working
-				 */
-				
-				//CertificateFactory factory = CertificateFactory.getInstance("X.509");
-				//this.certificate = (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(encodedCert));
-				
-
-				this.certificate = encodedCert;
-				this.type = 3;
-
-				if(LOG>4) console.log('CERTIFICATE FOUND: '+ this.certificate);
-				
-			} catch ( e) {
-				throw new Error("Cannot decode certificate: " +  e);
-			}
-			if (null == this.certificate) {
-				throw new Error("Cannot parse certificate! ");
-			}
-		} else  {
-			this.type = 1;
-
-
-			this.keyName = new KeyName();
-			this.keyName.from_ccnb(decoder);
-		}
-		decoder.readEndElement();
-	}
-	
-
-	KeyLocator.prototype.to_ccnb = function( encoder) {
-		
-		if(LOG>4) console.log('type is is ' + this.type);
-		//TODO Check if Name is missing
-		if (!this.validate()) {
-			throw new ContentEncodingException("Cannot encode " + this.getClass().getName() + ": field values missing.");
-		}
-
-		
-		//TODO FIX THIS TOO
-		encoder.writeStartElement(this.getElementLabel());
-		
-		if (this.type == KeyLocatorType.KEY) {
-			if(LOG>5)console.log('About to encode a public key' +this.publicKey);
-			encoder.writeElement(CCNProtocolDTags.Key, this.publicKey);
-			
-		} else if (this.type == KeyLocatorType.CERTIFICATE) {
-			
-			try {
-				encoder.writeElement(CCNProtocolDTags.Certificate, this.certificate);
-			} catch ( e) {
-				throw new Error("CertificateEncodingException attempting to write key locator: " + e);
-			}
-			
-		} else if (this.type == KeyLocatorType.NAME) {
-			
-			this.keyName.to_ccnb(encoder);
-		}
-		encoder.writeEndElement();
-		
-};
-
-KeyLocator.prototype.getElementLabel = function() {
-	return CCNProtocolDTags.KeyLocator; 
-};
-
-KeyLocator.prototype.validate = function() {
-	return (  (null != this.keyName) || (null != this.publicKey) || (null != this.certificate)   );
-};
-
-/**
- * KeyName is only used by KeyLocator.
- */
-var KeyName = function KeyName() {
-	
-
-	this.contentName = this.contentName;//contentName
-	this.publisherID =this.publisherID;//publisherID
-
-};
-
-KeyName.prototype.from_ccnb=function( decoder){
-	
-
-	decoder.readStartElement(this.getElementLabel());
-
-	this.contentName = new Name();
-	this.contentName.from_ccnb(decoder);
-	
-	if(LOG>4) console.log('KEY NAME FOUND: ');
-	
-	if ( PublisherID.peek(decoder) ) {
-		this.publisherID = new PublisherID();
-		this.publisherID.from_ccnb(decoder);
-	}
-	
-	decoder.readEndElement();
-};
-
-KeyName.prototype.to_ccnb = function( encoder) {
-	if (!this.validate()) {
-		throw new Error("Cannot encode : field values missing.");
-	}
-	
-	encoder.writeStartElement(this.getElementLabel());
-	
-	this.contentName.to_ccnb(encoder);
-	if (null != this.publisherID)
-		this.publisherID.to_ccnb(encoder);
-
-	encoder.writeEndElement();   		
-};
-	
-KeyName.prototype.getElementLabel = function() { return CCNProtocolDTags.KeyName; };
-
-KeyName.prototype.validate = function() {
-		// DKS -- do we do recursive validation?
-		// null signedInfo ok
-		return (null != this.contentName);
-};
-/*
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class represents Publisher and PublisherType Objects
- */
-
-
-var PublisherType = function PublisherType(_tag){
-    	this.KEY =(CCNProtocolDTags.PublisherPublicKeyDigest);
-    	this.CERTIFICATE= (CCNProtocolDTags.PublisherCertificateDigest);
-    	this.ISSUER_KEY=	(CCNProtocolDTags.PublisherIssuerKeyDigest);
-    	this.ISSUER_CERTIFICATE	=(CCNProtocolDTags.PublisherIssuerCertificateDigest);
-
-    	this.Tag = _tag;
-}; 
-
-var isTypeTagVal = function(tagVal) {
-		if ((tagVal == CCNProtocolDTags.PublisherPublicKeyDigest) ||
-			(tagVal == CCNProtocolDTags.PublisherCertificateDigest) ||
-			(tagVal == CCNProtocolDTags.PublisherIssuerKeyDigest) ||
-			(tagVal == CCNProtocolDTags.PublisherIssuerCertificateDigest)) {
-			return true;
-		}
-		return false;
-};
-
-
-
-
-var PublisherID = function PublisherID() {
-
-	this.PUBLISHER_ID_DIGEST_ALGORITHM = "SHA-256";
-	this.PUBLISHER_ID_LEN = 256/8;
-    
-	//TODO, implement publisherID creation and key creation
-
-    //TODO implement generatePublicKeyDigest
-    this.publisherID =null;//= generatePublicKeyDigest(key);//ByteArray
-    
-    //TODO implement generate key
-    //CryptoUtil.generateKeyID(PUBLISHER_ID_DIGEST_ALGORITHM, key);
-    this.publisherType = null;//isIssuer ? PublisherType.ISSUER_KEY : PublisherType.KEY;//publisher Type
-    
-};
-
-
-PublisherID.prototype.from_ccnb = function(decoder) {
-		
-		// We have a choice here of one of 4 binary element types.
-		var nextTag = decoder.peekStartElementAsLong();
-		
-		if (null == nextTag) {
-			throw new Error("Cannot parse publisher ID.");
-		} 
-		
-		this.publisherType = new PublisherType(nextTag); 
-		
-		if (!isTypeTagVal(nextTag)) {
-			throw new Error("Invalid publisher ID, got unexpected type: " + nextTag);
-		}
-		this.publisherID = decoder.readBinaryElement(nextTag);
-		if (null == this.publisherID) {
-			throw new ContentDecodingException(new Error("Cannot parse publisher ID of type : " + nextTag + "."));
-		}
-};
-
-PublisherID.prototype.to_ccnb = function(encoder) {
-	if (!this.validate()) {
-		throw new Error("Cannot encode " + this.getClass().getName() + ": field values missing.");
-	}
-
-	encoder.writeElement(this.getElementLabel(), this.publisherID);
-};
-	
-PublisherID.peek = function(/* XMLDecoder */ decoder) {
-
-		//Long
-		nextTag = decoder.peekStartElementAsLong();
-		
-		if (null == nextTag) {
-			// on end element
-			return false;
-		}
-		return (isTypeTagVal(nextTag));
-	};
-
-PublisherID.prototype.getElementLabel = function() { 
-	return this.publisherType.Tag;
-};
-
-PublisherID.prototype.validate = function(){
-	return ((null != id() && (null != type())));
-};
-
-
-
-/*
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class represents PublisherPublicKeyDigest Objects
- */
-var PublisherPublicKeyDigest = function PublisherPublicKeyDigest(_pkd){ 
-	
- 	 //this.PUBLISHER_ID_LEN = 256/8;
-	 this.PUBLISHER_ID_LEN = 512/8;
- 	 
-
-	 this.publisherPublicKeyDigest = _pkd;
- 	 //if( typeof _pkd == "object") this.publisherPublicKeyDigest = _pkd; // Byte Array
- 	 //else if( typeof _pkd == "PublicKey") ;//TODO...
-    
-};
-
-PublisherPublicKeyDigest.prototype.from_ccnb = function( decoder) {		
-
-		this.publisherPublicKeyDigest = decoder.readBinaryElement(this.getElementLabel());
-		
-		if(LOG>4)console.log('Publisher public key digest is ' + this.publisherPublicKeyDigest);
-
-		if (null == this.publisherPublicKeyDigest) {
-			throw new Error("Cannot parse publisher key digest.");
-		}
-		
-		//TODO check if the length of the PublisherPublicKeyDigest is correct ( Security reason)
-
-		if (this.publisherPublicKeyDigest.length != this.PUBLISHER_ID_LEN) {
-			if (LOG > 0)
-                console.log('LENGTH OF PUBLISHER ID IS WRONG! Expected ' + this.PUBLISHER_ID_LEN + ", got " + this.publisherPublicKeyDigest.length);
-			
-			//this.publisherPublicKeyDigest = new PublisherPublicKeyDigest(this.PublisherPublicKeyDigest).PublisherKeyDigest;		
-		}
-	};
-
-PublisherPublicKeyDigest.prototype.to_ccnb= function( encoder) {
-		//TODO Check that the ByteArray for the key is present
-		if (!this.validate()) {
-			throw new Error("Cannot encode : field values missing.");
-		}
-		if(LOG>3) console.log('PUBLISHER KEY DIGEST IS'+this.publisherPublicKeyDigest);
-		encoder.writeElement(this.getElementLabel(), this.publisherPublicKeyDigest);
-};
-	
-PublisherPublicKeyDigest.prototype.getElementLabel = function() { return CCNProtocolDTags.PublisherPublicKeyDigest; };
-
-PublisherPublicKeyDigest.prototype.validate =function() {
-		return (null != this.publisherPublicKeyDigest);
-};
-/*
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class represents Face Instances
- */
-
-var NetworkProtocol = { TCP:6, UDP:17};
-
-var FaceInstance  = function FaceInstance(
-	    _action,
-		_publisherPublicKeyDigest,
-		_faceID,
-		_ipProto,
-		_host,
-		_port,
-		_multicastInterface,
-		_multicastTTL,
-		_freshnessSeconds){
-	
-
-	this.action = _action;
-	this.publisherPublicKeyDigest = _publisherPublicKeyDigest;
-	this.faceID = _faceID;
-	this.ipProto = _ipProto;
-	this.host = _host;
-	this.Port = _port;
-	this.multicastInterface =_multicastInterface;
-	this.multicastTTL =_multicastTTL;
-	this.freshnessSeconds = _freshnessSeconds;
-	
-	//action           ::= ("newface" | "destroyface" | "queryface")
-	//publisherPublicKeyDigest ::= SHA-256 digest
-	//faceID           ::= nonNegativeInteger
-	//ipProto          ::= nonNegativeInteger [IANA protocol number, 6=TCP, 17=UDP]
-	//Host             ::= textual representation of numeric IPv4 or IPv6 address
-	//Port             ::= nonNegativeInteger [1..65535]
-	//MulticastInterface ::= textual representation of numeric IPv4 or IPv6 address
-	//MulticastTTL     ::= nonNegativeInteger [1..255]
-	//freshnessSeconds ::= nonNegativeInteger
-
-};
-
-/**
- * Used by NetworkObject to decode the object from a network stream.
- */
-FaceInstance.prototype.from_ccnb = function(//XMLDecoder 
-	decoder) {
-
-	decoder.readStartElement(this.getElementLabel());
-	
-	if (decoder.peekStartElement(CCNProtocolDTags.Action)) {
-		
-		this.action = decoder.readUTF8Element(CCNProtocolDTags.Action);
-		
-	}
-	if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
-		
-		this.publisherPublicKeyDigest = new PublisherPublicKeyDigest();
-		this.publisherPublicKeyDigest.from_ccnb(decoder);
-		
-	}
-	if (decoder.peekStartElement(CCNProtocolDTags.FaceID)) {
-		
-		this.faceID = decoder.readIntegerElement(CCNProtocolDTags.FaceID);
-		
-	}
-	if (decoder.peekStartElement(CCNProtocolDTags.IPProto)) {
-		
-		//int
-		var pI = decoder.readIntegerElement(CCNProtocolDTags.IPProto);
-		
-		this.ipProto = null;
-		
-		if (NetworkProtocol.TCP == pI) {
-			
-			this.ipProto = NetworkProtocol.TCP;
-			
-		} else if (NetworkProtocol.UDP == pI) {
-			
-			this.ipProto = NetworkProtocol.UDP;
-			
-		} else {
-			
-			throw new Error("FaceInstance.decoder.  Invalid " + 
-					CCNProtocolDTags.tagToString(CCNProtocolDTags.IPProto) + " field: " + pI);
-			
-		}
-	}
-	
-	if (decoder.peekStartElement(CCNProtocolDTags.Host)) {
-		
-		this.host = decoder.readUTF8Element(CCNProtocolDTags.Host);
-		
-	}
-	
-	if (decoder.peekStartElement(CCNProtocolDTags.Port)) {
-		this.Port = decoder.readIntegerElement(CCNProtocolDTags.Port); 
-	}
-	
-	if (decoder.peekStartElement(CCNProtocolDTags.MulticastInterface)) {
-		this.multicastInterface = decoder.readUTF8Element(CCNProtocolDTags.MulticastInterface); 
-	}
-	
-	if (decoder.peekStartElement(CCNProtocolDTags.MulticastTTL)) {
-		this.multicastTTL = decoder.readIntegerElement(CCNProtocolDTags.MulticastTTL); 
-	}
-	
-	if (decoder.peekStartElement(CCNProtocolDTags.FreshnessSeconds)) {
-		this.freshnessSeconds = decoder.readIntegerElement(CCNProtocolDTags.FreshnessSeconds); 
-	}
-	decoder.readEndElement();
-}
-
-/**
- * Used by NetworkObject to encode the object to a network stream.
- */
-FaceInstance.prototype.to_ccnb = function(//XMLEncoder
-	encoder){
-
-	//if (!this.validate()) {
-		//throw new Error("Cannot encode : field values missing.");
-		//throw new Error("")
-	//}
-	encoder.writeStartElement(this.getElementLabel());
-	
-	if (null != this.action && this.action.length != 0)
-		encoder.writeElement(CCNProtocolDTags.Action, this.action);	
-	
-	if (null != this.publisherPublicKeyDigest) {
-		this.publisherPublicKeyDigest.to_ccnb(encoder);
-	}
-	if (null != this.faceID) {
-		encoder.writeElement(CCNProtocolDTags.FaceID, this.faceID);
-	}
-	if (null != this.ipProto) {
-		//encoder.writeElement(CCNProtocolDTags.IPProto, this.IpProto.value());
-		encoder.writeElement(CCNProtocolDTags.IPProto, this.ipProto);
-	}
-	if (null != this.host && this.host.length != 0) {
-		encoder.writeElement(CCNProtocolDTags.Host, this.host);	
-	}
-	if (null != this.Port) {
-		encoder.writeElement(CCNProtocolDTags.Port, this.Port);
-	}
-	if (null != this.multicastInterface && this.multicastInterface.length != 0) {
-		encoder.writeElement(CCNProtocolDTags.MulticastInterface, this.multicastInterface);
-	}
-	if (null !=  this.multicastTTL) {
-		encoder.writeElement(CCNProtocolDTags.MulticastTTL, this.multicastTTL);
-	}
-	if (null != this.freshnessSeconds) {
-		encoder.writeElement(CCNProtocolDTags.FreshnessSeconds, this.freshnessSeconds);
-	}
-	encoder.writeEndElement();   			
-}
-
-
-FaceInstance.prototype.getElementLabel= function(){return CCNProtocolDTags.FaceInstance;};
-
-/*
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class represents Forwarding Entries
- */
-
-var ForwardingEntry = function ForwardingEntry(
-                                               //ActionType 
-		_action, 
-		//Name 
-		_prefixName, 
-		//PublisherPublicKeyDigest
-		_ccndId, 
-		//Integer 
-		_faceID, 
-		//Integer 
-		_flags, 
-		//Integer 
-		_lifetime){
-		
-		
-	
-		//String
-	this.action = _action;
-		//Name\
-	this.prefixName = _prefixName;
-		//PublisherPublicKeyDigest 
-	this.ccndID = _ccndId;
-		//Integer		
-	this.faceID = _faceID;
-		//Integer		
-	this.flags = _flags;
-		//Integer 		
-	this.lifetime = _lifetime;  // in seconds
-
-};
-
-ForwardingEntry.prototype.from_ccnb =function(
-	//XMLDecoder 
-	decoder) 
-	//throws ContentDecodingException
-	{
-			decoder.readStartElement(this.getElementLabel());
-			if (decoder.peekStartElement(CCNProtocolDTags.Action)) {
-				this.action = decoder.readUTF8Element(CCNProtocolDTags.Action); 
-			}
-			if (decoder.peekStartElement(CCNProtocolDTags.Name)) {
-				this.prefixName = new Name();
-				this.prefixName.from_ccnb(decoder) ;
-			}
-			if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
-				this.CcndId = new PublisherPublicKeyDigest();
-				this.CcndId.from_ccnb(decoder);
-			}
-			if (decoder.peekStartElement(CCNProtocolDTags.FaceID)) {
-				this.faceID = decoder.readIntegerElement(CCNProtocolDTags.FaceID); 
-			}
-			if (decoder.peekStartElement(CCNProtocolDTags.ForwardingFlags)) {
-				this.flags = decoder.readIntegerElement(CCNProtocolDTags.ForwardingFlags); 
-			}
-			if (decoder.peekStartElement(CCNProtocolDTags.FreshnessSeconds)) {
-				this.lifetime = decoder.readIntegerElement(CCNProtocolDTags.FreshnessSeconds); 
-			}
-			decoder.readEndElement();
-		};
-
-		/**
-		 * Used by NetworkObject to encode the object to a network stream.
-		 */
-ForwardingEntry.prototype.to_ccnb =function(
-	//XMLEncoder 
-encoder) 
-{
-
-
-			//if (!validate()) {
-				//throw new ContentEncodingException("Cannot encode " + this.getClass().getName() + ": field values missing.");
-			//}
-			encoder.writeStartElement(this.getElementLabel());
-			if (null != this.action && this.action.length != 0)
-				encoder.writeElement(CCNProtocolDTags.Action, this.action);	
-			if (null != this.prefixName) {
-				this.prefixName.to_ccnb(encoder);
-			}
-			if (null != this.CcndId) {
-				this.CcndId.to_ccnb(encoder);
-			}
-			if (null != this.faceID) {
-				encoder.writeElement(CCNProtocolDTags.FaceID, this.faceID);
-			}
-			if (null != this.flags) {
-				encoder.writeElement(CCNProtocolDTags.ForwardingFlags, this.flags);
-			}
-			if (null != this.lifetime) {
-				encoder.writeElement(CCNProtocolDTags.FreshnessSeconds, this.lifetime);
-			}
-			encoder.writeEndElement();   			
-		};
-
-ForwardingEntry.prototype.getElementLabel = function() { return CCNProtocolDTags.ForwardingEntry; }
-/*
- * This class is used to encode ccnb binary elements (blob, type/value pairs).
- * 
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- */
-
-var XML_EXT = 0x00; 
-	
-var XML_TAG = 0x01; 
-	
-var XML_DTAG = 0x02; 
-	
-var XML_ATTR = 0x03; 
- 
-var XML_DATTR = 0x04; 
-	
-var XML_BLOB = 0x05; 
-	
-var XML_UDATA = 0x06; 
-	
-var XML_CLOSE = 0x0;
-
-var XML_SUBTYPE_PROCESSING_INSTRUCTIONS = 16; 
-
-
-var XML_TT_BITS = 3;
-var XML_TT_MASK = ((1 << XML_TT_BITS) - 1);
-var XML_TT_VAL_BITS = XML_TT_BITS + 1;
-var XML_TT_VAL_MASK = ((1 << (XML_TT_VAL_BITS)) - 1);
-var XML_REG_VAL_BITS = 7;
-var XML_REG_VAL_MASK = ((1 << XML_REG_VAL_BITS) - 1);
-var XML_TT_NO_MORE = (1 << XML_REG_VAL_BITS); // 0x80
-var BYTE_MASK = 0xFF;
-var LONG_BYTES = 8;
-var LONG_BITS = 64;
-	
-var bits_11 = 0x0000007FF;
-var bits_18 = 0x00003FFFF;
-var bits_32 = 0x0FFFFFFFF;
-
-
-var BinaryXMLEncoder = function BinaryXMLEncoder(){
-	this.ostream = new Uint8Array(10000);
-	this.offset =0;
-	this.CODEC_NAME = "Binary";
-};
-
-/*
- * Encode utf8Content as utf8.
- */
-BinaryXMLEncoder.prototype.writeUString = function(/*String*/ utf8Content) {
-	this.encodeUString(utf8Content, XML_UDATA);
-};
-
-
-BinaryXMLEncoder.prototype.writeBlob = function(
-		/*Uint8Array*/ binaryContent
-		) {
-	
-	if(LOG >3) console.log(binaryContent);
-	
-	this.encodeBlob(binaryContent, binaryContent.length);
-};
-
-
-BinaryXMLEncoder.prototype.writeStartElement = function(
-	/*String*/ tag, 
-	/*TreeMap<String,String>*/ attributes
-	) {
-
-	/*Long*/ var dictionaryVal = tag; //stringToTag(tag);
-	
-	if (null == dictionaryVal) {
-		this.encodeUString(tag, XML_TAG);
-	} else {
-		this.encodeTypeAndVal(XML_DTAG, dictionaryVal);
-	}
-	
-	if (null != attributes) {
-		this.writeAttributes(attributes); 
-	}
-};
-
-
-BinaryXMLEncoder.prototype.writeEndElement = function() {
-	this.ostream[this.offset] = XML_CLOSE;
-	this.offset += 1;
-}
-
-
-BinaryXMLEncoder.prototype.writeAttributes = function(/*TreeMap<String,String>*/ attributes) {
-	if (null == attributes) {
-		return;
-	}
-
-	// the keySet of a TreeMap is sorted.
-
-	for(var i=0; i<attributes.length;i++){
-		var strAttr = attributes[i].k;
-		var strValue = attributes[i].v;
-
-		var dictionaryAttr = stringToTag(strAttr);
-		if (null == dictionaryAttr) {
-			// not in dictionary, encode as attr
-			// compressed format wants length of tag represented as length-1
-			// to save that extra bit, as tag cannot be 0 length.
-			// encodeUString knows to do that.
-			this.encodeUString(strAttr, XML_ATTR);
-		} else {
-			this.encodeTypeAndVal(XML_DATTR, dictionaryAttr);
-		}
-		// Write value
-		this.encodeUString(strValue);
-		
-	}
-}
-
-
-//returns a string
-stringToTag = function(/*long*/ tagVal) {
-	if ((tagVal >= 0) && (tagVal < CCNProtocolDTagsStrings.length)) {
-		return CCNProtocolDTagsStrings[tagVal];
-	} else if (tagVal == CCNProtocolDTags.CCNProtocolDataUnit) {
-		return CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT;
-	}
-	return null;
-};
-
-//returns a Long
-tagToString =  function(/*String*/ tagName) {
-	// the slow way, but right now we don't care.... want a static lookup for the forward direction
-	for (var i=0; i < CCNProtocolDTagsStrings.length; ++i) {
-		if ((null != CCNProtocolDTagsStrings[i]) && (CCNProtocolDTagsStrings[i] == tagName)) {
-			return i;
-		}
-	}
-	if (CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT == tagName) {
-		return CCNProtocolDTags.CCNProtocolDataUnit;
-	}
-	return null;
-};
-
-/*
- * If Content is a string, then encode as utf8 and write UDATA.
- */
-BinaryXMLEncoder.prototype.writeElement = function(
-		//long 
-		tag, 
-		//byte[] 
-		Content,
-		//TreeMap<String, String> 
-		attributes
-		) {
-	this.writeStartElement(tag, attributes);
-	// Will omit if 0-length
-	
-	if(typeof Content === 'number') {
-		if(LOG>4) console.log('GOING TO WRITE THE NUMBER .charCodeAt(0) ' + Content.toString().charCodeAt(0) );
-		if(LOG>4) console.log('GOING TO WRITE THE NUMBER ' + Content.toString() );
-		if(LOG>4) console.log('type of number is ' + typeof Content.toString() );
-		
-		this.writeUString(Content.toString());
-		//whatever
-	}
-	else if(typeof Content === 'string'){
-		if(LOG>4) console.log('GOING TO WRITE THE STRING  ' + Content );
-		if(LOG>4) console.log('type of STRING is ' + typeof Content );
-		
-		this.writeUString(Content);
-	}
-	else{
-		if(LOG>4) console.log('GOING TO WRITE A BLOB  ' + Content );
-
-		this.writeBlob(Content);
-	}
-	
-	this.writeEndElement();
-}
-
-
-
-var TypeAndVal = function TypeAndVal(_type,_val) {
-	this.type = _type;
-	this.val = _val;
-	
-};
-
-
-BinaryXMLEncoder.prototype.encodeTypeAndVal = function(
-		//int
-		type, 
-		//long 
-		val
-		) {
-	
-	if(LOG>4) console.log('Encoding type '+ type+ ' and value '+ val);
-	
-	if(LOG>4) console.log('OFFSET IS ' + this.offset);
-	
-	if ((type > XML_UDATA) || (type < 0) || (val < 0)) {
-		throw new Error("Tag and value must be positive, and tag valid.");
-	}
-	
-	// Encode backwards. Calculate how many bytes we need:
-	var numEncodingBytes = this.numEncodingBytes(val);
-	
-	if ((this.offset + numEncodingBytes) > this.ostream.length) {
-		throw new Error("Buffer space of " + (this.ostream.length - this.offset) + 
-											" bytes insufficient to hold " + 
-											numEncodingBytes + " of encoded type and value.");
-	}
-
-	// Bottom 4 bits of val go in last byte with tag.
-	this.ostream[this.offset + numEncodingBytes - 1] = 
-		//(byte)
-			(BYTE_MASK &
-					(((XML_TT_MASK & type) | 
-					 ((XML_TT_VAL_MASK & val) << XML_TT_BITS))) |
-					 XML_TT_NO_MORE); // set top bit for last byte
-	val = val >>> XML_TT_VAL_BITS;;
-	
-	// Rest of val goes into preceding bytes, 7 bits per byte, top bit
-	// is "more" flag.
-	var i = this.offset + numEncodingBytes - 2;
-	while ((0 != val) && (i >= this.offset)) {
-		this.ostream[i] = //(byte)
-				(BYTE_MASK & (val & XML_REG_VAL_MASK)); // leave top bit unset
-		val = val >>> XML_REG_VAL_BITS;
-		--i;
-	}
-	if (val != 0) {
-		throw new Error( "This should not happen: miscalculated encoding");
-		//Log.warning(Log.FAC_ENCODING, "This should not happen: miscalculated encoding length, have " + val + " left.");
-	}
-	this.offset+= numEncodingBytes;
-	
-	return numEncodingBytes;
-};
-
-/*
- * Encode ustring as utf8.
- */
-BinaryXMLEncoder.prototype.encodeUString = function(
-		//String 
-		ustring, 
-		//byte 
-		type) {
-	
-	if (null == ustring)
-		return;
-	if (type == XML_TAG || type == XML_ATTR && ustring.length == 0)
-		return;
-	
-	if(LOG>3) console.log("The string to write is ");
-	if(LOG>3) console.log(ustring);
-
-	var strBytes = DataUtils.stringToUtf8Array(ustring);
-	
-	this.encodeTypeAndVal(type, 
-						(((type == XML_TAG) || (type == XML_ATTR)) ?
-								(strBytes.length-1) :
-								strBytes.length));
-	
-	if(LOG>3) console.log("THE string to write is ");
-	
-	if(LOG>3) console.log(strBytes);
-	
-	this.writeString(strBytes,this.offset);
-	this.offset+= strBytes.length;
-};
-
-
-
-BinaryXMLEncoder.prototype.encodeBlob = function(
-		//Uint8Array 
-		blob, 
-		//int 
-		length) {
-
-
-	if (null == blob)
-		return;
-	
-	if(LOG>4) console.log('LENGTH OF XML_BLOB IS '+length);
-	
-	/*blobCopy = new Array(blob.Length);
-	
-	for (i = 0; i < blob.length; i++) //in InStr.ToCharArray())
-	{
-		blobCopy[i] = blob[i];
-	}*/
-
-	this.encodeTypeAndVal(XML_BLOB, length);
-
-	this.writeBlobArray(blob, this.offset);
-	this.offset += length;
-};
-
-var ENCODING_LIMIT_1_BYTE = ((1 << (XML_TT_VAL_BITS)) - 1);
-var ENCODING_LIMIT_2_BYTES = ((1 << (XML_TT_VAL_BITS + XML_REG_VAL_BITS)) - 1);
-var ENCODING_LIMIT_3_BYTES = ((1 << (XML_TT_VAL_BITS + 2 * XML_REG_VAL_BITS)) - 1);
-
-BinaryXMLEncoder.prototype.numEncodingBytes = function(
-		//long
-		x) {
-	if (x <= ENCODING_LIMIT_1_BYTE) return (1);
-	if (x <= ENCODING_LIMIT_2_BYTES) return (2);
-	if (x <= ENCODING_LIMIT_3_BYTES) return (3);
-	
-	var numbytes = 1;
-	
-	// Last byte gives you XML_TT_VAL_BITS
-	// Remainder each give you XML_REG_VAL_BITS
-	x = x >>> XML_TT_VAL_BITS;
-	while (x != 0) {
-        numbytes++;
-		x = x >>> XML_REG_VAL_BITS;
-	}
-	return (numbytes);
-};
-
-BinaryXMLEncoder.prototype.writeDateTime = function(
-		//String 
-		tag, 
-		//CCNTime 
-		dateTime) {
-	
-	if(LOG>4)console.log('ENCODING DATE with LONG VALUE');
-	if(LOG>4)console.log(dateTime.msec);
-	
-	//var binarydate = DataUtils.unsignedLongToByteArray( Math.round((dateTime.msec/1000) * 4096)  );
-	
-
-	//parse to hex
-	var binarydate =  Math.round((dateTime.msec/1000) * 4096).toString(16)  ;
-
-	//HACK
-	var binarydate =  DataUtils.toNumbers( '0'.concat(binarydate,'0')) ;
-
-	
-	if(LOG>4)console.log('ENCODING DATE with BINARY VALUE');
-	if(LOG>4)console.log(binarydate);
-	if(LOG>4)console.log('ENCODING DATE with BINARY VALUE(HEX)');
-	if(LOG>4)console.log(DataUtils.toHex(binarydate));
-	
-	this.writeElement(tag, binarydate);
-};
-
-BinaryXMLEncoder.prototype.writeString = function(
-		//String 
-		input,
-		//CCNTime 
-		offset) {
-	
-    if(typeof input === 'string'){
-		//console.log('went here');
-    	if(LOG>4) console.log('GOING TO WRITE A STRING');
-    	if(LOG>4) console.log(input);
-        
-		for (i = 0; i < input.length; i++) {
-			if(LOG>4) console.log('input.charCodeAt(i)=' + input.charCodeAt(i));
-		    this.ostream[this.offset+i] = (input.charCodeAt(i));
-		}
-	}
-    else{
-		if(LOG>4) console.log('GOING TO WRITE A STRING IN BINARY FORM');
-		if(LOG>4) console.log(input);
-		
-		this.writeBlobArray(input);
-    }
-    /*
-	else if(typeof input === 'object'){
-		
-	}	
-	*/
-};
-
-
-BinaryXMLEncoder.prototype.writeBlobArray = function(
-		//Uint8Array 
-		blob,
-		//int 
-		offset) {
-	
-	if(LOG>4) console.log('GOING TO WRITE A BLOB');
-    
-	/*for (var i = 0; i < Blob.length; i++) {
-	    this.ostream[this.offset+i] = Blob[i];
-	}*/
-	this.ostream.set(blob, this.offset);
-};
-
-
-BinaryXMLEncoder.prototype.getReducedOstream = function() {
-	return this.ostream.subarray(0, this.offset);
-};
-
-/*
- * This class is used to decode ccnb binary elements (blob, type/value pairs).
- * 
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- */
-
-var XML_EXT = 0x00; 
-	
-var XML_TAG = 0x01; 
-	
-var XML_DTAG = 0x02; 
-	
-var XML_ATTR = 0x03; 
- 
-var XML_DATTR = 0x04; 
-	
-var XML_BLOB = 0x05; 
-	
-var XML_UDATA = 0x06; 
-	
-var XML_CLOSE = 0x0;
-
-var XML_SUBTYPE_PROCESSING_INSTRUCTIONS = 16; 
-	
-
-var XML_TT_BITS = 3;
-var XML_TT_MASK = ((1 << XML_TT_BITS) - 1);
-var XML_TT_VAL_BITS = XML_TT_BITS + 1;
-var XML_TT_VAL_MASK = ((1 << (XML_TT_VAL_BITS)) - 1);
-var XML_REG_VAL_BITS = 7;
-var XML_REG_VAL_MASK = ((1 << XML_REG_VAL_BITS) - 1);
-var XML_TT_NO_MORE = (1 << XML_REG_VAL_BITS); // 0x80
-var BYTE_MASK = 0xFF;
-var LONG_BYTES = 8;
-var LONG_BITS = 64;
-	
-var bits_11 = 0x0000007FF;
-var bits_18 = 0x00003FFFF;
-var bits_32 = 0x0FFFFFFFF;
-
-
-
-//returns a string
-tagToString = function(/*long*/ tagVal) {
-	if ((tagVal >= 0) && (tagVal < CCNProtocolDTagsStrings.length)) {
-		return CCNProtocolDTagsStrings[tagVal];
-	} else if (tagVal == CCNProtocolDTags.CCNProtocolDataUnit) {
-		return CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT;
-	}
-	return null;
-};
-
-//returns a Long
-stringToTag =  function(/*String*/ tagName) {
-	// the slow way, but right now we don't care.... want a static lookup for the forward direction
-	for (var i=0; i < CCNProtocolDTagsStrings.length; ++i) {
-		if ((null != CCNProtocolDTagsStrings[i]) && (CCNProtocolDTagsStrings[i] == tagName)) {
-			return i;
-		}
-	}
-	if (CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT == tagName) {
-		return CCNProtocolDTags.CCNProtocolDataUnit;
-	}
-	return null;
-};
-
-//console.log(stringToTag(64));
-var BinaryXMLDecoder = function BinaryXMLDecoder(istream){
-	var MARK_LEN=512;
-	var DEBUG_MAX_LEN =  32768;
-	
-	this.istream = istream;
-	this.offset = 0;
-};
-
-BinaryXMLDecoder.prototype.readAttributes = function(
-	//TreeMap<String,String> 
-	attributes){
-	
-	if (null == attributes) {
-		return;
-	}
-
-	try {
-
-		//this.TypeAndVal 
-		var nextTV = this.peekTypeAndVal();
-
-		while ((null != nextTV) && ((XML_ATTR == nextTV.type()) ||
-				(XML_DATTR == nextTV.type()))) {
-
-			//this.TypeAndVal 
-			var thisTV = this.decodeTypeAndVal();
-
-			var attributeName = null;
-			if (XML_ATTR == thisTV.type()) {
-				
-				attributeName = this.decodeUString(thisTV.val()+1);
-
-			} else if (XML_DATTR == thisTV.type()) {
-				// DKS TODO are attributes same or different dictionary?
-				attributeName = tagToString(thisTV.val());
-				if (null == attributeName) {
-					throw new ContentDecodingException(new Error("Unknown DATTR value" + thisTV.val()));
-				}
-			}
-			
-			var attributeValue = this.decodeUString();
-
-			attributes.put(attributeName, attributeValue);
-
-			nextTV = this.peekTypeAndVal();
-		}
-
-	} catch ( e) {
-
-		throw new ContentDecodingException(new Error("readStartElement", e));
-	}
-};
-
-
-BinaryXMLDecoder.prototype.initializeDecoding = function() {
-		//if (!this.istream.markSupported()) {
-			//throw new IllegalArgumentException(this.getClass().getName() + ": input stream must support marking!");
-		//}
-}
-
-BinaryXMLDecoder.prototype.readStartDocument = function(){
-		// Currently no start document in binary encoding.
-	}
-
-BinaryXMLDecoder.prototype.readEndDocument = function() {
-		// Currently no end document in binary encoding.
-	};
-
-BinaryXMLDecoder.prototype.readStartElement = function(
-		//String 
-		startTag,
-		//TreeMap<String, String> 
-		attributes) {
-	
-		
-		//NOT SURE
-		//if(typeof startTag == 'number')
-			//startTag = tagToString(startTag);
-		
-			//TypeAndVal 
-			tv = this.decodeTypeAndVal();
-			
-			if (null == tv) {
-				throw new ContentDecodingException(new Error("Expected start element: " + startTag + " got something not a tag."));
-			}
-			
-			//String 
-			var decodedTag = null;
-			//console.log(tv);
-			//console.log(typeof tv);
-			
-			//console.log(XML_TAG);
-			if (tv.type() == XML_TAG) {
-				//console.log('got here');
-				//Log.info(Log.FAC_ENCODING, "Unexpected: got tag in readStartElement; looking for tag " + startTag + " got length: " + (int)tv.val()+1);
-				// Tag value represents length-1 as tags can never be empty.
-				var valval ;
-				if(typeof tv.val() == 'string'){
-					valval = (parseInt(tv.val())) + 1;
-				}
-				else
-					valval = (tv.val())+ 1;
-				
-				//console.log('valval is ' +valval);
-				
-				decodedTag = this.decodeUString(valval);
-				
-			} else if (tv.type() == XML_DTAG) {
-				//console.log('gothere');
-				//console.log(tv.val());
-				//decodedTag = tagToString(tv.val());
-				//console.log()
-				decodedTag = tv.val();
-			}
-			
-			//console.log(decodedTag);
-			//console.log('startTag is '+startTag);
-			
-			
-			if ((null ==  decodedTag) || decodedTag != startTag ) {
-				console.log('expecting '+ startTag + ' but got '+ decodedTag);
-				throw new ContentDecodingException(new Error("Expected start element: " + startTag + " got: " + decodedTag + "(" + tv.val() + ")"));
-			}
-			
-			// DKS: does not read attributes out of stream if caller doesn't
-			// ask for them. Should possibly peek and skip over them regardless.
-			// TODO: fix this
-			if (null != attributes) {
-				readAttributes(attributes); 
-			}
-	}
-	
-
-BinaryXMLDecoder.prototype.readAttributes = function(
-	//TreeMap<String,String> 
-	attributes) {
-	
-	if (null == attributes) {
-		return;
-	}
-
-	try {
-		// Now need to get attributes.
-		//TypeAndVal 
-		var nextTV = this.peekTypeAndVal();
-
-		while ((null != nextTV) && ((XML_ATTR == nextTV.type()) ||
-				(XML_DATTR == nextTV.type()))) {
-
-			// Decode this attribute. First, really read the type and value.
-			//this.TypeAndVal 
-			var thisTV = this.decodeTypeAndVal();
-
-			//String 
-			var attributeName = null;
-			if (XML_ATTR == thisTV.type()) {
-				// Tag value represents length-1 as attribute names cannot be empty.
-				var valval ;
-				if(typeof tv.val() == 'string'){
-					valval = (parseInt(tv.val())) + 1;
-				}
-				else
-					valval = (tv.val())+ 1;
-				
-				attributeName = this.decodeUString(valval);
-
-			} else if (XML_DATTR == thisTV.type()) {
-				// DKS TODO are attributes same or different dictionary?
-				attributeName = tagToString(thisTV.val());
-				if (null == attributeName) {
-					throw new ContentDecodingException(new Error("Unknown DATTR value" + thisTV.val()));
-				}
-			}
-			// Attribute values are always UDATA
-			//String
-			var attributeValue = this.decodeUString();
-
-			//
-			attributes.push([attributeName, attributeValue]);
-
-			nextTV = this.peekTypeAndVal();
-		}
-	} catch ( e) {
-		throw new ContentDecodingException(new Error("readStartElement", e));
-	}
-};
-
-//returns a string
-BinaryXMLDecoder.prototype.peekStartElementAsString = function() {
-	//this.istream.mark(MARK_LEN);
-
-	//String 
-	var decodedTag = null;
-	var previousOffset = this.offset;
-	try {
-		// Have to distinguish genuine errors from wrong tags. Could either use
-		// a special exception subtype, or redo the work here.
-		//this.TypeAndVal 
-		var tv = this.decodeTypeAndVal();
-
-		if (null != tv) {
-
-			if (tv.type() == XML_TAG) {
-				/*if (tv.val()+1 > DEBUG_MAX_LEN) {
-					throw new ContentDecodingException(new Error("Decoding error: length " + tv.val()+1 + " longer than expected maximum length!")(;
-				}*/
-
-				// Tag value represents length-1 as tags can never be empty.
-				var valval ;
-				if(typeof tv.val() == 'string'){
-					valval = (parseInt(tv.val())) + 1;
-				}
-				else
-					valval = (tv.val())+ 1;
-				
-				decodedTag = this.decodeUString(valval);
-				
-				//Log.info(Log.FAC_ENCODING, "Unexpected: got text tag in peekStartElement; length: " + valval + " decoded tag = " + decodedTag);
-
-			} else if (tv.type() == XML_DTAG) {
-				decodedTag = tagToString(tv.val());					
-			}
-
-		} // else, not a type and val, probably an end element. rewind and return false.
-
-	} catch ( e) {
-
-	} finally {
-		try {
-			this.offset = previousOffset;
-		} catch ( e) {
-			Log.logStackTrace(Log.FAC_ENCODING, Level.WARNING, e);
-			throw new ContentDecodingException(new Error("Cannot reset stream! " + e.getMessage(), e));
-		}
-	}
-	return decodedTag;
-};
-
-BinaryXMLDecoder.prototype.peekStartElement = function(
-		//String 
-		startTag) {
-	//String 
-	if(typeof startTag == 'string'){
-		var decodedTag = this.peekStartElementAsString();
-		
-		if ((null !=  decodedTag) && decodedTag == startTag) {
-			return true;
-		}
-		return false;
-	}
-	else if(typeof startTag == 'number'){
-		var decodedTag = this.peekStartElementAsLong();
-		if ((null !=  decodedTag) && decodedTag == startTag) {
-			return true;
-		}
-		return false;
-	}
-	else{
-		throw new ContentDecodingException(new Error("SHOULD BE STRING OR NUMBER"));
-	}
-}
-//returns Long
-BinaryXMLDecoder.prototype.peekStartElementAsLong = function() {
-		//this.istream.mark(MARK_LEN);
-
-		//Long
-		var decodedTag = null;
-		
-		var previousOffset = this.offset;
-		
-		try {
-			// Have to distinguish genuine errors from wrong tags. Could either use
-			// a special exception subtype, or redo the work here.
-			//this.TypeAndVal
-			var tv = this.decodeTypeAndVal();
-
-			if (null != tv) {
-
-				if (tv.type() == XML_TAG) {
-					if (tv.val()+1 > DEBUG_MAX_LEN) {
-						throw new ContentDecodingException(new Error("Decoding error: length " + tv.val()+1 + " longer than expected maximum length!"));
-					}
-
-					var valval ;
-					if(typeof tv.val() == 'string'){
-						valval = (parseInt(tv.val())) + 1;
-					}
-					else
-						valval = (tv.val())+ 1;
-					
-					// Tag value represents length-1 as tags can never be empty.
-					//String 
-					var strTag = this.decodeUString(valval);
-					
-					decodedTag = stringToTag(strTag);
-					
-					//Log.info(Log.FAC_ENCODING, "Unexpected: got text tag in peekStartElement; length: " + valval + " decoded tag = " + decodedTag);
-					
-				} else if (tv.type() == XML_DTAG) {
-					decodedTag = tv.val();					
-				}
-
-			} // else, not a type and val, probably an end element. rewind and return false.
-
-		} catch ( e) {
-			
-		} finally {
-			try {
-				//this.istream.reset();
-				this.offset = previousOffset;
-			} catch ( e) {
-				Log.logStackTrace(Log.FAC_ENCODING, Level.WARNING, e);
-				throw new Error("Cannot reset stream! " + e.getMessage(), e);
-			}
-		}
-		return decodedTag;
-	};
-
-
-// returns a byte[]
-BinaryXMLDecoder.prototype.readBinaryElement = function(
-		//long 
-		startTag,
-		//TreeMap<String, String> 
-		attributes){
-	//byte [] 
-	var blob = null;
-	
-	this.readStartElement(startTag, attributes);
-	blob = this.readBlob();	
-
-	return blob;
-};
-	
-	
-BinaryXMLDecoder.prototype.readEndElement = function(){
-			if(LOG>4)console.log('this.offset is '+this.offset);
-			
-			var next = this.istream[this.offset]; 
-			
-			this.offset++;
-			//read();
-			
-			if(LOG>4)console.log('XML_CLOSE IS '+XML_CLOSE);
-			if(LOG>4)console.log('next is '+next);
-			
-			if (next != XML_CLOSE) {
-				console.log("Expected end element, got: " + next);
-				throw new ContentDecodingException(new Error("Expected end element, got: " + next));
-			}
-	};
-
-
-//String	
-BinaryXMLDecoder.prototype.readUString = function(){
-			//String 
-			var ustring = this.decodeUString();	
-			this.readEndElement();
-			return ustring;
-
-	};
-	
-
-//returns a byte[]
-BinaryXMLDecoder.prototype.readBlob = function() {
-			//byte []
-			
-			var blob = this.decodeBlob();	
-			this.readEndElement();
-			return blob;
-
-	};
-
-
-//CCNTime
-BinaryXMLDecoder.prototype.readDateTime = function(
-	//long 
-	startTag)  {
-	//byte [] 
-	
-	var byteTimestamp = this.readBinaryElement(startTag);
-
-	//var lontimestamp = DataUtils.byteArrayToUnsignedLong(byteTimestamp);
-
-	byteTimestamp = DataUtils.toHex(byteTimestamp);
-	
-	
-	byteTimestamp = parseInt(byteTimestamp, 16);
-
-	var lontimestamp = (byteTimestamp/ 4096) * 1000;
-
-	//if(lontimestamp<0) lontimestamp =  - lontimestamp;
-
-	if(LOG>3) console.log('DECODED DATE WITH VALUE');
-	if(LOG>3) console.log(lontimestamp);
-	
-
-	//CCNTime 
-	var timestamp = new CCNTime(lontimestamp);
-	//timestamp.setDateBinary(byteTimestamp);
-	
-	if (null == timestamp) {
-		throw new ContentDecodingException(new Error("Cannot parse timestamp: " + DataUtils.printHexBytes(byteTimestamp)));
-	}		
-	return timestamp;
-};
-
-BinaryXMLDecoder.prototype.decodeTypeAndVal = function() {
-	
-	/*int*/var type = -1;
-	/*long*/var val = 0;
-	/*boolean*/var more = true;
-
-	do {
-		
-		var next = this.istream[this.offset ];
-		
-		
-		if (next < 0) {
-			return null; 
-		}
-
-		if ((0 == next) && (0 == val)) {
-			return null;
-		}
-		
-		more = (0 == (next & XML_TT_NO_MORE));
-		
-		if  (more) {
-			val = val << XML_REG_VAL_BITS;
-			val |= (next & XML_REG_VAL_MASK);
-		} else {
-
-			type = next & XML_TT_MASK;
-			val = val << XML_TT_VAL_BITS;
-			val |= ((next >>> XML_TT_BITS) & XML_TT_VAL_MASK);
-		}
-		
-		this.offset++;
-		
-	} while (more);
-	
-	if(LOG>3)console.log('TYPE is '+ type + ' VAL is '+ val);
-
-	return new TypeAndVal(type, val);
-};
-
-
-
-//TypeAndVal
-BinaryXMLDecoder.peekTypeAndVal = function() {
-	//TypeAndVal 
-	var tv = null;
-	
-	//this.istream.mark(LONG_BYTES*2);		
-	
-	var previousOffset = this.offset;
-	
-	try {
-		tv = this.decodeTypeAndVal();
-	} finally {
-		//this.istream.reset();
-		this.offset = previousOffset;
-	}
-	
-	return tv;
-};
-
-
-//Uint8Array
-BinaryXMLDecoder.prototype.decodeBlob = function(
-		//int 
-		blobLength) {
-	
-	if(null == blobLength){
-		//TypeAndVal
-		var tv = this.decodeTypeAndVal();
-
-		var valval ;
-		
-		if(typeof tv.val() == 'string'){
-			valval = (parseInt(tv.val()));
-		}
-		else
-			valval = (tv.val());
-		
-		//console.log('valval here is ' + valval);
-		return  this.decodeBlob(valval);
-	}
-	
-	//
-	//Uint8Array
-	var bytes = this.istream.subarray(this.offset, this.offset+ blobLength);
-	this.offset += blobLength;
-	
-	return bytes;
-};
-
-var count =0;
-
-//String
-BinaryXMLDecoder.prototype.decodeUString = function(
-		//int 
-		byteLength) {
-	
-	/*
-	console.log('COUNT IS '+count);
-	console.log('INPUT BYTELENGTH IS '+byteLength);
-	count++;
-	if(null == byteLength||  undefined == byteLength){
-		console.log("!!!!");
-		tv = this.decodeTypeAndVal();
-		var valval ;
-		if(typeof tv.val() == 'string'){
-			valval = (parseInt(tv.val()));
-		}
-		else
-			valval = (tv.val());
-		
-		if(LOG>4) console.log('valval  is ' + valval);
-		byteLength= this.decodeUString(valval);
-		
-		//if(LOG>4) console.log('byte Length found in type val is '+ byteLength.charCodeAt(0));
-		byteLength = parseInt(byteLength);
-		
-		
-		//byteLength = byteLength.charCodeAt(0);
-		//if(LOG>4) console.log('byte Length found in type val is '+ byteLength);
-	}
-	if(LOG>4)console.log('byteLength is '+byteLength);
-	if(LOG>4)console.log('type of byteLength is '+typeof byteLength);
-	
-	stringBytes = this.decodeBlob(byteLength);
-	
-	//console.log('String bytes are '+ stringBytes);
-	//console.log('stringBytes);
-	
-	if(LOG>4)console.log('byteLength is '+byteLength);
-	if(LOG>4)console.log('this.offset is '+this.offset);
-
-	tempBuffer = this.istream.slice(this.offset, this.offset+byteLength);
-	if(LOG>4)console.log('TEMPBUFFER IS' + tempBuffer);
-	if(LOG>4)console.log( tempBuffer);
-
-	if(LOG>4)console.log('ADDING to offset value' + byteLength);
-	this.offset+= byteLength;
-	//if(LOG>3)console.log('read the String' + tempBuffer.toString('ascii'));
-	//return tempBuffer.toString('ascii');//
-	
-	
-	//if(LOG>3)console.log( 'STRING READ IS '+ DataUtils.getUTF8StringFromBytes(stringBytes) ) ;
-	//if(LOG>3)console.log( 'STRING READ IS '+ DataUtils.getUTF8StringFromBytes(tempBuffer) ) ;
-	//if(LOG>3)console.log(DataUtils.getUTF8StringFromBytes(tempBuffer) ) ;
-	//return DataUtils.getUTF8StringFromBytes(tempBuffer);
-	
-	if(LOG>3)console.log( 'STRING READ IS '+ DataUtils.toString(stringBytes) ) ;
-	if(LOG>3)console.log( 'TYPE OF STRING READ IS '+ typeof DataUtils.toString(stringBytes) ) ;
-
-	return  DataUtils.toString(stringBytes);*/
-
-	if(null == byteLength ){
-		var tempStreamPosition = this.offset;
-			
-		//TypeAndVal 
-		var tv = this.decodeTypeAndVal();
-		
-		if(LOG>3)console.log('TV is '+tv);
-		if(LOG>3)console.log(tv);
-		
-		if(LOG>3)console.log('Type of TV is '+typeof tv);
-	
-		if ((null == tv) || (XML_UDATA != tv.type())) { // if we just have closers left, will get back null
-			//if (Log.isLoggable(Log.FAC_ENCODING, Level.FINEST))
-				//Log.finest(Log.FAC_ENCODING, "Expected UDATA, got " + ((null == tv) ? " not a tag " : tv.type()) + ", assuming elided 0-length blob.");
-			
-			this.offset = tempStreamPosition;
-			
-			return "";
-		}
-			
-		return this.decodeUString(tv.val());
-	}
-	else{
-		//byte [] 
-		var stringBytes = this.decodeBlob(byteLength);
-		
-		//return DataUtils.getUTF8StringFromBytes(stringBytes);
-		return  DataUtils.toString(stringBytes);
-		
-	}
-};
-
-
-
-
-//OBject containg a pair of type and value
-var TypeAndVal = function TypeAndVal(_type,_val) {
-	this.t = _type;
-	this.v = _val;
-};
-
-TypeAndVal.prototype.type = function(){
-	return this.t;
-};
-
-TypeAndVal.prototype.val = function(){
-	return this.v;
-};
-
-
-
-
-BinaryXMLDecoder.prototype.readIntegerElement =function(
-	//String 
-	startTag) {
-
-	//String 
-	if(LOG>4) console.log('READING INTEGER '+ startTag);
-	if(LOG>4) console.log('TYPE OF '+ typeof startTag);
-	
-	var strVal = this.readUTF8Element(startTag);
-	
-	return parseInt(strVal);
-};
-
-
-BinaryXMLDecoder.prototype.readUTF8Element =function(
-			//String 
-			startTag,
-			//TreeMap<String, String> 
-			attributes) {
-			//throws Error where name == "ContentDecodingException" 
-
-		this.readStartElement(startTag, attributes); // can't use getElementText, can't get attributes
-		//String 
-		var strElementText = this.readUString();
-		return strElementText;
-};
-
-
-/* 
- * Set the offset into the input, used for the next read.
- */
-BinaryXMLDecoder.prototype.seek = function(
-        //int
-        offset) {
-    this.offset = offset;
-}
-
-/*
- * Call with: throw new ContentDecodingException(new Error("message")).
- */
-function ContentDecodingException(error) {
-    this.message = error.message;
-    // Copy lineNumber, etc. from where new Error was called.
-    for (var prop in error)
-        this[prop] = error[prop];
-}
-ContentDecodingException.prototype = new Error();
-ContentDecodingException.prototype.name = "ContentDecodingException";
-
-/*
- * This class uses BinaryXMLDecoder to follow the structure of a ccnb binary element to 
- * determine its end.
- * 
- * @author: Jeff Thompson
- * See COPYING for copyright and distribution information.
- */
-
-var BinaryXMLStructureDecoder = function BinaryXMLDecoder() {
-    this.gotElementEnd = false;
-	this.offset = 0;
-    this.level = 0;
-    this.state = BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE;
-    this.headerLength = 0;
-    this.useHeaderBuffer = false;
-    this.headerBuffer = new Uint8Array(5);
-    this.nBytesToRead = 0;
-};
-
-BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE = 0;
-BinaryXMLStructureDecoder.READ_BYTES = 1;
-
-/*
- * Continue scanning input starting from this.offset.  If found the end of the element
- *   which started at offset 0 then return true, else false.
- * If this returns false, you should read more into input and call again.
- * You have to pass in input each time because the array could be reallocated.
- * This throws an exception for badly formed ccnb.
- */
-BinaryXMLStructureDecoder.prototype.findElementEnd = function(
-    // Uint8Array
-    input)
-{
-    if (this.gotElementEnd)
-        // Someone is calling when we already got the end.
-        return true;
-    
-    var decoder = new BinaryXMLDecoder(input);
-    
-    while (true) {
-        if (this.offset >= input.length)
-            // All the cases assume we have some input.
-            return false;
-                
-        switch (this.state) {
-            case BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE:               
-                // First check for XML_CLOSE.
-                if (this.headerLength == 0 && input[this.offset] == XML_CLOSE) {
-                    ++this.offset;
-                    // Close the level.
-                    --this.level;
-                    if (this.level == 0)
-                        // Finished.
-                        return true;
-                    if (this.level < 0)
-                        throw new Error("BinaryXMLStructureDecoder: Unexepected close tag at offset " +
-                            (this.offset - 1));
-                    
-                    // Get ready for the next header.
-                    this.startHeader();
-                    break;
-                }
-                
-                var startingHeaderLength = this.headerLength;
-                while (true) {
-                    if (this.offset >= input.length) {
-                        // We can't get all of the header bytes from this input. Save in headerBuffer.
-                        this.useHeaderBuffer = true;
-                        var nNewBytes = this.headerLength - startingHeaderLength;
-                        this.setHeaderBuffer
-                            (input.subarray(this.offset - nNewBytes, nNewBytes), startingHeaderLength);
-                        
-                        return false;
-                    }
-                    var headerByte = input[this.offset++];
-                    ++this.headerLength;
-                    if (headerByte & XML_TT_NO_MORE)
-                        // Break and read the header.
-                        break;
-                }
-                
-                var typeAndVal;
-                if (this.useHeaderBuffer) {
-                    // Copy the remaining bytes into headerBuffer.
-                    nNewBytes = this.headerLength - startingHeaderLength;
-                    this.setHeaderBuffer
-                        (input.subarray(this.offset - nNewBytes, nNewBytes), startingHeaderLength);
-
-                    typeAndVal = new BinaryXMLDecoder(this.headerBuffer).decodeTypeAndVal();
-                }
-                else {
-                    // We didn't have to use the headerBuffer.
-                    decoder.seek(this.offset - this.headerLength);
-                    typeAndVal = decoder.decodeTypeAndVal();
-                }
-                
-                if (typeAndVal == null)
-                    throw new Error("BinaryXMLStructureDecoder: Can't read header starting at offset " +
-                        (this.offset - this.headerLength));
-                
-                // Set the next state based on the type.
-                var type = typeAndVal.t;
-                if (type == XML_DATTR)
-                    // We already consumed the item. READ_HEADER_OR_CLOSE again.
-                    // ccnb has rules about what must follow an attribute, but we are just scanning.
-                    this.startHeader();
-                else if (type == XML_DTAG || type == XML_EXT) {
-                    // Start a new level and READ_HEADER_OR_CLOSE again.
-                    ++this.level;
-                    this.startHeader();
-                }
-                else if (type == XML_TAG || type == XML_ATTR) {
-                    if (type == XML_TAG)
-                        // Start a new level and read the tag.
-                        ++this.level;
-                    // Minimum tag or attribute length is 1.
-                    this.nBytesToRead = typeAndVal.v + 1;
-                    this.state = BinaryXMLStructureDecoder.READ_BYTES;
-                    // ccnb has rules about what must follow an attribute, but we are just scanning.
-                }
-                else if (type == XML_BLOB || type == XML_UDATA) {
-                    this.nBytesToRead = typeAndVal.v;
-                    this.state = BinaryXMLStructureDecoder.READ_BYTES;
-                }
-                else
-                    throw new Error("BinaryXMLStructureDecoder: Unrecognized header type " + type);
-                break;
-            
-            case BinaryXMLStructureDecoder.READ_BYTES:
-                var nRemainingBytes = input.length - this.offset;
-                if (nRemainingBytes < this.nBytesToRead) {
-                    // Need more.
-                    this.offset += nRemainingBytes;
-                    this.nBytesToRead -= nRemainingBytes;
-                    return false;
-                }
-                // Got the bytes.  Read a new header or close.
-                this.offset += this.nBytesToRead;
-                this.startHeader();
-                break;
-            
-            default:
-                // We don't expect this to happen.
-                throw new Error("BinaryXMLStructureDecoder: Unrecognized state " + this.state);
-        }
-    }
-};
-
-/*
- * Set the state to READ_HEADER_OR_CLOSE and set up to start reading the header
- */
-BinaryXMLStructureDecoder.prototype.startHeader = function() {
-    this.headerLength = 0;
-    this.useHeaderBuffer = false;
-    this.state = BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE;    
-}
-
-/*
- *  Set the offset into the input, used for the next read.
- */
-BinaryXMLStructureDecoder.prototype.seek = function(
-        //int
-        offset) {
-    this.offset = offset;
-}
-
-/*
- * Set call this.headerBuffer.set(subarray, bufferOffset), an reallocate the headerBuffer if needed.
- */
-BinaryXMLStructureDecoder.prototype.setHeaderBuffer = function(subarray, bufferOffset) {
-    var size = subarray.length + bufferOffset;
-    if (size > this.headerBuffer.length) {
-        // Reallocate the buffer.
-        var newHeaderBuffer = new Uint8Array(size + 5);
-        newHeaderBuffer.set(this.headerBuffer);
-        this.headerBuffer = newHeaderBuffer;
-    }
-    this.headerBuffer.set(subarray, bufferOffset);
-}/*
- * This class contains utilities to help parse the data
- * author: Meki Cheraoui, Jeff Thompson
- * See COPYING for copyright and distribution information.
- */
- 
-var DataUtils = function DataUtils(){
-	
-	
-};
-
-
-/*
- * NOTE THIS IS CURRENTLY NOT BEHING USED
- * 
- */
-
-DataUtils.keyStr = "ABCDEFGHIJKLMNOP" +
-               "QRSTUVWXYZabcdef" +
-               "ghijklmnopqrstuv" +
-               "wxyz0123456789+/" +
-               "=";
-
-               
-/**
- * Raw String to Base 64
- */
-DataUtils.stringtoBase64=function stringtoBase64(input) {
-     input = escape(input);
-     var output = "";
-     var chr1, chr2, chr3 = "";
-     var enc1, enc2, enc3, enc4 = "";
-     var i = 0;
-
-     do {
-        chr1 = input.charCodeAt(i++);
-        chr2 = input.charCodeAt(i++);
-        chr3 = input.charCodeAt(i++);
-
-        enc1 = chr1 >> 2;
-        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
-        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
-        enc4 = chr3 & 63;
-
-        if (isNaN(chr2)) {
-           enc3 = enc4 = 64;
-        } else if (isNaN(chr3)) {
-           enc4 = 64;
-        }
-
-        output = output +
-           DataUtils.keyStr.charAt(enc1) +
-           DataUtils.keyStr.charAt(enc2) +
-           DataUtils.keyStr.charAt(enc3) +
-           DataUtils.keyStr.charAt(enc4);
-        chr1 = chr2 = chr3 = "";
-        enc1 = enc2 = enc3 = enc4 = "";
-     } while (i < input.length);
-
-     return output;
-  }
-
-/**
- * Base 64 to Raw String 
- */
-DataUtils.base64toString = function base64toString(input) {
-     var output = "";
-     var chr1, chr2, chr3 = "";
-     var enc1, enc2, enc3, enc4 = "";
-     var i = 0;
-
-     // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
-     var base64test = /[^A-Za-z0-9\+\/\=]/g;
-     /* Test for invalid characters. */
-     if (base64test.exec(input)) {
-        alert("There were invalid base64 characters in the input text.\n" +
-              "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
-              "Expect errors in decoding.");
-     }
-     
-     input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
-
-     do {
-        enc1 = DataUtils.keyStr.indexOf(input.charAt(i++));
-        enc2 = DataUtils.keyStr.indexOf(input.charAt(i++));
-        enc3 = DataUtils.keyStr.indexOf(input.charAt(i++));
-        enc4 = DataUtils.keyStr.indexOf(input.charAt(i++));
-
-        chr1 = (enc1 << 2) | (enc2 >> 4);
-        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
-        chr3 = ((enc3 & 3) << 6) | enc4;
-
-        output = output + String.fromCharCode(chr1);
-
-        if (enc3 != 64) {
-           output = output + String.fromCharCode(chr2);
-        }
-        if (enc4 != 64) {
-           output = output + String.fromCharCode(chr3);
-        }
-
-        chr1 = chr2 = chr3 = "";
-        enc1 = enc2 = enc3 = enc4 = "";
-
-     } while (i < input.length);
-
-     return unescape(output);
-  };
-
-//byte [] 
-
-/**
- * NOT WORKING!!!!!
- * 
- * Unsiged Long Number to Byte Array
- */
-	
- /*
-DataUtils.unsignedLongToByteArray= function( value) {
-	
-	if(LOG>4)console.log('INPUT IS '+value);
-	
-	if( 0 == value )
-		return [0];
-
-	if( 0 <= value && value <= 0x00FF ) {
-		//byte [] 
-		var bb = new Array(1);
-		bb[0] = (value & 0x00FF);
-		return bb;
-	}
-
-	if(LOG>4) console.log('type of value is '+typeof value);
-	if(LOG>4) console.log('value is '+value);
-	//byte [] 
-	var out = null;
-	//int
-	var offset = -1;
-	for(var i = 7; i >=0; --i) {
-		//byte
-		console.log(i);
-		console.log('value is '+value);
-		console.log('(value >> (i * 8)) '+ (value >> (i * 8))  );
-		console.log(' ((value >> (i * 8)) & 0xFF) '+ ((value >> (i * 8)) & 0xFF)  );
-
-		var b = ((value >> (i * 8)) & 0xFF)  ;
-		
-		if(LOG>4) console.log('b is '+b);
-		
-		if( out == null && b != 0 ) {
-			//out = new byte[i+1];
-			out = new Array(i+1);
-			offset = i;
-		}
-		
-		if( out != null )
-			out[ offset - i ] = b;
-	}
-	if(LOG>4)console.log('OUTPUT IS ');
-	if(LOG>4)console.log(out);
-	return out;
-}
-*/
-	
-/**
- * NOT WORKING!!!!!
- * 
- * Unsiged Long Number to Byte Array
- *//*
-DataUtils.byteArrayToUnsignedLong = function(//final byte [] 
-	src) {
-		if(LOG>4) console.log('INPUT IS ');
-		if(LOG>4) console.log(src);
-		
-		var value = 0;
-		for(var i = 0; i < src.length; i++) {
-			value = value << 8;
-			// Java will assume the byte is signed, so extend it and trim it.
-			
-			
-			var b = ((src[i]) & 0xFF );
-			value |= b;
-		}
-		
-		if(LOG>4) console.log('OUTPUT IS ');
-		
-		if(LOG>4) console.log(value);
-
-		return value;
-	}*/
-
-
-/**
- * Hex String to Byte Array
- */
-	//THIS IS NOT WORKING
-/*
-DataUtils.HexStringtoByteArray = function(str) {
-    var byteArray = [];
-    for (var i = 0; i < str.length; i++)
-        if (str.charCodeAt(i) <= 0x7F)
-            byteArray.push(str.charCodeAt(i));
-        else {
-            var h = encodeURIComponent(str.charAt(i)).substr(1).split('%');
-            for (var j = 0; j < h.length; j++)
-                byteArray.push(parseInt(h[j], 16));
-        }
-    return byteArray;
-};
-*/
-
-/**
- * Uint8Array to Hex String
- */
-//http://ejohn.org/blog/numbers-hex-and-colors/
-DataUtils.toHex = function(arguments){
-	if (LOG>4) console.log('ABOUT TO CONVERT '+ arguments);
-	//console.log(arguments);
-  	var ret = "";
-  	for ( var i = 0; i < arguments.length; i++ )
-    	ret += (arguments[i] < 16 ? "0" : "") + arguments[i].toString(16);
-  	if (LOG>4) console.log('Converted to: ' + ret);
-  	return ret; //.toUpperCase();
-}
-
-/**
- * Raw string to hex string.
- */
-DataUtils.stringToHex = function(arguments){
-	var ret = "";
-	for (var i = 0; i < arguments.length; ++i) {
-		var value = arguments.charCodeAt(i);
-		ret += (value < 16 ? "0" : "") + value.toString(16);
-	}
-	return ret;
-}
-
-/**
- * Uint8Array to raw string.
- */
-DataUtils.toString = function(arguments){
-  //console.log(arguments);
-  var ret = "";
-  for ( var i = 0; i < arguments.length; i++ )
-    ret += String.fromCharCode(arguments[i]);
-  return ret;
-}
-
-/**
- * Hex String to Uint8Array.
- */
-DataUtils.toNumbers = function(str) {
-	if (typeof str == 'string') {
-		var ret = new Uint8Array(Math.floor(str.length / 2));
-        var i = 0;
-		str.replace(/(..)/g, function(str) {
-		    ret[i++] = parseInt(str, 16);
-		});
-		return ret;
-    }
-}
-
-/**
- * Hex String to raw string.
- */
-DataUtils.hexToRawString = function(str) {
-    if(typeof str =='string') {
-		var ret = "";
-		str.replace(/(..)/g, function(s) {
-			ret += String.fromCharCode(parseInt(s, 16));
-		});
-		return ret;
-    }
-}
-
-/**
- * Raw String to Uint8Array.
- */
-DataUtils.toNumbersFromString = function( str ){
-	var bytes = new Uint8Array(str.length);
-	for(var i=0;i<str.length;i++)
-		bytes[i] = str.charCodeAt(i);
-	return bytes;
-}
-
-/*
- * Encode str as utf8 and return as Uint8Array.
- * TODO: Use TextEncoder when available.
- */
-DataUtils.stringToUtf8Array = function(str) {
-    return DataUtils.toNumbersFromString(str2rstr_utf8(str));
-}
-
-/*
- * arrays is an array of Uint8Array. Return a new Uint8Array which is the concatenation of all.
- */
-DataUtils.concatArrays = function(arrays) {
-    var totalLength = 0;
-	for (var i = 0; i < arrays.length; ++i)
-        totalLength += arrays[i].length;
-    
-    var result = new Uint8Array(totalLength);
-    var offset = 0;
-	for (var i = 0; i < arrays.length; ++i) {
-        result.set(arrays[i], offset);
-        offset += arrays[i].length;
-    }
-    return result;
-    
-}
- 
-// TODO: Take Uint8Array and use TextDecoder when available.
-DataUtils.decodeUtf8 = function (utftext) {
-		var string = "";
-		var i = 0;
-		var c = 0;
-        var c1 = 0;
-        var c2 = 0;
- 
-		while ( i < utftext.length ) {
- 
-			c = utftext.charCodeAt(i);
- 
-			if (c < 128) {
-				string += String.fromCharCode(c);
-				i++;
-			}
-			else if((c > 191) && (c < 224)) {
-				c2 = utftext.charCodeAt(i+1);
-				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
-				i += 2;
-			}
-			else {
-				c2 = utftext.charCodeAt(i+1);
-				var c3 = utftext.charCodeAt(i+2);
-				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
-				i += 3;
-			}
- 
-		}
- 
-		return string;
-	};
-
-//NOT WORKING
-/*
-DataUtils.getUTF8StringFromBytes = function(bytes) {
-	
-	bytes = toString(bytes);
-
-    var ix = 0;
- 
-    if( bytes.slice(0,3) == "\xEF\xBB\xBF") {
-        ix = 3;
-    }
- 
-    var string = "";
-    for( ; ix < bytes.length; ix++ ) {
-        var byte1 = bytes[ix].charCodeAt(0);
-        if( byte1 < 0x80 ) {
-            string += String.fromCharCode(byte1);
-        } else if( byte1 >= 0xC2 && byte1 < 0xE0 ) {
-            var byte2 = bytes[++ix].charCodeAt(0);
-            string += String.fromCharCode(((byte1&0x1F)<<6) + (byte2&0x3F));
-        } else if( byte1 >= 0xE0 && byte1 < 0xF0 ) {
-            var byte2 = bytes[++ix].charCodeAt(0);
-            var byte3 = bytes[++ix].charCodeAt(0);
-            string += String.fromCharCode(((byte1&0xFF)<<12) + ((byte2&0x3F)<<6) + (byte3&0x3F));
-        } else if( byte1 >= 0xF0 && byte1 < 0xF5) {
-            var byte2 = bytes[++ix].charCodeAt(0);
-            var byte3 = bytes[++ix].charCodeAt(0);
-            var byte4 = bytes[++ix].charCodeAt(0);
-            var codepoint = ((byte1&0x07)<<18) + ((byte2&0x3F)<<12)+ ((byte3&0x3F)<<6) + (byte4&0x3F);
-            codepoint -= 0x10000;
-            string += String.fromCharCode(
-                (codepoint>>10) + 0xD800,
-                (codepoint&0x3FF) + 0xDC00
-            );
-        }
-    }
- 
-    return string;
-}*/
-
-/**
- * Return true if a1 and a2 are the same length with equal elements.
- */
-DataUtils.arraysEqual = function(a1, a2){
-    if (a1.length != a2.length)
-        return false;
-    
-    for (var i = 0; i < a1.length; ++i) {
-        if (a1[i] != a2[i])
-            return false;
-    }
-
-    return true;
-};
-
-/*
- * Convert the big endian Uint8Array to an unsigned int.
- * Don't check for overflow.
- */
-DataUtils.bigEndianToUnsignedInt = function(bytes) {
-    var result = 0;
-    for (var i = 0; i < bytes.length; ++i) {
-        result <<= 8;
-        result += bytes[i];
-    }
-    return result;
-};
-
-/*
- * Convert the int value to a new big endian Uint8Array and return.
- * If value is 0 or negative, return Uint8Array(0). 
- */
-DataUtils.nonNegativeIntToBigEndian = function(value) {
-    value = Math.round(value);
-    if (value <= 0)
-        return new Uint8Array(0);
-    
-    // Assume value is not over 64 bits.
-    var size = 8;
-    var result = new Uint8Array(size);
-    var i = 0;
-    while (value != 0) {
-        ++i;
-        result[size - i] = value & 0xff;
-        value >>= 8;
-    }
-    return result.subarray(size - i, size);
-};
-/*
  * This class defines MOME types based on the filename extension.
  * author: Jeff Thompson
  * See COPYING for copyright and distribution information.
@@ -4464,5024 +927,3 @@
   "zip": "application/zip",
   "zmt": "chemical/x-mopac-input"
 };
-/*
- * This file contains utilities to help encode and decode NDN objects.
- * author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- */
-
-function encodeToHexInterest(interest){
-    return DataUtils.toHex(encodeToBinaryInterest(interest));
-}
-
-
-function encodeToBinaryInterest(interest) {
-	var enc = new BinaryXMLEncoder();
-	interest.to_ccnb(enc);
-	
-	return enc.getReducedOstream();
-}
-
-
-function encodeToHexContentObject(co){
-    return DataUtils.toHex(encodeToBinaryContentObject(co));
-}
-
-function encodeToBinaryContentObject(co){
-	var enc = new BinaryXMLEncoder();
-	co.to_ccnb(enc);
-
-	return enc.getReducedOstream();
-}
-
-function encodeForwardingEntry(co){
-	var enc = new BinaryXMLEncoder();
- 
-	co.to_ccnb(enc);
-	
-	var bytes = enc.getReducedOstream();
-
-	return bytes;
-
-	
-}
-
-
-
-function decodeHexFaceInstance(result){
-	
-	var numbers = DataUtils.toNumbers(result);
-			
-	
-	decoder = new BinaryXMLDecoder(numbers);
-	
-	if(LOG>3)console.log('DECODING HEX FACE INSTANCE  \n'+numbers);
-
-	var faceInstance = new FaceInstance();
-
-	faceInstance.from_ccnb(decoder);
-
-	return faceInstance;
-	
-}
-
-
-
-function decodeHexInterest(result){
-	var numbers = DataUtils.toNumbers(result);	
-	
-	decoder = new BinaryXMLDecoder(numbers);
-	
-	if(LOG>3)console.log('DECODING HEX INTERST  \n'+numbers);
-
-	var interest = new Interest();
-
-	interest.from_ccnb(decoder);
-
-	return interest;
-	
-}
-
-
-
-function decodeHexContentObject(result){
-	var numbers = DataUtils.toNumbers(result);
-	
-	decoder = new BinaryXMLDecoder(numbers);
-	
-	if(LOG>3)console.log('DECODED HEX CONTENT OBJECT \n'+numbers);
-	
-	co = new ContentObject();
-
-	co.from_ccnb(decoder);
-
-	return co;
-	
-}
-
-
-
-function decodeHexForwardingEntry(result){
-	var numbers = DataUtils.toNumbers(result);
-
-	decoder = new BinaryXMLDecoder(numbers);
-	
-	if(LOG>3)console.log('DECODED HEX FORWARDING ENTRY \n'+numbers);
-	
-	forwardingEntry = new ForwardingEntry();
-
-	forwardingEntry.from_ccnb(decoder);
-
-	return forwardingEntry;
-	
-}
-
-/* Return a user friendly HTML string with the contents of co.
-   This also outputs to console.log.
- */
-function contentObjectToHtml(/* ContentObject */ co) {
-    var output ="";
-			
-    if(co==-1)
-	output+= "NO CONTENT FOUND"
-    else if (co==-2)
-	output+= "CONTENT NAME IS EMPTY"
-    else{
-	if(co.name!=null && co.name.components!=null){
-	    output+= "NAME: " + co.name.to_uri();
-        
-	    output+= "<br />";
-	    output+= "<br />";
-	}
-	
-	if(co.content !=null){
-	    output += "CONTENT(ASCII): "+ DataUtils.toString(co.content);
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	}
-	if(co.content !=null){
-	    output += "CONTENT(hex): "+ DataUtils.toHex(co.content);
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	}
-	if(co.signature !=null && co.signature.signature!=null){
-	    output += "SIGNATURE(hex): "+ DataUtils.toHex(co.signature.signature);
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	}
-	if(co.signedInfo !=null && co.signedInfo.publisher!=null && co.signedInfo.publisher.publisherPublicKeyDigest!=null){
-	    output += "Publisher Public Key Digest(hex): "+ DataUtils.toHex(co.signedInfo.publisher.publisherPublicKeyDigest);
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	}
-	if(co.signedInfo !=null && co.signedInfo.timestamp!=null){
-	    var d = new Date();
-	    d.setTime( co.signedInfo.timestamp.msec );
-	    
-	    var bytes = [217, 185, 12, 225, 217, 185, 12, 225];
-	    
-	    output += "TimeStamp: "+d;
-	    output+= "<br />";
-	    output += "TimeStamp(number): "+ co.signedInfo.timestamp.msec;
-	    
-	    output+= "<br />";
-	}
-	if(co.signedInfo !=null && co.signedInfo.finalBlockID!=null){
-	    output += "FinalBlockID: "+ DataUtils.toHex(co.signedInfo.finalBlockID);
-	    output+= "<br />";
-	}
-	if(co.signedInfo!=null && co.signedInfo.locator!=null && co.signedInfo.locator.certificate!=null){
-	    var tmp = DataUtils.toString(co.signedInfo.locator.certificate);
-	    var publickey = rstr2b64(tmp);
-	    var publickeyHex = DataUtils.toHex(co.signedInfo.locator.certificate).toLowerCase();
-	    var publickeyString = DataUtils.toString(co.signedInfo.locator.certificate);
-	    var signature = DataUtils.toHex(co.signature.signature).toLowerCase();
-	    var input = DataUtils.toString(co.rawSignatureData);
-	    
-	    output += "DER Certificate: "+publickey ;
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	    
-	    if(LOG>2) console.log(" ContentName + SignedInfo + Content = "+input);
-	    
-	    if(LOG>2) console.log("HEX OF ContentName + SignedInfo + Content = ");
-	    if(LOG>2) console.log(DataUtils.stringtoBase64(input));
-	    
-	    if(LOG>2) console.log(" PublicKey = "+publickey );
-	    if(LOG>2) console.log(" PublicKeyHex = "+publickeyHex );
-	    if(LOG>2) console.log(" PublicKeyString = "+publickeyString );
-	    
-	    if(LOG>2) console.log(" Signature is");
-	    if(LOG>2) console.log( signature );
-	    //if(LOG>2) console.log(" Signature NOW IS" );
-	    //if(LOG>2) console.log(co.signature.signature);
-
-	    var x509 = new X509();
-	    x509.readCertPEM(publickey);
-	    
-	    //x509.readCertPEMWithoutRSAInit(publickey);
-
-	    var result = x509.subjectPublicKeyRSA.verifyByteArray(co.rawSignatureData, signature);
-	    if(LOG>2) console.log('result is '+result);
-	    
-	    var n = x509.subjectPublicKeyRSA.n;
-	    var e =  x509.subjectPublicKeyRSA.e;
-	    
-	    if(LOG>2) console.log('PUBLIC KEY n after is ');
-	    if(LOG>2) console.log(n);
-
-	    if(LOG>2) console.log('EXPONENT e after is ');
-	    if(LOG>2) console.log(e);
-	    
-	    /*var rsakey = new RSAKey();
-	      
-	      var kp = publickeyHex.slice(56,314);
-	      
-	      output += "PUBLISHER KEY(hex): "+kp ;
-	      
-	      output+= "<br />";
-	      output+= "<br />";
-	      
-	      console.log('kp is '+kp);
-	      
-	      var exp = publickeyHex.slice(318,324);
-	      
-	      console.log('kp size is '+kp.length );
-	      output += "exponent: "+exp ;
-	      
-	      output+= "<br />";
-	      output+= "<br />";
-	      
-	      console.log('exp is '+exp);
-	      
-	      rsakey.setPublic(kp,exp);
-
-	      var result = rsakey.verifyString(input, signature);*/
-	    
-	    if(result)
-		output += 'SIGNATURE VALID';
-	    else
-		output += 'SIGNATURE INVALID';
-	    
-	    //output += "VALID: "+ toHex(co.signedInfo.locator.publicKey);
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	    
-	    //if(LOG>4) console.log('str'[1]);
-	}
-	if(co.signedInfo!=null && co.signedInfo.locator!=null && co.signedInfo.locator.publicKey!=null){
-	    var publickey = rstr2b64(DataUtils.toString(co.signedInfo.locator.publicKey));
-	    var publickeyHex = DataUtils.toHex(co.signedInfo.locator.publicKey).toLowerCase();
-	    var publickeyString = DataUtils.toString(co.signedInfo.locator.publicKey);
-	    var signature = DataUtils.toHex(co.signature.signature).toLowerCase();
-	    var input = DataUtils.toString(co.rawSignatureData);
-	    
-	    output += "DER Certificate: "+publickey ;
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	    
-	    if(LOG>2) console.log(" ContentName + SignedInfo + Content = "+input);
-	    if(LOG>2) console.log(" PublicKey = "+publickey );
-	    if(LOG>2) console.log(" PublicKeyHex = "+publickeyHex );
-	    if(LOG>2) console.log(" PublicKeyString = "+publickeyString );
-	    
-	    if(LOG>2) console.log(" Signature "+signature );
-	    
-	    if(LOG>2) console.log(" Signature NOW IS" );
-	    
-	    if(LOG>2) console.log(co.signature.signature);
-	    
-	    /*var x509 = new X509();
-	      
-	      x509.readCertPEM(publickey);
-	      
-	      
-	      //x509.readCertPEMWithoutRSAInit(publickey);
-
-	      var result = x509.subjectPublicKeyRSA.verifyString(input, signature);*/
-	    //console.log('result is '+result);
-	    
-	    var kp = publickeyHex.slice(56,314);
-	    
-	    output += "PUBLISHER KEY(hex): "+kp ;
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	    
-	    console.log('PUBLIC KEY IN HEX is ');
-	    console.log(kp);
-
-	    var exp = publickeyHex.slice(318,324);
-	    
-	    console.log('kp size is '+kp.length );
-	    output += "exponent: "+exp ;
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	    
-	    console.log('EXPONENT is ');
-	    console.log(exp);
-	    
-	    /*var c1 = hex_sha256(input);
-	      var c2 = signature;
-	      
-	      if(LOG>4)console.log('input is ');
-	      if(LOG>4)console.log(input);
-	      if(LOG>4)console.log('C1 is ');
-	      if(LOG>4)console.log(c1);
-	      if(LOG>4)console.log('C2 is ');
-	      if(LOG>4)console.log(c2);
-	      var result = c1 == c2;*/
-	    
-	    var rsakey = new RSAKey();
-	    
-	    rsakey.setPublic(kp,exp);
-	    
-	    var result = rsakey.verifyByteArray(co.rawSignatureData,signature);
-	    // var result = rsakey.verifyString(input, signature);
-	    
-	    console.log('PUBLIC KEY n after is ');
-	    console.log(rsakey.n);
-
-	    console.log('EXPONENT e after is ');
-	    console.log(rsakey.e);
-	    
-	    if(result)
-		output += 'SIGNATURE VALID';
-	    else
-		output += 'SIGNATURE INVALID';
-	    
-	    //output += "VALID: "+ toHex(co.signedInfo.locator.publicKey);
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	    
-	    //if(LOG>4) console.log('str'[1]);
-	}
-    }
-
-    return output;
-}
-/*
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- */
-
-var KeyManager = function KeyManager(){
-
-	
-//Certificate
-
-this.certificate = 'MIIBmzCCAQQCCQC32FyQa61S7jANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd'+
-
-'heGVsY2R2MB4XDTEyMDQyODIzNDQzN1oXDTEyMDUyODIzNDQzN1owEjEQMA4GA1'+
-
-'UEAxMHYXhlbGNkdjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4X0wp9goq'+
-
-'xuECxdULcr2IHr9Ih4Iaypg0Wy39URIup8/CLzQmdsh3RYqd55hqonu5VTTpH3i'+
-
-'MLx6xZDVJAZ8OJi7pvXcQ2C4Re2kjL2c8SanI0RfDhlS1zJadfr1VhRPmpivcYa'+
-
-'wJ4aFuOLAi+qHFxtN7lhcGCgpW1OV60oXd58CAwEAATANBgkqhkiG9w0BAQUFAA'+
-
-'OBgQDLOrA1fXzSrpftUB5Ro6DigX1Bjkf7F5Bkd69hSVp+jYeJFBBlsILQAfSxU'+
-
-'ZPQtD+2Yc3iCmSYNyxqu9PcufDRJlnvB7PG29+L3y9lR37tetzUV9eTscJ7rdp8'+
-
-'Wt6AzpW32IJ/54yKNfP7S6ZIoIG+LP6EIxq6s8K1MXRt8uBJKw==';
-
-
-//this.publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhfTCn2CirG4QLF1QtyvYgev0iHghrKmDRbLf1REi6nz8IvNCZ2yHdFip3nmGqie7lVNOkfeIwvHrFkNUkBnw4mLum9dxDYLhF7aSMvZzxJqcjRF8OGVLXMlp1+vVWFE+amK9xhrAnhoW44sCL6ocXG03uWFwYKClbU5XrShd3nwIDAQAB';
-this.publicKey ='30819F300D06092A864886F70D010101050003818D0030818902818100E17D30A7D828AB1B840B17542DCAF6207AFD221E086B2A60D16CB7F54448BA9F3F08BCD099DB21DD162A779E61AA89EEE554D3A47DE230BC7AC590D524067C3898BBA6F5DC4360B845EDA48CBD9CF126A723445F0E1952D7325A75FAF556144F9A98AF7186B0278685B8E2C08BEA87171B4DEE585C1828295B5395EB4A17779F0203010001';
-//Private Key
-
-this.privateKey ='MIICXQIBAAKBgQDhfTCn2CirG4QLF1QtyvYgev0iHghrKmDRbLf1REi6nz8IvNCZ2yHdFip3nmGqie7lVNOkfeIwvHrFkNUkBnw4mLum9dxDYLhF7aSMvZzxJqcjRF8OGVLXMlp1+vVWFE+amK9xhrAnhoW44sCL6ocXG03uWFwYKClbU5XrShd3nwIDAQABAoGAGkv6T6jC3WmhFZYL6CdCWvlc6gysmKrhjarrLTxgavtFY6R5g2ft5BXAsCCVbUkWxkIFSKqxpVNl0gKZCNGEzPDN6mHJOQI/h0rlxNIHAuGfoAbCzALnqmyZivhJAPGijAyKuU9tczsst5+Kpn+bn7ehzHQuj7iwJonS5WbojqECQQD851K8TpW2GrRizNgG4dx6orZxAaon/Jnl8lS7soXhllQty7qG+oDfzznmdMsiznCqEABzHUUKOVGE9RWPN3aRAkEA5D/w9N55d0ibnChFJlc8cUAoaqH+w+U3oQP2Lb6AZHJpLptN4y4b/uf5d4wYU5/i/gC7SSBH3wFhh9bjRLUDLwJAVOx8vN0Kqt7myfKNbCo19jxjVSlA8TKCn1Oznl/BU1I+rC4oUaEW25DjmX6IpAR8kq7S59ThVSCQPjxqY/A08QJBAIRaF2zGPITQk3r/VumemCvLWiRK/yG0noc9dtibqHOWbCtcXtOm/xDWjq+lis2i3ssOvYrvrv0/HcDY+Dv1An0CQQCLJtMsfSg4kvG/FRY5UMhtMuwo8ovYcMXt4Xv/LWaMhndD67b2UGawQCRqr5ghRTABWdDD/HuuMBjrkPsX0861';
-
-
-/*
-	this.certificate = 
-			'MIIBvTCCASYCCQD55fNzc0WF7TANBgkqhkiG9w0BAQUFADAjMQswCQYDVQQGEwJK'+
-			'UDEUMBIGA1UEChMLMDAtVEVTVC1SU0EwHhcNMTAwNTI4MDIwODUxWhcNMjAwNTI1'+
-			'MDIwODUxWjAjMQswCQYDVQQGEwJKUDEUMBIGA1UEChMLMDAtVEVTVC1SU0EwgZ8w'+
-			'DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANGEYXtfgDRlWUSDn3haY4NVVQiKI9Cz'+
-			'Thoua9+DxJuiseyzmBBe7Roh1RPqdvmtOHmEPbJ+kXZYhbozzPRbFGHCJyBfCLzQ'+
-			'fVos9/qUQ88u83b0SFA2MGmQWQAlRtLy66EkR4rDRwTj2DzR4EEXgEKpIvo8VBs/'+
-			'3+sHLF3ESgAhAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAEZ6mXFFq3AzfaqWHmCy1'+
-			'ARjlauYAa8ZmUFnLm0emg9dkVBJ63aEqARhtok6bDQDzSJxiLpCEF6G4b/Nv/M/M'+
-			'LyhP+OoOTmETMegAVQMq71choVJyOFE5BtQa6M/lCHEOya5QUfoRF2HF9EjRF44K'+
-			'3OK+u3ivTSj3zwjtpudY5Xo=';
-	
-	this.privateKey =
-			'MIICWwIBAAKBgQDRhGF7X4A0ZVlEg594WmODVVUIiiPQs04aLmvfg8SborHss5gQ'+
-			'Xu0aIdUT6nb5rTh5hD2yfpF2WIW6M8z0WxRhwicgXwi80H1aLPf6lEPPLvN29EhQ'+
-			'NjBpkFkAJUbS8uuhJEeKw0cE49g80eBBF4BCqSL6PFQbP9/rByxdxEoAIQIDAQAB'+
-			'AoGAA9/q3Zk6ib2GFRpKDLO/O2KMnAfR+b4XJ6zMGeoZ7Lbpi3MW0Nawk9ckVaX0'+
-			'ZVGqxbSIX5Cvp/yjHHpww+QbUFrw/gCjLiiYjM9E8C3uAF5AKJ0r4GBPl4u8K4bp'+
-			'bXeSxSB60/wPQFiQAJVcA5xhZVzqNuF3EjuKdHsw+dk+dPECQQDubX/lVGFgD/xY'+
-			'uchz56Yc7VHX+58BUkNSewSzwJRbcueqknXRWwj97SXqpnYfKqZq78dnEF10SWsr'+
-			'/NMKi+7XAkEA4PVqDv/OZAbWr4syXZNv/Mpl4r5suzYMMUD9U8B2JIRnrhmGZPzL'+
-			'x23N9J4hEJ+Xh8tSKVc80jOkrvGlSv+BxwJAaTOtjA3YTV+gU7Hdza53sCnSw/8F'+
-			'YLrgc6NOJtYhX9xqdevbyn1lkU0zPr8mPYg/F84m6MXixm2iuSz8HZoyzwJARi2p'+
-			'aYZ5/5B2lwroqnKdZBJMGKFpUDn7Mb5hiSgocxnvMkv6NjT66Xsi3iYakJII9q8C'+
-			'Ma1qZvT/cigmdbAh7wJAQNXyoizuGEltiSaBXx4H29EdXNYWDJ9SS5f070BRbAIl'+
-			'dqRh3rcNvpY6BKJqFapda1DjdcncZECMizT/GMrc1w==';
-			
-			*/
-};
-
-
-KeyManager.prototype.verify = function verify(message,signature){
-	
-	var input = message;
-
-	var  _PEM_X509CERT_STRING_ = this.certificate;
-	
-	var x509 = new X509();
-	
-	x509.readCertPEM(_PEM_X509CERT_STRING_);
-	
-	var result = x509.subjectPublicKeyRSA.verifyString(input, signature);
-	
-	return result;
-};
-
-KeyManager.prototype.sign= function sign(message){
-	
-	var input = message;
-		
-	var  _PEM_PRIVATE_KEY_STRING_ = this.privateKey;
-	
-	var rsa = new RSAKey();
-	
-	rsa.readPrivateKeyFromPEMString(_PEM_PRIVATE_KEY_STRING_);
-	
-	var hSig = rsa.signString(input, "sha256");
-	
-	return hSig;
-
-};
-
-
-
-var globalKeyManager = new KeyManager();
-//var KeyPair = { "public" : "PUBLIC KEY" , "private" : "PRIVATE KEY" };
-
-
-/*
- * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
- * in FIPS 180-1
- * Version 2.2 Copyright Paul Johnston 2000 - 2009.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for details.
- */
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
-var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
-
-/**
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function hex_sha1(s)    { return rstr2hex(rstr_sha1(str2rstr_utf8(s))); }
-function b64_sha1(s)    { return rstr2b64(rstr_sha1(str2rstr_utf8(s))); }
-function any_sha1(s, e) { return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); }
-function hex_hmac_sha1(k, d)
-  { return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function b64_hmac_sha1(k, d)
-  { return rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function any_hmac_sha1(k, d, e)
-  { return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
-
-/**
- * Perform a simple self-test to see if the VM is working
- */
-function sha1_vm_test()
-{
-  return hex_sha1("abc").toLowerCase() == "a9993e364706816aba3e25717850c26c9cd0d89d";
-}
-
-/**
- * Calculate the SHA1 of a raw string
- */
-function rstr_sha1(s)
-{
-  return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
-}
-
-/**
- * Calculate the HMAC-SHA1 of a key and some data (raw strings)
- */
-function rstr_hmac_sha1(key, data)
-{
-  var bkey = rstr2binb(key);
-  if(bkey.length > 16) bkey = binb_sha1(bkey, key.length * 8);
-
-  var ipad = Array(16), opad = Array(16);
-  for(var i = 0; i < 16; i++)
-  {
-    ipad[i] = bkey[i] ^ 0x36363636;
-    opad[i] = bkey[i] ^ 0x5C5C5C5C;
-  }
-
-  var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
-  return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160));
-}
-
-/**
- * Convert a raw string to a hex string
- */
-function rstr2hex(input)
-{
-  try { hexcase } catch(e) { hexcase=0; }
-  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
-  var output = "";
-  var x;
-  for(var i = 0; i < input.length; i++)
-  {
-    x = input.charCodeAt(i);
-    output += hex_tab.charAt((x >>> 4) & 0x0F)
-           +  hex_tab.charAt( x        & 0x0F);
-  }
-  return output;
-}
-
-/**
- * Convert a raw string to a base-64 string
- */
-function rstr2b64(input)
-{
-  try { b64pad } catch(e) { b64pad=''; }
-  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-  var output = "";
-  var len = input.length;
-  for(var i = 0; i < len; i += 3)
-  {
-    var triplet = (input.charCodeAt(i) << 16)
-                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
-                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
-    for(var j = 0; j < 4; j++)
-    {
-      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
-      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
-    }
-  }
-  return output;
-}
-
-/**
- * Convert a raw string to an arbitrary string encoding
- */
-function rstr2any(input, encoding)
-{
-  var divisor = encoding.length;
-  var remainders = Array();
-  var i, q, x, quotient;
-
-  /* Convert to an array of 16-bit big-endian values, forming the dividend */
-  var dividend = Array(Math.ceil(input.length / 2));
-  for(i = 0; i < dividend.length; i++)
-  {
-    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
-  }
-
-  /*
-   * Repeatedly perform a long division. The binary array forms the dividend,
-   * the length of the encoding is the divisor. Once computed, the quotient
-   * forms the dividend for the next step. We stop when the dividend is zero.
-   * All remainders are stored for later use.
-   */
-  while(dividend.length > 0)
-  {
-    quotient = Array();
-    x = 0;
-    for(i = 0; i < dividend.length; i++)
-    {
-      x = (x << 16) + dividend[i];
-      q = Math.floor(x / divisor);
-      x -= q * divisor;
-      if(quotient.length > 0 || q > 0)
-        quotient[quotient.length] = q;
-    }
-    remainders[remainders.length] = x;
-    dividend = quotient;
-  }
-
-  /* Convert the remainders to the output string */
-  var output = "";
-  for(i = remainders.length - 1; i >= 0; i--)
-    output += encoding.charAt(remainders[i]);
-
-  /* Append leading zero equivalents */
-  var full_length = Math.ceil(input.length * 8 /
-                                    (Math.log(encoding.length) / Math.log(2)));
-  for(i = output.length; i < full_length; i++)
-    output = encoding[0] + output;
-
-  return output;
-}
-
-/**
- * Encode a string as utf-8.
- * For efficiency, this assumes the input is valid utf-16.
- */
-function str2rstr_utf8(input)
-{
-  var output = "";
-  var i = -1;
-  var x, y;
-
-  while(++i < input.length)
-  {
-    /* Decode utf-16 surrogate pairs */
-    x = input.charCodeAt(i);
-    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
-    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
-    {
-      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
-      i++;
-    }
-
-    /* Encode output as utf-8 */
-    if(x <= 0x7F)
-      output += String.fromCharCode(x);
-    else if(x <= 0x7FF)
-      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0xFFFF)
-      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0x1FFFFF)
-      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
-                                    0x80 | ((x >>> 12) & 0x3F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-  }
-  return output;
-}
-
-/**
- * Encode a string as utf-16
- */
-function str2rstr_utf16le(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
-                                  (input.charCodeAt(i) >>> 8) & 0xFF);
-  return output;
-}
-
-function str2rstr_utf16be(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
-                                   input.charCodeAt(i)        & 0xFF);
-  return output;
-}
-
-/**
- * Convert a raw string to an array of big-endian words
- * Characters >255 have their high-byte silently ignored.
- */
-function rstr2binb(input)
-{
-  var output = Array(input.length >> 2);
-  for(var i = 0; i < output.length; i++)
-    output[i] = 0;
-  for(var i = 0; i < input.length * 8; i += 8)
-    output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
-  return output;
-}
-
-/**
- * Convert an array of big-endian words to a string
- */
-function binb2rstr(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length * 32; i += 8)
-    output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
-  return output;
-}
-
-/**
- * Calculate the SHA-1 of an array of big-endian words, and a bit length
- */
-function binb_sha1(x, len)
-{
-  /* append padding */
-  x[len >> 5] |= 0x80 << (24 - len % 32);
-  x[((len + 64 >> 9) << 4) + 15] = len;
-
-  var w = Array(80);
-  var a =  1732584193;
-  var b = -271733879;
-  var c = -1732584194;
-  var d =  271733878;
-  var e = -1009589776;
-
-  for(var i = 0; i < x.length; i += 16)
-  {
-    var olda = a;
-    var oldb = b;
-    var oldc = c;
-    var oldd = d;
-    var olde = e;
-
-    for(var j = 0; j < 80; j++)
-    {
-      if(j < 16) w[j] = x[i + j];
-      else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
-      var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
-                       safe_add(safe_add(e, w[j]), sha1_kt(j)));
-      e = d;
-      d = c;
-      c = bit_rol(b, 30);
-      b = a;
-      a = t;
-    }
-
-    a = safe_add(a, olda);
-    b = safe_add(b, oldb);
-    c = safe_add(c, oldc);
-    d = safe_add(d, oldd);
-    e = safe_add(e, olde);
-  }
-  return Array(a, b, c, d, e);
-
-}
-
-/**
- * Perform the appropriate triplet combination function for the current
- * iteration
- */
-function sha1_ft(t, b, c, d)
-{
-  if(t < 20) return (b & c) | ((~b) & d);
-  if(t < 40) return b ^ c ^ d;
-  if(t < 60) return (b & c) | (b & d) | (c & d);
-  return b ^ c ^ d;
-}
-
-/**
- * Determine the appropriate additive constant for the current iteration
- */
-function sha1_kt(t)
-{
-  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
-         (t < 60) ? -1894007588 : -899497514;
-}
-
-/**
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
-function safe_add(x, y)
-{
-  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
-  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
-  return (msw << 16) | (lsw & 0xFFFF);
-}
-
-/**
- * Bitwise rotate a 32-bit number to the left.
- */
-function bit_rol(num, cnt)
-{
-  return (num << cnt) | (num >>> (32 - cnt));
-}
-/*
- * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
- * in FIPS 180-2
- * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for details.
- * Also http://anmar.eu.org/projects/jssha2/
- */
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
-var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
-
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-
-//@author axelcdv
-/**
- * Computes the Sha-256 hash of the given byte array
- * @param {byte[]} 
- * @return the hex string corresponding to the Sha-256 hash of the byte array
- */
-function hex_sha256_from_bytes(byteArray){
-	return rstr2hex(binb2rstr(binb_sha256( byteArray2binb(byteArray), byteArray.length * 8)));
-}
-
-function hex_sha256(s)    { return rstr2hex(rstr_sha256(str2rstr_utf8(s))); }
-function b64_sha256(s)    { return rstr2b64(rstr_sha256(str2rstr_utf8(s))); }
-function any_sha256(s, e) { return rstr2any(rstr_sha256(str2rstr_utf8(s)), e); }
-function hex_hmac_sha256(k, d)
-  { return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function b64_hmac_sha256(k, d)
-  { return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function any_hmac_sha256(k, d, e)
-  { return rstr2any(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
-
-	
-/*
-	function hex_sha256(s)    { return rstr2hex(rstr_sha256(s)); }
-function b64_sha256(s)    { return rstr2b64(rstr_sha256(s)); }
-function any_sha256(s, e) { return rstr2any(rstr_sha256(s), e); }
-function hex_hmac_sha256(k, d)
-  { return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(k), d)); }
-function b64_hmac_sha256(k, d)
-  { return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(k), d)); }
-function any_hmac_sha256(k, d, e)
-  { return rstr2any(rstr_hmac_sha256(str2rstr_utf8(k), d), e); }
-*/
-	
-/*
- * Perform a simple self-test to see if the VM is working
- */
-function sha256_vm_test()
-{
-  return hex_sha256("abc").toLowerCase() ==
-            "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
-}
-
-/**
- * Calculate the sha256 of a raw string
- * @param s: the raw string
- */
-function rstr_sha256(s)
-{
-  return binb2rstr(binb_sha256(rstr2binb(s), s.length * 8));
-}
-
-/**
- * Calculate the HMAC-sha256 of a key and some data (raw strings)
- */
-function rstr_hmac_sha256(key, data)
-{
-  var bkey = rstr2binb(key);
-  if(bkey.length > 16) bkey = binb_sha256(bkey, key.length * 8);
-
-  var ipad = Array(16), opad = Array(16);
-  for(var i = 0; i < 16; i++)
-  {
-    ipad[i] = bkey[i] ^ 0x36363636;
-    opad[i] = bkey[i] ^ 0x5C5C5C5C;
-  }
-
-  var hash = binb_sha256(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
-  return binb2rstr(binb_sha256(opad.concat(hash), 512 + 256));
-}
-
-/**
- * Convert a raw string to a hex string
- */
-function rstr2hex(input)
-{
-  try { hexcase } catch(e) { hexcase=0; }
-  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
-  var output = "";
-  var x;
-  for(var i = 0; i < input.length; i++)
-  {
-    x = input.charCodeAt(i);
-    output += hex_tab.charAt((x >>> 4) & 0x0F)
-           +  hex_tab.charAt( x        & 0x0F);
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to a base-64 string
- */
-function rstr2b64(input)
-{
-  try { b64pad } catch(e) { b64pad=''; }
-  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-  var output = "";
-  var len = input.length;
-  for(var i = 0; i < len; i += 3)
-  {
-    var triplet = (input.charCodeAt(i) << 16)
-                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
-                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
-    for(var j = 0; j < 4; j++)
-    {
-      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
-      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
-    }
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to an arbitrary string encoding
- */
-function rstr2any(input, encoding)
-{
-  var divisor = encoding.length;
-  var remainders = Array();
-  var i, q, x, quotient;
-
-  /* Convert to an array of 16-bit big-endian values, forming the dividend */
-  var dividend = Array(Math.ceil(input.length / 2));
-  for(i = 0; i < dividend.length; i++)
-  {
-    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
-  }
-
-  /*
-   * Repeatedly perform a long division. The binary array forms the dividend,
-   * the length of the encoding is the divisor. Once computed, the quotient
-   * forms the dividend for the next step. We stop when the dividend is zero.
-   * All remainders are stored for later use.
-   */
-  while(dividend.length > 0)
-  {
-    quotient = Array();
-    x = 0;
-    for(i = 0; i < dividend.length; i++)
-    {
-      x = (x << 16) + dividend[i];
-      q = Math.floor(x / divisor);
-      x -= q * divisor;
-      if(quotient.length > 0 || q > 0)
-        quotient[quotient.length] = q;
-    }
-    remainders[remainders.length] = x;
-    dividend = quotient;
-  }
-
-  /* Convert the remainders to the output string */
-  var output = "";
-  for(i = remainders.length - 1; i >= 0; i--)
-    output += encoding.charAt(remainders[i]);
-
-  /* Append leading zero equivalents */
-  var full_length = Math.ceil(input.length * 8 /
-                                    (Math.log(encoding.length) / Math.log(2)))
-  for(i = output.length; i < full_length; i++)
-    output = encoding[0] + output;
-
-  return output;
-}
-
-/*
- * Encode a string as utf-8.
- * For efficiency, this assumes the input is valid utf-16.
- */
-function str2rstr_utf8(input)
-{
-  var output = "";
-  var i = -1;
-  var x, y;
-
-  while(++i < input.length)
-  {
-    /* Decode utf-16 surrogate pairs */
-    x = input.charCodeAt(i);
-    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
-    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
-    {
-      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
-      i++;
-    }
-
-    /* Encode output as utf-8 */
-    if(x <= 0x7F)
-      output += String.fromCharCode(x);
-    else if(x <= 0x7FF)
-      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0xFFFF)
-      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0x1FFFFF)
-      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
-                                    0x80 | ((x >>> 12) & 0x3F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-  }
-  return output;
-}
-
-/*
- * Encode a string as utf-16
- */
-function str2rstr_utf16le(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
-                                  (input.charCodeAt(i) >>> 8) & 0xFF);
-  return output;
-}
-
-function str2rstr_utf16be(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
-                                   input.charCodeAt(i)        & 0xFF);
-  return output;
-}
-
-/**
- * Convert a raw string to an array of big-endian words
- * Characters >255 have their high-byte silently ignored.
- */
-function rstr2binb(input)
-{
-  //console.log('Raw string comming is '+input);
-  var output = Array(input.length >> 2);
-  /* JavaScript automatically zeroizes a new array.
-  for(var i = 0; i < output.length; i++)
-    output[i] = 0;
-   */
-  for(var i = 0; i < input.length * 8; i += 8)
-    output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
-  return output;
-}
-
-/**
- * @author axelcdv
- * Convert a byte array to an array of big-endian words
- * @param {byte[]} input
- * @return the array of big-endian words
- */
-function byteArray2binb(input){
-	//console.log("Byte array coming is " + input);
-	var output = Array(input.length >> 2);
-      /* JavaScript automatically zeroizes a new array.
-	  for(var i = 0; i < output.length; i++)
-	    output[i] = 0;
-       */
-	  for(var i = 0; i < input.length * 8; i += 8)
-	    output[i>>5] |= (input[i / 8] & 0xFF) << (24 - i % 32);
-	  return output;
-}
-
-/*
- * Convert an array of big-endian words to a string
- */
-function binb2rstr(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length * 32; i += 8)
-    output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
-  return output;
-}
-
-/*
- * Main sha256 function, with its support functions
- */
-function sha256_S (X, n) {return ( X >>> n ) | (X << (32 - n));}
-function sha256_R (X, n) {return ( X >>> n );}
-function sha256_Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
-function sha256_Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
-function sha256_Sigma0256(x) {return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));}
-function sha256_Sigma1256(x) {return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));}
-function sha256_Gamma0256(x) {return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));}
-function sha256_Gamma1256(x) {return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));}
-function sha256_Sigma0512(x) {return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39));}
-function sha256_Sigma1512(x) {return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41));}
-function sha256_Gamma0512(x) {return (sha256_S(x, 1)  ^ sha256_S(x, 8) ^ sha256_R(x, 7));}
-function sha256_Gamma1512(x) {return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6));}
-
-var sha256_K = new Array
-(
-  1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993,
-  -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
-  1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
-  264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986,
-  -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
-  113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
-  1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885,
-  -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
-  430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
-  1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872,
-  -1866530822, -1538233109, -1090935817, -965641998
-);
-
-function binb_sha256(m, l)
-{
-  var HASH = new Array(1779033703, -1150833019, 1013904242, -1521486534,
-                       1359893119, -1694144372, 528734635, 1541459225);
-  var W = new Array(64);
-
-  /* append padding */
-  m[l >> 5] |= 0x80 << (24 - l % 32);
-  m[((l + 64 >> 9) << 4) + 15] = l;
- 
-  for(var offset = 0; offset < m.length; offset += 16)
-    processBlock_sha256(m, offset, HASH, W);
-
-  return HASH;
-}
-
-/*
- * Process a block of 16 4-byte words in m starting at offset and update HASH.  
- * offset must be a multiple of 16 and less than m.length.  W is a scratchpad Array(64).
- */
-function processBlock_sha256(m, offset, HASH, W) {
-    var a, b, c, d, e, f, g, h;
-    var j, T1, T2;
-    
-    a = HASH[0];
-    b = HASH[1];
-    c = HASH[2];
-    d = HASH[3];
-    e = HASH[4];
-    f = HASH[5];
-    g = HASH[6];
-    h = HASH[7];
-
-    for(j = 0; j < 64; j++)
-    {
-      if (j < 16) W[j] = m[j + offset];
-      else W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]),
-                                            sha256_Gamma0256(W[j - 15])), W[j - 16]);
-
-      T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
-                                                          sha256_K[j]), W[j]);
-      T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
-      h = g;
-      g = f;
-      f = e;
-      e = safe_add(d, T1);
-      d = c;
-      c = b;
-      b = a;
-      a = safe_add(T1, T2);
-    }
-
-    HASH[0] = safe_add(a, HASH[0]);
-    HASH[1] = safe_add(b, HASH[1]);
-    HASH[2] = safe_add(c, HASH[2]);
-    HASH[3] = safe_add(d, HASH[3]);
-    HASH[4] = safe_add(e, HASH[4]);
-    HASH[5] = safe_add(f, HASH[5]);
-    HASH[6] = safe_add(g, HASH[6]);
-    HASH[7] = safe_add(h, HASH[7]);
-}
-
-function safe_add (x, y)
-{
-  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
-  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
-  return (msw << 16) | (lsw & 0xFFFF);
-}
-
-/*
- * Create a Sha256, call update(data) multiple times, then call finalize().
- */
-var Sha256 = function Sha256() {
-    this.W = new Array(64);
-    this.hash = new Array(1779033703, -1150833019, 1013904242, -1521486534,
-                          1359893119, -1694144372, 528734635, 1541459225);
-    this.nTotalBytes = 0;
-    this.buffer = new Uint8Array(16 * 4);
-    this.nBufferBytes = 0;
-}
-
-/*
- * Update the hash with data, which is Uint8Array.
- */
-Sha256.prototype.update = function(data) {
-    this.nTotalBytes += data.length;
-    
-    if (this.nBufferBytes > 0) {
-        // Fill up the buffer and process it first.
-        var bytesNeeded = this.buffer.length - this.nBufferBytes;
-        if (data.length < bytesNeeded) {
-            this.buffer.set(data, this.nBufferBytes);
-            this.nBufferBytes += data.length;
-            return;
-        }
-        else {
-            this.buffer.set(data.subarray(0, bytesNeeded), this.nBufferBytes);
-            processBlock_sha256(byteArray2binb(this.buffer), 0, this.hash, this.W);
-            this.nBufferBytes = 0;
-            // Consume the bytes from data.
-            data = data.subarray(bytesNeeded, data.length);
-            if (data.length == 0)
-                return;
-        }
-    }
-    
-    // 2^6 is 16 * 4.
-    var nBlocks = data.length >> 6;
-    if (nBlocks > 0) {
-        var nBytes = nBlocks * 16 * 4;
-        var m = byteArray2binb(data.subarray(0, nBytes));
-        for(var offset = 0; offset < m.length; offset += 16)
-            processBlock_sha256(m, offset, this.hash, this.W);
-
-        data = data.subarray(nBytes, data.length);
-    }
-    
-    if (data.length > 0) {
-        // Save the remainder in the buffer.
-        this.buffer.set(data);
-        this.nBufferBytes = data.length;
-    }
-}
-
-/*
- * Finalize the hash and return the result as Uint8Array.
- * Only call this once.  Return values on subsequent calls are undefined.
- */
-Sha256.prototype.finalize = function() {
-    var m = byteArray2binb(this.buffer.subarray(0, this.nBufferBytes));
-    /* append padding */
-    var l = this.nBufferBytes * 8;
-    m[l >> 5] |= 0x80 << (24 - l % 32);
-    m[((l + 64 >> 9) << 4) + 15] = this.nTotalBytes * 8;
-
-    for(var offset = 0; offset < m.length; offset += 16)
-        processBlock_sha256(m, offset, this.hash, this.W);
-
-    return Sha256.binb2Uint8Array(this.hash);
-}
-
-/*
- * Convert an array of big-endian words to Uint8Array.
- */
-Sha256.binb2Uint8Array = function(input)
-{
-    var output = new Uint8Array(input.length * 4);
-    var iOutput = 0;
-    for (var i = 0; i < input.length * 32; i += 8)
-        output[iOutput++] = (input[i>>5] >>> (24 - i % 32)) & 0xFF;
-    return output;
-}
-/*
- * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined
- * in FIPS 180-2
- * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for details.
- */
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
-var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
-
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function hex_sha512(s)    { return rstr2hex(rstr_sha512(str2rstr_utf8(s))); }
-function b64_sha512(s)    { return rstr2b64(rstr_sha512(str2rstr_utf8(s))); }
-function any_sha512(s, e) { return rstr2any(rstr_sha512(str2rstr_utf8(s)), e);}
-function hex_hmac_sha512(k, d)
-  { return rstr2hex(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function b64_hmac_sha512(k, d)
-  { return rstr2b64(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function any_hmac_sha512(k, d, e)
-  { return rstr2any(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d)), e);}
-
-/*
- * Perform a simple self-test to see if the VM is working
- */
-function sha512_vm_test()
-{
-  return hex_sha512("abc").toLowerCase() ==
-    "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" +
-    "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
-}
-
-/*
- * Calculate the SHA-512 of a raw string
- */
-function rstr_sha512(s)
-{
-  return binb2rstr(binb_sha512(rstr2binb(s), s.length * 8));
-}
-
-/*
- * Calculate the HMAC-SHA-512 of a key and some data (raw strings)
- */
-function rstr_hmac_sha512(key, data)
-{
-  var bkey = rstr2binb(key);
-  if(bkey.length > 32) bkey = binb_sha512(bkey, key.length * 8);
-
-  var ipad = Array(32), opad = Array(32);
-  for(var i = 0; i < 32; i++)
-  {
-    ipad[i] = bkey[i] ^ 0x36363636;
-    opad[i] = bkey[i] ^ 0x5C5C5C5C;
-  }
-
-  var hash = binb_sha512(ipad.concat(rstr2binb(data)), 1024 + data.length * 8);
-  return binb2rstr(binb_sha512(opad.concat(hash), 1024 + 512));
-}
-
-/*
- * Convert a raw string to a hex string
- */
-function rstr2hex(input)
-{
-  try { hexcase } catch(e) { hexcase=0; }
-  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
-  var output = "";
-  var x;
-  for(var i = 0; i < input.length; i++)
-  {
-    x = input.charCodeAt(i);
-    output += hex_tab.charAt((x >>> 4) & 0x0F)
-           +  hex_tab.charAt( x        & 0x0F);
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to a base-64 string
- */
-function rstr2b64(input)
-{
-  try { b64pad } catch(e) { b64pad=''; }
-  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-  var output = "";
-  var len = input.length;
-  for(var i = 0; i < len; i += 3)
-  {
-    var triplet = (input.charCodeAt(i) << 16)
-                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
-                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
-    for(var j = 0; j < 4; j++)
-    {
-      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
-      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
-    }
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to an arbitrary string encoding
- */
-function rstr2any(input, encoding)
-{
-  var divisor = encoding.length;
-  var i, j, q, x, quotient;
-
-  /* Convert to an array of 16-bit big-endian values, forming the dividend */
-  var dividend = Array(Math.ceil(input.length / 2));
-  for(i = 0; i < dividend.length; i++)
-  {
-    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
-  }
-
-  /*
-   * Repeatedly perform a long division. The binary array forms the dividend,
-   * the length of the encoding is the divisor. Once computed, the quotient
-   * forms the dividend for the next step. All remainders are stored for later
-   * use.
-   */
-  var full_length = Math.ceil(input.length * 8 /
-                                    (Math.log(encoding.length) / Math.log(2)));
-  var remainders = Array(full_length);
-  for(j = 0; j < full_length; j++)
-  {
-    quotient = Array();
-    x = 0;
-    for(i = 0; i < dividend.length; i++)
-    {
-      x = (x << 16) + dividend[i];
-      q = Math.floor(x / divisor);
-      x -= q * divisor;
-      if(quotient.length > 0 || q > 0)
-        quotient[quotient.length] = q;
-    }
-    remainders[j] = x;
-    dividend = quotient;
-  }
-
-  /* Convert the remainders to the output string */
-  var output = "";
-  for(i = remainders.length - 1; i >= 0; i--)
-    output += encoding.charAt(remainders[i]);
-
-  return output;
-}
-
-/*
- * Encode a string as utf-8.
- * For efficiency, this assumes the input is valid utf-16.
- */
-function str2rstr_utf8(input)
-{
-  var output = "";
-  var i = -1;
-  var x, y;
-
-  while(++i < input.length)
-  {
-    /* Decode utf-16 surrogate pairs */
-    x = input.charCodeAt(i);
-    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
-    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
-    {
-      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
-      i++;
-    }
-
-    /* Encode output as utf-8 */
-    if(x <= 0x7F)
-      output += String.fromCharCode(x);
-    else if(x <= 0x7FF)
-      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0xFFFF)
-      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0x1FFFFF)
-      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
-                                    0x80 | ((x >>> 12) & 0x3F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-  }
-  return output;
-}
-
-/*
- * Encode a string as utf-16
- */
-function str2rstr_utf16le(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
-                                  (input.charCodeAt(i) >>> 8) & 0xFF);
-  return output;
-}
-
-function str2rstr_utf16be(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
-                                   input.charCodeAt(i)        & 0xFF);
-  return output;
-}
-
-/*
- * Convert a raw string to an array of big-endian words
- * Characters >255 have their high-byte silently ignored.
- */
-function rstr2binb(input)
-{
-  var output = Array(input.length >> 2);
-  for(var i = 0; i < output.length; i++)
-    output[i] = 0;
-  for(var i = 0; i < input.length * 8; i += 8)
-    output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
-  return output;
-}
-
-/*
- * Convert an array of big-endian words to a string
- */
-function binb2rstr(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length * 32; i += 8)
-    output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
-  return output;
-}
-
-/*
- * Calculate the SHA-512 of an array of big-endian dwords, and a bit length
- */
-var sha512_k;
-function binb_sha512(x, len)
-{
-  if(sha512_k == undefined)
-  {
-    //SHA512 constants
-    sha512_k = new Array(
-new int64(0x428a2f98, -685199838), new int64(0x71374491, 0x23ef65cd),
-new int64(-1245643825, -330482897), new int64(-373957723, -2121671748),
-new int64(0x3956c25b, -213338824), new int64(0x59f111f1, -1241133031),
-new int64(-1841331548, -1357295717), new int64(-1424204075, -630357736),
-new int64(-670586216, -1560083902), new int64(0x12835b01, 0x45706fbe),
-new int64(0x243185be, 0x4ee4b28c), new int64(0x550c7dc3, -704662302),
-new int64(0x72be5d74, -226784913), new int64(-2132889090, 0x3b1696b1),
-new int64(-1680079193, 0x25c71235), new int64(-1046744716, -815192428),
-new int64(-459576895, -1628353838), new int64(-272742522, 0x384f25e3),
-new int64(0xfc19dc6, -1953704523), new int64(0x240ca1cc, 0x77ac9c65),
-new int64(0x2de92c6f, 0x592b0275), new int64(0x4a7484aa, 0x6ea6e483),
-new int64(0x5cb0a9dc, -1119749164), new int64(0x76f988da, -2096016459),
-new int64(-1740746414, -295247957), new int64(-1473132947, 0x2db43210),
-new int64(-1341970488, -1728372417), new int64(-1084653625, -1091629340),
-new int64(-958395405, 0x3da88fc2), new int64(-710438585, -1828018395),
-new int64(0x6ca6351, -536640913), new int64(0x14292967, 0xa0e6e70),
-new int64(0x27b70a85, 0x46d22ffc), new int64(0x2e1b2138, 0x5c26c926),
-new int64(0x4d2c6dfc, 0x5ac42aed), new int64(0x53380d13, -1651133473),
-new int64(0x650a7354, -1951439906), new int64(0x766a0abb, 0x3c77b2a8),
-new int64(-2117940946, 0x47edaee6), new int64(-1838011259, 0x1482353b),
-new int64(-1564481375, 0x4cf10364), new int64(-1474664885, -1136513023),
-new int64(-1035236496, -789014639), new int64(-949202525, 0x654be30),
-new int64(-778901479, -688958952), new int64(-694614492, 0x5565a910),
-new int64(-200395387, 0x5771202a), new int64(0x106aa070, 0x32bbd1b8),
-new int64(0x19a4c116, -1194143544), new int64(0x1e376c08, 0x5141ab53),
-new int64(0x2748774c, -544281703), new int64(0x34b0bcb5, -509917016),
-new int64(0x391c0cb3, -976659869), new int64(0x4ed8aa4a, -482243893),
-new int64(0x5b9cca4f, 0x7763e373), new int64(0x682e6ff3, -692930397),
-new int64(0x748f82ee, 0x5defb2fc), new int64(0x78a5636f, 0x43172f60),
-new int64(-2067236844, -1578062990), new int64(-1933114872, 0x1a6439ec),
-new int64(-1866530822, 0x23631e28), new int64(-1538233109, -561857047),
-new int64(-1090935817, -1295615723), new int64(-965641998, -479046869),
-new int64(-903397682, -366583396), new int64(-779700025, 0x21c0c207),
-new int64(-354779690, -840897762), new int64(-176337025, -294727304),
-new int64(0x6f067aa, 0x72176fba), new int64(0xa637dc5, -1563912026),
-new int64(0x113f9804, -1090974290), new int64(0x1b710b35, 0x131c471b),
-new int64(0x28db77f5, 0x23047d84), new int64(0x32caab7b, 0x40c72493),
-new int64(0x3c9ebe0a, 0x15c9bebc), new int64(0x431d67c4, -1676669620),
-new int64(0x4cc5d4be, -885112138), new int64(0x597f299c, -60457430),
-new int64(0x5fcb6fab, 0x3ad6faec), new int64(0x6c44198c, 0x4a475817));
-  }
-
-  //Initial hash values
-  var H = new Array(
-new int64(0x6a09e667, -205731576),
-new int64(-1150833019, -2067093701),
-new int64(0x3c6ef372, -23791573),
-new int64(-1521486534, 0x5f1d36f1),
-new int64(0x510e527f, -1377402159),
-new int64(-1694144372, 0x2b3e6c1f),
-new int64(0x1f83d9ab, -79577749),
-new int64(0x5be0cd19, 0x137e2179));
-
-  var T1 = new int64(0, 0),
-    T2 = new int64(0, 0),
-    a = new int64(0,0),
-    b = new int64(0,0),
-    c = new int64(0,0),
-    d = new int64(0,0),
-    e = new int64(0,0),
-    f = new int64(0,0),
-    g = new int64(0,0),
-    h = new int64(0,0),
-    //Temporary variables not specified by the document
-    s0 = new int64(0, 0),
-    s1 = new int64(0, 0),
-    Ch = new int64(0, 0),
-    Maj = new int64(0, 0),
-    r1 = new int64(0, 0),
-    r2 = new int64(0, 0),
-    r3 = new int64(0, 0);
-  var j, i;
-  var W = new Array(80);
-  for(i=0; i<80; i++)
-    W[i] = new int64(0, 0);
-
-  // append padding to the source string. The format is described in the FIPS.
-  x[len >> 5] |= 0x80 << (24 - (len & 0x1f));
-  x[((len + 128 >> 10)<< 5) + 31] = len;
-
-  for(i = 0; i<x.length; i+=32) //32 dwords is the block size
-  {
-    int64copy(a, H[0]);
-    int64copy(b, H[1]);
-    int64copy(c, H[2]);
-    int64copy(d, H[3]);
-    int64copy(e, H[4]);
-    int64copy(f, H[5]);
-    int64copy(g, H[6]);
-    int64copy(h, H[7]);
-
-    for(j=0; j<16; j++)
-    {
-        W[j].h = x[i + 2*j];
-        W[j].l = x[i + 2*j + 1];
-    }
-
-    for(j=16; j<80; j++)
-    {
-      //sigma1
-      int64rrot(r1, W[j-2], 19);
-      int64revrrot(r2, W[j-2], 29);
-      int64shr(r3, W[j-2], 6);
-      s1.l = r1.l ^ r2.l ^ r3.l;
-      s1.h = r1.h ^ r2.h ^ r3.h;
-      //sigma0
-      int64rrot(r1, W[j-15], 1);
-      int64rrot(r2, W[j-15], 8);
-      int64shr(r3, W[j-15], 7);
-      s0.l = r1.l ^ r2.l ^ r3.l;
-      s0.h = r1.h ^ r2.h ^ r3.h;
-
-      int64add4(W[j], s1, W[j-7], s0, W[j-16]);
-    }
-
-    for(j = 0; j < 80; j++)
-    {
-      //Ch
-      Ch.l = (e.l & f.l) ^ (~e.l & g.l);
-      Ch.h = (e.h & f.h) ^ (~e.h & g.h);
-
-      //Sigma1
-      int64rrot(r1, e, 14);
-      int64rrot(r2, e, 18);
-      int64revrrot(r3, e, 9);
-      s1.l = r1.l ^ r2.l ^ r3.l;
-      s1.h = r1.h ^ r2.h ^ r3.h;
-
-      //Sigma0
-      int64rrot(r1, a, 28);
-      int64revrrot(r2, a, 2);
-      int64revrrot(r3, a, 7);
-      s0.l = r1.l ^ r2.l ^ r3.l;
-      s0.h = r1.h ^ r2.h ^ r3.h;
-
-      //Maj
-      Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l);
-      Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h);
-
-      int64add5(T1, h, s1, Ch, sha512_k[j], W[j]);
-      int64add(T2, s0, Maj);
-
-      int64copy(h, g);
-      int64copy(g, f);
-      int64copy(f, e);
-      int64add(e, d, T1);
-      int64copy(d, c);
-      int64copy(c, b);
-      int64copy(b, a);
-      int64add(a, T1, T2);
-    }
-    int64add(H[0], H[0], a);
-    int64add(H[1], H[1], b);
-    int64add(H[2], H[2], c);
-    int64add(H[3], H[3], d);
-    int64add(H[4], H[4], e);
-    int64add(H[5], H[5], f);
-    int64add(H[6], H[6], g);
-    int64add(H[7], H[7], h);
-  }
-
-  //represent the hash as an array of 32-bit dwords
-  var hash = new Array(16);
-  for(i=0; i<8; i++)
-  {
-    hash[2*i] = H[i].h;
-    hash[2*i + 1] = H[i].l;
-  }
-  return hash;
-}
-
-//A constructor for 64-bit numbers
-function int64(h, l)
-{
-  this.h = h;
-  this.l = l;
-  //this.toString = int64toString;
-}
-
-//Copies src into dst, assuming both are 64-bit numbers
-function int64copy(dst, src)
-{
-  dst.h = src.h;
-  dst.l = src.l;
-}
-
-//Right-rotates a 64-bit number by shift
-//Won't handle cases of shift>=32
-//The function revrrot() is for that
-function int64rrot(dst, x, shift)
-{
-    dst.l = (x.l >>> shift) | (x.h << (32-shift));
-    dst.h = (x.h >>> shift) | (x.l << (32-shift));
-}
-
-//Reverses the dwords of the source and then rotates right by shift.
-//This is equivalent to rotation by 32+shift
-function int64revrrot(dst, x, shift)
-{
-    dst.l = (x.h >>> shift) | (x.l << (32-shift));
-    dst.h = (x.l >>> shift) | (x.h << (32-shift));
-}
-
-//Bitwise-shifts right a 64-bit number by shift
-//Won't handle shift>=32, but it's never needed in SHA512
-function int64shr(dst, x, shift)
-{
-    dst.l = (x.l >>> shift) | (x.h << (32-shift));
-    dst.h = (x.h >>> shift);
-}
-
-//Adds two 64-bit numbers
-//Like the original implementation, does not rely on 32-bit operations
-function int64add(dst, x, y)
-{
-   var w0 = (x.l & 0xffff) + (y.l & 0xffff);
-   var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16);
-   var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16);
-   var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16);
-   dst.l = (w0 & 0xffff) | (w1 << 16);
-   dst.h = (w2 & 0xffff) | (w3 << 16);
-}
-
-//Same, except with 4 addends. Works faster than adding them one by one.
-function int64add4(dst, a, b, c, d)
-{
-   var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff);
-   var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16);
-   var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16);
-   var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16);
-   dst.l = (w0 & 0xffff) | (w1 << 16);
-   dst.h = (w2 & 0xffff) | (w3 << 16);
-}
-
-//Same, except with 5 addends
-function int64add5(dst, a, b, c, d, e)
-{
-   var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff);
-   var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16);
-   var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16);
-   var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16);
-   dst.l = (w0 & 0xffff) | (w1 << 16);
-   dst.h = (w2 & 0xffff) | (w3 << 16);
-}
-/*
- * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
- * Digest Algorithm, as defined in RFC 1321.
- * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for more info.
- */
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0;   /* hex output format. 0 - lowercase; 1 - uppercase        */
-var b64pad  = "";  /* base-64 pad character. "=" for strict RFC compliance   */
-
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function hex_md5(s)    { return rstr2hex(rstr_md5(str2rstr_utf8(s))); }
-function b64_md5(s)    { return rstr2b64(rstr_md5(str2rstr_utf8(s))); }
-function any_md5(s, e) { return rstr2any(rstr_md5(str2rstr_utf8(s)), e); }
-function hex_hmac_md5(k, d)
-  { return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function b64_hmac_md5(k, d)
-  { return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function any_hmac_md5(k, d, e)
-  { return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
-
-/*
- * Perform a simple self-test to see if the VM is working
- */
-function md5_vm_test()
-{
-  return hex_md5("abc").toLowerCase() == "900150983cd24fb0d6963f7d28e17f72";
-}
-
-/*
- * Calculate the MD5 of a raw string
- */
-function rstr_md5(s)
-{
-  return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
-}
-
-/*
- * Calculate the HMAC-MD5, of a key and some data (raw strings)
- */
-function rstr_hmac_md5(key, data)
-{
-  var bkey = rstr2binl(key);
-  if(bkey.length > 16) bkey = binl_md5(bkey, key.length * 8);
-
-  var ipad = Array(16), opad = Array(16);
-  for(var i = 0; i < 16; i++)
-  {
-    ipad[i] = bkey[i] ^ 0x36363636;
-    opad[i] = bkey[i] ^ 0x5C5C5C5C;
-  }
-
-  var hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
-  return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));
-}
-
-/*
- * Convert a raw string to a hex string
- */
-function rstr2hex(input)
-{
-  try { hexcase } catch(e) { hexcase=0; }
-  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
-  var output = "";
-  var x;
-  for(var i = 0; i < input.length; i++)
-  {
-    x = input.charCodeAt(i);
-    output += hex_tab.charAt((x >>> 4) & 0x0F)
-           +  hex_tab.charAt( x        & 0x0F);
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to a base-64 string
- */
-function rstr2b64(input)
-{
-  try { b64pad } catch(e) { b64pad=''; }
-  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-  var output = "";
-  var len = input.length;
-  for(var i = 0; i < len; i += 3)
-  {
-    var triplet = (input.charCodeAt(i) << 16)
-                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
-                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
-    for(var j = 0; j < 4; j++)
-    {
-      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
-      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
-    }
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to an arbitrary string encoding
- */
-function rstr2any(input, encoding)
-{
-  var divisor = encoding.length;
-  var i, j, q, x, quotient;
-
-  /* Convert to an array of 16-bit big-endian values, forming the dividend */
-  var dividend = Array(Math.ceil(input.length / 2));
-  for(i = 0; i < dividend.length; i++)
-  {
-    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
-  }
-
-  /*
-   * Repeatedly perform a long division. The binary array forms the dividend,
-   * the length of the encoding is the divisor. Once computed, the quotient
-   * forms the dividend for the next step. All remainders are stored for later
-   * use.
-   */
-  var full_length = Math.ceil(input.length * 8 /
-                                    (Math.log(encoding.length) / Math.log(2)));
-  var remainders = Array(full_length);
-  for(j = 0; j < full_length; j++)
-  {
-    quotient = Array();
-    x = 0;
-    for(i = 0; i < dividend.length; i++)
-    {
-      x = (x << 16) + dividend[i];
-      q = Math.floor(x / divisor);
-      x -= q * divisor;
-      if(quotient.length > 0 || q > 0)
-        quotient[quotient.length] = q;
-    }
-    remainders[j] = x;
-    dividend = quotient;
-  }
-
-  /* Convert the remainders to the output string */
-  var output = "";
-  for(i = remainders.length - 1; i >= 0; i--)
-    output += encoding.charAt(remainders[i]);
-
-  return output;
-}
-
-/*
- * Encode a string as utf-8.
- * For efficiency, this assumes the input is valid utf-16.
- */
-function str2rstr_utf8(input)
-{
-  var output = "";
-  var i = -1;
-  var x, y;
-
-  while(++i < input.length)
-  {
-    /* Decode utf-16 surrogate pairs */
-    x = input.charCodeAt(i);
-    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
-    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
-    {
-      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
-      i++;
-    }
-
-    /* Encode output as utf-8 */
-    if(x <= 0x7F)
-      output += String.fromCharCode(x);
-    else if(x <= 0x7FF)
-      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0xFFFF)
-      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0x1FFFFF)
-      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
-                                    0x80 | ((x >>> 12) & 0x3F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-  }
-  return output;
-}
-
-/*
- * Encode a string as utf-16
- */
-function str2rstr_utf16le(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
-                                  (input.charCodeAt(i) >>> 8) & 0xFF);
-  return output;
-}
-
-function str2rstr_utf16be(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
-                                   input.charCodeAt(i)        & 0xFF);
-  return output;
-}
-
-/*
- * Convert a raw string to an array of little-endian words
- * Characters >255 have their high-byte silently ignored.
- */
-function rstr2binl(input)
-{
-  var output = Array(input.length >> 2);
-  for(var i = 0; i < output.length; i++)
-    output[i] = 0;
-  for(var i = 0; i < input.length * 8; i += 8)
-    output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32);
-  return output;
-}
-
-/*
- * Convert an array of little-endian words to a string
- */
-function binl2rstr(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length * 32; i += 8)
-    output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF);
-  return output;
-}
-
-/*
- * Calculate the MD5 of an array of little-endian words, and a bit length.
- */
-function binl_md5(x, len)
-{
-  /* append padding */
-  x[len >> 5] |= 0x80 << ((len) % 32);
-  x[(((len + 64) >>> 9) << 4) + 14] = len;
-
-  var a =  1732584193;
-  var b = -271733879;
-  var c = -1732584194;
-  var d =  271733878;
-
-  for(var i = 0; i < x.length; i += 16)
-  {
-    var olda = a;
-    var oldb = b;
-    var oldc = c;
-    var oldd = d;
-
-    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
-    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
-    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
-    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
-    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
-    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
-    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
-    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
-    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
-    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
-    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
-    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
-    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
-    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
-    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
-    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);
-
-    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
-    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
-    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
-    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
-    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
-    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
-    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
-    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
-    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
-    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
-    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
-    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
-    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
-    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
-    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
-    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
-
-    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
-    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
-    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
-    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
-    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
-    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
-    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
-    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
-    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
-    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
-    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
-    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
-    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
-    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
-    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
-    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
-
-    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
-    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
-    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
-    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
-    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
-    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
-    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
-    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
-    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
-    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
-    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
-    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
-    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
-    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
-    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
-    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
-
-    a = safe_add(a, olda);
-    b = safe_add(b, oldb);
-    c = safe_add(c, oldc);
-    d = safe_add(d, oldd);
-  }
-  return Array(a, b, c, d);
-}
-
-/*
- * These functions implement the four basic operations the algorithm uses.
- */
-function md5_cmn(q, a, b, x, s, t)
-{
-  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
-}
-function md5_ff(a, b, c, d, x, s, t)
-{
-  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
-}
-function md5_gg(a, b, c, d, x, s, t)
-{
-  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
-}
-function md5_hh(a, b, c, d, x, s, t)
-{
-  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
-}
-function md5_ii(a, b, c, d, x, s, t)
-{
-  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
-}
-
-/*
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
-function safe_add(x, y)
-{
-  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
-  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
-  return (msw << 16) | (lsw & 0xFFFF);
-}
-
-/*
- * Bitwise rotate a 32-bit number to the left.
- */
-function bit_rol(num, cnt)
-{
-  return (num << cnt) | (num >>> (32 - cnt));
-}
-/*
- * A JavaScript implementation of the RIPEMD-160 Algorithm
- * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for details.
- * Also http://www.ocf.berkeley.edu/~jjlin/jsotp/
- */
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
-var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
-
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function hex_rmd160(s)    { return rstr2hex(rstr_rmd160(str2rstr_utf8(s))); }
-function b64_rmd160(s)    { return rstr2b64(rstr_rmd160(str2rstr_utf8(s))); }
-function any_rmd160(s, e) { return rstr2any(rstr_rmd160(str2rstr_utf8(s)), e); }
-function hex_hmac_rmd160(k, d)
-  { return rstr2hex(rstr_hmac_rmd160(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function b64_hmac_rmd160(k, d)
-  { return rstr2b64(rstr_hmac_rmd160(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function any_hmac_rmd160(k, d, e)
-  { return rstr2any(rstr_hmac_rmd160(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
-
-/*
- * Perform a simple self-test to see if the VM is working
- */
-function rmd160_vm_test()
-{
-  return hex_rmd160("abc").toLowerCase() == "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc";
-}
-
-/*
- * Calculate the rmd160 of a raw string
- */
-function rstr_rmd160(s)
-{
-  return binl2rstr(binl_rmd160(rstr2binl(s), s.length * 8));
-}
-
-/*
- * Calculate the HMAC-rmd160 of a key and some data (raw strings)
- */
-function rstr_hmac_rmd160(key, data)
-{
-  var bkey = rstr2binl(key);
-  if(bkey.length > 16) bkey = binl_rmd160(bkey, key.length * 8);
-
-  var ipad = Array(16), opad = Array(16);
-  for(var i = 0; i < 16; i++)
-  {
-    ipad[i] = bkey[i] ^ 0x36363636;
-    opad[i] = bkey[i] ^ 0x5C5C5C5C;
-  }
-
-  var hash = binl_rmd160(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
-  return binl2rstr(binl_rmd160(opad.concat(hash), 512 + 160));
-}
-
-/*
- * Convert a raw string to a hex string
- */
-function rstr2hex(input)
-{
-  try { hexcase } catch(e) { hexcase=0; }
-  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
-  var output = "";
-  var x;
-  for(var i = 0; i < input.length; i++)
-  {
-    x = input.charCodeAt(i);
-    output += hex_tab.charAt((x >>> 4) & 0x0F)
-           +  hex_tab.charAt( x        & 0x0F);
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to a base-64 string
- */
-function rstr2b64(input)
-{
-  try { b64pad } catch(e) { b64pad=''; }
-  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-  var output = "";
-  var len = input.length;
-  for(var i = 0; i < len; i += 3)
-  {
-    var triplet = (input.charCodeAt(i) << 16)
-                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
-                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
-    for(var j = 0; j < 4; j++)
-    {
-      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
-      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
-    }
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to an arbitrary string encoding
- */
-function rstr2any(input, encoding)
-{
-  var divisor = encoding.length;
-  var remainders = Array();
-  var i, q, x, quotient;
-
-  /* Convert to an array of 16-bit big-endian values, forming the dividend */
-  var dividend = Array(Math.ceil(input.length / 2));
-  for(i = 0; i < dividend.length; i++)
-  {
-    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
-  }
-
-  /*
-   * Repeatedly perform a long division. The binary array forms the dividend,
-   * the length of the encoding is the divisor. Once computed, the quotient
-   * forms the dividend for the next step. We stop when the dividend is zero.
-   * All remainders are stored for later use.
-   */
-  while(dividend.length > 0)
-  {
-    quotient = Array();
-    x = 0;
-    for(i = 0; i < dividend.length; i++)
-    {
-      x = (x << 16) + dividend[i];
-      q = Math.floor(x / divisor);
-      x -= q * divisor;
-      if(quotient.length > 0 || q > 0)
-        quotient[quotient.length] = q;
-    }
-    remainders[remainders.length] = x;
-    dividend = quotient;
-  }
-
-  /* Convert the remainders to the output string */
-  var output = "";
-  for(i = remainders.length - 1; i >= 0; i--)
-    output += encoding.charAt(remainders[i]);
-
-  /* Append leading zero equivalents */
-  var full_length = Math.ceil(input.length * 8 /
-                                    (Math.log(encoding.length) / Math.log(2)))
-  for(i = output.length; i < full_length; i++)
-    output = encoding[0] + output;
-
-  return output;
-}
-
-/*
- * Encode a string as utf-8.
- * For efficiency, this assumes the input is valid utf-16.
- */
-function str2rstr_utf8(input)
-{
-  var output = "";
-  var i = -1;
-  var x, y;
-
-  while(++i < input.length)
-  {
-    /* Decode utf-16 surrogate pairs */
-    x = input.charCodeAt(i);
-    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
-    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
-    {
-      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
-      i++;
-    }
-
-    /* Encode output as utf-8 */
-    if(x <= 0x7F)
-      output += String.fromCharCode(x);
-    else if(x <= 0x7FF)
-      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0xFFFF)
-      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0x1FFFFF)
-      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
-                                    0x80 | ((x >>> 12) & 0x3F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-  }
-  return output;
-}
-
-/*
- * Encode a string as utf-16
- */
-function str2rstr_utf16le(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
-                                  (input.charCodeAt(i) >>> 8) & 0xFF);
-  return output;
-}
-
-function str2rstr_utf16be(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
-                                   input.charCodeAt(i)        & 0xFF);
-  return output;
-}
-
-/*
- * Convert a raw string to an array of little-endian words
- * Characters >255 have their high-byte silently ignored.
- */
-function rstr2binl(input)
-{
-  var output = Array(input.length >> 2);
-  for(var i = 0; i < output.length; i++)
-    output[i] = 0;
-  for(var i = 0; i < input.length * 8; i += 8)
-    output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32);
-  return output;
-}
-
-/*
- * Convert an array of little-endian words to a string
- */
-function binl2rstr(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length * 32; i += 8)
-    output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF);
-  return output;
-}
-
-/*
- * Calculate the RIPE-MD160 of an array of little-endian words, and a bit length.
- */
-function binl_rmd160(x, len)
-{
-  /* append padding */
-  x[len >> 5] |= 0x80 << (len % 32);
-  x[(((len + 64) >>> 9) << 4) + 14] = len;
-
-  var h0 = 0x67452301;
-  var h1 = 0xefcdab89;
-  var h2 = 0x98badcfe;
-  var h3 = 0x10325476;
-  var h4 = 0xc3d2e1f0;
-
-  for (var i = 0; i < x.length; i += 16) {
-    var T;
-    var A1 = h0, B1 = h1, C1 = h2, D1 = h3, E1 = h4;
-    var A2 = h0, B2 = h1, C2 = h2, D2 = h3, E2 = h4;
-    for (var j = 0; j <= 79; ++j) {
-      T = safe_add(A1, rmd160_f(j, B1, C1, D1));
-      T = safe_add(T, x[i + rmd160_r1[j]]);
-      T = safe_add(T, rmd160_K1(j));
-      T = safe_add(bit_rol(T, rmd160_s1[j]), E1);
-      A1 = E1; E1 = D1; D1 = bit_rol(C1, 10); C1 = B1; B1 = T;
-      T = safe_add(A2, rmd160_f(79-j, B2, C2, D2));
-      T = safe_add(T, x[i + rmd160_r2[j]]);
-      T = safe_add(T, rmd160_K2(j));
-      T = safe_add(bit_rol(T, rmd160_s2[j]), E2);
-      A2 = E2; E2 = D2; D2 = bit_rol(C2, 10); C2 = B2; B2 = T;
-    }
-    T = safe_add(h1, safe_add(C1, D2));
-    h1 = safe_add(h2, safe_add(D1, E2));
-    h2 = safe_add(h3, safe_add(E1, A2));
-    h3 = safe_add(h4, safe_add(A1, B2));
-    h4 = safe_add(h0, safe_add(B1, C2));
-    h0 = T;
-  }
-  return [h0, h1, h2, h3, h4];
-}
-
-function rmd160_f(j, x, y, z)
-{
-  return ( 0 <= j && j <= 15) ? (x ^ y ^ z) :
-         (16 <= j && j <= 31) ? (x & y) | (~x & z) :
-         (32 <= j && j <= 47) ? (x | ~y) ^ z :
-         (48 <= j && j <= 63) ? (x & z) | (y & ~z) :
-         (64 <= j && j <= 79) ? x ^ (y | ~z) :
-         "rmd160_f: j out of range";
-}
-function rmd160_K1(j)
-{
-  return ( 0 <= j && j <= 15) ? 0x00000000 :
-         (16 <= j && j <= 31) ? 0x5a827999 :
-         (32 <= j && j <= 47) ? 0x6ed9eba1 :
-         (48 <= j && j <= 63) ? 0x8f1bbcdc :
-         (64 <= j && j <= 79) ? 0xa953fd4e :
-         "rmd160_K1: j out of range";
-}
-function rmd160_K2(j)
-{
-  return ( 0 <= j && j <= 15) ? 0x50a28be6 :
-         (16 <= j && j <= 31) ? 0x5c4dd124 :
-         (32 <= j && j <= 47) ? 0x6d703ef3 :
-         (48 <= j && j <= 63) ? 0x7a6d76e9 :
-         (64 <= j && j <= 79) ? 0x00000000 :
-         "rmd160_K2: j out of range";
-}
-var rmd160_r1 = [
-   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
-   7,  4, 13,  1, 10,  6, 15,  3, 12,  0,  9,  5,  2, 14, 11,  8,
-   3, 10, 14,  4,  9, 15,  8,  1,  2,  7,  0,  6, 13, 11,  5, 12,
-   1,  9, 11, 10,  0,  8, 12,  4, 13,  3,  7, 15, 14,  5,  6,  2,
-   4,  0,  5,  9,  7, 12,  2, 10, 14,  1,  3,  8, 11,  6, 15, 13
-];
-var rmd160_r2 = [
-   5, 14,  7,  0,  9,  2, 11,  4, 13,  6, 15,  8,  1, 10,  3, 12,
-   6, 11,  3,  7,  0, 13,  5, 10, 14, 15,  8, 12,  4,  9,  1,  2,
-  15,  5,  1,  3,  7, 14,  6,  9, 11,  8, 12,  2, 10,  0,  4, 13,
-   8,  6,  4,  1,  3, 11, 15,  0,  5, 12,  2, 13,  9,  7, 10, 14,
-  12, 15, 10,  4,  1,  5,  8,  7,  6,  2, 13, 14,  0,  3,  9, 11
-];
-var rmd160_s1 = [
-  11, 14, 15, 12,  5,  8,  7,  9, 11, 13, 14, 15,  6,  7,  9,  8,
-   7,  6,  8, 13, 11,  9,  7, 15,  7, 12, 15,  9, 11,  7, 13, 12,
-  11, 13,  6,  7, 14,  9, 13, 15, 14,  8, 13,  6,  5, 12,  7,  5,
-  11, 12, 14, 15, 14, 15,  9,  8,  9, 14,  5,  6,  8,  6,  5, 12,
-   9, 15,  5, 11,  6,  8, 13, 12,  5, 12, 13, 14, 11,  8,  5,  6
-];
-var rmd160_s2 = [
-   8,  9,  9, 11, 13, 15, 15,  5,  7,  7,  8, 11, 14, 14, 12,  6,
-   9, 13, 15,  7, 12,  8,  9, 11,  7,  7, 12,  7,  6, 15, 13, 11,
-   9,  7, 15, 11,  8,  6,  6, 14, 12, 13,  5, 14, 13, 13,  7,  5,
-  15,  5,  8, 11, 14, 14,  6, 14,  6,  9, 12,  9, 12,  5, 15,  8,
-   8,  5, 12,  9, 12,  5, 14,  6,  8, 13,  6,  5, 15, 13, 11, 11
-];
-
-/*
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
-function safe_add(x, y)
-{
-  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
-  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
-  return (msw << 16) | (lsw & 0xFFFF);
-}
-
-/*
- * Bitwise rotate a 32-bit number to the left.
- */
-function bit_rol(num, cnt)
-{
-  return (num << cnt) | (num >>> (32 - cnt));
-}
-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;
-    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;
-}
-// 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
- * @param s: the string to encode
- * @param n: the size in byte
- */ 
-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
- * @returns {RSAKey}
- */
-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
- * @param N
- * @param E
- * @returns {RSASetPublic}
- */
-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)
- * @param x
- * @returns 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);	// p1 = p - 1
-    var q1 = this.q.subtract(BigInteger.ONE);	// q1 = q - 1
-    var phi = p1.multiply(q1);
-    if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
-      this.n = this.p.multiply(this.q);	// this.n = p * q
-      this.d = ee.modInverse(phi);	// this.d = 
-      this.dmp1 = this.d.mod(p1);	// this.dmp1 = d mod (p - 1)
-      this.dmq1 = this.d.mod(q1);	// this.dmq1 = d mod (q - 1)
-      this.coeff = this.q.modInverse(this.p);	// this.coeff = (q ^ -1) mod p
-      break;
-    }
-  }
-}
-
-/**
- * Perform raw private operation on "x": return x^d (mod n)
- * @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); // xp=cp?
-  var xq = x.mod(this.q).modPow(this.dmq1, this.q); // xq=cq?
-
-  while(xp.compareTo(xq) < 0)
-    xp = xp.add(this.p);
-  // NOTE:
-  // xp.subtract(xq) => cp -cq
-  // xp.subtract(xq).multiply(this.coeff).mod(this.p) => (cp - cq) * u mod p = h
-  // xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq) => cq + (h * q) = M
-  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.b64_decrypt = RSAB64Decrypt;
-/*! rsapem-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
- */
-//
-// rsa-pem.js - adding function for reading/writing PKCS#1 PEM private key
-//              to RSAKey class.
-//
-// version: 1.1 (2012-May-10)
-//
-// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
-//
-// This software is licensed under the terms of the MIT License.
-// http://kjur.github.com/jsrsasign/license/
-//
-// 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 _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey) {
-  var a = new Array();
-  var v1 = ASN1HEX.getStartPosOfV_AtObj(hPrivateKey, 0);
-  var n1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, v1);
-  var e1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, n1);
-  var d1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, e1);
-  var p1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, d1);
-  var q1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, p1);
-  var dp1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, q1);
-  var dq1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, dp1);
-  var co1 = ASN1HEX.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 =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[0]);
-  var n =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[1]);
-  var e =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[2]);
-  var d =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[3]);
-  var p =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[4]);
-  var q =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[5]);
-  var dp = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[6]);
-  var dq = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[7]);
-  var co = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[8]);
-  var a = new Array();
-  a.push(v, n, e, d, p, q, dp, dq, co);
-  return a;
-}
-
-/**
- * read PKCS#1 private key from a string
- * @name readPrivateKeyFromPEMString
- * @memberOf RSAKey#
- * @function
- * @param {String} keyPEM string of PKCS#1 private key.
- */
-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]);
-}
-
-RSAKey.prototype.readPrivateKeyFromPEMString = _rsapem_readPrivateKeyFromPEMString;
-/*! rsasign-1.2.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
- */
-//
-// rsa-sign.js - adding signing functions to RSAKey class.
-//
-//
-// version: 1.2.1 (08 May 2012)
-//
-// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
-//
-// This software is licensed under the terms of the MIT License.
-// http://kjur.github.com/jsrsasign/license/
-//
-// 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
-
-/**
- * @property {Dictionary} _RSASIGN_DIHEAD
- * @description Array of head part of hexadecimal DigestInfo value for hash algorithms.
- * You can add any DigestInfo hash algorith for signing.
- * See PKCS#1 v2.1 spec (p38).
- */
-var _RSASIGN_DIHEAD = [];
-_RSASIGN_DIHEAD['sha1'] =      "3021300906052b0e03021a05000414";
-_RSASIGN_DIHEAD['sha256'] =    "3031300d060960864801650304020105000420";
-_RSASIGN_DIHEAD['sha384'] =    "3041300d060960864801650304020205000430";
-_RSASIGN_DIHEAD['sha512'] =    "3051300d060960864801650304020305000440";
-_RSASIGN_DIHEAD['md2'] =       "3020300c06082a864886f70d020205000410";
-_RSASIGN_DIHEAD['md5'] =       "3020300c06082a864886f70d020505000410";
-_RSASIGN_DIHEAD['ripemd160'] = "3021300906052b2403020105000414";
-
-/**
- * @property {Dictionary} _RSASIGN_HASHHEXFUNC
- * @description Array of functions which calculate hash and returns it as hexadecimal.
- * You can add any hash algorithm implementations.
- */
-var _RSASIGN_HASHHEXFUNC = [];
-_RSASIGN_HASHHEXFUNC['sha1'] =      function(s){return hex_sha1(s);};  // http://pajhome.org.uk/crypt/md5/md5.html
-_RSASIGN_HASHHEXFUNC['sha256'] =    function(s){return hex_sha256(s);} // http://pajhome.org.uk/crypt/md5/md5.html
-_RSASIGN_HASHHEXFUNC['sha512'] =    function(s){return hex_sha512(s);} // http://pajhome.org.uk/crypt/md5/md5.html
-_RSASIGN_HASHHEXFUNC['md5'] =       function(s){return hex_md5(s);};   // http://pajhome.org.uk/crypt/md5/md5.html
-_RSASIGN_HASHHEXFUNC['ripemd160'] = function(s){return hex_rmd160(s);};   // http://pajhome.org.uk/crypt/md5/md5.html
-
-//@author axelcdv
-var _RSASIGN_HASHBYTEFUNC = [];
-_RSASIGN_HASHBYTEFUNC['sha256'] = 	function(byteArray){return hex_sha256_from_bytes(byteArray);};
-
-//_RSASIGN_HASHHEXFUNC['sha1'] =   function(s){return sha1.hex(s);}   // http://user1.matsumoto.ne.jp/~goma/js/hash.html
-//_RSASIGN_HASHHEXFUNC['sha256'] = function(s){return sha256.hex;}    // http://user1.matsumoto.ne.jp/~goma/js/hash.html
-
-var _RE_HEXDECONLY = new RegExp("");
-_RE_HEXDECONLY.compile("[^0-9a-f]", "gi");
-
-// ========================================================================
-// 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";
-  }
-  sPaddedMessageHex = sHead + sMid + sTail;
-  return sPaddedMessageHex;
-}
-
-
-//@author: Meki Cheraoui
-function _rsasign_getHexPaddedDigestInfoForStringHEX(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";
-  }
-  sPaddedMessageHex = sHead + sMid + sTail;
-  return sPaddedMessageHex;
-}
-
-/**
- * Apply padding, then computes the hash of the given byte array, according to the key size and with the hash algorithm
- * @param byteArray (byte[])
- * @param keySize (int)
- * @param hashAlg the hash algorithm to apply (string)
- * @return the hash of byteArray
- */
-function _rsasign_getHexPaddedDigestInfoForByteArray(byteArray, keySize, hashAlg){
-	var pmStrLen = keySize / 4;
-	var hashFunc = _RSASIGN_HASHBYTEFUNC[hashAlg];
-	var sHashHex = hashFunc(byteArray); //returns hex hash
-	
-	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";
-	  }
-	  sPaddedMessageHex = sHead + sMid + sTail;
-	  return sPaddedMessageHex;
-}
-
-function _zeroPaddingOfSignature(hex, bitLength) {
-  var s = "";
-  var nZero = bitLength / 4 - hex.length;
-  for (var i = 0; i < nZero; i++) {
-    s = s + "0";
-  }
-  return s + hex;
-}
-
-/**
- * sign for a message string with RSA private key.<br/>
- * @name signString
- * @memberOf RSAKey#
- * @function
- * @param {String} s message string to be signed.
- * @param {String} hashAlg hash algorithm name for signing.<br/>
- * @return returns hexadecimal string of signature value.
- */
-function _rsasign_signString(s, hashAlg) {
-  //alert("this.n.bitLength() = " + this.n.bitLength());
-  var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), hashAlg);
-  var biPaddedMessage = parseBigInt(hPM, 16);
-  var biSign = this.doPrivate(biPaddedMessage);
-  var hexSign = biSign.toString(16);
-  return _zeroPaddingOfSignature(hexSign, this.n.bitLength());
-}
-
-//@author: ucla-cs
-function _rsasign_signStringHEX(s, hashAlg) {
-  //alert("this.n.bitLength() = " + this.n.bitLength());
-  var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), hashAlg);
-  var biPaddedMessage = parseBigInt(hPM, 16);
-  var biSign = this.doPrivate(biPaddedMessage);
-  var hexSign = biSign.toString(16);
-  return _zeroPaddingOfSignature(hexSign, this.n.bitLength());
-}
-
-
-/**
- * Sign a message byteArray with an RSA private key
- * @name signByteArray
- * @memberOf RSAKey#
- * @function
- * @param {byte[]} byteArray
- * @param {Sring} hashAlg the hash algorithm to apply
- * @param {RSAKey} rsa key to sign with: hack because the context is lost here
- * @return hexadecimal string of signature value
- */
-function _rsasign_signByteArray(byteArray, hashAlg, rsaKey) {
-	var hPM = _rsasign_getHexPaddedDigestInfoForByteArray(byteArray, rsaKey.n.bitLength(), hashAlg); ///hack because the context is lost here
-	var biPaddedMessage = parseBigInt(hPM, 16);
-	var biSign = rsaKey.doPrivate(biPaddedMessage); //hack because the context is lost here
-	var hexSign = biSign.toString(16);
-	return _zeroPaddingOfSignature(hexSign, rsaKey.n.bitLength()); //hack because the context is lost here
-}
-
-/**
- * Sign a byte array with the Sha-256 algorithm
- * @param {byte[]} byteArray
- * @return hexadecimal string of signature value
- */
-function _rsasign_signByteArrayWithSHA256(byteArray){
-	return _rsasign_signByteArray(byteArray, 'sha256', this); //Hack because the context is lost in the next function
-}
-
-
-function _rsasign_signStringWithSHA1(s) {
-  return _rsasign_signString(s, 'sha1');
-}
-
-function _rsasign_signStringWithSHA256(s) {
-  return _rsasign_signString(s, 'sha256');
-}
-
-// ========================================================================
-// 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;
-}
-
-/**
- * verifies a sigature for a message string with RSA public key.<br/>
- * @name verifyString
- * @memberOf RSAKey#
- * @function
- * @param {String} sMsg message string to be verified.
- * @param {String} hSig hexadecimal string of siganture.<br/>
- *                 non-hexadecimal charactors including new lines will be ignored.
- * @return returns 1 if valid, otherwise 0
- */
-function _rsasign_verifyString(sMsg, hSig) {
-  hSig = hSig.replace(_RE_HEXDECONLY, '');
-  
-  if(LOG>3)console.log('n is '+this.n);
-  if(LOG>3)console.log('e is '+this.e);
-  
-  if (hSig.length != this.n.bitLength() / 4) return 0;
-  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);
-}
-
-/**
- * verifies a sigature for a message byte array with RSA public key.<br/>
- * @name verifyByteArray
- * @memberOf RSAKey#
- * @function
- * @param {byte[]} byteArray message byte array to be verified.
- * @param {String} hSig hexadecimal string of signature.<br/>
- *                 non-hexadecimal charactors including new lines will be ignored.
- * @return returns 1 if valid, otherwise 0 
- */
-function _rsasign_verifyByteArray(byteArray, hSig) {
-	hSig = hSig.replace(_RE_HEXDECONLY, '');
-	  
-	  if(LOG>3)console.log('n is '+this.n);
-	  if(LOG>3)console.log('e is '+this.e);
-	  
-	  if (hSig.length != this.n.bitLength() / 4) return 0;
-	  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_HASHBYTEFUNC[algName];
-	  var msgHashValue = ff(byteArray);
-	  return (diHashValue == msgHashValue);
-}
-
-RSAKey.prototype.signString = _rsasign_signString;
-
-RSAKey.prototype.signByteArray = _rsasign_signByteArray; //@author axelcdv
-RSAKey.prototype.signByteArrayWithSHA256 = _rsasign_signByteArrayWithSHA256; //@author axelcdv
-
-RSAKey.prototype.signStringWithSHA1 = _rsasign_signStringWithSHA1;
-RSAKey.prototype.signStringWithSHA256 = _rsasign_signStringWithSHA256;
-RSAKey.prototype.sign = _rsasign_signString;
-RSAKey.prototype.signWithSHA1 = _rsasign_signStringWithSHA1;
-RSAKey.prototype.signWithSHA256 = _rsasign_signStringWithSHA256;
-
-
-/*RSAKey.prototype.signStringHEX = _rsasign_signStringHEX;
-RSAKey.prototype.signStringWithSHA1HEX = _rsasign_signStringWithSHA1HEX;
-RSAKey.prototype.signStringWithSHA256HEX = _rsasign_signStringWithSHA256HEX;
-RSAKey.prototype.signHEX = _rsasign_signStringHEX;
-RSAKey.prototype.signWithSHA1HEX = _rsasign_signStringWithSHA1HEX;
-RSAKey.prototype.signWithSHA256HEX = _rsasign_signStringWithSHA256HEX;
-*/
-
-RSAKey.prototype.verifyByteArray = _rsasign_verifyByteArray;
-RSAKey.prototype.verifyString = _rsasign_verifyString;
-RSAKey.prototype.verifyHexSignatureForMessage = _rsasign_verifyHexSignatureForMessage;
-RSAKey.prototype.verify = _rsasign_verifyString;
-RSAKey.prototype.verifyHexSignatureForByteArrayMessage = _rsasign_verifyHexSignatureForMessage;
-
-/*
-RSAKey.prototype.verifyStringHEX = _rsasign_verifyStringHEX;
-RSAKey.prototype.verifyHexSignatureForMessageHEX = _rsasign_verifyHexSignatureForMessageHEX;
-RSAKey.prototype.verifyHEX = _rsasign_verifyStringHEX;
-RSAKey.prototype.verifyHexSignatureForByteArrayMessageHEX = _rsasign_verifyHexSignatureForMessageHEX;
-*/
-	
-	
-/**
- * @name RSAKey
- * @class
- * @description Tom Wu's RSA Key class and extension
- */
-/*! asn1hex-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
- */
-//
-// asn1hex.js - Hexadecimal represented ASN.1 string library
-//
-// version: 1.1 (09-May-2012)
-//
-// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
-//
-// This software is licensed under the terms of the MIT License.
-// http://kjur.github.com/jsrsasign/license/
-//
-// 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 ...)
-//   - 
-/**
- * get byte length for ASN.1 L(length) bytes
- * @name getByteLengthOfL_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return byte length for ASN.1 L(length) bytes
- */
-function _asnhex_getByteLengthOfL_AtObj(s, pos) {
-  if (s.substring(pos + 2, pos + 3) != '8') return 1;
-  var i = parseInt(s.substring(pos + 3, pos + 4));
-  if (i == 0) return -1; 		// length octet '80' indefinite length
-  if (0 < i && i < 10) return i + 1;	// including '8?' octet;
-  return -2;				// malformed format
-}
-
-
-/**
- * get hexadecimal string for ASN.1 L(length) bytes
- * @name getHexOfL_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return {String} hexadecimal string for ASN.1 L(length) bytes
- */
-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
-/**
- * get integer value of ASN.1 length for ASN.1 data
- * @name getIntOfL_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return ASN.1 L(length) integer value
- */
-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'.
- * @name getStartPosOfV_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- */
-function _asnhex_getStartPosOfV_AtObj(s, pos) {
-  var l_len = _asnhex_getByteLengthOfL_AtObj(s, pos);
-  if (l_len < 0) return l_len;
-  return pos + (l_len + 1) * 2;
-}
-
-/**
- * get hexadecimal string of ASN.1 V(value)
- * @name getHexOfV_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return {String} hexadecimal string of ASN.1 value.
- */
-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);
-}
-
-/**
- * get hexadecimal string of ASN.1 TLV at
- * @name getHexOfTLV_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return {String} hexadecimal string of ASN.1 TLV.
- * @since 1.1
- */
-function _asnhex_getHexOfTLV_AtObj(s, pos) {
-  var hT = s.substr(pos, 2);
-  var hL = _asnhex_getHexOfL_AtObj(s, pos);
-  var hV = _asnhex_getHexOfV_AtObj(s, pos);
-  return hT + hL + hV;
-}
-
-/**
- * get next sibling starting index for ASN.1 object string
- * @name getPosOfNextSibling_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return next sibling starting index for ASN.1 object string
- */
-function _asnhex_getPosOfNextSibling_AtObj(s, pos) {
-  var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos);
-  var len = _asnhex_getIntOfL_AtObj(s, pos);
-  return pos1 + len * 2;
-}
-
-/**
- * get array of indexes of child ASN.1 objects
- * @name getPosArrayOfChildren_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} start string index of ASN.1 object
- * @return {Array of Number} array of indexes for childen of ASN.1 objects
- */
-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;
-}
-
-/**
- * get string index of nth child object of ASN.1 object refered by h, idx
- * @name getNthChildIndex_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} h hexadecimal string of ASN.1 DER encoded data
- * @param {Number} idx start string index of ASN.1 object
- * @param {Number} nth for child
- * @return {Number} string index of nth child.
- * @since 1.1
- */
-function _asnhex_getNthChildIndex_AtObj(h, idx, nth) {
-  var a = _asnhex_getPosArrayOfChildren_AtObj(h, idx);
-  return a[nth];
-}
-
-// ========== decendant methods ==============================
-
-/**
- * get string index of nth child object of ASN.1 object refered by h, idx
- * @name getDecendantIndexByNthList
- * @memberOf ASN1HEX
- * @function
- * @param {String} h hexadecimal string of ASN.1 DER encoded data
- * @param {Number} currentIndex start string index of ASN.1 object
- * @param {Array of Number} nthList array list of nth
- * @return {Number} string index refered by nthList
- * @since 1.1
- */
-function _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList) {
-  if (nthList.length == 0) {
-    return currentIndex;
-  }
-  var firstNth = nthList.shift();
-  var a = _asnhex_getPosArrayOfChildren_AtObj(h, currentIndex);
-  return _asnhex_getDecendantIndexByNthList(h, a[firstNth], nthList);
-}
-
-/**
- * get hexadecimal string of ASN.1 TLV refered by current index and nth index list.
- * @name getDecendantHexTLVByNthList
- * @memberOf ASN1HEX
- * @function
- * @param {String} h hexadecimal string of ASN.1 DER encoded data
- * @param {Number} currentIndex start string index of ASN.1 object
- * @param {Array of Number} nthList array list of nth
- * @return {Number} hexadecimal string of ASN.1 TLV refered by nthList
- * @since 1.1
- */
-function _asnhex_getDecendantHexTLVByNthList(h, currentIndex, nthList) {
-  var idx = _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList);
-  return _asnhex_getHexOfTLV_AtObj(h, idx);
-}
-
-/**
- * get hexadecimal string of ASN.1 V refered by current index and nth index list.
- * @name getDecendantHexVByNthList
- * @memberOf ASN1HEX
- * @function
- * @param {String} h hexadecimal string of ASN.1 DER encoded data
- * @param {Number} currentIndex start string index of ASN.1 object
- * @param {Array of Number} nthList array list of nth
- * @return {Number} hexadecimal string of ASN.1 V refered by nthList
- * @since 1.1
- */
-function _asnhex_getDecendantHexVByNthList(h, currentIndex, nthList) {
-  var idx = _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList);
-  return _asnhex_getHexOfV_AtObj(h, idx);
-}
-
-// ========== class definition ==============================
-
-/**
- * ASN.1 DER encoded hexadecimal string utility class
- * @class ASN.1 DER encoded hexadecimal string utility class
- * @author Kenji Urushima
- * @version 1.1 (09 May 2012)
- * @see <a href="http://kjur.github.com/jsrsasigns/">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a>
- * @since 1.1
- */
-function ASN1HEX() {
-  return ASN1HEX;
-}
-
-ASN1HEX.getByteLengthOfL_AtObj = _asnhex_getByteLengthOfL_AtObj;
-ASN1HEX.getHexOfL_AtObj = _asnhex_getHexOfL_AtObj;
-ASN1HEX.getIntOfL_AtObj = _asnhex_getIntOfL_AtObj;
-ASN1HEX.getStartPosOfV_AtObj = _asnhex_getStartPosOfV_AtObj;
-ASN1HEX.getHexOfV_AtObj = _asnhex_getHexOfV_AtObj;
-ASN1HEX.getHexOfTLV_AtObj = _asnhex_getHexOfTLV_AtObj;
-ASN1HEX.getPosOfNextSibling_AtObj = _asnhex_getPosOfNextSibling_AtObj;
-ASN1HEX.getPosArrayOfChildren_AtObj = _asnhex_getPosArrayOfChildren_AtObj;
-ASN1HEX.getNthChildIndex_AtObj = _asnhex_getNthChildIndex_AtObj;
-ASN1HEX.getDecendantIndexByNthList = _asnhex_getDecendantIndexByNthList;
-ASN1HEX.getDecendantHexVByNthList = _asnhex_getDecendantHexVByNthList;
-ASN1HEX.getDecendantHexTLVByNthList = _asnhex_getDecendantHexTLVByNthList;
-/*! x509-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
- */
-// 
-// x509.js - X509 class to read subject public key from certificate.
-//
-// version: 1.1 (10-May-2012)
-//
-// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
-//
-// This software is licensed under the terms of the MIT License.
-// http://kjur.github.com/jsrsasign/license
-//
-// The above copyright and license notice shall be 
-// included in all copies or substantial portions of the Software.
-// 
-
-// Depends:
-//   base64.js
-//   rsa.js
-//   asn1hex.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 = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);
-  return pTbsCert;
-}
-
-// NOTE: privateKeyUsagePeriod field of X509v2 not supported.
-// NOTE: v1 and v3 supported
-function _x509_getSubjectPublicKeyInfoPosFromCertHex(hCert) {
-  var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);
-  var a = ASN1HEX.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 = ASN1HEX.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 = ASN1HEX.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 = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, p); 
-  //var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, a[3]); 
-  if(LOG>4){
-	  console.log('a is now');
-	  console.log(a);
-  }
-  
-  //if (a.length != 2) return [];
-  if (a.length < 2) return [];
-
-  var hN = ASN1HEX.getHexOfV_AtObj(hCert, a[0]);
-  var hE = ASN1HEX.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;
-}
-
-// ===== get basic fields from hex =====================================
-/**
- * get hexadecimal string of serialNumber field of certificate.<br/>
- * @name getSerialNumberHex
- * @memberOf X509#
- * @function
- */
-function _x509_getSerialNumberHex() {
-  return ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 1]);
-}
-
-/**
- * get hexadecimal string of issuer field of certificate.<br/>
- * @name getIssuerHex
- * @memberOf X509#
- * @function
- */
-function _x509_getIssuerHex() {
-  return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]);
-}
-
-/**
- * get string of issuer field of certificate.<br/>
- * @name getIssuerString
- * @memberOf X509#
- * @function
- */
-function _x509_getIssuerString() {
-  return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]));
-}
-
-/**
- * get hexadecimal string of subject field of certificate.<br/>
- * @name getSubjectHex
- * @memberOf X509#
- * @function
- */
-function _x509_getSubjectHex() {
-  return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]);
-}
-
-/**
- * get string of subject field of certificate.<br/>
- * @name getSubjectString
- * @memberOf X509#
- * @function
- */
-function _x509_getSubjectString() {
-  return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]));
-}
-
-/**
- * get notBefore field string of certificate.<br/>
- * @name getNotBefore
- * @memberOf X509#
- * @function
- */
-function _x509_getNotBefore() {
-  var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 0]);
-  s = s.replace(/(..)/g, "%$1");
-  s = decodeURIComponent(s);
-  return s;
-}
-
-/**
- * get notAfter field string of certificate.<br/>
- * @name getNotAfter
- * @memberOf X509#
- * @function
- */
-function _x509_getNotAfter() {
-  var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 1]);
-  s = s.replace(/(..)/g, "%$1");
-  s = decodeURIComponent(s);
-  return s;
-}
-
-// ===== read certificate =====================================
-
-_x509_DN_ATTRHEX = {
-    "0603550406": "C",
-    "060355040a": "O",
-    "060355040b": "OU",
-    "0603550403": "CN",
-    "0603550405": "SN",
-    "0603550408": "ST",
-    "0603550407": "L" };
-
-function _x509_hex2dn(hDN) {
-  var s = "";
-  var a = ASN1HEX.getPosArrayOfChildren_AtObj(hDN, 0);
-  for (var i = 0; i < a.length; i++) {
-    var hRDN = ASN1HEX.getHexOfTLV_AtObj(hDN, a[i]);
-    s = s + "/" + _x509_hex2rdn(hRDN);
-  }
-  return s;
-}
-
-function _x509_hex2rdn(hRDN) {
-    var hType = ASN1HEX.getDecendantHexTLVByNthList(hRDN, 0, [0, 0]);
-    var hValue = ASN1HEX.getDecendantHexVByNthList(hRDN, 0, [0, 1]);
-    var type = "";
-    try { type = _x509_DN_ATTRHEX[hType]; } catch (ex) { type = hType; }
-    hValue = hValue.replace(/(..)/g, "%$1");
-    var value = decodeURIComponent(hValue);
-    return type + "=" + value;
-}
-
-// ===== read certificate =====================================
-
-
-/**
- * read PEM formatted X.509 certificate from string.<br/>
- * @name readCertPEM
- * @memberOf X509#
- * @function
- * @param {String} sCertPEM string for PEM formatted X.509 certificate
- */
-function _x509_readCertPEM(sCertPEM) {
-  var hCert = _x509_pemToHex(sCertPEM);
-  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
-  if(LOG>4){
-	  console.log('HEX VALUE IS ' + hCert);
-	  console.log('type of a' + typeof a);
-	  console.log('a VALUE IS ');
-	  console.log(a);
-	  console.log('a[0] VALUE IS ' + a[0]);
-	  console.log('a[1] VALUE IS ' + a[1]);
-  }
-  var rsa = new RSAKey();
-  rsa.setPublic(a[0], a[1]);
-  this.subjectPublicKeyRSA = rsa;
-  this.subjectPublicKeyRSA_hN = a[0];
-  this.subjectPublicKeyRSA_hE = a[1];
-  this.hex = hCert;
-}
-
-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];
-  this.hex = hCert;
-}
-
-/**
- * X.509 certificate class.<br/>
- * @class X.509 certificate class
- * @property {RSAKey} subjectPublicKeyRSA Tom Wu's RSAKey object
- * @property {String} subjectPublicKeyRSA_hN hexadecimal string for modulus of RSA public key
- * @property {String} subjectPublicKeyRSA_hE hexadecimal string for public exponent of RSA public key
- * @property {String} hex hexacedimal string for X.509 certificate.
- * @author Kenji Urushima
- * @version 1.0.1 (08 May 2012)
- * @see <a href="http://kjur.github.com/jsrsasigns/">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a>
- */
-function X509() {
-  this.subjectPublicKeyRSA = null;
-  this.subjectPublicKeyRSA_hN = null;
-  this.subjectPublicKeyRSA_hE = null;
-  this.hex = null;
-}
-
-X509.prototype.readCertPEM = _x509_readCertPEM;
-X509.prototype.readCertPEMWithoutRSAInit = _x509_readCertPEMWithoutRSAInit;
-X509.prototype.getSerialNumberHex = _x509_getSerialNumberHex;
-X509.prototype.getIssuerHex = _x509_getIssuerHex;
-X509.prototype.getSubjectHex = _x509_getSubjectHex;
-X509.prototype.getIssuerString = _x509_getIssuerString;
-X509.prototype.getSubjectString = _x509_getSubjectString;
-X509.prototype.getNotBefore = _x509_getNotBefore;
-X509.prototype.getNotAfter = _x509_getNotAfter;
-
-// 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;
-}
-if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
-  BigInteger.prototype.am = am2;
-  dbits = 30;
-}
-else if(j_lm && (navigator.appName != "Netscape")) {
-  BigInteger.prototype.am = am1;
-  dbits = 26;
-}
-else { // Mozilla/Netscape seems to prefer am3
-  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)
