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)
